From 8c5493f78e973fd3dc6227abc123d767c7baa953 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 25 Jan 2021 21:35:46 +0300 Subject: [PATCH 01/63] Added GravityModels, removed gravity switch - Added GravityModel - can specify gravity varying by location and time - Added GravityModelRegistry - Stored in WorldData - Removed Minecraft gravity mode --- .../client/graphics/world/LayerWorld.java | 13 +++--- .../progressia/common/world/GravityModel.java | 41 +++++++++++++++++++ .../common/world/GravityModelRegistry.java | 30 ++++++++++++++ .../progressia/common/world/WorldData.java | 16 ++++++++ .../progressia/test/LayerTestGUI.java | 11 ----- .../windcorp/progressia/test/TestContent.java | 3 ++ .../progressia/test/TestPlayerControls.java | 18 +------- .../progressia/test/gen/TestGravityModel.java | 34 +++++++++++++++ .../resources/assets/languages/en-US.lang | 1 - .../resources/assets/languages/ru-RU.lang | 1 - 10 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/GravityModel.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index 317dfa2..d8ac99a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -41,6 +41,7 @@ import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.colliders.Collider; import ru.windcorp.progressia.common.util.FloatMathUtil; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.test.CollisionModelRenderer; import ru.windcorp.progressia.test.TestPlayerControls; @@ -197,16 +198,18 @@ public class LayerWorld extends Layer { entity.getVelocity().mul((float) Math.exp(-FRICTION_COEFF / entity.getCollisionMass() * tickLength)); } - private static final float MC_g = Units.get("32 m/s^2"); - private static final float IRL_g = Units.get("9.8 m/s^2"); - private void tmp_applyGravity(EntityData entity, float tickLength) { if (ClientState.getInstance().getLocalPlayer().getEntity() == entity && tmp_testControls.isFlying()) { return; } - final float gravitationalAcceleration = tmp_testControls.useMinecraftGravity() ? MC_g : IRL_g; - entity.getVelocity().add(0, 0, -gravitationalAcceleration * tickLength); + Vec3 gravitationalAcceleration = Vectors.grab3(); + ClientState.getInstance().getWorld().getData().getGravityModel().getGravity(gravitationalAcceleration); + + gravitationalAcceleration.mul(tickLength); + entity.getVelocity().add(gravitationalAcceleration); + + Vectors.release(gravitationalAcceleration); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java new file mode 100644 index 0000000..ce21649 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java @@ -0,0 +1,41 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world; + +import glm.vec._3.Vec3; +import ru.windcorp.progressia.common.util.namespaces.Namespaced; + +public abstract class GravityModel extends Namespaced { + + public GravityModel(String id) { + super(id); + } + + public Vec3 getGravity(Vec3 output) { + if (output == null) { + output = new Vec3(); + } + + doGetGravity(output); + + return output; + } + + protected abstract void doGetGravity(Vec3 output); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java new file mode 100644 index 0000000..b48cd0c --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java @@ -0,0 +1,30 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; + +public class GravityModelRegistry extends NamespacedInstanceRegistry { + + public static final GravityModelRegistry INSTANCE = new GravityModelRegistry(); + + public static GravityModelRegistry getInstance() { + return INSTANCE; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 85c6188..6806c1b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -51,6 +51,8 @@ public class WorldData private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); + + private GravityModel gravityModel = GravityModelRegistry.getInstance().get("Test:TheGravityModel"); private float time = 0; @@ -200,6 +202,20 @@ public class WorldData return null; return block.getCollisionModel(); } + + /** + * @return the gravity model + */ + public GravityModel getGravityModel() { + return gravityModel; + } + + /** + * @param gravityModel the gravity model to set + */ + public void setGravityModel(GravityModel gravityModel) { + this.gravityModel = gravityModel; + } public Collection getListeners() { return listeners; diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java index 30cca35..fa50625 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java @@ -91,17 +91,6 @@ public class LayerTestGUI extends GUILayer { ) ); - panel.addChild( - new Label( - "GravityModeDisplay", - font, - tmp_dynFormat( - "LayerTestGUI.GravityModeDisplay", - () -> tpc.useMinecraftGravity() ? "Minecraft" : "Realistic" - ) - ) - ); - panel.addChild( new Label( "LanguageDisplay", diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 9fabd96..fe647f2 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -47,6 +47,7 @@ import ru.windcorp.progressia.common.collision.AABB; import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.comms.controls.*; import ru.windcorp.progressia.common.state.StatefulObjectRegistry.Factory; +import ru.windcorp.progressia.common.world.GravityModelRegistry; import ru.windcorp.progressia.common.world.block.*; import ru.windcorp.progressia.common.world.entity.*; import ru.windcorp.progressia.common.world.io.ChunkIO; @@ -56,6 +57,7 @@ import ru.windcorp.progressia.server.comms.controls.*; import ru.windcorp.progressia.server.world.block.*; import ru.windcorp.progressia.server.world.entity.*; import ru.windcorp.progressia.server.world.tile.*; +import ru.windcorp.progressia.test.gen.TestGravityModel; public class TestContent { @@ -423,6 +425,7 @@ public class TestContent { private static void registerMisc() { ChunkIO.registerCodec(new TestChunkCodec()); ChunkRenderOptimizerRegistry.getInstance().register("Core:SurfaceOptimizer", ChunkRenderOptimizerSurface::new); + GravityModelRegistry.getInstance().register(new TestGravityModel()); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java index 710cbc1..0a0d3d3 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java +++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java @@ -83,7 +83,6 @@ public class TestPlayerControls { private double lastSprintPress = Double.NEGATIVE_INFINITY; private boolean captureMouse = true; - private boolean useMinecraftGravity = false; private int selectedBlock = 0; private int selectedTile = 0; @@ -199,12 +198,6 @@ public class TestPlayerControls { handleCameraMode(); break; - case GLFW.GLFW_KEY_G: - if (!event.isPress()) - return false; - handleGravitySwitch(); - break; - case GLFW.GLFW_KEY_L: if (!event.isPress()) return false; @@ -269,7 +262,7 @@ public class TestPlayerControls { return; } - getEntity().getVelocity().add(0, 0, JUMP_VELOCITY * (useMinecraftGravity ? 2 : 1)); + getEntity().getVelocity().add(0, 0, JUMP_VELOCITY); } private void handleShift(int multiplier) { @@ -313,11 +306,6 @@ public class TestPlayerControls { } } - private void handleGravitySwitch() { - useMinecraftGravity = !useMinecraftGravity; - updateGUI(); - } - private void handleLanguageSwitch() { Localizer localizer = Localizer.getInstance(); if (localizer.getLanguage().equals("ru-RU")) { @@ -427,10 +415,6 @@ public class TestPlayerControls { return captureMouse; } - public boolean useMinecraftGravity() { - return useMinecraftGravity; - } - public BlockData getSelectedBlock() { return TestContent.PLACEABLE_BLOCKS.get(selectedBlock); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java new file mode 100644 index 0000000..0b666ce --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java @@ -0,0 +1,34 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import glm.vec._3.Vec3; +import ru.windcorp.progressia.common.world.GravityModel; + +public class TestGravityModel extends GravityModel { + + public TestGravityModel() { + super("Test:TheGravityModel"); + } + + @Override + protected void doGetGravity(Vec3 output) { + output.set(0, 0, -9.8); + } + +} diff --git a/src/main/resources/assets/languages/en-US.lang b/src/main/resources/assets/languages/en-US.lang index a47e216..62e2e6e 100644 --- a/src/main/resources/assets/languages/en-US.lang +++ b/src/main/resources/assets/languages/en-US.lang @@ -8,7 +8,6 @@ LayerTestGUI.IsFlyingDisplay = Flying: %5s (Space bar x2) LayerTestGUI.IsSprintingDisplay = Sprinting: %5s (W x2) LayerTestGUI.IsMouseCapturedDisplay = Mouse captured: %5s (Esc) LayerTestGUI.CameraModeDisplay = Camera mode: %5d (F5) -LayerTestGUI.GravityModeDisplay = Gravity: %9s (G) LayerTestGUI.LanguageDisplay = Language: %5s (L) LayerTestGUI.FPSDisplay = FPS: LayerTestGUI.TPSDisplay = TPS: diff --git a/src/main/resources/assets/languages/ru-RU.lang b/src/main/resources/assets/languages/ru-RU.lang index 180b25a..081a630 100644 --- a/src/main/resources/assets/languages/ru-RU.lang +++ b/src/main/resources/assets/languages/ru-RU.lang @@ -8,7 +8,6 @@ LayerTestGUI.IsFlyingDisplay = Полёт: %5s (Пробел x2) LayerTestGUI.IsSprintingDisplay = Бег: %5s (W x2) LayerTestGUI.IsMouseCapturedDisplay = Захват мыши: %5s (Esc) LayerTestGUI.CameraModeDisplay = Камера: %5d (F5) -LayerTestGUI.GravityModeDisplay = Гравитация: %9s (G) LayerTestGUI.LanguageDisplay = Язык: %5s (L) LayerTestGUI.FPSDisplay = FPS: LayerTestGUI.TPSDisplay = TPS: From 553837f2077e01f9dd914cf68777c31db5d5afcd Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 25 Jan 2021 22:06:34 +0300 Subject: [PATCH 02/63] GravityModels now take position into account - Also documented GravityModel --- .../client/graphics/world/LayerWorld.java | 2 +- .../progressia/common/world/GravityModel.java | 48 +++++++++++++++++-- .../progressia/test/gen/TestGravityModel.java | 2 +- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index d8ac99a..a8de633 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -204,7 +204,7 @@ public class LayerWorld extends Layer { } Vec3 gravitationalAcceleration = Vectors.grab3(); - ClientState.getInstance().getWorld().getData().getGravityModel().getGravity(gravitationalAcceleration); + ClientState.getInstance().getWorld().getData().getGravityModel().getGravity(entity.getPosition(), gravitationalAcceleration); gravitationalAcceleration.mul(tickLength); entity.getVelocity().add(gravitationalAcceleration); diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java index ce21649..f17c9b6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java @@ -17,25 +17,67 @@ */ package ru.windcorp.progressia.common.world; +import java.util.Objects; + import glm.vec._3.Vec3; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.util.namespaces.Namespaced; +/** + * Gravity model specifies the gravitational acceleration field. A gravity model may be queried for the vector of gravitational acceleration that should affect an object. This vector is, generally speaking, a function of space: gravity in two different locations may vary. Gravity may also be a zero vector. + * + * @author javapony + */ public abstract class GravityModel extends Namespaced { public GravityModel(String id) { super(id); } - public Vec3 getGravity(Vec3 output) { + /** + * Computes the vector of gravitational acceleration at the provided location. + * + * @param pos the position to compute gravity at + * @param output a {@link Vec3} where the result is stored. May be {@code null}. + * + * @return the vector of gravitational acceleration. The returned object will match {@code output} parameter is it is non-null. + */ + public Vec3 getGravity(Vec3 pos, Vec3 output) { + Objects.requireNonNull(pos, "pos"); + if (output == null) { output = new Vec3(); } - doGetGravity(output); + try { + doGetGravity(pos, output); + } catch (Exception e) { + throw CrashReports.report(e, "%s failed to compute gravity at (%d; %d; %d)", this, pos.x, pos.y, pos.z); + } return output; } - protected abstract void doGetGravity(Vec3 output); + /** + * Computes the up direction at the provided location. Up vector is defined as the normalized gravitational acceleration vector or {@code (0; 0; 0)} if there is no gravity. + * + * @param pos the position to compute up vector at + * @param output a {@link Vec3} where the result is stored. May be {@code null}. + * + * @return the up vector. The returned object will match {@code output} parameter is it is non-null. + */ + public Vec3 getUp(Vec3 pos, Vec3 output) { + output = getGravity(pos, output); + if (output.any()) output.normalize(); + return output; + } + + /** + * Computes the gravitational acceleration vector at the provided location. Actual computation of gravity is delegated to this method by the other methods in this class. + * + * @param pos the position to compute gravity at + * @param output a {@link Vec3} where the result must be stored. Never {@code null}. + */ + protected abstract void doGetGravity(Vec3 pos, Vec3 output); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java index 0b666ce..ebcf715 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java @@ -27,7 +27,7 @@ public class TestGravityModel extends GravityModel { } @Override - protected void doGetGravity(Vec3 output) { + protected void doGetGravity(Vec3 pos, Vec3 output) { output.set(0, 0, -9.8); } From f9717be412376662070ef3f72e7cee7bc767deab Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 29 Jan 2021 23:19:22 +0300 Subject: [PATCH 03/63] Switched to using looking-at vectors instead of Euler angles Also fixed camera jittering and added some vector functions --- .../client/graphics/world/Camera.java | 79 +++---- .../client/graphics/world/EntityAnchor.java | 24 +- .../client/graphics/world/Selection.java | 5 +- .../client/world/entity/EntityRenderable.java | 60 ++++- .../client/world/entity/HumanoidModel.java | 1 + .../client/world/entity/NPedModel.java | 206 ++++++++++++------ .../client/world/entity/QuadripedModel.java | 1 + .../progressia/common/util/VectorUtil.java | 74 ++++++- .../progressia/common/world/BlockRay.java | 12 +- .../common/world/entity/EntityData.java | 129 ++++++++--- .../progressia/server/PlayerManager.java | 11 +- .../windcorp/progressia/test/LayerTestUI.java | 29 +-- .../test/TestEntityRenderStatie.java | 2 +- .../progressia/test/TestPlayerControls.java | 92 +++++--- 14 files changed, 517 insertions(+), 208 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java index 46b551c..9c30a49 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java @@ -29,6 +29,9 @@ import glm.mat._4.Mat4; import glm.vec._3.Vec3; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.world.Camera.Anchor.Mode; +import ru.windcorp.progressia.client.world.entity.NPedModel; +import ru.windcorp.progressia.common.util.Matrices; +import ru.windcorp.progressia.common.util.Vectors; public class Camera { @@ -60,13 +63,13 @@ public class Camera { } } - void getCameraPosition(Vec3 output); + Vec3 getCameraPosition(Vec3 output); - void getCameraVelocity(Vec3 output); + Vec3 getCameraVelocity(Vec3 output); - float getCameraYaw(); - - float getCameraPitch(); + Vec3 getLookingAt(Vec3 output); + + Vec3 getUpVector(Vec3 output); Collection getCameraModes(); @@ -84,14 +87,11 @@ public class Camera { */ private final Vec3 lastAnchorPosition = new Vec3(); - private float lastAnchorYaw; - private float lastAnchorPitch; + private final Vec3 lastAnchorLookingAt = new Vec3(); + private final Vec3 lastAnchorUpVector = new Vec3(); private final Mat4 lastCameraMatrix = new Mat4(); - private final Vec3 lastAnchorLookingAt = new Vec3(); - private final Vec3 lastAnchorUp = new Vec3(); - { invalidateCache(); } @@ -108,6 +108,9 @@ public class Camera { */ public void apply(WorldRenderHelper helper) { + if (NPedModel.flag) { +// System.out.println("Camera.apply()"); + } applyPerspective(helper); rotateCoordinateSystem(helper); @@ -149,26 +152,34 @@ public class Camera { } private void applyDirection(WorldRenderHelper helper) { - float pitch = anchor.getCameraPitch(); - float yaw = anchor.getCameraYaw(); + anchor.getLookingAt(lastAnchorLookingAt); + anchor.getUpVector(lastAnchorUpVector); - helper.pushViewTransform() - .rotateY(-pitch) - .rotateZ(-yaw); + lookAt(helper.pushViewTransform()); + } - this.lastAnchorYaw = yaw; - this.lastAnchorPitch = pitch; - - this.lastAnchorLookingAt.set( - cos(pitch) * cos(yaw), - cos(pitch) * sin(yaw), - sin(pitch) - ); - this.lastAnchorUp.set( - cos(pitch + PI_F / 2) * cos(yaw), - cos(pitch + PI_F / 2) * sin(yaw), - sin(pitch + PI_F / 2) + private void lookAt(Mat4 result) { + Vec3 f = this.lastAnchorLookingAt; + Vec3 s = Vectors.grab3(); + Vec3 u = Vectors.grab3(); + + f.cross(this.lastAnchorUpVector, s); + s.normalize(); + + s.cross(f, u); + + Mat4 workspace = Matrices.grab4(); + workspace.set( + +f.x, -s.x, +u.x, 0, + +f.y, -s.y, +u.y, 0, + +f.z, -s.z, +u.z, 0, + 0, 0, 0, 1 ); + result.mul(workspace); + Matrices.release(workspace); + + Vectors.release(s); + Vectors.release(u); } private void applyPosition(WorldRenderHelper helper) { @@ -247,8 +258,6 @@ public class Camera { private void invalidateCache() { this.lastAnchorPosition.set(Float.NaN); - this.lastAnchorYaw = Float.NaN; - this.lastAnchorPitch = Float.NaN; this.lastCameraMatrix.set( Float.NaN, @@ -270,7 +279,7 @@ public class Camera { ); this.lastAnchorLookingAt.set(Float.NaN); - this.lastAnchorUp.set(Float.NaN); + this.lastAnchorUpVector.set(Float.NaN); } public Anchor.Mode getMode() { @@ -289,14 +298,6 @@ public class Camera { return currentModeIndex; } - public float getLastAnchorYaw() { - return lastAnchorYaw; - } - - public float getLastAnchorPitch() { - return lastAnchorPitch; - } - public Vec3 getLastAnchorPosition() { return lastAnchorPosition; } @@ -310,7 +311,7 @@ public class Camera { } public Vec3 getLastAnchorUp() { - return lastAnchorUp; + return lastAnchorUpVector; } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java index d11ea92..cb578d9 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java @@ -59,24 +59,32 @@ public class EntityAnchor implements Anchor { } @Override - public void getCameraPosition(Vec3 output) { + public Vec3 getCameraPosition(Vec3 output) { + if (output == null) output = new Vec3(); model.getViewPoint(output); - output.add(entity.getPosition()); + output.add(model.getPosition()); + return output; } @Override - public void getCameraVelocity(Vec3 output) { + public Vec3 getCameraVelocity(Vec3 output) { + if (output == null) output = new Vec3(); output.set(entity.getVelocity()); + return output; } @Override - public float getCameraYaw() { - return entity.getYaw(); + public Vec3 getLookingAt(Vec3 output) { + if (output == null) output = new Vec3(); + model.getLookingAt(output); + return output; } - + @Override - public float getCameraPitch() { - return entity.getPitch(); + public Vec3 getUpVector(Vec3 output) { + if (output == null) output = new Vec3(); + model.getUpVector(output); + return output; } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java index cd4ba29..e6cd57d 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java @@ -38,10 +38,9 @@ public class Selection { private BlockRay ray = new BlockRay(); public void update(WorldRender world, EntityData player) { - Vec3 direction = new Vec3(); Vec3 start = new Vec3(); - - player.getLookingAtVector(direction); + Vec3 direction = player.getLookingAt(); + world.getEntityRenderable(player).getViewPoint(start); start.add(player.getPosition()); diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java index eecaa16..24ea147 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java @@ -15,22 +15,49 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.entity; import glm.vec._3.Vec3; +import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.model.Renderable; +import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.GenericEntity; public abstract class EntityRenderable implements Renderable, GenericEntity { private final EntityData data; + + private long stateComputedForFrame = -1; public EntityRenderable(EntityData data) { this.data = data; } + /** + * Updates the state of this model. This method is invoked exactly once per + * renderable per frame before this entity is queried for the first time. + */ + protected void update() { + // Do nothing + } + + private void updateIfNecessary() { + if (stateComputedForFrame != GraphicsInterface.getFramesRendered()) { + update(); + stateComputedForFrame = GraphicsInterface.getFramesRendered(); + } + } + + @Override + public final void render(ShapeRenderHelper renderer) { + updateIfNecessary(); + doRender(renderer); + } + + protected abstract void doRender(ShapeRenderHelper renderer); + public EntityData getData() { return data; } @@ -45,7 +72,36 @@ public abstract class EntityRenderable implements Renderable, GenericEntity { return getData().getId(); } - public void getViewPoint(Vec3 output) { + public final Vec3 getLookingAt(Vec3 output) { + if (output == null) output = new Vec3(); + updateIfNecessary(); + doGetLookingAt(output); + return output; + } + + protected void doGetLookingAt(Vec3 output) { + output.set(getData().getLookingAt()); + } + + public final Vec3 getUpVector(Vec3 output) { + if (output == null) output = new Vec3(); + updateIfNecessary(); + doGetUpVector(output); + return output; + } + + protected void doGetUpVector(Vec3 output) { + output.set(getData().getUpVector()); + } + + public final Vec3 getViewPoint(Vec3 output) { + if (output == null) output = new Vec3(); + updateIfNecessary(); + doGetViewPoint(output); + return output; + } + + protected void doGetViewPoint(Vec3 output) { output.set(0, 0, 0); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java index 1609bfc..c33356f 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java @@ -43,6 +43,7 @@ public class HumanoidModel extends NPedModel { @Override protected void applyTransform(Mat4 mat, NPedModel model) { + super.applyTransform(mat, model); float phase = model.getWalkingFrequency() * model.getWalkingParameter() + animationOffset; float value = sin(phase); float amplitude = getSwingAmplitude((HumanoidModel) model) * model.getVelocityParameter(); diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java index ead6565..ecefd06 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java @@ -18,11 +18,8 @@ package ru.windcorp.progressia.client.world.entity; -import static java.lang.Math.atan2; -import static java.lang.Math.min; import static java.lang.Math.pow; import static java.lang.Math.toRadians; -import static ru.windcorp.progressia.common.util.FloatMathUtil.normalizeAngle; import glm.Glm; import glm.mat._4.Mat4; @@ -32,6 +29,9 @@ import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.util.FloatMathUtil; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.entity.EntityData; public abstract class NPedModel extends EntityRenderable { @@ -51,29 +51,30 @@ public abstract class NPedModel extends EntityRenderable { ShapeRenderHelper renderer, NPedModel model ) { - renderer.pushTransform().translate(translation); applyTransform(renderer.pushTransform(), model); renderable.render(renderer); renderer.popTransform(); - renderer.popTransform(); } - protected abstract void applyTransform(Mat4 mat, NPedModel model); + protected void applyTransform(Mat4 mat, NPedModel model) { + mat.translate(getTranslation()); + } public Vec3 getTranslation() { return translation; } + + public Mat4 getTransform(Mat4 output, NPedModel model) { + if (output == null) output = new Mat4().identity(); + applyTransform(output, model); + return output; + } } public static class Body extends BodyPart { public Body(Renderable renderable) { super(renderable, null); } - - @Override - protected void applyTransform(Mat4 mat, NPedModel model) { - // Do nothing - } } public static class Head extends BodyPart { @@ -97,7 +98,8 @@ public abstract class NPedModel extends EntityRenderable { @Override protected void applyTransform(Mat4 mat, NPedModel model) { - mat.rotateZ(model.getHeadYaw()).rotateY(model.getHeadPitch()); + super.applyTransform(mat, model); + mat.rotateZ(-model.getHeadYaw()).rotateY(-model.getHeadPitch()); } public Vec3 getViewPoint() { @@ -105,6 +107,8 @@ public abstract class NPedModel extends EntityRenderable { } } + public static boolean flag; + protected final Body body; protected final Head head; @@ -128,7 +132,9 @@ public abstract class NPedModel extends EntityRenderable { private float walkingFrequency; - private float bodyYaw = Float.NaN; + private final Vec3 bodyLookingAt = new Vec3().set(0); + private final Mat4 bodyTransform = new Mat4(); + private float headYaw; private float headPitch; @@ -138,68 +144,122 @@ public abstract class NPedModel extends EntityRenderable { this.head = head; this.scale = scale; - evaluateAngles(); + computeRotations(); } @Override - public void render(ShapeRenderHelper renderer) { - renderer.pushTransform().scale(scale).rotateZ(bodyYaw); + protected void doRender(ShapeRenderHelper renderer) { + renderer.pushTransform().scale(scale).mul(bodyTransform); renderBodyParts(renderer); renderer.popTransform(); - - accountForVelocity(); - evaluateAngles(); } protected void renderBodyParts(ShapeRenderHelper renderer) { body.render(renderer, this); head.render(renderer, this); } - - private void evaluateAngles() { - float globalYaw = normalizeAngle(getData().getYaw()); - - if (Float.isNaN(bodyYaw)) { - bodyYaw = globalYaw; - headYaw = 0; - } else { - headYaw = normalizeAngle(globalYaw - bodyYaw); - - if (headYaw > +head.maxYaw) { - bodyYaw += headYaw - +head.maxYaw; - headYaw = +head.maxYaw; - } else if (headYaw < -head.maxYaw) { - bodyYaw += headYaw - -head.maxYaw; - headYaw = -head.maxYaw; - } - } - - bodyYaw = normalizeAngle(bodyYaw); - - headPitch = Glm.clamp( - getData().getPitch(), - -head.maxPitch, - head.maxPitch - ); + + @Override + protected void update() { + advanceTime(); + computeRotations(); } - private void accountForVelocity() { - Vec3 horizontal = new Vec3(getData().getVelocity()); - horizontal.z = 0; + private void computeRotations() { + if (!bodyLookingAt.any()) { + getData().getForwardVector(bodyLookingAt); + headYaw = 0; + } else { + ensureBodyLookingAtIsPerpendicularToUpVector(); + computeDesiredHeadYaw(); + clampHeadYawAndChangeBodyLookingAt(); + } + + recomputeBodyTransform(); + + setHeadPitch(); + } + + private void ensureBodyLookingAtIsPerpendicularToUpVector() { + Vec3 up = getData().getUpVector(); + if (up.dot(bodyLookingAt) > 1 - 1e-4) return; + + Vec3 tmp = Vectors.grab3(); + + tmp.set(up).mul(-up.dot(bodyLookingAt)).add(bodyLookingAt); + + float tmpLength = tmp.length(); + if (tmpLength > 1e-4) { + bodyLookingAt.set(tmp).div(tmpLength); + } else { + // bodyLookingAt is suddenly parallel to up vector -- PANIC! ENTERING RESCUE MODE! + getData().getForwardVector(bodyLookingAt); + } + + Vectors.release(tmp); + } + + private void computeDesiredHeadYaw() { + Vec3 newDirection = getData().getForwardVector(null); + Vec3 oldDirection = bodyLookingAt; + Vec3 up = getData().getUpVector(); + + headYaw = (float) VectorUtil.getAngle(oldDirection, newDirection, up); + } + + private void clampHeadYawAndChangeBodyLookingAt() { + float bodyYawChange = 0; + + if (headYaw > +head.maxYaw) { + bodyYawChange = headYaw - +head.maxYaw; + headYaw = +head.maxYaw; + } else if (headYaw < -head.maxYaw) { + bodyYawChange = headYaw - -head.maxYaw; + headYaw = -head.maxYaw; + } + + if (bodyYawChange != 0) { + VectorUtil.rotate(bodyLookingAt, getData().getUpVector(), bodyYawChange); + } + } + + private void recomputeBodyTransform() { + Vec3 u = getData().getUpVector(); + Vec3 f = bodyLookingAt; + Vec3 s = Vectors.grab3(); + + s.set(u).cross(f); + + bodyTransform.identity().set( + +f.x, -s.x, +u.x, 0, + +f.y, -s.y, +u.y, 0, + +f.z, -s.z, +u.z, 0, + 0, 0, 0, 1 + ); + + Vectors.release(s); + } + + private void setHeadPitch() { + headPitch = Glm.clamp((float) getData().getPitch(), -head.maxPitch, +head.maxPitch); + } + + private void advanceTime() { + Vec3 horizontal = getData().getUpVector() + .mul_(-getData().getUpVector().dot(getData().getVelocity())) + .add(getData().getVelocity()); velocity = horizontal.length(); - evaluateVelocityCoeff(); + computeVelocityParameter(); // TODO switch to world time walkingParameter += velocity * GraphicsInterface.getFrameLength() * 1000; - - bodyYaw += velocityParameter * normalizeAngle( - (float) (atan2(horizontal.y, horizontal.x) - bodyYaw) - ) * min(1, GraphicsInterface.getFrameLength() * 10); + + rotateBodyWithMovement(horizontal); } - private void evaluateVelocityCoeff() { + private void computeVelocityParameter() { if (velocity > maxEffectiveVelocity) { velocityParameter = 1; } else { @@ -207,17 +267,39 @@ public abstract class NPedModel extends EntityRenderable { } } + private void rotateBodyWithMovement(Vec3 target) { + if (velocityParameter == 0 || !target.any() || Glm.equals(target, bodyLookingAt)) { + return; + } + + Vec3 axis = getData().getUpVector(); + + float yawDifference = FloatMathUtil.normalizeAngle( + (float) VectorUtil.getAngle( + bodyLookingAt, + target.normalize_(), + axis + ) + ); + + float bodyYawChange = + velocityParameter * + yawDifference * + (float) Math.expm1(GraphicsInterface.getFrameLength() * 10); + + VectorUtil.rotate(bodyLookingAt, axis, bodyYawChange); + } + @Override - public void getViewPoint(Vec3 output) { + protected void doGetViewPoint(Vec3 output) { Mat4 m = new Mat4(); Vec4 v = new Vec4(); m.identity() .scale(scale) - .rotateZ(bodyYaw) - .translate(head.getTranslation()) - .rotateZ(headYaw) - .rotateY(headPitch); + .mul(bodyTransform); + + head.getTransform(m, this); v.set(head.getViewPoint(), 1); m.mul(v); @@ -232,9 +314,9 @@ public abstract class NPedModel extends EntityRenderable { public Head getHead() { return head; } - - public float getBodyYaw() { - return bodyYaw; + + public Vec3 getBodyLookingAt() { + return bodyLookingAt; } public float getHeadYaw() { diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java index 8755b08..db6dbf4 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java @@ -44,6 +44,7 @@ public class QuadripedModel extends NPedModel { @Override protected void applyTransform(Mat4 mat, NPedModel model) { + super.applyTransform(mat, model); float phase = model.getWalkingFrequency() * model.getWalkingParameter() + animationOffset; float value = sin(phase); float amplitude = ((QuadripedModel) model).getWalkingSwing() * model.getVelocityParameter(); diff --git a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java index 00ede3e..1de0848 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java @@ -20,6 +20,8 @@ package ru.windcorp.progressia.common.util; import java.util.function.Consumer; +import glm.Glm; +import glm.mat._3.Mat3; import glm.mat._4.Mat4; import glm.vec._2.Vec2; import glm.vec._2.d.Vec2d; @@ -135,12 +137,72 @@ public class VectorUtil { } public static void applyMat4(Vec3 inOut, Mat4 mat) { - Vec4 vec4 = Vectors.grab4(); - vec4.set(inOut, 1f); - - mat.mul(vec4); - - inOut.set(vec4.x, vec4.y, vec4.z); + applyMat4(inOut, mat, inOut); + } + + public static void rotate(Vec3 in, Vec3 axis, float angle, Vec3 out) { + Mat3 mat = Matrices.grab3(); + + mat.identity().rotate(angle, axis); + mat.mul(in, out); + + Matrices.release(mat); + } + + public static void rotate(Vec3 inOut, Vec3 axis, float angle) { + rotate(inOut, axis, angle, inOut); + } + + public static double getAngle(Vec3 from, Vec3 to, Vec3 normal) { + Vec3 left = Vectors.grab3(); + + left.set(normal).cross(from); + double sign = Math.signum(left.dot(to)); + + double result = (float) Math.acos(Glm.clamp(from.dot(to), -1, +1)) * sign; + + Vectors.release(left); + return result; + } + + public static Vec3 projectOnSurface(Vec3 in, Vec3 normal, Vec3 out) { + if (in == out) { + return projectOnSurface(in, normal); + } + + if (out == null) { + out = new Vec3(); + } + + out.set(normal).mul(-normal.dot(in)).add(in); + + return out; + } + + public static Vec3 projectOnSurface(Vec3 inOut, Vec3 normal) { + Vec3 buffer = Vectors.grab3(); + + projectOnSurface(inOut, normal, buffer); + inOut.set(buffer); + + Vectors.release(buffer); + + return inOut; + } + + public static Vec3 projectOnVector(Vec3 in, Vec3 vector, Vec3 out) { + if (out == null) { + out = new Vec3(); + } + + float dot = vector.dot(in); + out.set(vector).mul(dot); + + return out; + } + + public static Vec3 projectOnVector(Vec3 inOut, Vec3 vector) { + return projectOnVector(inOut, vector); } public static Vec3 linearCombination( diff --git a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java index 4d5f1f9..743d238 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java +++ b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java @@ -39,9 +39,17 @@ public class BlockRay { private boolean isValid = false; public void start(Vec3 position, Vec3 direction) { - if (!direction.any()) { + if (direction.x == 0 && direction.y == 0 && direction.z == 0) { throw new IllegalArgumentException("Direction is a zero vector"); } + + if (Float.isNaN(direction.x) || Float.isNaN(direction.y) || Float.isNaN(direction.z)) { + throw new IllegalArgumentException("Direction contains NaN: " + direction); + } + + if (Float.isNaN(position.x) || Float.isNaN(position.y) || Float.isNaN(position.z)) { + throw new IllegalArgumentException("Position contains NaN: " + position); + } isValid = true; this.position.set(position).sub(0.5f); // Make sure lattice points are @@ -75,6 +83,8 @@ public class BlockRay { tMin = tz; axis = Axis.Z; } + + assert tMin > 0 : "tMin is not positive (" + tMin + ")"; // block.(axis) += signum(direction.(axis)) VectorUtil.set(block, axis, VectorUtil.get(block, axis) + (int) signum(VectorUtil.get(direction, axis))); diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index 7b3325c..2dcdf3e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -15,14 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import glm.vec._2.Vec2; import glm.vec._3.Vec3; import ru.windcorp.jputil.chars.StringUtil; import ru.windcorp.progressia.common.collision.Collideable; @@ -36,7 +35,8 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn private final Vec3 position = new Vec3(); private final Vec3 velocity = new Vec3(); - private final Vec2 direction = new Vec2(); + private final Vec3 lookingAt = new Vec3(1, 0, 0); + private final Vec3 upVector = new Vec3(0, 0, 1); /** * The unique {@code long} value guaranteed to never be assigned to an @@ -79,22 +79,6 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn this.velocity.set(velocity); } - public Vec2 getDirection() { - return direction; - } - - public void setDirection(Vec2 direction) { - this.direction.set(direction.x, direction.y); - } - - public float getYaw() { - return getDirection().x; - } - - public float getPitch() { - return getDirection().y; - } - public long getEntityId() { return entityId; } @@ -152,16 +136,90 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn getVelocity().add(velocityChange); } - public Vec3 getLookingAtVector(Vec3 output) { - output.set( - Math.cos(getPitch()) * Math.cos(getYaw()), - Math.cos(getPitch()) * Math.sin(getYaw()), - -Math.sin(getPitch()) - ); + public Vec3 getLookingAt() { + return lookingAt; + } + public void setLookingAt(Vec3 lookingAt) { + float lengthSq = lookingAt.x * lookingAt.x + lookingAt.y * lookingAt.y + lookingAt.z * lookingAt.z; + if (lengthSq == 1) { + this.lookingAt.set(lookingAt); + } else if (lengthSq == 0) { + throw new IllegalArgumentException("lookingAt is zero-length"); + } else { + float length = (float) Math.sqrt(lengthSq); + this.lookingAt.set( + lookingAt.x / length, + lookingAt.y / length, + lookingAt.z / length + ); + } + } + + public Vec3 getUpVector() { + return upVector; + } + + /** + * Sets this entity's up vector without updating looking at-vector. + * + * @param upVector the Vec3 to copy up vector from + * @see #changeUpVector(Vec3) + */ + public void setUpVector(Vec3 upVector) { + float lengthSq = upVector.x * upVector.x + upVector.y * upVector.y + upVector.z * upVector.z; + if (lengthSq == 1) { + this.upVector.set(upVector); + } else if (lengthSq == 0) { + throw new IllegalArgumentException("upVector is zero-length"); + } else { + float length = (float) Math.sqrt(lengthSq); + this.upVector.set( + upVector.x / length, + upVector.y / length, + upVector.z / length + ); + } + } + + /** + * Computes the forward vector of this entity. An entity's forward vector is + * defined as a normalized projection of the looking at-vector onto the + * plane perpendicular to up vector, or {@code (NaN; NaN; NaN)} if looking + * at-vector is parallel to the up vector. + * + * @param output a {@link Vec3} where the result is stored. May be + * {@code null}. + * @return the computed forward vector or {@code (NaN; NaN; NaN)} + */ + public Vec3 getForwardVector(Vec3 output) { + if (output == null) + output = new Vec3(); + output.set(getUpVector()).mul(-getUpVector().dot(getLookingAt())).add(getLookingAt()).normalize(); return output; } + public double getPitch() { + return -Math.acos(getLookingAt().dot(getUpVector())) + Math.PI / 2; + } + + /** + * Updates this entity's up vector and alters looking at-vector to match the + * rotation of the up vector. + *

+ * This method assumes that the up vector has changed due to rotation around + * some axis. The axis and the angle are computed, after which the same + * rotation is applied to the looking at-vector. + * + * @param newUpVector the Vec3 to copy up vector from. May be equal to + * current up vector + * @see #setLookingAt(Vec3) + */ + public void changeUpVector(Vec3 newUpVector) { + // TODO + this.upVector.set(newUpVector); + } + @Override public String toString() { return new StringBuilder(super.toString()) @@ -189,8 +247,13 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn output.writeFloat(getVelocity().y); output.writeFloat(getVelocity().z); - output.writeFloat(getDirection().x); - output.writeFloat(getDirection().y); + output.writeFloat(getLookingAt().x); + output.writeFloat(getLookingAt().y); + output.writeFloat(getLookingAt().z); + + output.writeFloat(getUpVector().x); + output.writeFloat(getUpVector().y); + output.writeFloat(getUpVector().z); super.write(output, context); } @@ -209,14 +272,22 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn input.readFloat() ); - Vec2 direction = new Vec2( + Vec3 lookingAt = new Vec3( + input.readFloat(), + input.readFloat(), + input.readFloat() + ); + + Vec3 upVector = new Vec3( + input.readFloat(), input.readFloat(), input.readFloat() ); setPosition(position); setVelocity(velocity); - setDirection(direction); + setLookingAt(lookingAt); + setUpVector(upVector); super.read(input, context); } diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java index 38d0f32..8e34b49 100644 --- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import glm.vec._2.Vec2; +import glm.vec._3.Vec3; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityDataRegistry; @@ -61,12 +61,9 @@ public class PlayerManager { player.setEntityId(TestContent.PLAYER_ENTITY_ID); player.setPosition(TestContent.SPAWN); - player.setDirection( - new Vec2( - Math.toRadians(40), - Math.toRadians(10) - ) - ); + + player.setUpVector(new Vec3(0, 0, 1)); + player.setLookingAt(new Vec3(2, 1, 0)); getServer().getWorld().getData().addEntity(player); diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java index c93a055..7962ca1 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java @@ -24,7 +24,6 @@ import com.google.common.eventbus.Subscribe; import glm.mat._4.Mat4; import glm.vec._4.Vec4; -import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.flat.AssembledFlatLayer; @@ -34,7 +33,6 @@ import ru.windcorp.progressia.client.graphics.input.bus.Input; import ru.windcorp.progressia.client.graphics.model.LambdaModel; import ru.windcorp.progressia.client.graphics.texture.SimpleTextures; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.client.graphics.world.Camera; public class LayerTestUI extends AssembledFlatLayer { @@ -46,9 +44,12 @@ public class LayerTestUI extends AssembledFlatLayer { private boolean flag = false; - private static final int WIDTH = 80; - private static final int HEIGHT = 80; + private static final int SCALE = 4; + private static final int TEX_SIZE = 16 * SCALE; + private static final int TEX_SHADOW = SCALE / 2; private static final int BORDER = 5; + private static final int HEIGHT = TEX_SIZE + 4 * BORDER; + private static final int WIDTH = HEIGHT; @Override protected void assemble(RenderTarget target) { @@ -64,25 +65,22 @@ public class LayerTestUI extends AssembledFlatLayer { target.fill(x, y, WIDTH, HEIGHT, borderColor); target.fill(x + BORDER, y + BORDER, WIDTH - 2 * BORDER, HEIGHT - 2 * BORDER, boxColor); - final int texShadow = 2; - final int texSize = HEIGHT - 4 * BORDER; - target.pushTransform(new Mat4().identity().translate(x + 2 * BORDER, y + 2 * BORDER, 0)); final Texture compassBg = SimpleTextures.get("compass_icon"); final Texture compassFg = SimpleTextures.get("compass_icon_arrow"); - target.drawTexture(texShadow, -texShadow, texSize, texSize, Colors.BLACK, compassBg); - target.drawTexture(0, 0, texSize, texSize, compassBg); + target.drawTexture(TEX_SHADOW, -TEX_SHADOW, TEX_SIZE, TEX_SIZE, Colors.BLACK, compassBg); + target.drawTexture(0, 0, TEX_SIZE, TEX_SIZE, compassBg); target.addCustomRenderer( new LambdaModel( LambdaModel.lambdaBuilder() .addDynamicPart( - target.createRectagle(0, 0, texSize, texSize, Colors.WHITE, compassFg), - mat -> mat.translate(texSize / 2, texSize / 2, 0) + target.createRectagle(0, 0, TEX_SIZE, TEX_SIZE, Colors.WHITE, compassFg), + mat -> mat.translate(TEX_SIZE / 2, TEX_SIZE / 2, 0) .rotateZ(getCompassRotation()) - .translate(-texSize / 2, -texSize / 2, 0) + .translate(-TEX_SIZE / 2, -TEX_SIZE / 2, 0) ) ) ); @@ -92,12 +90,7 @@ public class LayerTestUI extends AssembledFlatLayer { } private double getCompassRotation() { - Camera.Anchor anchor = ClientState.getInstance().getCamera().getAnchor(); - - if (anchor == null) - return 0; - - return -anchor.getCameraYaw(); + return 0; } private void drawCross(RenderTarget target) { diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java index 47990fd..fa595e7 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java @@ -44,7 +44,7 @@ public class TestEntityRenderStatie extends EntityRender { public EntityRenderable createRenderable(EntityData entity) { return new EntityRenderable(entity) { @Override - public void render(ShapeRenderHelper renderer) { + public void doRender(ShapeRenderHelper renderer) { renderer.pushTransform().scale( ((TestEntityDataStatie) entity).getSize() / 24.0f ); diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java index 0a0d3d3..1254399 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java +++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.test; import glm.Glm; import glm.mat._3.Mat3; -import glm.vec._2.Vec2; +import glm.mat._4.Mat4; import glm.vec._3.Vec3; import org.lwjgl.glfw.GLFW; import ru.windcorp.progressia.client.ClientState; @@ -36,7 +36,9 @@ import ru.windcorp.progressia.client.graphics.input.bus.Input; import ru.windcorp.progressia.client.graphics.world.LocalPlayer; import ru.windcorp.progressia.client.localization.Localizer; import ru.windcorp.progressia.common.Units; -import ru.windcorp.progressia.common.util.FloatMathUtil; +import ru.windcorp.progressia.common.util.Matrices; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.tile.TileData; @@ -108,17 +110,17 @@ public class TestPlayerControls { authority = WALKING_CONTROL_AUTHORITY; } - Mat3 angMat = new Mat3().identity().rotateZ(player.getYaw()); - Vec3 desiredVelocity = new Vec3(movementForward, -movementRight, 0); - - if (movementForward != 0 && movementRight != 0) + Mat3 movementTransform = getMovementTransform(player, null); + Vec3 desiredVelocity = new Vec3(movementForward, movementRight, 0); + if (movementForward != 0 && movementRight != 0) { desiredVelocity.normalize(); - angMat.mul_(desiredVelocity); // bug in jglm, .mul() and mul_() are - // swapped + } desiredVelocity.z = movementUp; + movementTransform.mul_(desiredVelocity); // bug in jglm, .mul() and mul_() are + // swapped desiredVelocity.mul(speed); - Vec3 change = new Vec3() + Vec3 newVelocity = new Vec3() .set(desiredVelocity) .sub(player.getVelocity()) .mul((float) Math.exp(-authority * GraphicsInterface.getFrameLength())) @@ -126,10 +128,12 @@ public class TestPlayerControls { .add(desiredVelocity); if (!isFlying) { - change.z = player.getVelocity().z; + Vec3 up = player.getUpVector(); + Vec3 wantedVertical = VectorUtil.projectOnVector(player.getVelocity(), up, null); + VectorUtil.projectOnSurface(newVelocity, up).add(wantedVertical); } - player.getVelocity().set(change); + player.getVelocity().set(newVelocity); // THIS IS TERRIBLE TEST EntityData serverEntity = ServerState.getInstance().getWorld().getData() @@ -140,6 +144,22 @@ public class TestPlayerControls { } + private Mat3 getMovementTransform(EntityData player, Mat3 mat) { + if (mat == null) { + mat = new Mat3(); + } + + Vec3 f = player.getForwardVector(null); + Vec3 u = player.getUpVector(); + Vec3 s = u.cross_(f); + + return mat.set( + +f.x, -s.x, +u.x, + +f.y, -s.y, +u.y, + +f.z, -s.z, +u.z + ); + } + public void handleInput(Input input) { InputEvent event = input.getEvent(); @@ -318,36 +338,44 @@ public class TestPlayerControls { } private void onMouseMoved(CursorMoveEvent event) { - if (!captureMouse) + if (!captureMouse) { return; + } if (ClientState.getInstance() == null || !ClientState.getInstance().isReady()) { return; } - final float yawScale = -0.002f; - final float pitchScale = yawScale; + final double yawScale = -0.002f; + final double pitchScale = -yawScale; + final double pitchExtremum = Math.PI/2 * 0.95f; + + double yawChange = event.getChangeX() * yawScale; + double pitchChange = event.getChangeY() * pitchScale; EntityData player = getEntity(); + + double startPitch = player.getPitch(); + double endPitch = startPitch + pitchChange; + endPitch = Glm.clamp(endPitch, -pitchExtremum, +pitchExtremum); + pitchChange = endPitch - startPitch; + + Mat4 mat = Matrices.grab4(); + Vec3 lookingAt = Vectors.grab3(); + Vec3 rightVector = Vectors.grab3(); - normalizeAngles( - player.getDirection().add( - (float) (event.getChangeX() * yawScale), - (float) (event.getChangeY() * pitchScale) - ) - ); - } - - private void normalizeAngles(Vec2 dir) { - // Normalize yaw - dir.x = FloatMathUtil.normalizeAngle(dir.x); - - // Clamp pitch - dir.y = Glm.clamp( - dir.y, - -FloatMathUtil.PI_F / 2, - +FloatMathUtil.PI_F / 2 - ); + rightVector.set(player.getLookingAt()).cross(player.getUpVector()).normalize(); + + mat.identity() + .rotate((float) yawChange, player.getUpVector()) + .rotate((float) pitchChange, rightVector); + + VectorUtil.applyMat4(player.getLookingAt(), mat, lookingAt); + player.setLookingAt(lookingAt); + + Vectors.release(rightVector); + Vectors.release(lookingAt); + Matrices.release(mat); } private void onWheelScroll(WheelScrollEvent event) { From b1666fa4b9a5d3be01bd229c7af31887c5ca2fc8 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 31 Jan 2021 23:34:24 +0300 Subject: [PATCH 04/63] Fixed a bunch of issues with gravity and implemented gravity changes Also added DebugGraphics and made VectorUtil comply with the general Vec contract --- .../client/graphics/world/LayerWorld.java | 10 +- .../client/world/entity/NPedModel.java | 7 +- .../progressia/common/util/VectorUtil.java | 32 +++++-- .../progressia/common/world/GravityModel.java | 55 +++++++---- .../common/world/entity/EntityData.java | 79 ++++++++++++++- .../progressia/test/DebugGraphics.java | 95 +++++++++++++++++++ .../progressia/test/TestPlayerControls.java | 16 +++- .../progressia/test/gen/TestGravityModel.java | 9 +- 8 files changed, 263 insertions(+), 40 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/DebugGraphics.java diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index a8de633..c58b806 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -42,6 +42,7 @@ import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.colliders.Collider; import ru.windcorp.progressia.common.util.FloatMathUtil; import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.test.CollisionModelRenderer; import ru.windcorp.progressia.test.TestPlayerControls; @@ -199,12 +200,19 @@ public class LayerWorld extends Layer { } private void tmp_applyGravity(EntityData entity, float tickLength) { + GravityModel gm = ClientState.getInstance().getWorld().getData().getGravityModel(); + + Vec3 upVector = Vectors.grab3(); + gm.getUp(entity.getPosition(), upVector); + entity.changeUpVector(upVector); + Vectors.release(upVector); + if (ClientState.getInstance().getLocalPlayer().getEntity() == entity && tmp_testControls.isFlying()) { return; } Vec3 gravitationalAcceleration = Vectors.grab3(); - ClientState.getInstance().getWorld().getData().getGravityModel().getGravity(entity.getPosition(), gravitationalAcceleration); + gm.getGravity(entity.getPosition(), gravitationalAcceleration); gravitationalAcceleration.mul(tickLength); entity.getVelocity().add(gravitationalAcceleration); diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java index ecefd06..12a078e 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java @@ -231,9 +231,9 @@ public abstract class NPedModel extends EntityRenderable { s.set(u).cross(f); bodyTransform.identity().set( - +f.x, -s.x, +u.x, 0, - +f.y, -s.y, +u.y, 0, - +f.z, -s.z, +u.z, 0, + +f.x, +f.y, +f.z, 0, + -s.x, -s.y, -s.z, 0, + +u.x, +u.y, +u.z, 0, 0, 0, 0, 1 ); @@ -253,7 +253,6 @@ public abstract class NPedModel extends EntityRenderable { computeVelocityParameter(); - // TODO switch to world time walkingParameter += velocity * GraphicsInterface.getFrameLength() * 1000; rotateBodyWithMovement(horizontal); diff --git a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java index 1de0848..1d86fce 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java @@ -126,7 +126,11 @@ public class VectorUtil { iterateCuboidAround(center.x, center.y, center.z, diameter, action); } - public static void applyMat4(Vec3 in, Mat4 mat, Vec3 out) { + public static Vec3 applyMat4(Vec3 in, Mat4 mat, Vec3 out) { + if (out == null) { + out = new Vec3(); + } + Vec4 vec4 = Vectors.grab4(); vec4.set(in, 1f); @@ -134,23 +138,31 @@ public class VectorUtil { out.set(vec4.x, vec4.y, vec4.z); Vectors.release(vec4); + + return out; } - public static void applyMat4(Vec3 inOut, Mat4 mat) { - applyMat4(inOut, mat, inOut); + public static Vec3 applyMat4(Vec3 inOut, Mat4 mat) { + return applyMat4(inOut, mat, inOut); } - public static void rotate(Vec3 in, Vec3 axis, float angle, Vec3 out) { + public static Vec3 rotate(Vec3 in, Vec3 axis, float angle, Vec3 out) { + if (out == null) { + out = new Vec3(); + } + Mat3 mat = Matrices.grab3(); mat.identity().rotate(angle, axis); mat.mul(in, out); Matrices.release(mat); + + return out; } - public static void rotate(Vec3 inOut, Vec3 axis, float angle) { - rotate(inOut, axis, angle, inOut); + public static Vec3 rotate(Vec3 inOut, Vec3 axis, float angle) { + return rotate(inOut, axis, angle, inOut); } public static double getAngle(Vec3 from, Vec3 to, Vec3 normal) { @@ -212,6 +224,10 @@ public class VectorUtil { float kb, Vec3 output ) { + if (output == null) { + output = new Vec3(); + } + output.set( va.x * ka + vb.x * kb, va.y * ka + vb.y * kb, @@ -229,6 +245,10 @@ public class VectorUtil { float kc, Vec3 output ) { + if (output == null) { + output = new Vec3(); + } + output.set( va.x * ka + vb.x * kb + vc.x * kc, va.y * ka + vb.y * kb + vc.y * kc, diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java index f17c9b6..eecfc3b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java @@ -24,59 +24,72 @@ import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.util.namespaces.Namespaced; /** - * Gravity model specifies the gravitational acceleration field. A gravity model may be queried for the vector of gravitational acceleration that should affect an object. This vector is, generally speaking, a function of space: gravity in two different locations may vary. Gravity may also be a zero vector. + * Gravity model specifies the gravitational acceleration field. A gravity model + * may be queried for the vector of gravitational acceleration that should + * affect an object. This vector is, generally speaking, a function of space: + * gravity in two different locations may vary. Gravity may also be a zero + * vector. * * @author javapony */ public abstract class GravityModel extends Namespaced { - + public GravityModel(String id) { super(id); } /** - * Computes the vector of gravitational acceleration at the provided location. + * Computes the vector of gravitational acceleration at the provided + * location. * - * @param pos the position to compute gravity at - * @param output a {@link Vec3} where the result is stored. May be {@code null}. - * - * @return the vector of gravitational acceleration. The returned object will match {@code output} parameter is it is non-null. + * @param pos the position to compute gravity at + * @param output a {@link Vec3} where the result is stored. May be + * {@code null}. + * @return the vector of gravitational acceleration. The returned object + * will match {@code output} parameter is it is non-null. */ public Vec3 getGravity(Vec3 pos, Vec3 output) { Objects.requireNonNull(pos, "pos"); - + if (output == null) { output = new Vec3(); } - + try { doGetGravity(pos, output); } catch (Exception e) { throw CrashReports.report(e, "%s failed to compute gravity at (%d; %d; %d)", this, pos.x, pos.y, pos.z); } - + return output; } - + /** - * Computes the up direction at the provided location. Up vector is defined as the normalized gravitational acceleration vector or {@code (0; 0; 0)} if there is no gravity. + * Computes the up direction at the provided location. Up vector is defined + * as the additive inverse of the normalized gravitational acceleration + * vector or {@code (0; 0; 0)} if there is no gravity. * - * @param pos the position to compute up vector at - * @param output a {@link Vec3} where the result is stored. May be {@code null}. - * - * @return the up vector. The returned object will match {@code output} parameter is it is non-null. + * @param pos the position to compute up vector at + * @param output a {@link Vec3} where the result is stored. May be + * {@code null}. + * @return the up vector. The returned object will match {@code output} + * parameter is it is non-null. */ public Vec3 getUp(Vec3 pos, Vec3 output) { output = getGravity(pos, output); - if (output.any()) output.normalize(); + if (output.any()) + output.normalize().negate(); return output; } - + /** - * Computes the gravitational acceleration vector at the provided location. Actual computation of gravity is delegated to this method by the other methods in this class. + * Computes the gravitational acceleration vector at the provided location. + * Actual computation of gravity is delegated to this method by the other + * methods in this class. * - * @param pos the position to compute gravity at - * @param output a {@link Vec3} where the result must be stored. Never {@code null}. + * @param pos the position to compute gravity at + * @param output a {@link Vec3} where the result must be stored. Never + * {@code null}. */ protected abstract void doGetGravity(Vec3 pos, Vec3 output); diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index 2dcdf3e..344439a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -21,13 +21,16 @@ package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.util.Objects; +import glm.mat._3.Mat3; import glm.vec._3.Vec3; import ru.windcorp.jputil.chars.StringUtil; import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.util.Matrices; import ru.windcorp.progressia.common.world.generic.GenericEntity; public class EntityData extends StatefulObject implements Collideable, GenericEntity { @@ -146,6 +149,8 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn this.lookingAt.set(lookingAt); } else if (lengthSq == 0) { throw new IllegalArgumentException("lookingAt is zero-length"); + } else if (!Float.isFinite(lengthSq)) { + throw new IllegalArgumentException("lookingAt is not finite: " + lookingAt); } else { float length = (float) Math.sqrt(lengthSq); this.lookingAt.set( @@ -172,6 +177,8 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn this.upVector.set(upVector); } else if (lengthSq == 0) { throw new IllegalArgumentException("upVector is zero-length"); + } else if (!Float.isFinite(lengthSq)) { + throw new IllegalArgumentException("upVector is not finite: " + upVector); } else { float length = (float) Math.sqrt(lengthSq); this.upVector.set( @@ -216,8 +223,76 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn * @see #setLookingAt(Vec3) */ public void changeUpVector(Vec3 newUpVector) { - // TODO - this.upVector.set(newUpVector); + Objects.requireNonNull(newUpVector, "newUpVector"); + + Vec3 u0 = upVector; + Vec3 u1 = newUpVector; + + if (u1.x == 0 && u1.y == 0 && u1.z == 0) { + // Entering weightlessness, not changing anything + return; + } + + if (u0.x == u1.x && u0.y == u1.y && u0.z == u1.z) { + // Nothing changed + return; + } + + if (u0.x == -u1.x && u0.y == -u1.y && u0.z == -u1.z) { + // Welp, don't do anything stupid then + upVector.set(newUpVector); + return; + } + + float u1LengthSq = u1.x*u1.x + u1.y*u1.y + u1.z*u1.z; + float u1Length = 1; + + if (!Float.isFinite(u1LengthSq)) { + throw new IllegalArgumentException("newUpVector is not finite: " + newUpVector); + } else if (u1LengthSq != 1) { + u1Length = (float) Math.sqrt(u1LengthSq); + } + + // u0 and u1 are now both definitely two different usable vectors + + if (rotateLookingAtToMatchUpVectorRotation(u0, u1, u1Length, lookingAt)) { + return; + } + + upVector.set(newUpVector).div(u1Length); + } + + private static boolean rotateLookingAtToMatchUpVectorRotation(Vec3 u0, Vec3 u1, float u1Length, Vec3 lookingAt) { + // Determine rotation parameters + Vec3 axis = u0.cross_(u1); + float cos = u0.dot(u1) / u1Length; + float sin = axis.length() / u1Length; + + if (sin == 0) { + return true; + } + + axis.div(sin * u1Length); // normalize axis + + float x = axis.x; + float y = axis.y; + float z = axis.z; + + Mat3 matrix = Matrices.grab3(); + + // Don't format. @formatter:off + matrix.set( + cos + (1 - cos)*x*x, (1 - cos)*x*y - sin*z, (1 - cos)*x*z + sin*y, + (1 - cos)*y*x + sin*z, cos + (1 - cos)*y*y, (1 - cos)*y*z - sin*x, + (1 - cos)*z*x - sin*y, (1 - cos)*z*y + sin*x, cos + (1 - cos)*z*z + ); + // @formatter:on + + matrix.mul_(lookingAt); // bug in jglm, .mul() and .mul_() are swapped + + Matrices.release(matrix); + + return false; } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/DebugGraphics.java b/src/main/java/ru/windcorp/progressia/test/DebugGraphics.java new file mode 100644 index 0000000..859132f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/DebugGraphics.java @@ -0,0 +1,95 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test; + +import glm.mat._4.Mat4; +import glm.vec._3.Vec3; +import glm.vec._4.Vec4; +import ru.windcorp.progressia.client.graphics.Colors; +import ru.windcorp.progressia.client.graphics.model.Renderable; +import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; +import ru.windcorp.progressia.client.graphics.model.Shapes; +import ru.windcorp.progressia.client.graphics.model.StaticModel; +import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.common.util.Vectors; + +public class DebugGraphics { + + private static final float TAIL_THICKNESS = 0.03f; + private static final float HEAD_SIZE = 0.1f; + + private static final Renderable THE_VECTOR = StaticModel.builder().addPart( + new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null) + .setSize(1.0f, TAIL_THICKNESS, TAIL_THICKNESS) + .setOrigin(0, -TAIL_THICKNESS / 2, -TAIL_THICKNESS / 2) + .create() + ).addPart( + new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null) + .setSize(HEAD_SIZE, HEAD_SIZE, HEAD_SIZE) + .setOrigin((1 - HEAD_SIZE / 2), -HEAD_SIZE / 2, -HEAD_SIZE / 2) + .create() + ).build(); + + public static void drawVector(Vec3 vector, Vec4 color, Vec3 origin, float scale, ShapeRenderHelper renderer) { + float length = vector.length(); + if (length == 0) return; + + if (scale == 0) scale = 1 / length; + + Mat4 mat = renderer.pushTransform(); + + mat.translate(origin); + + Vec3 somePerpendicular = new Vec3(); + + if (Math.abs(vector.z) > (1 - 1e-4f) * length) { + somePerpendicular.set(1, 0, 0); + } else { + somePerpendicular.set(0, 0, 1); + } + + Vec3 f = vector; + Vec3 s = somePerpendicular.cross_(f).normalize(); + Vec3 u = somePerpendicular.set(f).cross(s).normalize(); + + // @formatter:off + mat.mul(new Mat4( + +f.x * scale, +f.y * scale, +f.z * scale, 0, + -s.x, -s.y, -s.z, 0, + +u.x, +u.y, +u.z, 0, + 0, 0, 0, 1 + )); + // @formatter:on + + renderer.pushColorMultiplier().mul(color); + THE_VECTOR.render(renderer); + renderer.popColorMultiplier(); + + renderer.popTransform(); + } + + public static void drawVector(Vec3 vector, ShapeRenderHelper renderer) { + drawVector(vector, Colors.GRAY_A, Vectors.ZERO_3, 1, renderer); + } + + public static void drawDirection(Vec3 vector, ShapeRenderHelper renderer) { + drawVector(vector, Colors.GRAY_A, Vectors.ZERO_3, 0, renderer); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java index 1254399..541d909 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java +++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java @@ -116,7 +116,7 @@ public class TestPlayerControls { desiredVelocity.normalize(); } desiredVelocity.z = movementUp; - movementTransform.mul_(desiredVelocity); // bug in jglm, .mul() and mul_() are + movementTransform.mul_(desiredVelocity); // bug in jglm, .mul() and .mul_() are // swapped desiredVelocity.mul(speed); @@ -154,9 +154,9 @@ public class TestPlayerControls { Vec3 s = u.cross_(f); return mat.set( - +f.x, -s.x, +u.x, - +f.y, -s.y, +u.y, - +f.z, -s.z, +u.z + +f.x, +f.y, +f.z, + -s.x, -s.y, -s.z, + +u.x, +u.y, +u.z ); } @@ -282,7 +282,13 @@ public class TestPlayerControls { return; } - getEntity().getVelocity().add(0, 0, JUMP_VELOCITY); + Vec3 up = getEntity().getUpVector(); + + getEntity().getVelocity().add( + up.x * JUMP_VELOCITY, + up.y * JUMP_VELOCITY, + up.z * JUMP_VELOCITY + ); } private void handleShift(int multiplier) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java index ebcf715..39e889e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java @@ -28,7 +28,14 @@ public class TestGravityModel extends GravityModel { @Override protected void doGetGravity(Vec3 pos, Vec3 output) { - output.set(0, 0, -9.8); + output.set(pos); + + if (output.length() < 10) { + output.set(0); + return; + } + + output.normalize().mul(-9.8f); } } From 848178b3437d6fcac260987d97e0976edc869b22 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 1 Feb 2021 17:25:07 +0300 Subject: [PATCH 05/63] Renamed BlockFace and BlockRelation to AbsFace and AbsRelation - Renamed BlockFace to AbsFace - Renamed BlockRelation to AbsRelation - Renamed AbsFace constants using the following scheme: POS_X, NEG_Y, etc. --- .../graphics/model/BlockFaceVectors.java | 72 ++++++++--------- .../client/graphics/model/Faces.java | 4 +- .../client/graphics/model/Shapes.java | 16 ++-- .../graphics/texture/ComplexTexture.java | 8 +- .../client/graphics/world/Selection.java | 6 +- .../progressia/client/world/ChunkRender.java | 8 +- .../client/world/ChunkRenderModel.java | 10 +-- .../client/world/ChunkUpdateListener.java | 6 +- .../world/block/BlockRenderOpaqueCube.java | 28 +++---- .../world/block/BlockRenderTexturedCube.java | 42 +++++----- .../block/BlockRenderTransparentCube.java | 28 +++---- .../world/cro/ChunkRenderOptimizer.java | 6 +- .../cro/ChunkRenderOptimizerSurface.java | 34 ++++---- .../client/world/tile/TileRender.java | 6 +- .../client/world/tile/TileRenderGrass.java | 10 +-- .../client/world/tile/TileRenderNone.java | 4 +- .../world/tile/TileRenderOpaqueSurface.java | 4 +- .../client/world/tile/TileRenderSurface.java | 12 +-- .../tile/TileRenderTransparentSurface.java | 4 +- .../progressia/common/collision/AABBoid.java | 4 +- .../common/collision/TranslatedAABB.java | 4 +- .../collision/colliders/AABBoidCollider.java | 4 +- .../progressia/common/world/BlockRay.java | 14 ++-- .../progressia/common/world/ChunkData.java | 46 +++++------ .../common/world/ChunkDataListener.java | 4 +- .../block/{BlockFace.java => AbsFace.java} | 81 ++++++++++--------- .../{BlockRelation.java => AbsRelation.java} | 6 +- .../common/world/generic/GenericChunk.java | 8 +- .../world/generic/GenericTileStack.java | 4 +- .../common/world/generic/GenericWorld.java | 10 +-- .../common/world/tile/PacketAddTile.java | 4 +- .../common/world/tile/PacketAffectTile.java | 10 +-- .../common/world/tile/PacketRemoveTile.java | 4 +- .../progressia/server/world/ChunkLogic.java | 8 +- .../server/world/TickAndUpdateUtil.java | 10 +-- .../server/world/TickContextMutable.java | 16 ++-- .../server/world/UpdateTriggerer.java | 4 +- .../server/world/block/BlockLogic.java | 6 +- .../server/world/block/BlockTickContext.java | 12 +-- .../world/tasks/BlockTriggeredUpdate.java | 4 +- .../server/world/tasks/TickChunk.java | 6 +- .../world/tasks/TileTriggeredUpdate.java | 6 +- .../server/world/tasks/WorldAccessor.java | 10 +-- .../server/world/tile/TSTickContext.java | 4 +- .../server/world/tile/TileLogic.java | 4 +- .../progressia/test/ControlPlaceTileData.java | 8 +- .../progressia/test/TestBlockLogicAir.java | 4 +- .../progressia/test/TestBlockLogicGlass.java | 4 +- .../progressia/test/TestChunkCodec.java | 4 +- .../windcorp/progressia/test/TestContent.java | 2 +- .../test/TestEntityRenderJavapony.java | 12 +-- .../progressia/test/TestTileLogicGrass.java | 10 +-- .../test/gen/TestWorldGenerator.java | 18 ++--- 53 files changed, 333 insertions(+), 330 deletions(-) rename src/main/java/ru/windcorp/progressia/common/world/block/{BlockFace.java => AbsFace.java} (58%) rename src/main/java/ru/windcorp/progressia/common/world/block/{BlockRelation.java => AbsRelation.java} (95%) diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java index 3b929c0..0b07363 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java @@ -18,23 +18,23 @@ package ru.windcorp.progressia.client.graphics.model; -import static ru.windcorp.progressia.common.world.block.BlockFace.*; +import static ru.windcorp.progressia.common.world.block.AbsFace.*; import com.google.common.collect.ImmutableMap; import glm.vec._3.Vec3; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; class BlockFaceVectors { private static BlockFaceVectors createInner(BlockFaceVectors outer) { - ImmutableMap.Builder originBuilder = ImmutableMap.builder(); + ImmutableMap.Builder originBuilder = ImmutableMap.builder(); - ImmutableMap.Builder widthBuilder = ImmutableMap.builder(); + ImmutableMap.Builder widthBuilder = ImmutableMap.builder(); - ImmutableMap.Builder heightBuilder = ImmutableMap.builder(); + ImmutableMap.Builder heightBuilder = ImmutableMap.builder(); - for (BlockFace face : getFaces()) { + for (AbsFace face : getFaces()) { Vec3 width = outer.getWidth(face); Vec3 height = outer.getHeight(face); @@ -59,36 +59,36 @@ class BlockFaceVectors { static { OUTER = new BlockFaceVectors( - ImmutableMap.builder() + ImmutableMap.builder() - .put(TOP, new Vec3(-0.5f, +0.5f, +0.5f)) - .put(BOTTOM, new Vec3(-0.5f, -0.5f, -0.5f)) - .put(NORTH, new Vec3(+0.5f, -0.5f, -0.5f)) - .put(SOUTH, new Vec3(-0.5f, +0.5f, -0.5f)) - .put(WEST, new Vec3(+0.5f, +0.5f, -0.5f)) - .put(EAST, new Vec3(-0.5f, -0.5f, -0.5f)) + .put(POS_Z, new Vec3(-0.5f, +0.5f, +0.5f)) + .put(NEG_Z, new Vec3(-0.5f, -0.5f, -0.5f)) + .put(POS_X, new Vec3(+0.5f, -0.5f, -0.5f)) + .put(NEG_X, new Vec3(-0.5f, +0.5f, -0.5f)) + .put(POS_Y, new Vec3(+0.5f, +0.5f, -0.5f)) + .put(NEG_Y, new Vec3(-0.5f, -0.5f, -0.5f)) .build(), - ImmutableMap.builder() + ImmutableMap.builder() - .put(TOP, new Vec3(0, -1, 0)) - .put(BOTTOM, new Vec3(0, +1, 0)) - .put(NORTH, new Vec3(0, +1, 0)) - .put(SOUTH, new Vec3(0, -1, 0)) - .put(WEST, new Vec3(-1, 0, 0)) - .put(EAST, new Vec3(+1, 0, 0)) + .put(POS_Z, new Vec3(0, -1, 0)) + .put(NEG_Z, new Vec3(0, +1, 0)) + .put(POS_X, new Vec3(0, +1, 0)) + .put(NEG_X, new Vec3(0, -1, 0)) + .put(POS_Y, new Vec3(-1, 0, 0)) + .put(NEG_Y, new Vec3(+1, 0, 0)) .build(), - ImmutableMap.builder() + ImmutableMap.builder() - .put(TOP, new Vec3(+1, 0, 0)) - .put(BOTTOM, new Vec3(+1, 0, 0)) - .put(NORTH, new Vec3(0, 0, +1)) - .put(SOUTH, new Vec3(0, 0, +1)) - .put(WEST, new Vec3(0, 0, +1)) - .put(EAST, new Vec3(0, 0, +1)) + .put(POS_Z, new Vec3(+1, 0, 0)) + .put(NEG_Z, new Vec3(+1, 0, 0)) + .put(POS_X, new Vec3(0, 0, +1)) + .put(NEG_X, new Vec3(0, 0, +1)) + .put(POS_Y, new Vec3(0, 0, +1)) + .put(NEG_Y, new Vec3(0, 0, +1)) .build() ); @@ -100,29 +100,29 @@ class BlockFaceVectors { return inner ? INNER : OUTER; } - private final ImmutableMap origins; - private final ImmutableMap widths; - private final ImmutableMap heights; + private final ImmutableMap origins; + private final ImmutableMap widths; + private final ImmutableMap heights; public BlockFaceVectors( - ImmutableMap origins, - ImmutableMap widths, - ImmutableMap heights + ImmutableMap origins, + ImmutableMap widths, + ImmutableMap heights ) { this.origins = origins; this.widths = widths; this.heights = heights; } - public Vec3 getOrigin(BlockFace face) { + public Vec3 getOrigin(AbsFace face) { return origins.get(face); } - public Vec3 getWidth(BlockFace face) { + public Vec3 getWidth(AbsFace face) { return widths.get(face); } - public Vec3 getHeight(BlockFace face) { + public Vec3 getHeight(AbsFace face) { return heights.get(face); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java index d1e9c07..ff0f08f 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java @@ -25,7 +25,7 @@ import glm.vec._3.Vec3; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram.VertexBuilder; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class Faces { @@ -94,7 +94,7 @@ public class Faces { Texture texture, Vec4 colorMultiplier, Vec3 blockCenter, - BlockFace face, + AbsFace face, boolean inner ) { BlockFaceVectors vectors = BlockFaceVectors.get(inner); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java index 7ddd5d6..8e30d14 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java @@ -24,7 +24,7 @@ import glm.vec._3.Vec3; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.backend.Usage; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class Shapes { @@ -165,16 +165,16 @@ public class Shapes { public PppBuilder( ShapeRenderProgram program, - Map textureMap + Map textureMap ) { this( program, - textureMap.get(BlockFace.TOP), - textureMap.get(BlockFace.BOTTOM), - textureMap.get(BlockFace.NORTH), - textureMap.get(BlockFace.SOUTH), - textureMap.get(BlockFace.EAST), - textureMap.get(BlockFace.WEST) + textureMap.get(AbsFace.POS_Z), + textureMap.get(AbsFace.NEG_Z), + textureMap.get(AbsFace.POS_X), + textureMap.get(AbsFace.NEG_X), + textureMap.get(AbsFace.NEG_Y), + textureMap.get(AbsFace.POS_Y) ); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java index a4f2881..40fefbd 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client.graphics.texture; import java.util.Map; import glm.vec._2.Vec2; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class ComplexTexture { @@ -54,14 +54,14 @@ public class ComplexTexture { ); } - public Map getCuboidTextures( + public Map getCuboidTextures( int x, int y, int width, int height, int depth ) { - return BlockFace.mapToFaces( + return AbsFace.mapToFaces( get( x + depth + width, y + height + depth, @@ -86,7 +86,7 @@ public class ComplexTexture { ); } - public Map getCuboidTextures( + public Map getCuboidTextures( int x, int y, int size diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java index e6cd57d..b4dc7dc 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java @@ -23,13 +23,13 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.world.WorldRender; import ru.windcorp.progressia.common.world.BlockRay; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; public class Selection { private final Vec3i block = new Vec3i(); - private BlockFace surface = null; + private AbsFace surface = null; private final Vec2 pointOnSurface = new Vec2(0.5f, 0.5f); private final Vec3 point = new Vec3(); @@ -70,7 +70,7 @@ public class Selection { return exists ? point : null; } - public BlockFace getSurface() { + public AbsFace getSurface() { return exists ? surface : null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index 21f6098..b746843 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -30,7 +30,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderRegistry; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.tile.TileDataStack; @@ -64,12 +64,12 @@ public class ChunkRender } @Override - public TileRenderStack getTiles(Vec3i blockInChunk, BlockFace face) { + public TileRenderStack getTiles(Vec3i blockInChunk, AbsFace face) { return getTileStackWrapper(getData().getTiles(blockInChunk, face)); } @Override - public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { + public boolean hasTiles(Vec3i blockInChunk, AbsFace face) { return getData().hasTiles(blockInChunk, face); } @@ -119,7 +119,7 @@ public class ChunkRender } @Override - public BlockFace getFace() { + public AbsFace getFace() { return parent.getFace(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 9653abe..2b4ead7 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -36,7 +36,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class ChunkRenderModel implements Renderable { @@ -99,7 +99,7 @@ public class ChunkRenderModel implements Renderable { private void processBlockAndTiles(Vec3i blockInChunk, Builder sink) { processBlock(blockInChunk, sink); - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { processTileStack(blockInChunk, face, sink); } } @@ -127,7 +127,7 @@ public class ChunkRenderModel implements Renderable { } } - private void processTileStack(Vec3i blockInChunk, BlockFace face, Builder sink) { + private void processTileStack(Vec3i blockInChunk, AbsFace face, Builder sink) { TileRenderStack trs = chunk.getTilesOrNull(blockInChunk, face); if (trs == null || trs.isEmpty()) { @@ -137,7 +137,7 @@ public class ChunkRenderModel implements Renderable { trs.forEach(tile -> processTile(tile, blockInChunk, face, sink)); } - private void processTile(TileRender tile, Vec3i blockInChunk, BlockFace face, Builder sink) { + private void processTile(TileRender tile, Vec3i blockInChunk, AbsFace face, Builder sink) { if (tile instanceof TileRenderNone) { return; } @@ -152,7 +152,7 @@ public class ChunkRenderModel implements Renderable { processTileWithCROs(tile, blockInChunk, face); } - private void processTileWithCROs(TileRender tile, Vec3i blockInChunk, BlockFace face) { + private void processTileWithCROs(TileRender tile, Vec3i blockInChunk, AbsFace face) { for (ChunkRenderOptimizer optimizer : optimizers) { optimizer.addTile(tile, blockInChunk, face); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java index 32a950f..9b873ee 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java @@ -22,7 +22,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; class ChunkUpdateListener implements ChunkDataListener { @@ -41,7 +41,7 @@ class ChunkUpdateListener implements ChunkDataListener { @Override public void onChunkLoaded(ChunkData chunk) { Vec3i cursor = new Vec3i(); - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { cursor.set(chunk.getX(), chunk.getY(), chunk.getZ()); cursor.add(face.getVector()); world.markChunkForUpdate(cursor); @@ -57,7 +57,7 @@ class ChunkUpdateListener implements ChunkDataListener { public void onChunkTilesChanged( ChunkData chunk, Vec3i blockInChunk, - BlockFace face, + AbsFace face, TileData tile, boolean wasAdded ) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java index e4d8723..7913fa8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java @@ -19,27 +19,27 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class BlockRenderOpaqueCube extends BlockRenderTexturedCube { public BlockRenderOpaqueCube( String id, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture + Texture posZTexture, + Texture negZTexture, + Texture posXTexture, + Texture negXTexture, + Texture negYTexture, + Texture posYTexture ) { super( id, - topTexture, - bottomTexture, - northTexture, - southTexture, - eastTexture, - westTexture + posZTexture, + negZTexture, + posXTexture, + negXTexture, + negYTexture, + posYTexture ); } @@ -56,7 +56,7 @@ public class BlockRenderOpaqueCube extends BlockRenderTexturedCube { } @Override - public boolean isOpaque(BlockFace face) { + public boolean isOpaque(AbsFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java index 1042a46..b1b41d5 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.client.world.block; -import static ru.windcorp.progressia.common.world.block.BlockFace.*; +import static ru.windcorp.progressia.common.world.block.AbsFace.*; import java.util.HashMap; import java.util.Map; @@ -38,44 +38,44 @@ import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.BlockOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public abstract class BlockRenderTexturedCube extends BlockRender implements BlockOptimizedSurface { - private final Map textures = new HashMap<>(); + private final Map textures = new HashMap<>(); public BlockRenderTexturedCube( String id, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture + Texture posZTexture, + Texture negZTexture, + Texture posXTexture, + Texture negXTexture, + Texture negYTexture, + Texture posYTexture ) { super(id); - textures.put(TOP, topTexture); - textures.put(BOTTOM, bottomTexture); - textures.put(NORTH, northTexture); - textures.put(SOUTH, southTexture); - textures.put(EAST, eastTexture); - textures.put(WEST, westTexture); + textures.put(POS_Z, posZTexture); + textures.put(NEG_Z, negZTexture); + textures.put(POS_X, posXTexture); + textures.put(NEG_X, negXTexture); + textures.put(NEG_Y, negYTexture); + textures.put(POS_Y, posYTexture); } - public Texture getTexture(BlockFace blockFace) { + public Texture getTexture(AbsFace blockFace) { return textures.get(blockFace); } - public Vec4 getColorMultiplier(BlockFace blockFace) { + public Vec4 getColorMultiplier(AbsFace blockFace) { return Colors.WHITE; } @Override public final void getFaces( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, + ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -84,7 +84,7 @@ public abstract class BlockRenderTexturedCube } private Face createFace( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, + ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, Vec3 offset ) { @@ -105,12 +105,12 @@ public abstract class BlockRenderTexturedCube Face[] faces = new Face[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { - faces[i] = createFace(chunk, blockInChunk, BlockFace.getFaces().get(i), false, Vectors.ZERO_3); + faces[i] = createFace(chunk, blockInChunk, AbsFace.getFaces().get(i), false, Vectors.ZERO_3); } if (!opaque) { for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { - faces[i + BLOCK_FACE_COUNT] = createFace(chunk, blockInChunk, BlockFace.getFaces().get(i), true, Vectors.ZERO_3); + faces[i + BLOCK_FACE_COUNT] = createFace(chunk, blockInChunk, AbsFace.getFaces().get(i), true, Vectors.ZERO_3); } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java index 7f3df03..424e4f0 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java @@ -19,27 +19,27 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class BlockRenderTransparentCube extends BlockRenderTexturedCube { public BlockRenderTransparentCube( String id, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture + Texture posZTexture, + Texture negZTexture, + Texture posXTexture, + Texture negXTexture, + Texture negYTexture, + Texture posYTexture ) { super( id, - topTexture, - bottomTexture, - northTexture, - southTexture, - eastTexture, - westTexture + posZTexture, + negZTexture, + posXTexture, + negXTexture, + negYTexture, + posYTexture ); } @@ -56,7 +56,7 @@ public class BlockRenderTransparentCube extends BlockRenderTexturedCube { } @Override - public boolean isOpaque(BlockFace face) { + public boolean isOpaque(AbsFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java index b684c6a..a42aa6f 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; /** * Chunk render optimizer (CRO) is an object that produces optimized models for @@ -44,7 +44,7 @@ import ru.windcorp.progressia.common.world.block.BlockFace; * instance. *

  • {@link #startRender()} is invoked. The CRO must reset its state.
  • *
  • {@link #addBlock(BlockRender, Vec3i)} and - * {@link #addTile(TileRender, Vec3i, BlockFace)} are invoked for each block and + * {@link #addTile(TileRender, Vec3i, AbsFace)} are invoked for each block and * tile that this CRO should optimize. {@code addTile} specifies tiles in order * of ascension within a tile stack.
  • *
  • {@link #endRender()} is invoked. The CRO may perform any pending @@ -116,7 +116,7 @@ public abstract class ChunkRenderOptimizer extends Namespaced { * @param blockInChunk the position of the block that the tile belongs to * @param blockFace the face that the tile belongs to */ - public abstract void addTile(TileRender tile, Vec3i blockInChunk, BlockFace blockFace); + public abstract void addTile(TileRender tile, Vec3i blockInChunk, AbsFace blockFace); /** * Requests that the CRO assembles and outputs its model. This method may diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index 488938e..fc0bd5c 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.cro; import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; -import static ru.windcorp.progressia.common.world.block.BlockFace.BLOCK_FACE_COUNT; +import static ru.windcorp.progressia.common.world.block.AbsFace.BLOCK_FACE_COUNT; import static ru.windcorp.progressia.common.world.generic.GenericTileStack.TILES_PER_FACE; import java.util.ArrayList; @@ -38,7 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @@ -69,7 +69,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { void getFaces( ChunkData chunk, Vec3i blockInChunk, - BlockFace blockFace, + AbsFace blockFace, boolean inner, Consumer output, Vec3 offset /* kostyl 156% */ @@ -77,14 +77,14 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { /** * Returns the opacity of the surface identified by the provided - * {@link BlockFace}. + * {@link AbsFace}. * Opaque surfaces prevent surfaces behind them from being included in * chunk models. * * @param blockFace the face to query * @return {@code true} iff the surface is opaque. */ - boolean isOpaque(BlockFace blockFace); + boolean isOpaque(AbsFace blockFace); } /** @@ -168,7 +168,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } @Override - public void addTile(TileRender tile, Vec3i pos, BlockFace face) { + public void addTile(TileRender tile, Vec3i pos, AbsFace face) { if (!(tile instanceof TileOptimizedSurface)) return; @@ -180,7 +180,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { getBlock(pos).block = block; } - private void addTile(Vec3i pos, BlockFace face, TileOptimizedSurface tile) { + private void addTile(Vec3i pos, AbsFace face, TileOptimizedSurface tile) { FaceInfo faceInfo = getFace(pos, face); int index = faceInfo.tileCount; @@ -201,7 +201,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { return data[cursor.x][cursor.y][cursor.z]; } - protected FaceInfo getFace(Vec3i cursor, BlockFace face) { + protected FaceInfo getFace(Vec3i cursor, AbsFace face) { return getBlock(cursor).faces[face.getId()]; } @@ -238,12 +238,12 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { Vec3i blockInChunk, Consumer output ) { - for (BlockFace blockFace : BlockFace.getFaces()) { + for (AbsFace blockFace : AbsFace.getFaces()) { processOuterFace(blockInChunk, blockFace, output); } } - private void processOuterFace(Vec3i blockInChunk, BlockFace blockFace, Consumer output) { + private void processOuterFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { if (!shouldRenderOuterFace(blockInChunk, blockFace)) return; @@ -274,12 +274,12 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { Vec3i blockInChunk, Consumer output ) { - for (BlockFace blockFace : BlockFace.getFaces()) { + for (AbsFace blockFace : AbsFace.getFaces()) { processInnerFace(blockInChunk, blockFace, output); } } - private void processInnerFace(Vec3i blockInChunk, BlockFace blockFace, Consumer output) { + private void processInnerFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { if (!shouldRenderInnerFace(blockInChunk, blockFace)) return; @@ -306,7 +306,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } } - private boolean shouldRenderOuterFace(Vec3i blockInChunk, BlockFace face) { + private boolean shouldRenderOuterFace(Vec3i blockInChunk, AbsFace face) { blockInChunk.add(face.getVector()); try { return shouldRenderWhenFacing(blockInChunk, face); @@ -315,11 +315,11 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } } - private boolean shouldRenderInnerFace(Vec3i blockInChunk, BlockFace face) { + private boolean shouldRenderInnerFace(Vec3i blockInChunk, AbsFace face) { return shouldRenderWhenFacing(blockInChunk, face); } - private boolean shouldRenderWhenFacing(Vec3i blockInChunk, BlockFace face) { + private boolean shouldRenderWhenFacing(Vec3i blockInChunk, AbsFace face) { if (chunk.containsBiC(blockInChunk)) { return shouldRenderWhenFacingLocal(blockInChunk, face); } else { @@ -327,7 +327,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } } - private boolean shouldRenderWhenFacingLocal(Vec3i blockInChunk, BlockFace face) { + private boolean shouldRenderWhenFacingLocal(Vec3i blockInChunk, AbsFace face) { BlockOptimizedSurface block = getBlock(blockInChunk).block; if (block == null) { @@ -340,7 +340,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { return true; } - private boolean shouldRenderWhenFacingNeighbor(Vec3i blockInLocalChunk, BlockFace face) { + private boolean shouldRenderWhenFacingNeighbor(Vec3i blockInLocalChunk, AbsFace face) { Vec3i blockInChunk = Vectors.grab3i().set(blockInLocalChunk.x, blockInLocalChunk.y, blockInLocalChunk.z); Vec3i chunkPos = Vectors.grab3i().set(chunk.getX(), chunk.getY(), chunk.getZ()); diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java index 4f82d86..4cef07e 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizer; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericTile; public class TileRender extends Namespaced implements GenericTile { @@ -33,13 +33,13 @@ public class TileRender extends Namespaced implements GenericTile { super(id); } - public void render(ShapeRenderHelper renderer, BlockFace face) { + public void render(ShapeRenderHelper renderer, AbsFace face) { throw new UnsupportedOperationException( "TileRender.render() not implemented in " + this ); } - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, BlockFace face) { + public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, AbsFace face) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java index c73647b..86ed0dc 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class TileRenderGrass extends TileRenderSurface { @@ -37,13 +37,13 @@ public class TileRenderGrass extends TileRenderSurface { } @Override - public Texture getTexture(BlockFace face) { - return (face == BlockFace.TOP) ? topTexture : sideTexture; + public Texture getTexture(AbsFace face) { + return (face == AbsFace.POS_Z) ? topTexture : sideTexture; } @Override - public boolean isOpaque(BlockFace face) { - return face == BlockFace.TOP; + public boolean isOpaque(AbsFace face) { + return face == AbsFace.POS_Z; } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java index 8e2a6e4..3b3c345 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java @@ -21,7 +21,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class TileRenderNone extends TileRender { @@ -30,7 +30,7 @@ public class TileRenderNone extends TileRender { } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, BlockFace face) { + public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, AbsFace face) { return EmptyModel.getInstance(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java index e4990e8..62bf758 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class TileRenderOpaqueSurface extends TileRenderSurface { @@ -28,7 +28,7 @@ public class TileRenderOpaqueSurface extends TileRenderSurface { } @Override - public boolean isOpaque(BlockFace face) { + public boolean isOpaque(AbsFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java index eebcb07..76d8fbb 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java @@ -34,7 +34,7 @@ import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.TileOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public abstract class TileRenderSurface extends TileRender implements TileOptimizedSurface { @@ -49,17 +49,17 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi this(id, null); } - public Texture getTexture(BlockFace blockFace) { + public Texture getTexture(AbsFace blockFace) { return texture; } - public Vec4 getColorMultiplier(BlockFace blockFace) { + public Vec4 getColorMultiplier(AbsFace blockFace) { return Colors.WHITE; } @Override public final void getFaces( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, + ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -68,7 +68,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } private Face createFace( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, + ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, Vec3 offset ) { @@ -83,7 +83,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace) { + public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace) { return new Shape( Usage.STATIC, WorldRenderProgram.getDefault(), diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java index b35986e..29a99ac 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class TileRenderTransparentSurface extends TileRenderSurface { @@ -28,7 +28,7 @@ public class TileRenderTransparentSurface extends TileRenderSurface { } @Override - public boolean isOpaque(BlockFace face) { + public boolean isOpaque(AbsFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java b/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java index ab2cd80..c22d4b6 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public interface AABBoid extends CollisionModel { @@ -27,7 +27,7 @@ public interface AABBoid extends CollisionModel { void getSize(Vec3 output); - default Wall getWall(BlockFace face) { + default Wall getWall(AbsFace face) { return getWall(face.getId()); } diff --git a/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java b/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java index 4c33ad2..4568f75 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public class TranslatedAABB implements AABBoid { @@ -51,7 +51,7 @@ public class TranslatedAABB implements AABBoid { private AABBoid parent; private final Vec3 translation = new Vec3(); - private final TranslatedAABBWall[] walls = new TranslatedAABBWall[BlockFace.BLOCK_FACE_COUNT]; + private final TranslatedAABBWall[] walls = new TranslatedAABBWall[AbsFace.BLOCK_FACE_COUNT]; { for (int id = 0; id < walls.length; ++id) { diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java index 5fab3d8..28802b2 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java @@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.collision.colliders.Collider.ColliderWorksp import ru.windcorp.progressia.common.collision.colliders.Collider.Collision; import ru.windcorp.progressia.common.util.Matrices; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; class AABBoidCollider { @@ -50,7 +50,7 @@ class AABBoidCollider { computeCollisionVelocity(collisionVelocity, obstacleBody, colliderBody); // For every wall of collision space - for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) { + for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { Wall wall = originCollisionSpace.getWall(i); Collision collision = computeWallCollision( diff --git a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java index 743d238..6dc4750 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java +++ b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java @@ -22,7 +22,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.VectorUtil.Axis; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import static java.lang.Math.*; @@ -34,7 +34,7 @@ public class BlockRay { private float distance; private final Vec3i block = new Vec3i(); - private BlockFace currentFace = null; + private AbsFace currentFace = null; private boolean isValid = false; @@ -120,18 +120,18 @@ public class BlockRay { return (edge - c) / dir; } - private BlockFace computeCurrentFace(Axis axis, int sign) { + private AbsFace computeCurrentFace(Axis axis, int sign) { if (sign == 0) throw new IllegalStateException("sign is zero"); switch (axis) { case X: - return sign > 0 ? BlockFace.SOUTH : BlockFace.NORTH; + return sign > 0 ? AbsFace.NEG_X : AbsFace.POS_X; case Y: - return sign > 0 ? BlockFace.EAST : BlockFace.WEST; + return sign > 0 ? AbsFace.NEG_Y : AbsFace.POS_Y; default: case Z: - return sign > 0 ? BlockFace.BOTTOM : BlockFace.TOP; + return sign > 0 ? AbsFace.NEG_Z : AbsFace.POS_Z; } } @@ -147,7 +147,7 @@ public class BlockRay { return output; } - public BlockFace getCurrentFace() { + public AbsFace getCurrentFace() { return currentFace; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 252429c..4857479 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.block.BlockFace.*; +import static ru.windcorp.progressia.common.world.block.AbsFace.*; import java.util.ArrayList; import java.util.Arrays; @@ -31,7 +31,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; @@ -83,31 +83,31 @@ public class ChunkData } @Override - public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { + public TileDataStack getTilesOrNull(Vec3i blockInChunk, AbsFace face) { return tiles[getTileIndex(blockInChunk, face)]; } /** * Internal use only. Modify a list returned by - * {@link #getTiles(Vec3i, BlockFace)} or - * {@link #getTilesOrNull(Vec3i, BlockFace)} + * {@link #getTiles(Vec3i, AbsFace)} or + * {@link #getTilesOrNull(Vec3i, AbsFace)} * to change tiles. */ protected void setTiles( Vec3i blockInChunk, - BlockFace face, + AbsFace face, TileDataStack tiles ) { this.tiles[getTileIndex(blockInChunk, face)] = tiles; } @Override - public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { + public boolean hasTiles(Vec3i blockInChunk, AbsFace face) { return getTilesOrNull(blockInChunk, face) != null; } @Override - public TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { + public TileDataStack getTiles(Vec3i blockInChunk, AbsFace face) { int index = getTileIndex(blockInChunk, face); if (tiles[index] == null) { @@ -117,15 +117,15 @@ public class ChunkData return tiles[index]; } - private void createTileStack(Vec3i blockInChunk, BlockFace face) { + private void createTileStack(Vec3i blockInChunk, AbsFace face) { Vec3i independentBlockInChunk = conjureIndependentBlockInChunkVec3i(blockInChunk); TileDataStackImpl stack = new TileDataStackImpl(independentBlockInChunk, face); setTiles(blockInChunk, face, stack); } private Vec3i conjureIndependentBlockInChunkVec3i(Vec3i blockInChunk) { - for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) { - TileDataStack stack = getTilesOrNull(blockInChunk, BlockFace.getFaces().get(i)); + for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { + TileDataStack stack = getTilesOrNull(blockInChunk, AbsFace.getFaces().get(i)); if (stack instanceof TileDataStackImpl) { return ((TileDataStackImpl) stack).blockInChunk; } @@ -142,7 +142,7 @@ public class ChunkData posInChunk.x; } - private static int getTileIndex(Vec3i posInChunk, BlockFace face) { + private static int getTileIndex(Vec3i posInChunk, AbsFace face) { return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + face.getId(); } @@ -162,14 +162,14 @@ public class ChunkData posInChunk.z >= 0 && posInChunk.z < BLOCKS_PER_CHUNK; } - public boolean isBorder(Vec3i blockInChunk, BlockFace face) { + public boolean isBorder(Vec3i blockInChunk, AbsFace face) { final int min = 0, max = BLOCKS_PER_CHUNK - 1; - return (blockInChunk.x == min && face == SOUTH) || - (blockInChunk.x == max && face == NORTH) || - (blockInChunk.y == min && face == EAST) || - (blockInChunk.y == max && face == WEST) || - (blockInChunk.z == min && face == BOTTOM) || - (blockInChunk.z == max && face == TOP); + return (blockInChunk.x == min && face == NEG_X) || + (blockInChunk.x == max && face == POS_X) || + (blockInChunk.y == min && face == NEG_Y) || + (blockInChunk.y == max && face == POS_Y) || + (blockInChunk.z == min && face == NEG_Z) || + (blockInChunk.z == max && face == POS_Z); } public void forEachBlock(Consumer action) { @@ -186,7 +186,7 @@ public class ChunkData public void forEachTileStack(Consumer action) { forEachBlock(blockInChunk -> { - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { TileDataStack stack = getTilesOrNull(blockInChunk, face); if (stack == null) continue; @@ -309,9 +309,9 @@ public class ChunkData * Potentially shared */ private final Vec3i blockInChunk; - private final BlockFace face; + private final AbsFace face; - public TileDataStackImpl(Vec3i blockInChunk, BlockFace face) { + public TileDataStackImpl(Vec3i blockInChunk, AbsFace face) { this.blockInChunk = blockInChunk; this.face = face; } @@ -325,7 +325,7 @@ public class ChunkData } @Override - public BlockFace getFace() { + public AbsFace getFace() { return face; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java index 72008c4..3913468 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.common.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface ChunkDataListener { @@ -55,7 +55,7 @@ public interface ChunkDataListener { default void onChunkTilesChanged( ChunkData chunk, Vec3i blockInChunk, - BlockFace face, + AbsFace face, TileData tile, boolean wasAdded ) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java b/src/main/java/ru/windcorp/progressia/common/world/block/AbsFace.java similarity index 58% rename from src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java rename to src/main/java/ru/windcorp/progressia/common/world/block/AbsFace.java index 9023500..06747d6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/AbsFace.java @@ -23,65 +23,68 @@ import com.google.common.collect.ImmutableMap; import glm.vec._3.i.Vec3i; -public final class BlockFace extends BlockRelation { +public final class AbsFace extends AbsRelation { - public static final BlockFace TOP = new BlockFace(0, 0, +1, true, "TOP"), - BOTTOM = new BlockFace(0, 0, -1, false, "BOTTOM"), - NORTH = new BlockFace(+1, 0, 0, true, "NORTH"), - SOUTH = new BlockFace(-1, 0, 0, false, "SOUTH"), - WEST = new BlockFace(0, +1, 0, false, "WEST"), - EAST = new BlockFace(0, -1, 0, true, "EAST"); + // @formatter:off + public static final AbsFace + POS_Z = new AbsFace( 0, 0, +1, true, "POS_Z"), + NEG_Z = new AbsFace( 0, 0, -1, false, "NEG_Z"), + POS_X = new AbsFace(+1, 0, 0, true, "POS_X"), + NEG_X = new AbsFace(-1, 0, 0, false, "NEG_X"), + POS_Y = new AbsFace( 0, +1, 0, false, "POS_Y"), + NEG_Y = new AbsFace( 0, -1, 0, true, "NEG_Y"); + // @formatter:on - private static final ImmutableList ALL_FACES = ImmutableList.of(TOP, BOTTOM, NORTH, SOUTH, WEST, EAST); + private static final ImmutableList ALL_FACES = ImmutableList.of(POS_Z, NEG_Z, POS_X, NEG_X, POS_Y, NEG_Y); static { - link(TOP, BOTTOM); - link(NORTH, SOUTH); - link(WEST, EAST); + link(POS_Z, NEG_Z); + link(POS_X, NEG_X); + link(POS_Y, NEG_Y); } - private static final ImmutableList PRIMARY_FACES = ALL_FACES.stream().filter(BlockFace::isPrimary) + private static final ImmutableList PRIMARY_FACES = ALL_FACES.stream().filter(AbsFace::isPrimary) .collect(ImmutableList.toImmutableList()); - private static final ImmutableList SECONDARY_FACES = ALL_FACES.stream().filter(BlockFace::isSecondary) + private static final ImmutableList SECONDARY_FACES = ALL_FACES.stream().filter(AbsFace::isSecondary) .collect(ImmutableList.toImmutableList()); public static final int BLOCK_FACE_COUNT = ALL_FACES.size(); public static final int PRIMARY_BLOCK_FACE_COUNT = PRIMARY_FACES.size(); public static final int SECONDARY_BLOCK_FACE_COUNT = SECONDARY_FACES.size(); - public static ImmutableList getFaces() { + public static ImmutableList getFaces() { return ALL_FACES; } - public static ImmutableList getPrimaryFaces() { + public static ImmutableList getPrimaryFaces() { return PRIMARY_FACES; } - public static ImmutableList getSecondaryFaces() { + public static ImmutableList getSecondaryFaces() { return SECONDARY_FACES; } - private static void link(BlockFace a, BlockFace b) { + private static void link(AbsFace a, AbsFace b) { a.counterFace = b; b.counterFace = a; } - public static ImmutableMap mapToFaces( - E top, - E bottom, - E north, - E south, - E east, - E west + public static ImmutableMap mapToFaces( + E posZ, + E negZ, + E posX, + E negX, + E negY, + E posY ) { - return ImmutableMap.builderWithExpectedSize(6) - .put(TOP, top) - .put(BOTTOM, bottom) - .put(NORTH, north) - .put(SOUTH, south) - .put(EAST, east) - .put(WEST, west) + return ImmutableMap.builderWithExpectedSize(6) + .put(POS_Z, posZ) + .put(NEG_Z, negZ) + .put(POS_X, posX) + .put(NEG_X, negX) + .put(NEG_Y, negY) + .put(POS_Y, posY) .build(); } @@ -89,10 +92,10 @@ public final class BlockFace extends BlockRelation { private final int id; private final String name; - private BlockFace counterFace; + private AbsFace counterFace; private final boolean isPrimary; - private BlockFace(int x, int y, int z, boolean isPrimary, String name) { + private AbsFace(int x, int y, int z, boolean isPrimary, String name) { super(x, y, z); this.id = nextId++; this.isPrimary = isPrimary; @@ -107,14 +110,14 @@ public final class BlockFace extends BlockRelation { return isPrimary; } - public BlockFace getPrimary() { + public AbsFace getPrimary() { if (isPrimary) return this; else return counterFace; } - public BlockFace getPrimaryAndMoveCursor(Vec3i cursor) { + public AbsFace getPrimaryAndMoveCursor(Vec3i cursor) { if (isPrimary) return this; @@ -126,14 +129,14 @@ public final class BlockFace extends BlockRelation { return !isPrimary; } - public BlockFace getSecondary() { + public AbsFace getSecondary() { if (isPrimary) return counterFace; else return this; } - public BlockFace getSecondaryAndMoveCursor(Vec3i cursor) { + public AbsFace getSecondaryAndMoveCursor(Vec3i cursor) { if (!isPrimary) return this; @@ -141,11 +144,11 @@ public final class BlockFace extends BlockRelation { return counterFace; } - public BlockFace getCounter() { + public AbsFace getCounter() { return counterFace; } - public BlockFace getCounterAndMoveCursor(Vec3i cursor) { + public AbsFace getCounterAndMoveCursor(Vec3i cursor) { cursor.add(getVector()); return counterFace; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java b/src/main/java/ru/windcorp/progressia/common/world/block/AbsRelation.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java rename to src/main/java/ru/windcorp/progressia/common/world/block/AbsRelation.java index 659a5fa..a14b4f0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/AbsRelation.java @@ -24,19 +24,19 @@ import static java.lang.Math.max; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -public class BlockRelation { +public class AbsRelation { private final Vec3i vector = new Vec3i(); private final Vec3 floatVector = new Vec3(); private final Vec3 normalized = new Vec3(); - public BlockRelation(int x, int y, int z) { + public AbsRelation(int x, int y, int z) { vector.set(x, y, z); floatVector.set(x, y, z); normalized.set(x, y, z).normalize(); } - public BlockRelation(Vec3i vector) { + public AbsRelation(Vec3i vector) { this(vector.x, vector.y, vector.z); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 656304f..c2e9611 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -24,7 +24,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public interface GenericChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> { @@ -34,9 +34,9 @@ public interface GenericChunk, B exten B getBlock(Vec3i blockInChunk); - TS getTiles(Vec3i blockInChunk, BlockFace face); + TS getTiles(Vec3i blockInChunk, AbsFace face); - boolean hasTiles(Vec3i blockInChunk, BlockFace face); + boolean hasTiles(Vec3i blockInChunk, AbsFace face); default int getX() { return getPosition().x; @@ -182,7 +182,7 @@ public interface GenericChunk, B exten ); } - default TS getTilesOrNull(Vec3i blockInChunk, BlockFace face) { + default TS getTilesOrNull(Vec3i blockInChunk, AbsFace face) { if (hasTiles(blockInChunk, face)) { return getTiles(blockInChunk, face); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java index 31a5158..5b6ea89 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java @@ -25,7 +25,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public abstract class GenericTileStack, T extends GenericTile, C extends GenericChunk> extends AbstractList @@ -41,7 +41,7 @@ public abstract class GenericTileStack public abstract C getChunk(); - public abstract BlockFace getFace(); + public abstract AbsFace getFace(); public Vec3i getBlockInWorld(Vec3i output) { // This is safe diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java index 943067e..af5ebb9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java @@ -26,7 +26,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; public interface GenericWorld, C extends GenericChunk, E extends GenericEntity> { @@ -63,7 +63,7 @@ public interface GenericWorld { TileLogic tile = context.getTile(); @@ -106,7 +106,7 @@ public class TickAndUpdateUtil { } } - public static void updateTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { + public static void updateTile(WorldLogic world, Vec3i blockInWorld, AbsFace face, int layer) { TileLogic tile = world.getTile(blockInWorld, face, layer); if (!(tile instanceof UpdateableTile)) return; @@ -116,7 +116,7 @@ public class TickAndUpdateUtil { updateTile((UpdateableTile) tile, tickContext); } - public static void updateTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { + public static void updateTiles(WorldLogic world, Vec3i blockInWorld, AbsFace face) { TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() .forEachTile(context -> { TileLogic tile = context.getTile(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java index 68185d9..86e75bb 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java @@ -25,7 +25,7 @@ import java.util.function.Function; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericTileStack; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; @@ -126,7 +126,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } public static interface Block extends Builder { - Builder.TileStack withFace(BlockFace face); + Builder.TileStack withFace(AbsFace face); } public static interface TileStack extends Builder { @@ -148,7 +148,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont protected Server server; protected final Vec3i chunk = new Vec3i(); protected final Vec3i blockInWorld = new Vec3i(); - protected BlockFace face; + protected AbsFace face; protected int layer; protected Role role = Role.NONE; @@ -188,7 +188,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public BlockFace getFace() { + public AbsFace getFace() { checkContextState(Role.TILE_STACK); return this.face; } @@ -277,7 +277,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public TileStack withFace(BlockFace face) { + public TileStack withFace(AbsFace face) { Objects.requireNonNull(face, "face"); checkBuilderState(Role.BLOCK); @@ -339,12 +339,12 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont @Override public void forEachFace(Consumer action) { checkContextState(Role.BLOCK); - BlockFace previousFace = this.face; + AbsFace previousFace = this.face; Role previousRole = this.role; this.role = Role.TILE_STACK; - for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) { - this.face = BlockFace.getFaces().get(i); + for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { + this.face = AbsFace.getFaces().get(i); action.accept(this); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index 511170e..6d8bf22 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -23,7 +23,7 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; @@ -49,7 +49,7 @@ public class UpdateTriggerer implements ChunkDataListener { public void onChunkTilesChanged( ChunkData chunk, Vec3i blockInChunk, - BlockFace face, + AbsFace face, TileData tile, boolean wasAdded ) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index 794259f..5522813 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericBlock; public class BlockLogic extends Namespaced implements GenericBlock { @@ -28,11 +28,11 @@ public class BlockLogic extends Namespaced implements GenericBlock { super(id); } - public boolean isSolid(BlockTickContext context, BlockFace face) { + public boolean isSolid(BlockTickContext context, AbsFace face) { return isSolid(face); } - public boolean isSolid(BlockFace face) { + public boolean isSolid(AbsFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java index a305b9a..3f3dbc2 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java @@ -25,8 +25,8 @@ import java.util.function.Function; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockFace; -import ru.windcorp.progressia.common.world.block.BlockRelation; +import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.block.AbsRelation; import ru.windcorp.progressia.server.world.ChunkTickContext; import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.tile.TSTickContext; @@ -56,7 +56,7 @@ public interface BlockTickContext extends ChunkTickContext { Objects.requireNonNull(action, "action"); TickContextMutable context = TickContextMutable.uninitialized(); - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { context.rebuild().withServer(getServer()).withBlock(getBlockInWorld()).withFace(face).build(); action.accept(context); } @@ -67,7 +67,7 @@ public interface BlockTickContext extends ChunkTickContext { return TickContextMutable.copyWorld(this).withBlock(getBlockInWorld().add_(direction)).build(); } - default BlockTickContext getNeighbor(BlockRelation relation) { + default BlockTickContext getNeighbor(AbsRelation relation) { Objects.requireNonNull(relation, "relation"); return getNeighbor(relation.getVector()); } @@ -78,7 +78,7 @@ public interface BlockTickContext extends ChunkTickContext { return action.apply(getNeighbor(direction)); } - default R evalNeighbor(BlockRelation relation, Function action) { + default R evalNeighbor(AbsRelation relation, Function action) { Objects.requireNonNull(action, "action"); Objects.requireNonNull(relation, "relation"); return evalNeighbor(relation.getVector(), action); @@ -93,7 +93,7 @@ public interface BlockTickContext extends ChunkTickContext { }); } - default void forNeighbor(BlockRelation relation, Consumer action) { + default void forNeighbor(AbsRelation relation, Consumer action) { Objects.requireNonNull(action, "action"); Objects.requireNonNull(relation, "relation"); forNeighbor(relation.getVector(), action); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java index 331a5c4..369492e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; import ru.windcorp.progressia.server.world.WorldLogic; @@ -41,7 +41,7 @@ class BlockTriggeredUpdate extends CachedEvaluation { WorldLogic world = server.getWorld(); - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { TickAndUpdateUtil.updateTiles(world, cursor, face); cursor.add(face.getVector()); TickAndUpdateUtil.updateBlock(world, cursor); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index c0895e1..07fab12 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableList; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatMathUtil; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.ChunkLogic; @@ -54,7 +54,7 @@ public class TickChunk extends Evaluation { List> randomTickMethods = new ArrayList<>(); randomTickMethods.add(this::tickRandomBlock); - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { randomTickMethods.add(s -> this.tickRandomTile(s, face)); } @@ -151,7 +151,7 @@ public class TickChunk extends Evaluation { tickable.tick(context); } - private void tickRandomTile(Server server, BlockFace face) { + private void tickRandomTile(Server server, AbsFace face) { Random random = server.getAdHocRandom(); Vec3i blockInChunk = new Vec3i( diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java index 76fc414..b69ca2b 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; import ru.windcorp.progressia.server.world.WorldLogic; @@ -30,7 +30,7 @@ import ru.windcorp.progressia.server.world.WorldLogic; class TileTriggeredUpdate extends CachedEvaluation { private final Vec3i blockInWorld = new Vec3i(); - private BlockFace face = null; + private AbsFace face = null; public TileTriggeredUpdate(Consumer disposer) { super(disposer); @@ -53,7 +53,7 @@ class TileTriggeredUpdate extends CachedEvaluation { // complement } - public void init(Vec3i blockInWorld, BlockFace face) { + public void init(Vec3i blockInWorld, AbsFace face) { this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); this.face = face; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java index 2c83ccd..0b34bcf 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java @@ -24,7 +24,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.MultiLOC; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; @@ -64,17 +64,17 @@ public class WorldAccessor { setBlock(blockInWorld, BlockDataRegistry.getInstance().get(id)); } - public void addTile(Vec3i blockInWorld, BlockFace face, TileData tile) { + public void addTile(Vec3i blockInWorld, AbsFace face, TileData tile) { AddTile change = cache.grab(AddTile.class); change.getPacket().set(tile, blockInWorld, face); server.requestChange(change); } - public void addTile(Vec3i blockInWorld, BlockFace face, String id) { + public void addTile(Vec3i blockInWorld, AbsFace face, String id) { addTile(blockInWorld, face, TileDataRegistry.getInstance().get(id)); } - public void removeTile(Vec3i blockInWorld, BlockFace face, int tag) { + public void removeTile(Vec3i blockInWorld, AbsFace face, int tag) { RemoveTile change = cache.grab(RemoveTile.class); change.getPacket().set(blockInWorld, face, tag); server.requestChange(change); @@ -112,7 +112,7 @@ public class WorldAccessor { * @param face */ // TODO rename to something meaningful - public void triggerUpdates(Vec3i blockInWorld, BlockFace face) { + public void triggerUpdates(Vec3i blockInWorld, AbsFace face) { TileTriggeredUpdate evaluation = cache.grab(TileTriggeredUpdate.class); evaluation.init(blockInWorld, face); server.requestEvaluation(evaluation); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index 399f7b8..0110469 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -23,7 +23,7 @@ import java.util.function.Consumer; import java.util.function.Function; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; @@ -35,7 +35,7 @@ public interface TSTickContext extends BlockTickContext { * Specifications */ - BlockFace getFace(); + AbsFace getFace(); /* * Getters diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java index 4a97ead..f10283b 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericTile; public class TileLogic extends Namespaced implements GenericTile { @@ -32,7 +32,7 @@ public class TileLogic extends Namespaced implements GenericTile { return canOccupyFace(context.getFace()); } - public boolean canOccupyFace(BlockFace face) { + public boolean canOccupyFace(AbsFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java b/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java index 5a37b6f..6df061c 100644 --- a/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java +++ b/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java @@ -20,14 +20,14 @@ package ru.windcorp.progressia.test; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.comms.controls.ControlData; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; public class ControlPlaceTileData extends ControlData { private TileData tile; private final Vec3i blockInWorld = new Vec3i(); - private BlockFace face; + private AbsFace face; public ControlPlaceTileData(String id) { super(id); @@ -41,11 +41,11 @@ public class ControlPlaceTileData extends ControlData { return blockInWorld; } - public BlockFace getFace() { + public AbsFace getFace() { return face; } - public void set(TileData block, Vec3i blockInWorld, BlockFace face) { + public void set(TileData block, Vec3i blockInWorld, AbsFace face) { this.tile = block; this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); this.face = face; diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java index e378dbf..a31f521 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.server.world.block.BlockLogic; public class TestBlockLogicAir extends BlockLogic { @@ -28,7 +28,7 @@ public class TestBlockLogicAir extends BlockLogic { } @Override - public boolean isSolid(BlockFace face) { + public boolean isSolid(AbsFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java index eca9e5c..f0386d6 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.server.world.block.BlockLogic; public class TestBlockLogicGlass extends BlockLogic { @@ -28,7 +28,7 @@ public class TestBlockLogicGlass extends BlockLogic { } @Override - public boolean isSolid(BlockFace face) { + public boolean isSolid(AbsFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index a4f891b..82c14f7 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -38,7 +38,7 @@ import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.io.ChunkCodec; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; @@ -138,7 +138,7 @@ public class TestChunkCodec extends ChunkCodec { break; bic.set(xOrEndMarker, input.readByte() & 0xFF, input.readByte() & 0xFF); - BlockFace face = BlockFace.getFaces().get(input.readByte() & 0xFF); + AbsFace face = AbsFace.getFaces().get(input.readByte() & 0xFF); int tiles = input.readByte() & 0xFF; diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index fe647f2..2f7d461 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -413,7 +413,7 @@ public class TestContent { ControlPlaceTileData controlData = ((ControlPlaceTileData) packet.getControl()); TileData tile = controlData.getTile(); Vec3i blockInWorld = controlData.getBlockInWorld(); - BlockFace face = controlData.getFace(); + AbsFace face = controlData.getFace(); if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) return; diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java index aefa1c6..0b6c7a2 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java @@ -39,7 +39,7 @@ import ru.windcorp.progressia.client.world.entity.EntityRender; import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry; import ru.windcorp.progressia.client.world.entity.EntityRenderable; import ru.windcorp.progressia.client.world.entity.QuadripedModel; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; public class TestEntityRenderJavapony extends EntityRender { @@ -78,7 +78,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addStaticPart( new PppBuilder( WorldRenderProgram.getDefault(), - BlockFace.mapToFaces( + AbsFace.mapToFaces( tailStartTexture, tailStartTexture, tailStartTexture, @@ -97,7 +97,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addStaticPart( new PppBuilder( WorldRenderProgram.getDefault(), - BlockFace.mapToFaces( + AbsFace.mapToFaces( neckTexture, neckTexture, neckTexture, @@ -360,7 +360,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addPart( new PppBuilder( program, - BlockFace.mapToFaces( + AbsFace.mapToFaces( texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), texture.get(32 + 8, 64, 16, 8), @@ -375,7 +375,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addPart( new PppBuilder( program, - BlockFace.mapToFaces( + AbsFace.mapToFaces( texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), texture.get(32 + 12, 64 + 8, 8, 4), @@ -416,7 +416,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addPart( new PppBuilder( program, - BlockFace.mapToFaces( + AbsFace.mapToFaces( texture.get(128, 96, 16, 16), texture.get(128, 96, 16, 16), texture.get(128, 96, 16, 32), diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index 06afc77..9c96d16 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockTickContext; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; @@ -34,12 +34,12 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile @Override public boolean canOccupyFace(TileTickContext context) { - return context.getFace() != BlockFace.BOTTOM && super.canOccupyFace(context); + return context.getFace() != AbsFace.NEG_Z && super.canOccupyFace(context); } @Override - public boolean canOccupyFace(BlockFace face) { - return face != BlockFace.BOTTOM; + public boolean canOccupyFace(AbsFace face) { + return face != AbsFace.NEG_Z; } @Override @@ -64,7 +64,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile } private boolean isBlockAboveTransparent(BlockTickContext context) { - return context.evalNeighbor(BlockFace.TOP, bctxt -> { + return context.evalNeighbor(AbsFace.POS_Z, bctxt -> { BlockLogic block = bctxt.getBlock(); if (block == null) return true; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 1b35ffc..e206ebb 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -33,7 +33,7 @@ import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.world.WorldLogic; @@ -238,9 +238,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); - world.getTiles(biw, BlockFace.TOP).add(grass); + world.getTiles(biw, AbsFace.POS_Z).add(grass); - for (BlockFace face : BlockFace.getFaces()) { + for (AbsFace face : AbsFace.getFaces()) { if (face.getVector().z != 0) continue; biw.add(face.getVector()); @@ -257,25 +257,25 @@ public class TestWorldGenerator extends AbstractWorldGenerator { private void addDecor(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt) { if (isDirt) { if (random.nextInt(8) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( + world.getTiles(biw, AbsFace.POS_Z).addFarthest( TileDataRegistry.getInstance().get("Test:Sand") ); } if (random.nextInt(8) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( + world.getTiles(biw, AbsFace.POS_Z).addFarthest( TileDataRegistry.getInstance().get("Test:Stones") ); } if (random.nextInt(8) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( + world.getTiles(biw, AbsFace.POS_Z).addFarthest( TileDataRegistry.getInstance().get("Test:YellowFlowers") ); } } else { if (random.nextInt(2) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( + world.getTiles(biw, AbsFace.POS_Z).addFarthest( TileDataRegistry.getInstance().get("Test:Stones") ); } @@ -300,8 +300,8 @@ public class TestWorldGenerator extends AbstractWorldGenerator { double halfChance = computeSnowHalfChance(height, grad); double opaqueChance = computeSnowOpaqueChance(height, grad); - for (BlockFace face : BlockFace.getFaces()) { - if (face == BlockFace.BOTTOM) + for (AbsFace face : AbsFace.getFaces()) { + if (face == AbsFace.NEG_Z) continue; if (face.getVector().z == 0) { From acef9d32df56214915ac10a83931c6269ba27d7e Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 1 Feb 2021 19:14:49 +0300 Subject: [PATCH 06/63] Changed packages for relations, renamed Face to ShapePart - Added BlockRelation as an abstract superclass to existing relations - Must be given an absolute "up" direction before use - Moved AbsFace, AbsRelation and BlockRelation to .world.rels - Renamed Face to ShapePart to reduce confusion with AbsFace --- .../client/graphics/flat/RenderTarget.java | 18 +-- .../client/graphics/font/SpriteTypeface.java | 14 +- .../graphics/model/BlockFaceVectors.java | 4 +- .../client/graphics/model/Shape.java | 124 +++++++++--------- .../model/{Face.java => ShapePart.java} | 12 +- .../{FaceGroup.java => ShapePartGroup.java} | 6 +- .../model/{Faces.java => ShapeParts.java} | 12 +- .../graphics/model/ShapeRenderProgram.java | 8 +- .../client/graphics/model/Shapes.java | 14 +- .../graphics/texture/ComplexTexture.java | 2 +- .../client/graphics/world/Selection.java | 2 +- .../graphics/world/WorldRenderProgram.java | 10 +- .../progressia/client/world/ChunkRender.java | 2 +- .../client/world/ChunkRenderModel.java | 2 +- .../client/world/ChunkUpdateListener.java | 2 +- .../world/block/BlockRenderOpaqueCube.java | 2 +- .../world/block/BlockRenderTexturedCube.java | 18 +-- .../block/BlockRenderTransparentCube.java | 2 +- .../world/cro/ChunkRenderOptimizer.java | 2 +- .../cro/ChunkRenderOptimizerSurface.java | 40 +++--- .../client/world/tile/TileRender.java | 2 +- .../client/world/tile/TileRenderGrass.java | 2 +- .../client/world/tile/TileRenderNone.java | 2 +- .../world/tile/TileRenderOpaqueSurface.java | 2 +- .../client/world/tile/TileRenderSurface.java | 14 +- .../tile/TileRenderTransparentSurface.java | 2 +- .../progressia/common/collision/AABBoid.java | 2 +- .../common/collision/TranslatedAABB.java | 2 +- .../collision/colliders/AABBoidCollider.java | 2 +- .../progressia/common/world/BlockRay.java | 2 +- .../progressia/common/world/ChunkData.java | 4 +- .../common/world/ChunkDataListener.java | 2 +- .../common/world/generic/GenericChunk.java | 2 +- .../world/generic/GenericTileStack.java | 2 +- .../common/world/generic/GenericWorld.java | 2 +- .../common/world/{block => rels}/AbsFace.java | 2 +- .../common/world/rels/AbsRelation.java | 76 +++++++++++ .../BlockRelation.java} | 43 +++--- .../common/world/tile/PacketAddTile.java | 2 +- .../common/world/tile/PacketAffectTile.java | 2 +- .../common/world/tile/PacketRemoveTile.java | 2 +- .../progressia/server/world/ChunkLogic.java | 2 +- .../server/world/TickAndUpdateUtil.java | 2 +- .../server/world/TickContextMutable.java | 2 +- .../server/world/UpdateTriggerer.java | 2 +- .../server/world/block/BlockLogic.java | 2 +- .../server/world/block/BlockTickContext.java | 4 +- .../world/tasks/BlockTriggeredUpdate.java | 2 +- .../server/world/tasks/TickChunk.java | 2 +- .../world/tasks/TileTriggeredUpdate.java | 2 +- .../server/world/tasks/WorldAccessor.java | 2 +- .../server/world/tile/TSTickContext.java | 2 +- .../server/world/tile/TileLogic.java | 2 +- .../progressia/test/ControlPlaceTileData.java | 2 +- .../progressia/test/TestBlockLogicAir.java | 2 +- .../progressia/test/TestBlockLogicGlass.java | 2 +- .../progressia/test/TestChunkCodec.java | 2 +- .../windcorp/progressia/test/TestContent.java | 1 + .../test/TestEntityRenderJavapony.java | 38 +++--- .../progressia/test/TestTileLogicGrass.java | 2 +- .../test/gen/TestWorldGenerator.java | 2 +- 61 files changed, 305 insertions(+), 239 deletions(-) rename src/main/java/ru/windcorp/progressia/client/graphics/model/{Face.java => ShapePart.java} (95%) rename src/main/java/ru/windcorp/progressia/client/graphics/model/{FaceGroup.java => ShapePartGroup.java} (93%) rename src/main/java/ru/windcorp/progressia/client/graphics/model/{Faces.java => ShapeParts.java} (91%) rename src/main/java/ru/windcorp/progressia/common/world/{block => rels}/AbsFace.java (98%) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java rename src/main/java/ru/windcorp/progressia/common/world/{block/AbsRelation.java => rels/BlockRelation.java} (76%) diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java index 1fea54e..0501897 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java @@ -29,8 +29,8 @@ import glm.vec._3.Vec3; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; -import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapeParts; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -84,7 +84,7 @@ public class RenderTarget { private final Deque maskStack = new LinkedList<>(); private final Deque transformStack = new LinkedList<>(); - private final List currentClipFaces = new ArrayList<>(); + private final List currentClipFaces = new ArrayList<>(); private int depth = 0; @@ -94,8 +94,8 @@ public class RenderTarget { protected void assembleCurrentClipFromFaces() { if (!currentClipFaces.isEmpty()) { - Face[] faces = currentClipFaces.toArray( - new Face[currentClipFaces.size()] + ShapePart[] faces = currentClipFaces.toArray( + new ShapePart[currentClipFaces.size()] ); currentClipFaces.clear(); @@ -198,7 +198,7 @@ public class RenderTarget { ); } - protected void addFaceToCurrentClip(Face face) { + protected void addFaceToCurrentClip(ShapePart face) { currentClipFaces.add(face); } @@ -270,7 +270,7 @@ public class RenderTarget { fill(Colors.toVector(color)); } - public Face createRectagleFace( + public ShapePart createRectagleFace( int x, int y, int width, @@ -280,7 +280,7 @@ public class RenderTarget { ) { float depth = this.depth--; - return Faces.createRectangle( + return ShapeParts.createRectangle( FlatRenderProgram.getDefault(), texture, color, @@ -291,7 +291,7 @@ public class RenderTarget { ); } - public Face createRectagleFace( + public ShapePart createRectagleFace( int x, int y, int width, diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java index 7920799..d1db43a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java @@ -33,8 +33,8 @@ import gnu.trove.stack.TIntStack; import gnu.trove.stack.array.TIntArrayStack; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; -import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapeParts; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram; @@ -144,7 +144,7 @@ public abstract class SpriteTypeface extends Typeface { return new Shape( Usage.STATIC, getProgram(), - Faces.createRectangle( + ShapeParts.createRectangle( getProgram(), getTexture(c), Colors.WHITE, @@ -167,7 +167,7 @@ public abstract class SpriteTypeface extends Typeface { private final Renderable unitLine = new Shape( Usage.STATIC, getProgram(), - Faces.createRectangle( + ShapeParts.createRectangle( getProgram(), null, Vectors.UNIT_4, @@ -257,7 +257,7 @@ public abstract class SpriteTypeface extends Typeface { private class SDWorkspace extends SpriteTypeface.Workspace { - private final Collection faces = new ArrayList<>(); + private final Collection faces = new ArrayList<>(); private final Vec3 origin = new Vec3(); private final Vec3 width = new Vec3(); @@ -298,7 +298,7 @@ public abstract class SpriteTypeface extends Typeface { workspace.height.sub(workspace.origin); workspace.faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( getProgram(), texture, color, @@ -314,7 +314,7 @@ public abstract class SpriteTypeface extends Typeface { return new Shape( Usage.STATIC, getProgram(), - workspace.faces.toArray(new Face[workspace.faces.size()]) + workspace.faces.toArray(new ShapePart[workspace.faces.size()]) ); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java index 0b07363..7d94fb2 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java @@ -18,12 +18,12 @@ package ru.windcorp.progressia.client.graphics.model; -import static ru.windcorp.progressia.common.world.block.AbsFace.*; +import static ru.windcorp.progressia.common.world.rels.AbsFace.*; import com.google.common.collect.ImmutableMap; import glm.vec._3.Vec3; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; class BlockFaceVectors { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java index 145b149..d465ad2 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java @@ -30,10 +30,10 @@ import ru.windcorp.progressia.client.graphics.backend.VertexBufferObject; public class Shape implements Renderable { private final ShapeRenderProgram program; - private final Face[] faces; + private final ShapePart[] parts; private final Usage usage; - private FaceGroup[] groups; + private ShapePartGroup[] groups; private ByteBuffer vertices; private ShortBuffer indices; @@ -45,33 +45,33 @@ public class Shape implements Renderable { private VertexBufferObject verticesVbo; private VertexBufferObject indicesVbo; - public Shape(Usage usage, ShapeRenderProgram program, Face... faces) { + public Shape(Usage usage, ShapeRenderProgram program, ShapePart... parts) { this.program = program; - this.faces = faces; + this.parts = parts; this.usage = usage; - configureFaces(); + configureParts(); program.preprocess(this); assembleBuffers(); } - private void configureFaces() { - for (Face face : faces) { - face.setShape(this); + private void configureParts() { + for (ShapePart part : parts) { + part.setShape(this); } } private void assembleBuffers() { // TODO optimize: only update faces that requested it - sortFaces(); + sortParts(); resizeBuffers(); - for (Face face : faces) { - assembleVertices(face); - assembleIndices(face); - face.resetUpdateFlags(); + for (ShapePart part : parts) { + assembleVertices(part); + assembleIndices(part); + part.resetUpdateFlags(); } this.vertices.flip(); @@ -85,110 +85,110 @@ public class Shape implements Renderable { private void resizeBuffers() { int verticesRequired = 0, indicesRequired = 0; - for (Face face : faces) { - verticesRequired += face.getVertices().remaining(); - indicesRequired += face.getIndices().remaining(); + for (ShapePart part : parts) { + verticesRequired += part.getVertices().remaining(); + indicesRequired += part.getIndices().remaining(); } - if (this.vertices == null || vertices.capacity() < verticesRequired) { + if (vertices == null || vertices.capacity() < verticesRequired) { this.vertices = BufferUtils.createByteBuffer(verticesRequired); } else { - this.vertices.position(0).limit(verticesRequired); + vertices.position(0).limit(verticesRequired); } - if (this.indices == null || this.indices.capacity() < indicesRequired) { + if (indices == null || indices.capacity() < indicesRequired) { this.indices = BufferUtils.createShortBuffer(indicesRequired); } else { - this.indices.position(0).limit(indicesRequired); + indices.position(0).limit(indicesRequired); } } - private void assembleVertices(Face face) { - face.locationOfVertices = this.vertices.position(); + private void assembleVertices(ShapePart part) { + part.locationOfVertices = this.vertices.position(); - insertVertices(face); - linkVerticesWith(face); + insertVertices(part); + linkVerticesWith(part); } - private void insertVertices(Face face) { - ByteBuffer faceVertices = face.getVertices(); + private void insertVertices(ShapePart part) { + ByteBuffer partVertices = part.getVertices(); - faceVertices.mark(); - this.vertices.put(faceVertices); - faceVertices.reset(); + partVertices.mark(); + this.vertices.put(partVertices); + partVertices.reset(); } - private void linkVerticesWith(Face face) { + private void linkVerticesWith(ShapePart part) { int limit = vertices.limit(); int position = vertices.position(); - vertices.limit(position).position(face.getLocationOfVertices()); - face.vertices = vertices.slice(); + vertices.limit(position).position(part.getLocationOfVertices()); + part.vertices = vertices.slice(); vertices.position(position).limit(limit); } - private void assembleIndices(Face face) { - short vertexOffset = (short) (face.getLocationOfVertices() / program.getBytesPerVertex()); + private void assembleIndices(ShapePart part) { + short vertexOffset = (short) (part.getLocationOfVertices() / program.getBytesPerVertex()); - face.locationOfIndices = indices.position(); + part.locationOfIndices = indices.position(); - ShortBuffer faceIndices = face.getIndices(); + ShortBuffer partIndices = part.getIndices(); - if (faceIndices == null) { - for (int i = 0; i < face.getVertexCount(); ++i) { + if (partIndices == null) { + for (int i = 0; i < part.getVertexCount(); ++i) { this.indices.put((short) (vertexOffset + i)); } } else { - for (int i = faceIndices.position(); i < faceIndices.limit(); ++i) { - short faceIndex = faceIndices.get(i); - faceIndex += vertexOffset; - this.indices.put(faceIndex); + for (int i = partIndices.position(); i < partIndices.limit(); ++i) { + short partIndex = partIndices.get(i); + partIndex += vertexOffset; + this.indices.put(partIndex); } } } - private void sortFaces() { - Arrays.sort(faces); + private void sortParts() { + Arrays.sort(parts); } private void assembleGroups() { - int unique = countUniqueFaces(); - this.groups = new FaceGroup[unique]; + int unique = countUniqueParts(); + this.groups = new ShapePartGroup[unique]; - if (faces.length == 0) + if (parts.length == 0) return; - int previousHandle = faces[0].getSortingIndex(); + int previousHandle = parts[0].getSortingIndex(); int start = 0; int groupIndex = 0; - for (int i = 1; i < faces.length; ++i) { - if (previousHandle != faces[i].getSortingIndex()) { + for (int i = 1; i < parts.length; ++i) { + if (previousHandle != parts[i].getSortingIndex()) { - groups[groupIndex] = new FaceGroup(faces, start, i); + groups[groupIndex] = new ShapePartGroup(parts, start, i); start = i; groupIndex++; - previousHandle = faces[i].getSortingIndex(); + previousHandle = parts[i].getSortingIndex(); } } assert groupIndex == groups.length - 1; - groups[groupIndex] = new FaceGroup(faces, start, faces.length); + groups[groupIndex] = new ShapePartGroup(parts, start, parts.length); } - private int countUniqueFaces() { - if (faces.length == 0) + private int countUniqueParts() { + if (parts.length == 0) return 0; int result = 1; - int previousHandle = faces[0].getSortingIndex(); + int previousHandle = parts[0].getSortingIndex(); - for (int i = 1; i < faces.length; ++i) { - if (previousHandle != faces[i].getSortingIndex()) { + for (int i = 1; i < parts.length; ++i) { + if (previousHandle != parts[i].getSortingIndex()) { result++; - previousHandle = faces[i].getSortingIndex(); + previousHandle = parts[i].getSortingIndex(); } } @@ -238,11 +238,11 @@ public class Shape implements Renderable { return program; } - public Face[] getFaces() { - return faces; + public ShapePart[] getParts() { + return parts; } - public FaceGroup[] getGroups() { + public ShapePartGroup[] getGroups() { return groups; } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePart.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java rename to src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePart.java index 79da464..aef0ad9 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePart.java @@ -24,7 +24,7 @@ import java.util.Objects; import ru.windcorp.progressia.client.graphics.texture.Texture; -public class Face implements Comparable { +public class ShapePart implements Comparable { private static final ShortBuffer GENERATE_SUCCESSIVE_LATER = null; @@ -40,7 +40,7 @@ public class Face implements Comparable { private ShortBuffer userIndices; private boolean userIndicesUpdated = true; - public Face( + public ShapePart( Texture texture, ByteBuffer vertices, ShortBuffer indices @@ -50,7 +50,7 @@ public class Face implements Comparable { setIndices(indices); } - public Face( + public ShapePart( Texture texture, ByteBuffer vertices ) { @@ -155,7 +155,7 @@ public class Face implements Comparable { return vertices; } - public Face setVertices(ByteBuffer vertices) { + public ShapePart setVertices(ByteBuffer vertices) { this.vertices = Objects.requireNonNull(vertices, "vertices"); markForVertexUpdate(); return this; @@ -202,7 +202,7 @@ public class Face implements Comparable { return userIndices.remaining(); } - public Face setIndices(ShortBuffer indices) { + public ShapePart setIndices(ShortBuffer indices) { if (indices == null) { indices = GENERATE_SUCCESSIVE_LATER; } @@ -245,7 +245,7 @@ public class Face implements Comparable { } @Override - public int compareTo(Face o) { + public int compareTo(ShapePart o) { return Integer.compare(getSortingIndex(), o.getSortingIndex()); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePartGroup.java similarity index 93% rename from src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java rename to src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePartGroup.java index ee91544..4f138fe 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePartGroup.java @@ -21,13 +21,13 @@ package ru.windcorp.progressia.client.graphics.model; import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.texture.TexturePrimitive; -public class FaceGroup { +public class ShapePartGroup { private final TexturePrimitive texture; private final int indexCount; private final int byteOffsetOfIndices; - FaceGroup(Face[] faces, int start, int end) { + ShapePartGroup(ShapePart[] faces, int start, int end) { Texture t = faces[start].getTexture(); this.texture = t == null ? null : t.getSprite().getPrimitive(); @@ -36,7 +36,7 @@ public class FaceGroup { int indexCount = 0; for (int i = start; i < end; ++i) { - Face face = faces[i]; + ShapePart face = faces[i]; assert this.texture == null ? (face.getTexture() == null) diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java similarity index 91% rename from src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java rename to src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java index ff0f08f..50f744f 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java @@ -25,14 +25,14 @@ import glm.vec._3.Vec3; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram.VertexBuilder; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; -public class Faces { +public class ShapeParts { - private Faces() { + private ShapeParts() { } - public static Face createRectangle( + public static ShapePart createRectangle( ShapeRenderProgram program, Texture texture, Vec4 colorMultiplier, @@ -82,14 +82,14 @@ public class Faces { } ); - return new Face( + return new ShapePart( texture, builder.assemble(), buffer ); } - public static Face createBlockFace( + public static ShapePart createBlockFace( ShapeRenderProgram program, Texture texture, Vec4 colorMultiplier, diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java index e27bc77..6c7bdf6 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java @@ -116,7 +116,7 @@ public class ShapeRenderProgram extends Program { try { enableAttributes(); - for (FaceGroup group : shape.getGroups()) { + for (ShapePartGroup group : shape.getGroups()) { renderFaceGroup(group); } } finally { @@ -182,7 +182,7 @@ public class ShapeRenderProgram extends Program { indices.bind(BindTarget.ELEMENT_ARRAY); } - protected void renderFaceGroup(FaceGroup group) { + protected void renderFaceGroup(ShapePartGroup group) { TexturePrimitive texture = group.getTexture(); if (texture != null) { @@ -206,12 +206,12 @@ public class ShapeRenderProgram extends Program { } public void preprocess(Shape shape) { - for (Face face : shape.getFaces()) { + for (ShapePart face : shape.getParts()) { applySprites(face); } } - private void applySprites(Face face) { + private void applySprites(ShapePart face) { if (face.getTexture() == null) return; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java index 8e30d14..92d9872 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java @@ -24,7 +24,7 @@ import glm.vec._3.Vec3; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.backend.Usage; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class Shapes { @@ -50,7 +50,7 @@ public class Shapes { boolean flip ) { - Face top = Faces.createRectangle( + ShapePart top = ShapeParts.createRectangle( program, topTexture, colorMultiplier, @@ -60,7 +60,7 @@ public class Shapes { flip ); - Face bottom = Faces.createRectangle( + ShapePart bottom = ShapeParts.createRectangle( program, bottomTexture, colorMultiplier, @@ -70,7 +70,7 @@ public class Shapes { flip ); - Face north = Faces.createRectangle( + ShapePart north = ShapeParts.createRectangle( program, northTexture, colorMultiplier, @@ -80,7 +80,7 @@ public class Shapes { flip ); - Face south = Faces.createRectangle( + ShapePart south = ShapeParts.createRectangle( program, southTexture, colorMultiplier, @@ -90,7 +90,7 @@ public class Shapes { flip ); - Face east = Faces.createRectangle( + ShapePart east = ShapeParts.createRectangle( program, eastTexture, colorMultiplier, @@ -100,7 +100,7 @@ public class Shapes { flip ); - Face west = Faces.createRectangle( + ShapePart west = ShapeParts.createRectangle( program, westTexture, colorMultiplier, diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java index 40fefbd..a54ca51 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client.graphics.texture; import java.util.Map; import glm.vec._2.Vec2; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class ComplexTexture { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java index b4dc7dc..f3d6394 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java @@ -23,8 +23,8 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.world.WorldRender; import ru.windcorp.progressia.common.world.BlockRay; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class Selection { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java index 5e55297..c005454 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java @@ -33,7 +33,7 @@ import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.backend.VertexBufferObject; import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.*; import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.*; -import ru.windcorp.progressia.client.graphics.model.Face; +import ru.windcorp.progressia.client.graphics.model.ShapePart; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram; @@ -138,12 +138,12 @@ public class WorldRenderProgram extends ShapeRenderProgram { public void preprocess(Shape shape) { super.preprocess(shape); - for (Face face : shape.getFaces()) { + for (ShapePart face : shape.getParts()) { computeNormals(face); } } - private void computeNormals(Face face) { + private void computeNormals(ShapePart face) { Vec3 a = Vectors.grab3(); Vec3 b = Vectors.grab3(); Vec3 c = Vectors.grab3(); @@ -183,7 +183,7 @@ public class WorldRenderProgram extends ShapeRenderProgram { normal.normalize(); } - private void loadVertexPosition(Face face, int index, Vec3 result) { + private void loadVertexPosition(ShapePart face, int index, Vec3 result) { ByteBuffer vertices = face.getVertices(); int offset = vertices.position() + index * getBytesPerVertex(); @@ -194,7 +194,7 @@ public class WorldRenderProgram extends ShapeRenderProgram { ); } - private void saveVertexNormal(Face face, int index, Vec3 normal) { + private void saveVertexNormal(ShapePart face, int index, Vec3 normal) { ByteBuffer vertices = face.getVertices(); int offset = vertices.position() + index * getBytesPerVertex() + (3 * Float.BYTES + 4 * Float.BYTES + diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index b746843..02f6dd3 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -30,8 +30,8 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderRegistry; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; public class ChunkRender diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 2b4ead7..1da9163 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -36,7 +36,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class ChunkRenderModel implements Renderable { diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java index 9b873ee..e87e623 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java @@ -22,7 +22,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; class ChunkUpdateListener implements ChunkDataListener { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java index 7913fa8..4948206 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class BlockRenderOpaqueCube extends BlockRenderTexturedCube { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java index b1b41d5..918ea55 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.client.world.block; -import static ru.windcorp.progressia.common.world.block.AbsFace.*; +import static ru.windcorp.progressia.common.world.rels.AbsFace.*; import java.util.HashMap; import java.util.Map; @@ -29,8 +29,8 @@ import glm.vec._3.i.Vec3i; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; -import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapeParts; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -38,7 +38,7 @@ import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.BlockOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public abstract class BlockRenderTexturedCube extends BlockRender @@ -74,21 +74,21 @@ public abstract class BlockRenderTexturedCube } @Override - public final void getFaces( + public final void getShapeParts( ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, - Consumer output, + Consumer output, Vec3 offset ) { output.accept(createFace(chunk, blockInChunk, blockFace, inner, offset)); } - private Face createFace( + private ShapePart createFace( ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, Vec3 offset ) { - return Faces.createBlockFace( + return ShapeParts.createBlockFace( WorldRenderProgram.getDefault(), getTexture(blockFace), getColorMultiplier(blockFace), @@ -102,7 +102,7 @@ public abstract class BlockRenderTexturedCube public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { boolean opaque = isBlockOpaque(); - Face[] faces = new Face[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; + ShapePart[] faces = new ShapePart[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { faces[i] = createFace(chunk, blockInChunk, AbsFace.getFaces().get(i), false, Vectors.ZERO_3); diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java index 424e4f0..9b03802 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class BlockRenderTransparentCube extends BlockRenderTexturedCube { diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java index a42aa6f..56e7537 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; /** * Chunk render optimizer (CRO) is an object that produces optimized models for diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index fc0bd5c..0f0eeb8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -19,8 +19,8 @@ package ru.windcorp.progressia.client.world.cro; import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; -import static ru.windcorp.progressia.common.world.block.AbsFace.BLOCK_FACE_COUNT; import static ru.windcorp.progressia.common.world.generic.GenericTileStack.TILES_PER_FACE; +import static ru.windcorp.progressia.common.world.rels.AbsFace.BLOCK_FACE_COUNT; import java.util.ArrayList; import java.util.Collection; @@ -29,7 +29,7 @@ import java.util.function.Consumer; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; +import ru.windcorp.progressia.client.graphics.model.ShapePart; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; @@ -38,7 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @@ -52,26 +52,26 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { private static interface OptimizedSurface { /** - * Creates and outputs a set of faces that correspond to this surface. - * The coordinates of the face vertices must be in chunk coordinate - * system. + * Creates and outputs a set of shape parts that correspond to this + * surface. The coordinates of the face vertices must be in chunk + * coordinate system. * * @param chunk the chunk that contains the requested face * @param blockInChunk the block in chunk * @param blockFace the requested face * @param inner whether this face should be visible from inside * ({@code true}) or outside ({@code false}) - * @param output a consumer that the created faces must be given - * to + * @param output a consumer that the created shape parts must be + * given to * @param offset an additional offset that must be applied to all * vertices */ - void getFaces( + void getShapeParts( ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, - Consumer output, + Consumer output, Vec3 offset /* kostyl 156% */ ); @@ -207,12 +207,12 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @Override public Renderable endRender() { - Collection shapeFaces = new ArrayList<>( + Collection shapeParts = new ArrayList<>( BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * 3 ); Vec3i cursor = new Vec3i(); - Consumer consumer = shapeFaces::add; + Consumer consumer = shapeParts::add; for (cursor.x = 0; cursor.x < BLOCKS_PER_CHUNK; ++cursor.x) { for (cursor.y = 0; cursor.y < BLOCKS_PER_CHUNK; ++cursor.y) { @@ -223,27 +223,27 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } } - if (shapeFaces.isEmpty()) { + if (shapeParts.isEmpty()) { return null; } return new Shape( Usage.STATIC, WorldRenderProgram.getDefault(), - shapeFaces.toArray(new Face[shapeFaces.size()]) + shapeParts.toArray(new ShapePart[shapeParts.size()]) ); } private void processOuterFaces( Vec3i blockInChunk, - Consumer output + Consumer output ) { for (AbsFace blockFace : AbsFace.getFaces()) { processOuterFace(blockInChunk, blockFace, output); } } - private void processOuterFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { + private void processOuterFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { if (!shouldRenderOuterFace(blockInChunk, blockFace)) return; @@ -264,7 +264,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { if (surface == null) continue; // layer may be BLOCK_LAYER, then block may be null - surface.getFaces(chunk.getData(), blockInChunk, blockFace, false, output, faceOrigin); + surface.getShapeParts(chunk.getData(), blockInChunk, blockFace, false, output, faceOrigin); faceOrigin.add(offset); } @@ -272,14 +272,14 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { private void processInnerFaces( Vec3i blockInChunk, - Consumer output + Consumer output ) { for (AbsFace blockFace : AbsFace.getFaces()) { processInnerFace(blockInChunk, blockFace, output); } } - private void processInnerFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { + private void processInnerFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { if (!shouldRenderInnerFace(blockInChunk, blockFace)) return; @@ -300,7 +300,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { if (surface == null) continue; // layer may be BLOCK_LAYER, then block may be null - surface.getFaces(chunk.getData(), blockInChunk, blockFace, true, output, faceOrigin); + surface.getShapeParts(chunk.getData(), blockInChunk, blockFace, true, output, faceOrigin); faceOrigin.add(offset); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java index 4cef07e..52519ed 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java @@ -24,8 +24,8 @@ import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizer; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TileRender extends Namespaced implements GenericTile { diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java index 86ed0dc..1845fa6 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TileRenderGrass extends TileRenderSurface { diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java index 3b3c345..fd26e8d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java @@ -21,7 +21,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TileRenderNone extends TileRender { diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java index 62bf758..8abaa5f 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TileRenderOpaqueSurface extends TileRenderSurface { diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java index 76d8fbb..3773699 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java @@ -25,8 +25,8 @@ import glm.vec._3.i.Vec3i; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; -import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapeParts; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -34,7 +34,7 @@ import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.TileOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public abstract class TileRenderSurface extends TileRender implements TileOptimizedSurface { @@ -58,21 +58,21 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } @Override - public final void getFaces( + public final void getShapeParts( ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, - Consumer output, + Consumer output, Vec3 offset ) { output.accept(createFace(chunk, blockInChunk, blockFace, inner, offset)); } - private Face createFace( + private ShapePart createFace( ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, boolean inner, Vec3 offset ) { - return Faces.createBlockFace( + return ShapeParts.createBlockFace( WorldRenderProgram.getDefault(), getTexture(blockFace), getColorMultiplier(blockFace), diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java index 29a99ac..e2a2d69 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TileRenderTransparentSurface extends TileRenderSurface { diff --git a/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java b/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java index c22d4b6..17fffff 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public interface AABBoid extends CollisionModel { diff --git a/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java b/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java index 4568f75..cdc41a3 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TranslatedAABB implements AABBoid { diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java index 28802b2..d6c31c1 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java @@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.collision.colliders.Collider.ColliderWorksp import ru.windcorp.progressia.common.collision.colliders.Collider.Collision; import ru.windcorp.progressia.common.util.Matrices; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; class AABBoidCollider { diff --git a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java index 6dc4750..9f35d4c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java +++ b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java @@ -22,7 +22,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.VectorUtil.Axis; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import static java.lang.Math.*; diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 4857479..93c596d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.block.AbsFace.*; +import static ru.windcorp.progressia.common.world.rels.AbsFace.*; import java.util.ArrayList; import java.util.Arrays; @@ -31,8 +31,8 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java index 3913468..e366c93 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.common.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface ChunkDataListener { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index c2e9611..e9f2c50 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -24,7 +24,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public interface GenericChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java index 5b6ea89..9cda66c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java @@ -25,7 +25,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public abstract class GenericTileStack, T extends GenericTile, C extends GenericChunk> extends AbstractList diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java index af5ebb9..4dd3d07 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java @@ -26,7 +26,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public interface GenericWorld, C extends GenericChunk, E extends GenericEntity> { diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/AbsFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/common/world/block/AbsFace.java rename to src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java index 06747d6..e341ad3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/AbsFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.block; +package ru.windcorp.progressia.common.world.rels; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java new file mode 100644 index 0000000..6744770 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java @@ -0,0 +1,76 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.rels; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; + +public class AbsRelation extends BlockRelation { + + private final Vec3i vector = new Vec3i(); + private final Vec3 floatVector = new Vec3(); + private final Vec3 normalized = new Vec3(); + + public AbsRelation(int x, int y, int z) { + vector.set(x, y, z); + floatVector.set(x, y, z); + normalized.set(x, y, z); + + if (x != 0 || y != 0 || z != 0) { + normalized.normalize(); + } + } + + public AbsRelation(Vec3i vector) { + this(vector.x, vector.y, vector.z); + } + + @Override + public AbsRelation resolve(AbsFace up) { + return this; + } + + @Override + public Vec3i getVector(AbsFace up) { + return vector; + } + + @Override + public Vec3 getFloatVector(AbsFace up) { + return floatVector; + } + + @Override + public Vec3 getNormalized(AbsFace up) { + return normalized; + } + + public Vec3i getVector() { + return vector; + } + + public Vec3 getFloatVector() { + return floatVector; + } + + public Vec3 getNormalized() { + return normalized; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/AbsRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java similarity index 76% rename from src/main/java/ru/windcorp/progressia/common/world/block/AbsRelation.java rename to src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java index a14b4f0..c55a122 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/AbsRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java @@ -15,8 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -package ru.windcorp.progressia.common.world.block; +package ru.windcorp.progressia.common.world.rels; import static java.lang.Math.abs; import static java.lang.Math.max; @@ -24,34 +23,22 @@ import static java.lang.Math.max; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -public class AbsRelation { +public abstract class BlockRelation { - private final Vec3i vector = new Vec3i(); - private final Vec3 floatVector = new Vec3(); - private final Vec3 normalized = new Vec3(); - - public AbsRelation(int x, int y, int z) { - vector.set(x, y, z); - floatVector.set(x, y, z); - normalized.set(x, y, z).normalize(); - } - - public AbsRelation(Vec3i vector) { - this(vector.x, vector.y, vector.z); - } - - public Vec3i getVector() { - return vector; + public abstract AbsRelation resolve(AbsFace up); + + public Vec3i getVector(AbsFace up) { + return resolve(up).getVector(); } - public Vec3 getFloatVector() { - return floatVector; + public Vec3 getFloatVector(AbsFace up) { + return resolve(up).getFloatVector(); } - - public Vec3 getNormalized() { - return normalized; + + public Vec3 getNormalized(AbsFace up) { + return resolve(up).getNormalized(); } - + /** * Returns the distance between the source and destination blocks, as * defined by the Euclidean space. Your everyday distance. @@ -59,7 +46,7 @@ public class AbsRelation { * @return square root of the sum of the squares of the coordinates */ public float getEuclideanDistance() { - return vector.length(); + return getVector(AbsFace.POS_Z).length(); } /** @@ -72,6 +59,7 @@ public class AbsRelation { * @return the sum of the absolute values of the coordinates */ public int getManhattanDistance() { + Vec3i vector = getVector(AbsFace.POS_Z); return abs(vector.x) + abs(vector.y) + abs(vector.z); } @@ -83,7 +71,8 @@ public class AbsRelation { * @return the maximum of the absolute values of the coordinates */ public int getChebyshevDistance() { + Vec3i vector = getVector(AbsFace.POS_Z); return max(abs(vector.x), max(abs(vector.y), abs(vector.z))); } - + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java index 296d315..4a1e7a0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java @@ -25,7 +25,7 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class PacketAddTile extends PacketAffectTile { diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java index 47498b9..9be01e2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java @@ -26,7 +26,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.PacketAffectChunk; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public abstract class PacketAffectTile extends PacketAffectChunk { diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java index 320a916..9bb66af 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java @@ -26,7 +26,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class PacketRemoveTile extends PacketAffectTile { diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index 420bd08..612c1b9 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -28,8 +28,8 @@ import java.util.function.BiConsumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.server.world.block.BlockLogic; diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index ded4750..4c92990 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -20,8 +20,8 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockTickContext; diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java index 86e75bb..6b0d789 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java @@ -25,8 +25,8 @@ import java.util.function.Function; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericTileStack; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.server.Server; diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index 6d8bf22..2262f00 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -23,7 +23,7 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index 5522813..7a313c0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -19,8 +19,8 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class BlockLogic extends Namespaced implements GenericBlock { diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java index 3f3dbc2..358fe71 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java @@ -25,8 +25,8 @@ import java.util.function.Function; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.AbsFace; -import ru.windcorp.progressia.common.world.block.AbsRelation; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.server.world.ChunkTickContext; import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.tile.TSTickContext; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java index 369492e..5ddd08f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; import ru.windcorp.progressia.server.world.WorldLogic; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index 07fab12..186fa55 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableList; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatMathUtil; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.ChunkLogic; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java index b69ca2b..bb9d480 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; import ru.windcorp.progressia.server.world.WorldLogic; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java index 0b34bcf..9389b8f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java @@ -24,8 +24,8 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.MultiLOC; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.Server; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index 0110469..6a670bf 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -23,7 +23,7 @@ import java.util.function.Consumer; import java.util.function.Function; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java index f10283b..c5343b0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -19,8 +19,8 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TileLogic extends Namespaced implements GenericTile { diff --git a/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java b/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java index 6df061c..7944116 100644 --- a/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java +++ b/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.test; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.comms.controls.ControlData; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; public class ControlPlaceTileData extends ControlData { diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java index a31f521..8fed375 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.world.block.BlockLogic; public class TestBlockLogicAir extends BlockLogic { diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java index f0386d6..3d29519 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.world.block.BlockLogic; public class TestBlockLogicGlass extends BlockLogic { diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index 82c14f7..6a47d41 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -38,8 +38,8 @@ import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.io.ChunkCodec; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 2f7d461..9b5b28f 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -51,6 +51,7 @@ import ru.windcorp.progressia.common.world.GravityModelRegistry; import ru.windcorp.progressia.common.world.block.*; import ru.windcorp.progressia.common.world.entity.*; import ru.windcorp.progressia.common.world.io.ChunkIO; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.*; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.comms.controls.*; diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java index 0b6c7a2..00c3005 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java @@ -25,8 +25,8 @@ import glm.vec._3.Vec3; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; -import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapeParts; import ru.windcorp.progressia.client.graphics.model.LambdaModel; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.Shape; @@ -39,8 +39,8 @@ import ru.windcorp.progressia.client.world.entity.EntityRender; import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry; import ru.windcorp.progressia.client.world.entity.EntityRenderable; import ru.windcorp.progressia.client.world.entity.QuadripedModel; -import ru.windcorp.progressia.common.world.block.AbsFace; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TestEntityRenderJavapony extends EntityRender { @@ -124,11 +124,11 @@ public class TestEntityRenderJavapony extends EntityRender { private static Renderable createMainBody(ComplexTexture texture) { WorldRenderProgram program = WorldRenderProgram.getDefault(); - List faces = new ArrayList<>(); + List faces = new ArrayList<>(); // F BODY faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(80, 16, 32, 32), Colors.WHITE, @@ -141,7 +141,7 @@ public class TestEntityRenderJavapony extends EntityRender { // NECK BASE faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(80, 48, 32, 16), Colors.WHITE, @@ -154,7 +154,7 @@ public class TestEntityRenderJavapony extends EntityRender { // T BODY (BACK) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(128, 0, 32, 48), Colors.WHITE, @@ -167,7 +167,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BOTTOM B (upper) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(144, 48, 32, 16), Colors.WHITE, @@ -180,7 +180,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BOTTOM B (lower) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(144, 48, 32, 16), Colors.WHITE, @@ -193,7 +193,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BOTTOM B (stomach) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(144, 48, 32, 16), Colors.WHITE, @@ -206,7 +206,7 @@ public class TestEntityRenderJavapony extends EntityRender { // STOMACH faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(224, 96, 32, 32), Colors.WHITE, @@ -219,7 +219,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BOTTOM F faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(112, 48, 32, 16), Colors.WHITE, @@ -232,7 +232,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BODY L faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(112, 16, 16, 32), Colors.WHITE, @@ -245,7 +245,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BODY SIDES (left) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(96, 96, 32, 32), Colors.WHITE, @@ -258,7 +258,7 @@ public class TestEntityRenderJavapony extends EntityRender { // QT MARK (left) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(16, 96, 16, 32), Colors.WHITE, @@ -271,7 +271,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BODY R faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(64, 16, 16, 32), Colors.WHITE, @@ -284,7 +284,7 @@ public class TestEntityRenderJavapony extends EntityRender { // BODY SIDES (right) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(96, 96, 32, 32), Colors.WHITE, @@ -297,7 +297,7 @@ public class TestEntityRenderJavapony extends EntityRender { // QT MARK (right) faces.add( - Faces.createRectangle( + ShapeParts.createRectangle( program, texture.get(16, 96, 16, 32), Colors.WHITE, @@ -311,7 +311,7 @@ public class TestEntityRenderJavapony extends EntityRender { return new Shape( Usage.STATIC, program, - faces.toArray(new Face[faces.size()]) + faces.toArray(new ShapePart[faces.size()]) ); } diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index 9c96d16..e2141d8 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockTickContext; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index e206ebb..6a2f1cb 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -33,7 +33,7 @@ import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.AbsFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.world.WorldLogic; From 10d271059c9f197655bdd776505ef2c4c64f691f Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Tue, 2 Feb 2021 18:49:55 +0300 Subject: [PATCH 07/63] Added RelRelation and RelFace; added discrete up vector to GravityModel --- .../progressia/common/util/VectorUtil.java | 34 +++++ .../progressia/common/world/GravityModel.java | 85 ++++++++++- .../progressia/common/world/rels/AbsFace.java | 121 +++++++++++++++ .../common/world/rels/BlockRelation.java | 10 +- .../progressia/common/world/rels/RelFace.java | 124 ++++++++++++++++ .../common/world/rels/RelRelation.java | 140 ++++++++++++++++++ .../progressia/test/gen/TestGravityModel.java | 8 + 7 files changed, 513 insertions(+), 9 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java diff --git a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java index 1d86fce..6bef350 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java @@ -38,6 +38,40 @@ public class VectorUtil { public static enum Axis { X, Y, Z, W; } + + public static enum SignedAxis { + POS_X(Axis.X, +1), + NEG_X(Axis.X, -1), + POS_Y(Axis.Y, +1), + NEG_Y(Axis.Y, -1), + POS_Z(Axis.Z, +1), + NEG_Z(Axis.Z, -1), + POS_W(Axis.W, +1), + NEG_W(Axis.W, -1); + + private final Axis axis; + private final boolean isPositive; + + private SignedAxis(Axis axis, int sign) { + this.axis = axis; + this.isPositive = (sign == +1 ? true : false); + } + + /** + * @return the axis + */ + public Axis getAxis() { + return axis; + } + + public boolean isPositive() { + return isPositive; + } + + public int getSign() { + return isPositive ? +1 : -1; + } + } public static void iterateCuboid( int x0, diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java index eecfc3b..14f61e9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java @@ -20,15 +20,33 @@ package ru.windcorp.progressia.common.world; import java.util.Objects; import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.util.namespaces.Namespaced; +import ru.windcorp.progressia.common.world.rels.AbsFace; /** - * Gravity model specifies the gravitational acceleration field. A gravity model - * may be queried for the vector of gravitational acceleration that should - * affect an object. This vector is, generally speaking, a function of space: - * gravity in two different locations may vary. Gravity may also be a zero - * vector. + * Gravity model specifies the gravitational acceleration field, the up + * direction field and the discrete up direction field. + *

    + * A gravity model may be queried for the vector of gravitational acceleration + * that should affect an object. This vector is, generally speaking, a function + * of space: gravity in two different locations may vary. Gravity may also be a + * zero vector. + *

    + * The vector of gravitational acceleration defines the up direction. Up vector + * is defined as the additive inverse of the normalized gravitational + * acceleration vector or {@code (0; 0; 0)} if there is no gravity. + *

    + * Separately from the gravitational acceleration and the up vectors, a + * discrete up vector field is specified by a gravity model. This field + * is defined for each chunk uniquely and may only take the value of one of the + * six {@linkplain AbsFace absolute directions}. This vector specifies the + * rotation of blocks, tiles and other objects that may not have a + * non-axis-aligned direction. Discrete up vector must be specified even for + * chunks that have a zero or an ambiguous up direction. Although discrete up + * direction is not technically linked to the up direction, is it expected by + * the players that they generally align. * * @author javapony */ @@ -77,11 +95,54 @@ public abstract class GravityModel extends Namespaced { */ public Vec3 getUp(Vec3 pos, Vec3 output) { output = getGravity(pos, output); - if (output.any()) + + if (output.any()) { output.normalize().negate(); + } + return output; } + /** + * Computes the discrete up vector for the chunk at the specified + * coordinates. + * + * @param chunkPos the coordinates of chunk to compute discrete up at + * @return an {@link AbsFace} that corresponds to the up direction in the + * specified chunk. Never {@code null}. + */ + public AbsFace getDiscreteUp(Vec3i chunkPos) { + Objects.requireNonNull(chunkPos, "chunkPos"); + + final AbsFace result; + + try { + result = doGetDiscreteUp(chunkPos); + } catch (Exception e) { + throw CrashReports.report( + e, + "%s failed to compute discrete up at (%d; %d; %d)", + this, + chunkPos.x, + chunkPos.y, + chunkPos.z + ); + } + + if (result == null) { + throw CrashReports.report( + null, + "%s has computed null as the discrete up at (%d; %d; %d). This is forbidden.", + this, + chunkPos.x, + chunkPos.y, + chunkPos.z + ); + } + + return result; + } + /** * Computes the gravitational acceleration vector at the provided location. * Actual computation of gravity is delegated to this method by the other @@ -93,4 +154,16 @@ public abstract class GravityModel extends Namespaced { */ protected abstract void doGetGravity(Vec3 pos, Vec3 output); + /** + * Computes the discrete up vector for the chunk at the specified + * coordinates. A direction must be assigned under any circumstances. Actual + * computation of discrete up is delegated to this method by the other + * methods in this class. + * + * @param chunkPos the coordinates of chunk to compute discrete up at + * @return an {@link AbsFace} that corresponds to the up direction in the + * specified chunk. Never {@code null}. + */ + protected abstract AbsFace doGetDiscreteUp(Vec3i chunkPos); + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java index e341ad3..5e9db57 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java @@ -18,9 +18,12 @@ package ru.windcorp.progressia.common.world.rels; +import java.util.Objects; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; public final class AbsFace extends AbsRelation { @@ -87,6 +90,124 @@ public final class AbsFace extends AbsRelation { .put(POS_Y, posY) .build(); } + + /** + * Rounds the provided vector to one of {@link AbsFace}s. The returned face + * is pointing in the same general direction as the provided vector. The + * result is undefined for arguments where two largest in absolute values + * coordinates are equal (e.g. for {@code (5; -5; 2)}). For a zero vector + * the result is {@code null}. Infinite vectors are handled correctly. + * + * @param vector the vector to round + * @return the face most adequately describing the provided vector, or + * {@code null} iff {@code vector.x = vector.y = vector.z = 0} + * @throws IllegalArgumentException if one of the coordinates is a NaN + */ + public static AbsFace roundToFace(Vec3 vector) { + Objects.requireNonNull(vector, "vector"); + return roundToFace(vector.x, vector.y, vector.z); + } + + /** + * Rounds the provided vector to one of {@link AbsFace}s. The returned face + * is pointing in the same general direction as the provided vector. The + * result is undefined for arguments where two largest in absolute values + * coordinates are equal (e.g. for {@code (5; -5; 2)}). For a zero vector + * the result is {@code null}. Infinite arguments are handled correctly. + * + * @param x the X coordinate + * @param y the Y coordinate + * @param z the Z coordinate + * @return the face most adequately describing the provided vector, or + * {@code null} iff {@code x = y = z = 0} + * @throws IllegalArgumentException if one of the coordinates is a NaN + */ + public static AbsFace roundToFace(float x, float y, float z) { + if (x == 0 && y == 0 && z == 0) { + return null; + } + + if (Float.isNaN(x) || Float.isNaN(y) || Float.isNaN(z)) { + throw new IllegalArgumentException("Vector contains NaN: (" + x + "; " + y + "; " + z + ")"); + } + + // The following code handles infinite x, y or z properly + + float absX = Math.abs(x); + float absY = Math.abs(y); + float absZ = Math.abs(z); + + if (absX > absY) { + if (absX > absZ) { + return x > 0 ? POS_X : NEG_X; + } else { + // Z is the answer; exit decision tree + } + } else { + if (absY > absZ) { + return y > 0 ? POS_Y : NEG_Y; + } else { + // Z is the answer; exit decision tree + } + } + + return z > 0 ? POS_Z : NEG_Z; + } + + /** + * Rounds the provided vector to one of {@link AbsFace}s. The returned face + * is pointing in the same general direction as the provided vector. The + * result is undefined for arguments where two largest in absolute values + * coordinates are equal (e.g. for {@code (5; -5; 2)}). For a zero vector + * the result is {@code null}. + * + * @param vector the vector to round + * @return the face most adequately describing the provided vector, or + * {@code null} iff {@code vector.x = vector.y = vector.z = 0} + */ + public static AbsFace roundToFace(Vec3i vector) { + Objects.requireNonNull(vector, "vector"); + return roundToFace(vector.x, vector.y, vector.z); + } + + /** + * Rounds the provided vector to one of {@link AbsFace}s. The returned face + * is pointing in the same general direction as the provided vector. The + * result is undefined for arguments where two largest in absolute values + * coordinates are equal (e.g. for {@code (5; -5; 2)}). For a zero vector + * the result is {@code null}. + * + * @param x the X coordinate + * @param y the Y coordinate + * @param z the Z coordinate + * @return the face most adequately describing the provided vector, or + * {@code null} iff {@code x = y = z = 0} + */ + public static AbsFace roundToFace(int x, int y, int z) { + if (x == 0 && y == 0 && z == 0) { + return null; + } + + int absX = Math.abs(x); + int absY = Math.abs(y); + int absZ = Math.abs(z); + + if (absX > absY) { + if (absX > absZ) { + return x > 0 ? POS_X : NEG_X; + } else { + // Z is the answer; exit decision tree + } + } else { + if (absY > absZ) { + return y > 0 ? POS_Y : NEG_Y; + } else { + // Z is the answer; exit decision tree + } + } + + return z > 0 ? POS_Z : NEG_Z; + } private static int nextId = 0; diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java index c55a122..f235fc4 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockRelation.java @@ -39,6 +39,10 @@ public abstract class BlockRelation { return resolve(up).getNormalized(); } + protected Vec3i getSample() { + return getVector(AbsFace.POS_Z); + } + /** * Returns the distance between the source and destination blocks, as * defined by the Euclidean space. Your everyday distance. @@ -46,7 +50,7 @@ public abstract class BlockRelation { * @return square root of the sum of the squares of the coordinates */ public float getEuclideanDistance() { - return getVector(AbsFace.POS_Z).length(); + return getSample().length(); } /** @@ -59,7 +63,7 @@ public abstract class BlockRelation { * @return the sum of the absolute values of the coordinates */ public int getManhattanDistance() { - Vec3i vector = getVector(AbsFace.POS_Z); + Vec3i vector = getSample(); return abs(vector.x) + abs(vector.y) + abs(vector.z); } @@ -71,7 +75,7 @@ public abstract class BlockRelation { * @return the maximum of the absolute values of the coordinates */ public int getChebyshevDistance() { - Vec3i vector = getVector(AbsFace.POS_Z); + Vec3i vector = getSample(); return max(abs(vector.x), max(abs(vector.y), abs(vector.z))); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java new file mode 100644 index 0000000..9d4b658 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java @@ -0,0 +1,124 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.rels; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import glm.vec._3.i.Vec3i; + +public class RelFace extends RelRelation { + + // @formatter:off + public static final RelFace + UP = new RelFace( 0, 0, +1, "UP"), + DOWN = new RelFace( 0, 0, -1, "DOWN"), + NORTH = new RelFace(+1, 0, 0, "NORTH"), + SOUTH = new RelFace(-1, 0, 0, "SOUTH"), + WEST = new RelFace( 0, +1, 0, "WEST"), + EAST = new RelFace( 0, -1, 0, "EAST"); + // @formatter:on + + private static final ImmutableList ALL_FACES = ImmutableList.of(UP, DOWN, NORTH, SOUTH, WEST, EAST); + + static { + link(UP, DOWN); + link(NORTH, SOUTH); + link(WEST, EAST); + } + + public static ImmutableList getFaces() { + return ALL_FACES; + } + + private static void link(RelFace a, RelFace b) { + a.counterFace = b; + b.counterFace = a; + } + + public static ImmutableMap mapToFaces( + E up, + E down, + E north, + E south, + E west, + E east + ) { + return ImmutableMap.builderWithExpectedSize(6) + .put(UP, up) + .put(DOWN, down) + .put(NORTH, north) + .put(SOUTH, south) + .put(WEST, west) + .put(EAST, east) + .build(); + } + + private static int nextId = 0; + + private final int id; + private final String name; + private RelFace counterFace; + + private RelFace(int x, int y, int z, String name) { + super(x, y, z, true); + this.id = nextId++; + this.name = name; + } + + public String getName() { + return name; + } + + /** + * @return the id + */ + public int getId() { + return id; + } + + public RelFace getCounter() { + return counterFace; + } + + public RelFace getCounterAndMoveCursor(Vec3i cursor) { + cursor.add(getVector()); + return counterFace; + } + + @Override + public float getEuclideanDistance() { + return 1.0f; + } + + @Override + public int getChebyshevDistance() { + return 1; + } + + @Override + public int getManhattanDistance() { + return 1; + } + + @Override + public String toString() { + return getName(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java new file mode 100644 index 0000000..a4d23d4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java @@ -0,0 +1,140 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.rels; + +import java.util.Map; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.VectorUtil.SignedAxis; + +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.*; + +/** + * Name stands for Relative Relation + */ +public class RelRelation extends BlockRelation { + + private static class Rotation { + private final SignedAxis northDestination; + private final SignedAxis westDestination; + private final SignedAxis upDestination; + + public Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) { + this.northDestination = northDestination; + this.westDestination = westDestination; + this.upDestination = upDestination; + } + + public Vec3i apply(Vec3i output, Vec3i input) { + if (output == null) { + return output; + } + + set(output, input.x, northDestination); + set(output, input.y, westDestination); + set(output, input.z, upDestination); + + return output; + } + + private static void set(Vec3i output, int value, SignedAxis axis) { + VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value); + } + } + + private final static Map TRANSFORMATIONS = AbsFace.mapToFaces( + new Rotation(POS_X, POS_Y, POS_Z), + new Rotation(POS_X, NEG_Y, NEG_Z), + new Rotation(POS_Z, NEG_Y, POS_X), + new Rotation(POS_Z, POS_Y, NEG_X), + new Rotation(POS_Z, NEG_X, NEG_Y), + new Rotation(POS_Z, POS_X, POS_Y) + ); + + private final Vec3i vector = new Vec3i(); + private AbsRelation[] resolved = null; + + public RelRelation(int north, int west, int up) { + this(north, west, up, false); + } + + protected RelRelation(int north, int west, int up, boolean precomputeAllResolutions) { + vector.set(north, west, up); + + if (precomputeAllResolutions) { + for (AbsFace face : AbsFace.getFaces()) { + resolve(face); + } + } + } + + /** + * @return the relative vector (northward, westward, upward) + */ + public Vec3i getVector() { + return vector; + } + + public int getNorthward() { + return vector.x; + } + + public int getWestward() { + return vector.y; + } + + public int getUpward() { + return vector.z; + } + + public int getSouthward() { + return -getNorthward(); + } + + public int getEastward() { + return -getWestward(); + } + + public int getDownward() { + return -getUpward(); + } + + @Override + public AbsRelation resolve(AbsFace up) { + if (resolved == null) { + resolved = new AbsRelation[AbsFace.BLOCK_FACE_COUNT]; + } + + if (resolved[up.getId()] == null) { + resolved[up.getId()] = computeResolution(up); + } + + return resolved[up.getId()]; + } + + private AbsRelation computeResolution(AbsFace up) { + return new AbsRelation(TRANSFORMATIONS.get(up).apply(new Vec3i(), vector)); + } + + @Override + protected Vec3i getSample() { + return getVector(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java index 39e889e..24dbf2b 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java @@ -18,7 +18,9 @@ package ru.windcorp.progressia.test.gen; import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.GravityModel; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TestGravityModel extends GravityModel { @@ -37,5 +39,11 @@ public class TestGravityModel extends GravityModel { output.normalize().mul(-9.8f); } + + @Override + protected AbsFace doGetDiscreteUp(Vec3i chunkPos) { + AbsFace rounded = AbsFace.roundToFace(chunkPos.x, chunkPos.y, chunkPos.z - 54); + return rounded == null ? AbsFace.POS_Z : rounded; + } } From d3c5011063b6fd8e20a9905f747dde34dc8bc78a Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 7 Feb 2021 00:45:43 +0300 Subject: [PATCH 08/63] Replaced AbsFace with RelFace or BlockFace where appropriate - Added BlockFace - a *Face superclass - Refactored and optimized Rel{Relation, Face} - Replaced most AbsFace references with BlockFace or RelFace - Chunks now have an up direction - Determined by GravityModel's discrete up - Static; cannot change unless chunk is reloaded - Chunk models are now rendered rotated accordingly - Fixed some minor bugs that were somehow revealed by these changes - Moved TileLogicGrass to .test, where it belongs - Disabled grass despawn until a new worldgen is implemented --- .../progressia/client/world/ChunkRender.java | 13 +- .../client/world/ChunkRenderModel.java | 53 +++--- .../client/world/ChunkUpdateListener.java | 3 +- .../client/world/block/BlockRender.java | 9 +- .../world/block/BlockRenderOpaqueCube.java | 40 +++-- .../world/block/BlockRenderTexturedCube.java | 38 ++--- .../block/BlockRenderTransparentCube.java | 40 +++-- .../world/cro/ChunkRenderOptimizer.java | 30 ++-- .../cro/ChunkRenderOptimizerSurface.java | 159 +++++++++--------- .../client/world/tile/TileRender.java | 11 +- .../client/world/tile/TileRenderNone.java | 4 +- .../world/tile/TileRenderOpaqueSurface.java | 4 +- .../client/world/tile/TileRenderSurface.java | 15 +- .../tile/TileRenderTransparentSurface.java | 4 +- .../progressia/common/world/ChunkData.java | 89 ++++++---- .../common/world/ChunkDataListener.java | 4 +- .../common/world/generic/GenericChunk.java | 70 +++++++- .../world/generic/GenericTileStack.java | 4 +- .../common/world/generic/GenericWorld.java | 13 +- .../progressia/common/world/rels/AbsFace.java | 13 +- .../common/world/rels/AbsRelation.java | 12 ++ .../common/world/rels/BlockFace.java | 42 +++++ .../common/world/rels/BlockFaceResolver.java | 78 +++++++++ .../progressia/common/world/rels/RelFace.java | 24 ++- .../common/world/rels/RelRelation.java | 159 +++++++++++++++++- .../ru/windcorp/progressia/server/Server.java | 2 +- .../progressia/server/world/ChunkLogic.java | 13 +- .../server/world/ChunkTickContext.java | 5 + .../server/world/TickAndUpdateUtil.java | 24 ++- .../server/world/TickContextMutable.java | 38 +++-- .../server/world/UpdateTriggerer.java | 4 +- .../progressia/server/world/WorldLogic.java | 9 +- .../server/world/block/BlockLogic.java | 6 +- .../server/world/block/BlockTickContext.java | 14 +- .../server/world/tasks/WorldAccessor.java | 17 +- .../server/world/tile/TSTickContext.java | 6 +- .../server/world/tile/TileLogic.java | 4 +- .../progressia/test/TestBlockLogicAir.java | 4 +- .../progressia/test/TestBlockLogicGlass.java | 4 +- .../progressia/test/TestChunkCodec.java | 7 +- .../windcorp/progressia/test/TestContent.java | 5 +- .../test/TestEntityRenderJavapony.java | 18 +- .../progressia/test/TestTileLogicGrass.java | 12 +- .../TestTileRenderGrass.java} | 17 +- .../progressia/test/gen/TestGravityModel.java | 9 +- 45 files changed, 781 insertions(+), 368 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/rels/BlockFace.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java rename src/main/java/ru/windcorp/progressia/{client/world/tile/TileRenderGrass.java => test/TestTileRenderGrass.java} (70%) diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index 02f6dd3..ca58bf7 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -32,6 +32,8 @@ import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; public class ChunkRender @@ -55,6 +57,11 @@ public class ChunkRender public Vec3i getPosition() { return getData().getPosition(); } + + @Override + public AbsFace getUp() { + return getData().getUp(); + } @Override public BlockRender getBlock(Vec3i posInChunk) { @@ -64,12 +71,12 @@ public class ChunkRender } @Override - public TileRenderStack getTiles(Vec3i blockInChunk, AbsFace face) { + public TileRenderStack getTiles(Vec3i blockInChunk, BlockFace face) { return getTileStackWrapper(getData().getTiles(blockInChunk, face)); } @Override - public boolean hasTiles(Vec3i blockInChunk, AbsFace face) { + public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { return getData().hasTiles(blockInChunk, face); } @@ -119,7 +126,7 @@ public class ChunkRender } @Override - public AbsFace getFace() { + public RelFace getFace() { return parent.getFace(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 1da9163..471fb92 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -36,7 +36,8 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; public class ChunkRenderModel implements Renderable { @@ -53,11 +54,15 @@ public class ChunkRenderModel implements Renderable { public void render(ShapeRenderHelper renderer) { if (model == null) return; + float offset = ChunkData.BLOCKS_PER_CHUNK / 2 - 0.5f; + renderer.pushTransform().translate( chunk.getX() * ChunkData.BLOCKS_PER_CHUNK, chunk.getY() * ChunkData.BLOCKS_PER_CHUNK, chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK - ); + ).translate(offset, offset, offset) + .mul(RelRelation.getResolutionMatrix4(chunk.getUp())) + .translate(-offset, -offset, -offset); model.render(renderer); @@ -71,8 +76,8 @@ public class ChunkRenderModel implements Renderable { optimizers.forEach(ChunkRenderOptimizer::startRender); - chunk.forEachBiC(blockInChunk -> { - processBlockAndTiles(blockInChunk, sink); + chunk.forEachBiC(relBlockInChunk -> { + processBlockAndTiles(relBlockInChunk, sink); }); for (ChunkRenderOptimizer optimizer : optimizers) { @@ -96,16 +101,16 @@ public class ChunkRenderModel implements Renderable { } } - private void processBlockAndTiles(Vec3i blockInChunk, Builder sink) { - processBlock(blockInChunk, sink); + private void processBlockAndTiles(Vec3i relBlockInChunk, Builder sink) { + processBlock(relBlockInChunk, sink); - for (AbsFace face : AbsFace.getFaces()) { - processTileStack(blockInChunk, face, sink); + for (RelFace face : RelFace.getFaces()) { + processTileStack(relBlockInChunk, face, sink); } } - private void processBlock(Vec3i blockInChunk, Builder sink) { - BlockRender block = chunk.getBlock(blockInChunk); + private void processBlock(Vec3i relBlockInChunk, Builder sink) { + BlockRender block = chunk.getBlockRel(relBlockInChunk); if (block instanceof BlockRenderNone) { return; @@ -113,48 +118,48 @@ public class ChunkRenderModel implements Renderable { if (block.needsOwnRenderable()) { sink.addPart( - block.createRenderable(chunk.getData(), blockInChunk), - new Mat4().identity().translate(blockInChunk.x, blockInChunk.y, blockInChunk.z) + block.createRenderable(chunk.getData(), relBlockInChunk), + new Mat4().identity().translate(relBlockInChunk.x, relBlockInChunk.y, relBlockInChunk.z) ); } - processBlockWithCROs(block, blockInChunk); + processBlockWithCROs(block, relBlockInChunk); } - private void processBlockWithCROs(BlockRender block, Vec3i blockInChunk) { + private void processBlockWithCROs(BlockRender block, Vec3i relBlockInChunk) { for (ChunkRenderOptimizer optimizer : optimizers) { - optimizer.addBlock(block, blockInChunk); + optimizer.addBlock(block, relBlockInChunk); } } - private void processTileStack(Vec3i blockInChunk, AbsFace face, Builder sink) { - TileRenderStack trs = chunk.getTilesOrNull(blockInChunk, face); + private void processTileStack(Vec3i relBlockInChunk, RelFace face, Builder sink) { + TileRenderStack trs = chunk.getTilesOrNullRel(relBlockInChunk, face); if (trs == null || trs.isEmpty()) { return; } - trs.forEach(tile -> processTile(tile, blockInChunk, face, sink)); + trs.forEach(tile -> processTile(tile, relBlockInChunk, face, sink)); } - private void processTile(TileRender tile, Vec3i blockInChunk, AbsFace face, Builder sink) { + private void processTile(TileRender tile, Vec3i relBlockInChunk, RelFace face, Builder sink) { if (tile instanceof TileRenderNone) { return; } if (tile.needsOwnRenderable()) { sink.addPart( - tile.createRenderable(chunk.getData(), blockInChunk, face), - new Mat4().identity().translate(blockInChunk.x, blockInChunk.y, blockInChunk.z) + tile.createRenderable(chunk.getData(), relBlockInChunk, face), + new Mat4().identity().translate(relBlockInChunk.x, relBlockInChunk.y, relBlockInChunk.z) ); } - processTileWithCROs(tile, blockInChunk, face); + processTileWithCROs(tile, relBlockInChunk, face); } - private void processTileWithCROs(TileRender tile, Vec3i blockInChunk, AbsFace face) { + private void processTileWithCROs(TileRender tile, Vec3i relBlockInChunk, RelFace face) { for (ChunkRenderOptimizer optimizer : optimizers) { - optimizer.addTile(tile, blockInChunk, face); + optimizer.addTile(tile, relBlockInChunk, face); } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java index e87e623..37ea0ba 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java @@ -23,6 +23,7 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; class ChunkUpdateListener implements ChunkDataListener { @@ -57,7 +58,7 @@ class ChunkUpdateListener implements ChunkDataListener { public void onChunkTilesChanged( ChunkData chunk, Vec3i blockInChunk, - AbsFace face, + RelFace face, TileData tile, boolean wasAdded ) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java index d350fa8..2a3c8e1 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java @@ -18,7 +18,6 @@ package ru.windcorp.progressia.client.world.block; -import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.generic.GenericBlock; @@ -31,13 +30,7 @@ public abstract class BlockRender extends Namespaced implements GenericBlock { super(id); } - public void render(ShapeRenderHelper renderer) { - throw new UnsupportedOperationException( - "BlockRender.render() not implemented in " + this - ); - } - - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { + public Renderable createRenderable(ChunkData chunk, Vec3i relBlockInChunk) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java index 4948206..01a6011 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java @@ -19,27 +19,27 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class BlockRenderOpaqueCube extends BlockRenderTexturedCube { public BlockRenderOpaqueCube( String id, - Texture posZTexture, - Texture negZTexture, - Texture posXTexture, - Texture negXTexture, - Texture negYTexture, - Texture posYTexture + Texture topTexture, + Texture bottomTexture, + Texture northTexture, + Texture southTexture, + Texture westTexture, + Texture eastTexture ) { super( id, - posZTexture, - negZTexture, - posXTexture, - negXTexture, - negYTexture, - posYTexture + topTexture, + bottomTexture, + northTexture, + southTexture, + westTexture, + eastTexture ); } @@ -54,9 +54,21 @@ public class BlockRenderOpaqueCube extends BlockRenderTexturedCube { texture ); } + + public BlockRenderOpaqueCube(String id, Texture topTexture, Texture bottomTexture, Texture sideTexture) { + this( + id, + topTexture, + bottomTexture, + sideTexture, + sideTexture, + sideTexture, + sideTexture + ); + } @Override - public boolean isOpaque(AbsFace face) { + public boolean isOpaque(RelFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java index 918ea55..6ed7ef7 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java @@ -20,7 +20,6 @@ package ru.windcorp.progressia.client.world.block; import static ru.windcorp.progressia.common.world.rels.AbsFace.*; -import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; @@ -39,43 +38,38 @@ import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.Block import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public abstract class BlockRenderTexturedCube extends BlockRender implements BlockOptimizedSurface { - private final Map textures = new HashMap<>(); + private final Map textures; public BlockRenderTexturedCube( String id, - Texture posZTexture, - Texture negZTexture, - Texture posXTexture, - Texture negXTexture, - Texture negYTexture, - Texture posYTexture + Texture topTexture, + Texture bottomTexture, + Texture northTexture, + Texture southTexture, + Texture westTexture, + Texture eastTexture ) { super(id); - - textures.put(POS_Z, posZTexture); - textures.put(NEG_Z, negZTexture); - textures.put(POS_X, posXTexture); - textures.put(NEG_X, negXTexture); - textures.put(NEG_Y, negYTexture); - textures.put(POS_Y, posYTexture); + this.textures = RelFace.mapToFaces(topTexture, bottomTexture, northTexture, southTexture, westTexture, eastTexture); } - public Texture getTexture(AbsFace blockFace) { + public Texture getTexture(RelFace blockFace) { return textures.get(blockFace); } - public Vec4 getColorMultiplier(AbsFace blockFace) { + public Vec4 getColorMultiplier(RelFace blockFace) { return Colors.WHITE; } @Override public final void getShapeParts( - ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, + ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -84,7 +78,7 @@ public abstract class BlockRenderTexturedCube } private ShapePart createFace( - ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, + ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Vec3 offset ) { @@ -93,7 +87,7 @@ public abstract class BlockRenderTexturedCube getTexture(blockFace), getColorMultiplier(blockFace), offset, - blockFace, + blockFace.resolve(AbsFace.POS_Z), inner ); } @@ -105,12 +99,12 @@ public abstract class BlockRenderTexturedCube ShapePart[] faces = new ShapePart[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { - faces[i] = createFace(chunk, blockInChunk, AbsFace.getFaces().get(i), false, Vectors.ZERO_3); + faces[i] = createFace(chunk, blockInChunk, RelFace.getFaces().get(i), false, Vectors.ZERO_3); } if (!opaque) { for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { - faces[i + BLOCK_FACE_COUNT] = createFace(chunk, blockInChunk, AbsFace.getFaces().get(i), true, Vectors.ZERO_3); + faces[i + BLOCK_FACE_COUNT] = createFace(chunk, blockInChunk, RelFace.getFaces().get(i), true, Vectors.ZERO_3); } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java index 9b03802..f9801ca 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java @@ -19,27 +19,27 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class BlockRenderTransparentCube extends BlockRenderTexturedCube { public BlockRenderTransparentCube( String id, - Texture posZTexture, - Texture negZTexture, - Texture posXTexture, - Texture negXTexture, - Texture negYTexture, - Texture posYTexture + Texture topTexture, + Texture bottomTexture, + Texture northTexture, + Texture southTexture, + Texture westTexture, + Texture eastTexture ) { super( id, - posZTexture, - negZTexture, - posXTexture, - negXTexture, - negYTexture, - posYTexture + topTexture, + bottomTexture, + northTexture, + southTexture, + westTexture, + eastTexture ); } @@ -54,9 +54,21 @@ public class BlockRenderTransparentCube extends BlockRenderTexturedCube { texture ); } + + public BlockRenderTransparentCube(String id, Texture topTexture, Texture bottomTexture, Texture sideTexture) { + this( + id, + topTexture, + bottomTexture, + sideTexture, + sideTexture, + sideTexture, + sideTexture + ); + } @Override - public boolean isOpaque(AbsFace face) { + public boolean isOpaque(RelFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java index 56e7537..12396dc 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; /** * Chunk render optimizer (CRO) is an object that produces optimized models for @@ -35,6 +35,12 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; * tiles. An example of a CRO is {@link ChunkRenderOptimizerSurface}: it removes * block surfaces and tiles that it knows cannot be seen, thus significantly * reducing total polygon count. + *

    + * As with everything related to rendering chunks, CROs are interacted with + * using the relative local chunk coordinate system. In this coordinate system, + * the coordinates are the chunk coordinates relativized using the chunks's up + * direction. In simpler terms, coordinates are {@code [0; BLOCKS_PER_CHUNK)} + * and Z is always up. *

    CRO lifecycle

    * A CRO instance is created by {@link ChunkRenderOptimizerRegistry}. It may * then be used to work on multiple chunks sequentially. Each chunk is processed @@ -44,7 +50,7 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; * instance.
  • *
  • {@link #startRender()} is invoked. The CRO must reset its state.
  • *
  • {@link #addBlock(BlockRender, Vec3i)} and - * {@link #addTile(TileRender, Vec3i, AbsFace)} are invoked for each block and + * {@link #addTile(TileRender, Vec3i, RelFace)} are invoked for each block and * tile that this CRO should optimize. {@code addTile} specifies tiles in order * of ascension within a tile stack.
  • *
  • {@link #endRender()} is invoked. The CRO may perform any pending @@ -98,12 +104,13 @@ public abstract class ChunkRenderOptimizer extends Namespaced { * method is only invoked once per block. This method is not necessarily * invoked for each block. * - * @param block a {@link BlockRender} instance describing the block. - * It corresponds to - * {@code getChunk().getBlock(blockInChunk)}. - * @param blockInChunk the position of the block + * @param block a {@link BlockRender} instance describing the + * block. + * It corresponds to + * {@code getChunk().getBlock(blockInChunk)}. + * @param relBlockInChunk the relative position of the block */ - public abstract void addBlock(BlockRender block, Vec3i blockInChunk); + public abstract void addBlock(BlockRender block, Vec3i relBlockInChunk); /** * Requests that this CRO processes the provided tile. This method may only @@ -112,11 +119,12 @@ public abstract class ChunkRenderOptimizer extends Namespaced { * invoked for each tile. When multiple tiles in a tile stack are requested, * this method is invoked for lower tiles first. * - * @param tile a {@link BlockRender} instance describing the tile - * @param blockInChunk the position of the block that the tile belongs to - * @param blockFace the face that the tile belongs to + * @param tile a {@link BlockRender} instance describing the tile + * @param relBlockInChunk the relative position of the block that the tile + * belongs to + * @param blockFace the face that the tile belongs to */ - public abstract void addTile(TileRender tile, Vec3i blockInChunk, AbsFace blockFace); + public abstract void addTile(TileRender tile, Vec3i relBlockInChunk, RelFace blockFace); /** * Requests that the CRO assembles and outputs its model. This method may diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index 0f0eeb8..f30b91c 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -38,7 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @@ -56,20 +56,23 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { * surface. The coordinates of the face vertices must be in chunk * coordinate system. * - * @param chunk the chunk that contains the requested face - * @param blockInChunk the block in chunk - * @param blockFace the requested face - * @param inner whether this face should be visible from inside - * ({@code true}) or outside ({@code false}) - * @param output a consumer that the created shape parts must be - * given to - * @param offset an additional offset that must be applied to all - * vertices + * @param chunk the chunk that contains the requested face + * @param relBlockInChunk the relative block in chunk + * @param blockFace the requested face + * @param inner whether this face should be visible from + * inside + * ({@code true}) or outside ({@code false}) + * @param output a consumer that the created shape parts must + * be + * given to + * @param offset an additional offset that must be applied to + * all + * vertices */ void getShapeParts( ChunkData chunk, - Vec3i blockInChunk, - AbsFace blockFace, + Vec3i relBlockInChunk, + RelFace blockFace, boolean inner, Consumer output, Vec3 offset /* kostyl 156% */ @@ -77,14 +80,14 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { /** * Returns the opacity of the surface identified by the provided - * {@link AbsFace}. + * {@link RelFace}. * Opaque surfaces prevent surfaces behind them from being included in * chunk models. * * @param blockFace the face to query * @return {@code true} iff the surface is opaque. */ - boolean isOpaque(AbsFace blockFace); + boolean isOpaque(RelFace blockFace); } /** @@ -159,29 +162,29 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } @Override - public void addBlock(BlockRender block, Vec3i pos) { + public void addBlock(BlockRender block, Vec3i relBlockInChunk) { if (!(block instanceof BlockOptimizedSurface)) return; BlockOptimizedSurface bos = (BlockOptimizedSurface) block; - addBlock(pos, bos); + addBlock(relBlockInChunk, bos); } @Override - public void addTile(TileRender tile, Vec3i pos, AbsFace face) { + public void addTile(TileRender tile, Vec3i relBlockInChunk, RelFace face) { if (!(tile instanceof TileOptimizedSurface)) return; TileOptimizedSurface tos = (TileOptimizedSurface) tile; - addTile(pos, face, tos); + addTile(relBlockInChunk, face, tos); } - protected void addBlock(Vec3i pos, BlockOptimizedSurface block) { - getBlock(pos).block = block; + private void addBlock(Vec3i relBlockInChunk, BlockOptimizedSurface block) { + getBlock(relBlockInChunk).block = block; } - private void addTile(Vec3i pos, AbsFace face, TileOptimizedSurface tile) { - FaceInfo faceInfo = getFace(pos, face); + private void addTile(Vec3i relBlockInChunk, RelFace face, TileOptimizedSurface tile) { + FaceInfo faceInfo = getFace(relBlockInChunk, face); int index = faceInfo.tileCount; faceInfo.tileCount++; @@ -197,12 +200,12 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } } - protected BlockInfo getBlock(Vec3i cursor) { - return data[cursor.x][cursor.y][cursor.z]; + protected BlockInfo getBlock(Vec3i relBlockInChunk) { + return data[relBlockInChunk.x][relBlockInChunk.y][relBlockInChunk.z]; } - protected FaceInfo getFace(Vec3i cursor, AbsFace face) { - return getBlock(cursor).faces[face.getId()]; + protected FaceInfo getFace(Vec3i relBlockInChunk, RelFace face) { + return getBlock(relBlockInChunk).faces[face.getId()]; } @Override @@ -211,17 +214,12 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * 3 ); - Vec3i cursor = new Vec3i(); Consumer consumer = shapeParts::add; - for (cursor.x = 0; cursor.x < BLOCKS_PER_CHUNK; ++cursor.x) { - for (cursor.y = 0; cursor.y < BLOCKS_PER_CHUNK; ++cursor.y) { - for (cursor.z = 0; cursor.z < BLOCKS_PER_CHUNK; ++cursor.z) { - processInnerFaces(cursor, consumer); - processOuterFaces(cursor, consumer); - } - } - } + chunk.forEachBiC(relBlockInChunk -> { + processInnerFaces(relBlockInChunk, consumer); + processOuterFaces(relBlockInChunk, consumer); + }); if (shapeParts.isEmpty()) { return null; @@ -235,25 +233,25 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } private void processOuterFaces( - Vec3i blockInChunk, + Vec3i relBlockInChunk, Consumer output ) { - for (AbsFace blockFace : AbsFace.getFaces()) { - processOuterFace(blockInChunk, blockFace, output); + for (RelFace blockFace : RelFace.getFaces()) { + processOuterFace(relBlockInChunk, blockFace, output); } } - private void processOuterFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { - if (!shouldRenderOuterFace(blockInChunk, blockFace)) + private void processOuterFace(Vec3i relBlockInChunk, RelFace blockFace, Consumer output) { + if (!shouldRenderOuterFace(relBlockInChunk, blockFace)) return; - FaceInfo info = getFace(blockInChunk, blockFace); + FaceInfo info = getFace(relBlockInChunk, blockFace); if (info.tileCount == 0 && info.block.block == null) return; - Vec3 faceOrigin = new Vec3(blockInChunk.x, blockInChunk.y, blockInChunk.z); - Vec3 offset = new Vec3(blockFace.getFloatVector()).mul(OVERLAY_OFFSET); + Vec3 faceOrigin = new Vec3(relBlockInChunk.x, relBlockInChunk.y, relBlockInChunk.z); + Vec3 offset = new Vec3(blockFace.getRelFloatVector()).mul(OVERLAY_OFFSET); for ( int layer = info.topOpaqueSurface; @@ -264,32 +262,29 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { if (surface == null) continue; // layer may be BLOCK_LAYER, then block may be null - surface.getShapeParts(chunk.getData(), blockInChunk, blockFace, false, output, faceOrigin); + surface.getShapeParts(chunk.getData(), relBlockInChunk, blockFace, false, output, faceOrigin); faceOrigin.add(offset); } } - private void processInnerFaces( - Vec3i blockInChunk, - Consumer output - ) { - for (AbsFace blockFace : AbsFace.getFaces()) { - processInnerFace(blockInChunk, blockFace, output); + private void processInnerFaces(Vec3i relBlockInChunk, Consumer output) { + for (RelFace blockFace : RelFace.getFaces()) { + processInnerFace(relBlockInChunk, blockFace, output); } } - private void processInnerFace(Vec3i blockInChunk, AbsFace blockFace, Consumer output) { - if (!shouldRenderInnerFace(blockInChunk, blockFace)) + private void processInnerFace(Vec3i relBlockInChunk, RelFace blockFace, Consumer output) { + if (!shouldRenderInnerFace(relBlockInChunk, blockFace)) return; - FaceInfo info = getFace(blockInChunk, blockFace); + FaceInfo info = getFace(relBlockInChunk, blockFace); if (info.tileCount == 0 && info.block.block == null) return; - Vec3 faceOrigin = new Vec3(blockInChunk.x, blockInChunk.y, blockInChunk.z); - Vec3 offset = new Vec3(blockFace.getFloatVector()).mul(OVERLAY_OFFSET); + Vec3 faceOrigin = new Vec3(relBlockInChunk.x, relBlockInChunk.y, relBlockInChunk.z); + Vec3 offset = new Vec3(blockFace.getRelFloatVector()).mul(OVERLAY_OFFSET); for ( int layer = FaceInfo.BLOCK_LAYER; @@ -300,35 +295,35 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { if (surface == null) continue; // layer may be BLOCK_LAYER, then block may be null - surface.getShapeParts(chunk.getData(), blockInChunk, blockFace, true, output, faceOrigin); + surface.getShapeParts(chunk.getData(), relBlockInChunk, blockFace, true, output, faceOrigin); faceOrigin.add(offset); } } - private boolean shouldRenderOuterFace(Vec3i blockInChunk, AbsFace face) { - blockInChunk.add(face.getVector()); + private boolean shouldRenderOuterFace(Vec3i relBlockInChunk, RelFace face) { + relBlockInChunk.add(face.getRelVector()); try { - return shouldRenderWhenFacing(blockInChunk, face); + return shouldRenderWhenFacing(relBlockInChunk, face); } finally { - blockInChunk.sub(face.getVector()); + relBlockInChunk.sub(face.getRelVector()); } } - private boolean shouldRenderInnerFace(Vec3i blockInChunk, AbsFace face) { - return shouldRenderWhenFacing(blockInChunk, face); + private boolean shouldRenderInnerFace(Vec3i relBlockInChunk, RelFace face) { + return shouldRenderWhenFacing(relBlockInChunk, face); } - private boolean shouldRenderWhenFacing(Vec3i blockInChunk, AbsFace face) { - if (chunk.containsBiC(blockInChunk)) { - return shouldRenderWhenFacingLocal(blockInChunk, face); + private boolean shouldRenderWhenFacing(Vec3i relBlockInChunk, RelFace face) { + if (chunk.containsBiC(relBlockInChunk)) { + return shouldRenderWhenFacingLocal(relBlockInChunk, face); } else { - return shouldRenderWhenFacingNeighbor(blockInChunk, face); + return shouldRenderWhenFacingNeighbor(relBlockInChunk, face); } } - private boolean shouldRenderWhenFacingLocal(Vec3i blockInChunk, AbsFace face) { - BlockOptimizedSurface block = getBlock(blockInChunk).block; + private boolean shouldRenderWhenFacingLocal(Vec3i relBlockInChunk, RelFace face) { + BlockOptimizedSurface block = getBlock(relBlockInChunk).block; if (block == null) { return true; @@ -340,36 +335,37 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { return true; } - private boolean shouldRenderWhenFacingNeighbor(Vec3i blockInLocalChunk, AbsFace face) { - Vec3i blockInChunk = Vectors.grab3i().set(blockInLocalChunk.x, blockInLocalChunk.y, blockInLocalChunk.z); + private boolean shouldRenderWhenFacingNeighbor(Vec3i relBlockInLocalChunk, RelFace face) { + Vec3i blockInChunk = Vectors.grab3i(); + chunk.resolve(relBlockInLocalChunk, blockInChunk); Vec3i chunkPos = Vectors.grab3i().set(chunk.getX(), chunk.getY(), chunk.getZ()); try { // Determine blockInChunk and chunkPos - if (blockInLocalChunk.x == -1) { + if (blockInChunk.x == -1) { blockInChunk.x = BLOCKS_PER_CHUNK - 1; chunkPos.x -= 1; - } else if (blockInLocalChunk.x == BLOCKS_PER_CHUNK) { + } else if (blockInChunk.x == BLOCKS_PER_CHUNK) { blockInChunk.x = 0; chunkPos.x += 1; - } else if (blockInLocalChunk.y == -1) { + } else if (blockInChunk.y == -1) { blockInChunk.y = BLOCKS_PER_CHUNK - 1; chunkPos.y -= 1; - } else if (blockInLocalChunk.y == BLOCKS_PER_CHUNK) { + } else if (blockInChunk.y == BLOCKS_PER_CHUNK) { blockInChunk.y = 0; chunkPos.y += 1; - } else if (blockInLocalChunk.z == -1) { + } else if (blockInChunk.z == -1) { blockInChunk.z = BLOCKS_PER_CHUNK - 1; chunkPos.z -= 1; - } else if (blockInLocalChunk.z == BLOCKS_PER_CHUNK) { + } else if (blockInChunk.z == BLOCKS_PER_CHUNK) { blockInChunk.z = 0; chunkPos.z += 1; } else { throw new AssertionError( "Requested incorrent neighbor (" - + blockInLocalChunk.x + "; " - + blockInLocalChunk.y + "; " - + blockInLocalChunk.z + ")" + + relBlockInLocalChunk.x + "; " + + relBlockInLocalChunk.y + "; " + + relBlockInLocalChunk.z + ")" ); } @@ -382,8 +378,11 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { return true; BlockOptimizedSurface bos = (BlockOptimizedSurface) block; - if (!bos.isOpaque(face)) + RelFace rotatedFace = face.rotate(this.chunk.getUp(), chunk.getUp()); + + if (!bos.isOpaque(rotatedFace)) { return true; + } return false; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java index 52519ed..38c4ae9 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java @@ -18,14 +18,13 @@ package ru.windcorp.progressia.client.world.tile; -import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizer; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class TileRender extends Namespaced implements GenericTile { @@ -33,13 +32,7 @@ public class TileRender extends Namespaced implements GenericTile { super(id); } - public void render(ShapeRenderHelper renderer, AbsFace face) { - throw new UnsupportedOperationException( - "TileRender.render() not implemented in " + this - ); - } - - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, AbsFace face) { + public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace face) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java index fd26e8d..f8ad55b 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java @@ -21,7 +21,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class TileRenderNone extends TileRender { @@ -30,7 +30,7 @@ public class TileRenderNone extends TileRender { } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, AbsFace face) { + public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace face) { return EmptyModel.getInstance(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java index 8abaa5f..102da82 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class TileRenderOpaqueSurface extends TileRenderSurface { @@ -28,7 +28,7 @@ public class TileRenderOpaqueSurface extends TileRenderSurface { } @Override - public boolean isOpaque(AbsFace face) { + public boolean isOpaque(RelFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java index 3773699..91eeb00 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java @@ -35,6 +35,7 @@ import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.TileO import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public abstract class TileRenderSurface extends TileRender implements TileOptimizedSurface { @@ -49,26 +50,26 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi this(id, null); } - public Texture getTexture(AbsFace blockFace) { + public Texture getTexture(RelFace blockFace) { return texture; } - public Vec4 getColorMultiplier(AbsFace blockFace) { + public Vec4 getColorMultiplier(RelFace blockFace) { return Colors.WHITE; } @Override public final void getShapeParts( - ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, + ChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, boolean inner, Consumer output, Vec3 offset ) { - output.accept(createFace(chunk, blockInChunk, blockFace, inner, offset)); + output.accept(createFace(chunk, relBlockInChunk, blockFace, inner, offset)); } private ShapePart createFace( - ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace, + ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Vec3 offset ) { @@ -77,13 +78,13 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi getTexture(blockFace), getColorMultiplier(blockFace), offset, - blockFace, + blockFace.resolve(AbsFace.POS_Z), inner ); } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, AbsFace blockFace) { + public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace blockFace) { return new Shape( Usage.STATIC, WorldRenderProgram.getDefault(), diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java index e2a2d69..72f9fcf 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class TileRenderTransparentSurface extends TileRenderSurface { @@ -28,7 +28,7 @@ public class TileRenderTransparentSurface extends TileRenderSurface { } @Override - public boolean isOpaque(AbsFace face) { + public boolean isOpaque(RelFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 93c596d..ac0fb93 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.rels.AbsFace.*; +import static ru.windcorp.progressia.common.world.rels.BlockFace.BLOCK_FACE_COUNT; import java.util.ArrayList; import java.util.Arrays; @@ -33,6 +33,8 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; @@ -50,6 +52,8 @@ public class ChunkData private final TileDataStack[] tiles = new TileDataStack[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCK_FACE_COUNT]; + + private final AbsFace up; private Object generationHint = null; @@ -58,12 +62,18 @@ public class ChunkData public ChunkData(Vec3i position, WorldData world) { this.position.set(position.x, position.y, position.z); this.world = world; + this.up = world.getGravityModel().getDiscreteUp(position); } @Override public Vec3i getPosition() { return position; } + + @Override + public AbsFace getUp() { + return up; + } @Override public BlockData getBlock(Vec3i posInChunk) { @@ -83,31 +93,31 @@ public class ChunkData } @Override - public TileDataStack getTilesOrNull(Vec3i blockInChunk, AbsFace face) { + public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { return tiles[getTileIndex(blockInChunk, face)]; } /** * Internal use only. Modify a list returned by - * {@link #getTiles(Vec3i, AbsFace)} or - * {@link #getTilesOrNull(Vec3i, AbsFace)} + * {@link #getTiles(Vec3i, BlockFace)} or + * {@link #getTilesOrNull(Vec3i, BlockFace)} * to change tiles. */ protected void setTiles( Vec3i blockInChunk, - AbsFace face, + BlockFace face, TileDataStack tiles ) { this.tiles[getTileIndex(blockInChunk, face)] = tiles; } @Override - public boolean hasTiles(Vec3i blockInChunk, AbsFace face) { + public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { return getTilesOrNull(blockInChunk, face) != null; } @Override - public TileDataStack getTiles(Vec3i blockInChunk, AbsFace face) { + public TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { int index = getTileIndex(blockInChunk, face); if (tiles[index] == null) { @@ -117,7 +127,7 @@ public class ChunkData return tiles[index]; } - private void createTileStack(Vec3i blockInChunk, AbsFace face) { + private void createTileStack(Vec3i blockInChunk, BlockFace face) { Vec3i independentBlockInChunk = conjureIndependentBlockInChunkVec3i(blockInChunk); TileDataStackImpl stack = new TileDataStackImpl(independentBlockInChunk, face); setTiles(blockInChunk, face, stack); @@ -142,15 +152,15 @@ public class ChunkData posInChunk.x; } - private static int getTileIndex(Vec3i posInChunk, AbsFace face) { + private int getTileIndex(Vec3i posInChunk, BlockFace face) { return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + - face.getId(); + face.resolve(getUp()).getId(); } private static void checkLocalCoordinates(Vec3i posInChunk) { if (!isInBounds(posInChunk)) { throw new IllegalCoordinatesException( - "Coordinates " + str(posInChunk) + " " + "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " + "are not legal chunk coordinates" ); } @@ -162,14 +172,15 @@ public class ChunkData posInChunk.z >= 0 && posInChunk.z < BLOCKS_PER_CHUNK; } - public boolean isBorder(Vec3i blockInChunk, AbsFace face) { + public boolean isBorder(Vec3i blockInChunk, BlockFace face) { final int min = 0, max = BLOCKS_PER_CHUNK - 1; - return (blockInChunk.x == min && face == NEG_X) || - (blockInChunk.x == max && face == POS_X) || - (blockInChunk.y == min && face == NEG_Y) || - (blockInChunk.y == max && face == POS_Y) || - (blockInChunk.z == min && face == NEG_Z) || - (blockInChunk.z == max && face == POS_Z); + AbsFace absFace = face.resolve(getUp()); + return (blockInChunk.x == min && absFace == AbsFace.NEG_X) || + (blockInChunk.x == max && absFace == AbsFace.POS_X) || + (blockInChunk.y == min && absFace == AbsFace.NEG_Y) || + (blockInChunk.y == max && absFace == AbsFace.POS_Y) || + (blockInChunk.z == min && absFace == AbsFace.NEG_Z) || + (blockInChunk.z == max && absFace == AbsFace.POS_Z); } public void forEachBlock(Consumer action) { @@ -221,10 +232,6 @@ public class ChunkData this.listeners.remove(listener); } - private static String str(Vec3i v) { - return "(" + v.x + "; " + v.y + "; " + v.z + ")"; - } - protected void onLoaded() { getListeners().forEach(l -> l.onChunkLoaded(this)); } @@ -309,11 +316,11 @@ public class ChunkData * Potentially shared */ private final Vec3i blockInChunk; - private final AbsFace face; + private final RelFace face; - public TileDataStackImpl(Vec3i blockInChunk, AbsFace face) { + public TileDataStackImpl(Vec3i blockInChunk, BlockFace face) { this.blockInChunk = blockInChunk; - this.face = face; + this.face = face.relativize(getUp()); } @Override @@ -325,7 +332,7 @@ public class ChunkData } @Override - public AbsFace getFace() { + public RelFace getFace() { return face; } @@ -389,7 +396,7 @@ public class ChunkData references[index] = null; for (int tag = 0; tag < indicesByTag.length; ++tag) { - if (tagsByIndex[tag] == -1) { + if (indicesByTag[tag] == -1) { indicesByTag[tag] = index; tagsByIndex[index] = tag; break; @@ -405,21 +412,29 @@ public class ChunkData @Override public void load(TileData tile, int tag) { addFarthest(tile); - - int assignedTag = getIndexByTag(tag); - - if (assignedTag == tag) + + int assignedIndex = size() - 1; + + // Skip if we already have the correct tag + int assignedTag = getTagByIndex(assignedIndex); + if (assignedTag == tag) { return; - if (assignedTag == -1) { + } + assert assignedTag != -1 : "Adding farthest tile resulted in -1 tag"; + + // Make sure we aren't trying to assign a tag already in use + int tileWithRequestedTag = getIndexByTag(tag); + if (tileWithRequestedTag != -1) { throw new IllegalArgumentException( - "Tag " + tag + " already used by tile at index " + getIndexByTag(tag) + "Tag " + tag + " already used by tile at index " + tileWithRequestedTag ); } + assert tileWithRequestedTag != assignedIndex : "tag == assignedTag yet tileWithRequestedTag != assignedIndex"; - indicesByTag[tagsByIndex[size() - 1]] = -1; - tagsByIndex[size() - 1] = tag; - indicesByTag[tag] = size() - 1; - + // Do the tag editing + indicesByTag[assignedTag] = -1; // Release assigned tag + tagsByIndex[assignedIndex] = tag; // Reroute assigned index to requested tag + indicesByTag[tag] = assignedIndex; // Claim requested tag assert checkConsistency(); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java index e366c93..0dc7088 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.common.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface ChunkDataListener { @@ -55,7 +55,7 @@ public interface ChunkDataListener { default void onChunkTilesChanged( ChunkData chunk, Vec3i blockInChunk, - AbsFace face, + RelFace face, TileData tile, boolean wasAdded ) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index e9f2c50..1768119 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -25,19 +25,64 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; public interface GenericChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> { public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; Vec3i getPosition(); + + AbsFace getUp(); B getBlock(Vec3i blockInChunk); - TS getTiles(Vec3i blockInChunk, AbsFace face); - - boolean hasTiles(Vec3i blockInChunk, AbsFace face); + TS getTiles(Vec3i blockInChunk, BlockFace face); + boolean hasTiles(Vec3i blockInChunk, BlockFace face); + + default Vec3i resolve(Vec3i relativeBlockInChunk, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + final int offset = BLOCKS_PER_CHUNK - 1; + + output.set(relativeBlockInChunk.x, relativeBlockInChunk.y, relativeBlockInChunk.z); + output.mul(2).sub(offset); + + RelRelation.resolve(output, getUp(), output); + + output.add(offset).div(2); + + return output; + } + + default B getBlockRel(Vec3i relativeBlockInChunk) { + Vec3i absoluteBlockInChunk = Vectors.grab3i(); + resolve(relativeBlockInChunk, absoluteBlockInChunk); + B result = getBlock(absoluteBlockInChunk); + Vectors.release(absoluteBlockInChunk); + return result; + } + + default TS getTilesRel(Vec3i relativeBlockInChunk, BlockFace face) { + Vec3i absoluteBlockInChunk = Vectors.grab3i(); + resolve(relativeBlockInChunk, absoluteBlockInChunk); + TS result = getTiles(absoluteBlockInChunk, face); + Vectors.release(absoluteBlockInChunk); + return result; + } + + default boolean hasTilesRel(Vec3i relativeBlockInChunk, BlockFace face) { + Vec3i absoluteBlockInChunk = Vectors.grab3i(); + resolve(relativeBlockInChunk, absoluteBlockInChunk); + boolean result = hasTiles(absoluteBlockInChunk, face); + Vectors.release(absoluteBlockInChunk); + return result; + } + default int getX() { return getPosition().x; } @@ -182,12 +227,29 @@ public interface GenericChunk, B exten ); } - default TS getTilesOrNull(Vec3i blockInChunk, AbsFace face) { + default TS getTilesOrNull(Vec3i blockInChunk, BlockFace face) { if (hasTiles(blockInChunk, face)) { return getTiles(blockInChunk, face); } return null; } + + default TS getTilesOrNullRel(Vec3i relativeBlockInChunk, BlockFace face) { + Vec3i absoluteBlockInChunk = Vectors.grab3i(); + resolve(relativeBlockInChunk, absoluteBlockInChunk); + + TS result; + + if (hasTiles(absoluteBlockInChunk, face)) { + result = getTiles(absoluteBlockInChunk, face); + } else { + result = null; + } + + Vectors.release(absoluteBlockInChunk); + + return result; + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java index 9cda66c..a2e8a4d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java @@ -25,7 +25,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public abstract class GenericTileStack, T extends GenericTile, C extends GenericChunk> extends AbstractList @@ -41,7 +41,7 @@ public abstract class GenericTileStack public abstract C getChunk(); - public abstract AbsFace getFace(); + public abstract RelFace getFace(); public Vec3i getBlockInWorld(Vec3i output) { // This is safe diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java index 4dd3d07..c71ef54 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java @@ -27,6 +27,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; public interface GenericWorld, C extends GenericChunk, E extends GenericEntity> { @@ -47,6 +48,10 @@ public interface GenericWorld SECONDARY_FACES = ALL_FACES.stream().filter(AbsFace::isSecondary) .collect(ImmutableList.toImmutableList()); - public static final int BLOCK_FACE_COUNT = ALL_FACES.size(); public static final int PRIMARY_BLOCK_FACE_COUNT = PRIMARY_FACES.size(); public static final int SECONDARY_BLOCK_FACE_COUNT = SECONDARY_FACES.size(); @@ -226,6 +225,16 @@ public final class AbsFace extends AbsRelation { public String getName() { return name; } + + @Override + public AbsFace resolve(AbsFace up) { + return this; + } + + @Override + public RelFace relativize(AbsFace up) { + return BlockFaceResolver.relativize(this, up); + } public boolean isPrimary() { return isPrimary; diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java index 6744770..b14abdd 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsRelation.java @@ -41,6 +41,18 @@ public class AbsRelation extends BlockRelation { this(vector.x, vector.y, vector.z); } + public static AbsRelation of(Vec3i vector) { + return of(vector.x, vector.y, vector.z); + } + + public static AbsRelation of(int x, int y, int z) { + if (Math.abs(x) + Math.abs(y) + Math.abs(z) == 1) { + return AbsFace.roundToFace(x, y, z); + } + + return new AbsRelation(x, y, z); + } + @Override public AbsRelation resolve(AbsFace up) { return this; diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFace.java new file mode 100644 index 0000000..bdbccaf --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFace.java @@ -0,0 +1,42 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.rels; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; + +public interface BlockFace { + + public static final int BLOCK_FACE_COUNT = 6; + + AbsFace resolve(AbsFace up); + RelFace relativize(AbsFace up); + + public default Vec3i getVector(AbsFace up) { + return resolve(up).getVector(); + } + + public default Vec3 getFloatVector(AbsFace up) { + return resolve(up).getFloatVector(); + } + + public default Vec3 getNormalized(AbsFace up) { + return resolve(up).getNormalized(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java new file mode 100644 index 0000000..3e25e1b --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java @@ -0,0 +1,78 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.rels; + +import java.util.Objects; + +import static ru.windcorp.progressia.common.world.rels.AbsFace.BLOCK_FACE_COUNT; + +public class BlockFaceResolver { + + /** + * A mapping from (up; relative) to absolute. Face IDs are used as keys. + */ + private static final AbsFace[][] RESOLUTION_TABLE = new AbsFace[BLOCK_FACE_COUNT][BLOCK_FACE_COUNT]; + + /** + * A mapping from (up; absolute) to relative. Face IDs are used as keys. + */ + private static final RelFace[][] RELATIVIZATION_TABLE = new RelFace[BLOCK_FACE_COUNT][BLOCK_FACE_COUNT]; + + static { + for (AbsFace up : AbsFace.getFaces()) { + for (RelFace relative : RelFace.getFaces()) { + + AbsFace absolute = (AbsFace) AbsRelation.of(RelRelation.resolve(relative.getRelVector(), up, null)); + + RESOLUTION_TABLE[up.getId()][relative.getId()] = absolute; + RELATIVIZATION_TABLE[up.getId()][absolute.getId()] = relative; + + } + } + } + + public static AbsFace resolve(RelFace relative, AbsFace up) { + Objects.requireNonNull(relative, "relative"); + Objects.requireNonNull(up, "up"); + + if (relative == RelFace.UP) { + return up; + } else if (relative == RelFace.DOWN) { + return up.getCounter(); + } + + return RESOLUTION_TABLE[up.getId()][relative.getId()]; + } + + public static RelFace relativize(AbsFace absolute, AbsFace up) { + Objects.requireNonNull(absolute, "absolute"); + Objects.requireNonNull(up, "up"); + + if (absolute == up) { + return RelFace.UP; + } else if (absolute.getCounter() == up) { + return RelFace.DOWN; + } + + return RELATIVIZATION_TABLE[up.getId()][absolute.getId()]; + } + + private BlockFaceResolver() { + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java index 9d4b658..7f3ddb7 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java @@ -22,7 +22,7 @@ import com.google.common.collect.ImmutableMap; import glm.vec._3.i.Vec3i; -public class RelFace extends RelRelation { +public class RelFace extends RelRelation implements BlockFace { // @formatter:off public static final RelFace @@ -76,7 +76,7 @@ public class RelFace extends RelRelation { private RelFace counterFace; private RelFace(int x, int y, int z, String name) { - super(x, y, z, true); + super(x, y, z, false); this.id = nextId++; this.name = name; } @@ -84,6 +84,24 @@ public class RelFace extends RelRelation { public String getName() { return name; } + + @Override + public AbsFace resolve(AbsFace up) { + return BlockFaceResolver.resolve(this, up); + } + + @Override + public RelFace relativize(AbsFace up) { + return this; + } + + public RelFace rotate(AbsFace fromUp, AbsFace toUp) { + if (fromUp == toUp) { + return this; + } + + return resolve(fromUp).relativize(toUp); + } /** * @return the id @@ -97,7 +115,7 @@ public class RelFace extends RelRelation { } public RelFace getCounterAndMoveCursor(Vec3i cursor) { - cursor.add(getVector()); + cursor.add(getRelVector()); return counterFace; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java index a4d23d4..5268a26 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java @@ -19,8 +19,12 @@ package ru.windcorp.progressia.common.world.rels; import java.util.Map; +import glm.mat._3.Mat3; +import glm.mat._4.Mat4; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.VectorUtil.SignedAxis; import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.*; @@ -35,20 +39,64 @@ public class RelRelation extends BlockRelation { private final SignedAxis westDestination; private final SignedAxis upDestination; - public Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) { + private final Mat3 resolutionMatrix3 = new Mat3(); + private final Mat4 resolutionMatrix4 = new Mat4(); + + private final Mat3 relativizationMatrix3 = new Mat3(); + private final Mat4 relativizationMatrix4 = new Mat4(); + + private Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) { this.northDestination = northDestination; this.westDestination = westDestination; this.upDestination = upDestination; + + resolutionMatrix3.c0(apply(null, new Vec3(1, 0, 0))); + resolutionMatrix3.c1(apply(null, new Vec3(0, 1, 0))); + resolutionMatrix3.c2(apply(null, new Vec3(0, 0, 1))); + resolutionMatrix3.toMat4(resolutionMatrix4); + + relativizationMatrix3.set(resolutionMatrix3).transpose(); + relativizationMatrix4.set(resolutionMatrix4).transpose(); + } + + /** + * @return the resolutionMatrix3 + */ + public Mat3 getResolutionMatrix3() { + return resolutionMatrix3; + } + + /** + * @return the resolutionMatrix4 + */ + public Mat4 getResolutionMatrix4() { + return resolutionMatrix4; + } + + /** + * @return the relativizationMatrix3 + */ + public Mat3 getRelativizationMatrix3() { + return relativizationMatrix3; + } + + /** + * @return the relativizationMatrix4 + */ + public Mat4 getRelativizationMatrix4() { + return relativizationMatrix4; } public Vec3i apply(Vec3i output, Vec3i input) { if (output == null) { - return output; + output = new Vec3i(); } - set(output, input.x, northDestination); - set(output, input.y, westDestination); - set(output, input.z, upDestination); + int inX = input.x, inY = input.y, inZ = input.z; + + set(output, inX, northDestination); + set(output, inY, westDestination); + set(output, inZ, upDestination); return output; } @@ -56,6 +104,24 @@ public class RelRelation extends BlockRelation { private static void set(Vec3i output, int value, SignedAxis axis) { VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value); } + + public Vec3 apply(Vec3 output, Vec3 input) { + if (output == null) { + output = new Vec3(); + } + + float inX = input.x, inY = input.y, inZ = input.z; + + set(output, inX, northDestination); + set(output, inY, westDestination); + set(output, inZ, upDestination); + + return output; + } + + private static void set(Vec3 output, float value, SignedAxis axis) { + VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value); + } } private final static Map TRANSFORMATIONS = AbsFace.mapToFaces( @@ -68,14 +134,27 @@ public class RelRelation extends BlockRelation { ); private final Vec3i vector = new Vec3i(); + private final Vec3 floatVector = new Vec3(); + private final Vec3 normalized = new Vec3(); + private AbsRelation[] resolved = null; public RelRelation(int north, int west, int up) { this(north, west, up, false); } + public RelRelation(Vec3i vector) { + this(vector.x, vector.y, vector.z, false); + } + protected RelRelation(int north, int west, int up, boolean precomputeAllResolutions) { vector.set(north, west, up); + floatVector.set(north, west, up); + normalized.set(north, west, up); + + if (normalized.any()) { + normalized.normalize(); + } if (precomputeAllResolutions) { for (AbsFace face : AbsFace.getFaces()) { @@ -84,13 +163,46 @@ public class RelRelation extends BlockRelation { } } + public static RelRelation of(Vec3i vector) { + return of(vector.x, vector.y, vector.z); + } + + public static RelRelation of(int north, int west, int up) { + if (Math.abs(north) + Math.abs(west) + Math.abs(up) == 1) { + if (up == 1) { + return RelFace.UP; + } else if (up == -1) { + return RelFace.DOWN; + } else if (north == 1) { + return RelFace.NORTH; + } else if (north == -1) { + return RelFace.SOUTH; + } else if (west == 1) { + return RelFace.WEST; + } else { + assert west == -1; + return RelFace.EAST; + } + } + + return new RelRelation(north, west, up); + } + /** * @return the relative vector (northward, westward, upward) */ - public Vec3i getVector() { + public Vec3i getRelVector() { return vector; } + public Vec3 getRelFloatVector() { + return floatVector; + } + + public Vec3 getRelNormalized() { + return normalized; + } + public int getNorthward() { return vector.x; } @@ -129,12 +241,43 @@ public class RelRelation extends BlockRelation { } private AbsRelation computeResolution(AbsFace up) { - return new AbsRelation(TRANSFORMATIONS.get(up).apply(new Vec3i(), vector)); + Vec3i resolution = Vectors.grab3i(); + resolve(vector, up, resolution); + AbsRelation result = AbsRelation.of(resolution); + Vectors.release(resolution); + return result; + } + + public static Vec3i resolve(Vec3i relative, AbsFace up, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + TRANSFORMATIONS.get(up).apply(output, relative); + + return output; + } + + public static Mat3 getResolutionMatrix3(AbsFace up) { + return TRANSFORMATIONS.get(up).getResolutionMatrix3(); + } + + public static Mat4 getResolutionMatrix4(AbsFace up) { + return TRANSFORMATIONS.get(up).getResolutionMatrix4(); + } + + + public static Mat3 getRelativizationMatrix3(AbsFace up) { + return TRANSFORMATIONS.get(up).getRelativizationMatrix3(); + } + + public static Mat4 getRelativizationMatrix4(AbsFace up) { + return TRANSFORMATIONS.get(up).getRelativizationMatrix4(); } @Override protected Vec3i getSample() { - return getVector(); + return getRelVector(); } } diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 8aca03c..a46100a 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -68,9 +68,9 @@ public class Server { this.chunkManager = new ChunkManager(this); this.entityManager = new EntityManager(this); - schedule(this::scheduleWorldTicks); schedule(chunkManager::tick); schedule(entityManager::tick); + schedule(this::scheduleWorldTicks); // Must run after chunkManager so it only schedules chunks that hadn't unloaded } /** diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index 612c1b9..2ee89d6 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -30,6 +30,8 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.server.world.block.BlockLogic; @@ -66,6 +68,11 @@ public class ChunkLogic implements GenericChunk action) { TickContextMutable context = TickContextMutable.uninitialized(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index 4c92990..9f8f265 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockTickContext; @@ -61,17 +61,22 @@ public class TickAndUpdateUtil { } } - public static void tickTile(WorldLogic world, Vec3i blockInWorld, AbsFace face, int layer) { + public static void tickTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { TileLogic tile = world.getTile(blockInWorld, face, layer); - if (!(tile instanceof TickableTile)) + if (!(tile instanceof TickableTile)) { return; + } TileTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face) .withLayer(layer); tickTile((TickableTile) tile, tickContext); } - public static void tickTiles(WorldLogic world, Vec3i blockInWorld, AbsFace face) { + public static void tickTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { + if (!world.isBlockLoaded(blockInWorld)) { + return; + } + TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() .forEachTile(context -> { TileLogic tile = context.getTile(); @@ -106,17 +111,22 @@ public class TickAndUpdateUtil { } } - public static void updateTile(WorldLogic world, Vec3i blockInWorld, AbsFace face, int layer) { + public static void updateTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { TileLogic tile = world.getTile(blockInWorld, face, layer); - if (!(tile instanceof UpdateableTile)) + if (!(tile instanceof UpdateableTile)) { return; + } TileTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face) .withLayer(layer); updateTile((UpdateableTile) tile, tickContext); } - public static void updateTiles(WorldLogic world, Vec3i blockInWorld, AbsFace face) { + public static void updateTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { + if (!world.isBlockLoaded(blockInWorld)) { + return; + } + TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() .forEachTile(context -> { TileLogic tile = context.getTile(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java index 6b0d789..6eb1cbf 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import java.util.Objects; @@ -26,7 +26,8 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.generic.GenericTileStack; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.server.Server; @@ -126,7 +127,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } public static interface Block extends Builder { - Builder.TileStack withFace(AbsFace face); + Builder.TileStack withFace(BlockFace face); } public static interface TileStack extends Builder { @@ -148,7 +149,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont protected Server server; protected final Vec3i chunk = new Vec3i(); protected final Vec3i blockInWorld = new Vec3i(); - protected AbsFace face; + protected RelFace face; protected int layer; protected Role role = Role.NONE; @@ -188,7 +189,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public AbsFace getFace() { + public RelFace getFace() { checkContextState(Role.TILE_STACK); return this.face; } @@ -261,8 +262,9 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont public TileStack withTS(GenericTileStack tileStack) { Objects.requireNonNull(tileStack, "tileStack"); - return withBlock(tileStack.getBlockInWorld(this.blockInWorld)).withFace(tileStack.getFace()); - // ^^^^^^^^^^^^^^^^^ This is safe + return withBlock( + tileStack.getBlockInWorld(this.blockInWorld) // This is safe + ).withFace(tileStack.getFace()); } @Override @@ -277,11 +279,11 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public TileStack withFace(AbsFace face) { + public TileStack withFace(BlockFace face) { Objects.requireNonNull(face, "face"); checkBuilderState(Role.BLOCK); - this.face = face; + this.face = face.relativize(server.getWorld().getChunk(chunk).getUp()); this.role = Role.TILE_STACK; return this; @@ -339,12 +341,12 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont @Override public void forEachFace(Consumer action) { checkContextState(Role.BLOCK); - AbsFace previousFace = this.face; + RelFace previousFace = this.face; Role previousRole = this.role; this.role = Role.TILE_STACK; - for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { - this.face = AbsFace.getFaces().get(i); + for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) { + this.face = RelFace.getFaces().get(i); action.accept(this); } @@ -393,11 +395,13 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont Objects.requireNonNull(action, "action"); checkContextState(Role.TILE_STACK); - this.blockInWorld.add(this.face.getVector()); + Vec3i vector = this.face.getVector(getUp()); + + this.blockInWorld.add(vector); this.face = this.face.getCounter(); R result = action.apply(this); this.face = this.face.getCounter(); - this.blockInWorld.sub(this.face.getVector()); + this.blockInWorld.sub(vector); return result; } @@ -407,11 +411,13 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont Objects.requireNonNull(action, "action"); checkContextState(Role.TILE_STACK); - this.blockInWorld.add(this.face.getVector()); + Vec3i vector = this.face.getVector(getUp()); + + this.blockInWorld.add(vector); this.face = this.face.getCounter(); action.accept(this); this.face = this.face.getCounter(); - this.blockInWorld.sub(this.face.getVector()); + this.blockInWorld.sub(vector); } /* diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index 2262f00..d0b9562 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -23,7 +23,7 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; @@ -49,7 +49,7 @@ public class UpdateTriggerer implements ChunkDataListener { public void onChunkTilesChanged( ChunkData chunk, Vec3i blockInChunk, - AbsFace face, + RelFace face, TileData tile, boolean wasAdded ) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 93a1028..ad255f0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -39,13 +39,8 @@ import ru.windcorp.progressia.server.world.tile.TileLogic; import ru.windcorp.progressia.server.world.tile.TileLogicStack; public class WorldLogic - implements GenericWorld { private final WorldData data; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index 7a313c0..fdc35e2 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class BlockLogic extends Namespaced implements GenericBlock { @@ -28,11 +28,11 @@ public class BlockLogic extends Namespaced implements GenericBlock { super(id); } - public boolean isSolid(BlockTickContext context, AbsFace face) { + public boolean isSolid(BlockTickContext context, RelFace face) { return isSolid(face); } - public boolean isSolid(AbsFace face) { + public boolean isSolid(RelFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java index 358fe71..7069aa9 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java @@ -26,7 +26,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.AbsRelation; +import ru.windcorp.progressia.common.world.rels.BlockRelation; import ru.windcorp.progressia.server.world.ChunkTickContext; import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.tile.TSTickContext; @@ -67,9 +67,9 @@ public interface BlockTickContext extends ChunkTickContext { return TickContextMutable.copyWorld(this).withBlock(getBlockInWorld().add_(direction)).build(); } - default BlockTickContext getNeighbor(AbsRelation relation) { + default BlockTickContext getNeighbor(BlockRelation relation) { Objects.requireNonNull(relation, "relation"); - return getNeighbor(relation.getVector()); + return getNeighbor(relation.getVector(getChunkData().getUp())); } default R evalNeighbor(Vec3i direction, Function action) { @@ -78,10 +78,10 @@ public interface BlockTickContext extends ChunkTickContext { return action.apply(getNeighbor(direction)); } - default R evalNeighbor(AbsRelation relation, Function action) { + default R evalNeighbor(BlockRelation relation, Function action) { Objects.requireNonNull(action, "action"); Objects.requireNonNull(relation, "relation"); - return evalNeighbor(relation.getVector(), action); + return evalNeighbor(relation.getVector(getChunkData().getUp()), action); } default void forNeighbor(Vec3i direction, Consumer action) { @@ -93,10 +93,10 @@ public interface BlockTickContext extends ChunkTickContext { }); } - default void forNeighbor(AbsRelation relation, Consumer action) { + default void forNeighbor(BlockRelation relation, Consumer action) { Objects.requireNonNull(action, "action"); Objects.requireNonNull(relation, "relation"); - forNeighbor(relation.getVector(), action); + forNeighbor(relation.getVector(getChunkData().getUp()), action); } /* diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java index 9389b8f..15ab504 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java @@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.util.MultiLOC; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.Server; @@ -64,19 +64,19 @@ public class WorldAccessor { setBlock(blockInWorld, BlockDataRegistry.getInstance().get(id)); } - public void addTile(Vec3i blockInWorld, AbsFace face, TileData tile) { + public void addTile(Vec3i blockInWorld, BlockFace face, TileData tile) { AddTile change = cache.grab(AddTile.class); - change.getPacket().set(tile, blockInWorld, face); + change.getPacket().set(tile, blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld))); server.requestChange(change); } - public void addTile(Vec3i blockInWorld, AbsFace face, String id) { + public void addTile(Vec3i blockInWorld, BlockFace face, String id) { addTile(blockInWorld, face, TileDataRegistry.getInstance().get(id)); } - public void removeTile(Vec3i blockInWorld, AbsFace face, int tag) { + public void removeTile(Vec3i blockInWorld, BlockFace face, int tag) { RemoveTile change = cache.grab(RemoveTile.class); - change.getPacket().set(blockInWorld, face, tag); + change.getPacket().set(blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld)), tag); server.requestChange(change); } @@ -91,6 +91,7 @@ public class WorldAccessor { public void tickBlock(Vec3i blockInWorld) { // TODO + System.err.println("WorldAccessor.tickBlock(Vec3i) NYI!"); } /** @@ -112,9 +113,9 @@ public class WorldAccessor { * @param face */ // TODO rename to something meaningful - public void triggerUpdates(Vec3i blockInWorld, AbsFace face) { + public void triggerUpdates(Vec3i blockInWorld, BlockFace face) { TileTriggeredUpdate evaluation = cache.grab(TileTriggeredUpdate.class); - evaluation.init(blockInWorld, face); + evaluation.init(blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld))); server.requestEvaluation(evaluation); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index 6a670bf..e965ffb 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -23,7 +23,7 @@ import java.util.function.Consumer; import java.util.function.Function; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; @@ -35,7 +35,7 @@ public interface TSTickContext extends BlockTickContext { * Specifications */ - AbsFace getFace(); + RelFace getFace(); /* * Getters @@ -91,7 +91,7 @@ public interface TSTickContext extends BlockTickContext { default TSTickContext getComplementary() { return TickContextMutable.copyWorld(this) - .withBlock(getBlockInWorld().add_(getFace().getVector())) + .withBlock(getBlockInWorld().add_(getFace().getVector(getUp()))) .withFace(getFace().getCounter()) .build(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java index c5343b0..2bd43f5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; public class TileLogic extends Namespaced implements GenericTile { @@ -32,7 +32,7 @@ public class TileLogic extends Namespaced implements GenericTile { return canOccupyFace(context.getFace()); } - public boolean canOccupyFace(AbsFace face) { + public boolean canOccupyFace(RelFace face) { return true; } diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java index 8fed375..e596092 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; public class TestBlockLogicAir extends BlockLogic { @@ -28,7 +28,7 @@ public class TestBlockLogicAir extends BlockLogic { } @Override - public boolean isSolid(AbsFace face) { + public boolean isSolid(RelFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java index 3d29519..cd73ab3 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; public class TestBlockLogicGlass extends BlockLogic { @@ -28,7 +28,7 @@ public class TestBlockLogicGlass extends BlockLogic { } @Override - public boolean isSolid(AbsFace face) { + public boolean isSolid(RelFace face) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index 6a47d41..9e94d64 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -39,7 +39,7 @@ import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.io.ChunkCodec; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; @@ -91,6 +91,9 @@ public class TestChunkCodec extends ChunkCodec { TileData[] tilePalette = readTilePalette(input); ChunkData chunk = new ChunkData(position, world); + + assert chunk.getUp() == ru.windcorp.progressia.server.ServerState.getInstance().getWorld().getData().getChunk(position).getUp(); + readBlocks(input, blockPalette, chunk); readTiles(input, tilePalette, chunk); @@ -138,7 +141,7 @@ public class TestChunkCodec extends ChunkCodec { break; bic.set(xOrEndMarker, input.readByte() & 0xFF, input.readByte() & 0xFF); - AbsFace face = AbsFace.getFaces().get(input.readByte() & 0xFF); + RelFace face = RelFace.getFaces().get(input.readByte() & 0xFF); int tiles = input.readByte() & 0xFF; diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 9b5b28f..2b0b90c 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -137,9 +137,6 @@ public class TestContent { "Test:Log", getBlockTexture("LogTop"), getBlockTexture("LogTop"), - getBlockTexture("LogSide"), - getBlockTexture("LogSide"), - getBlockTexture("LogSide"), getBlockTexture("LogSide") ) ); @@ -159,7 +156,7 @@ public class TestContent { Set placeableBlacklist = new HashSet<>(); register(new TileData("Test:Grass")); - register(new TileRenderGrass("Test:Grass", getTileTexture("GrassTop"), getTileTexture("GrassSide"))); + register(new TestTileRenderGrass("Test:Grass", getTileTexture("GrassTop"), getTileTexture("GrassSide"))); register(new TestTileLogicGrass("Test:Grass")); register(new TileData("Test:Stones")); diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java index 00c3005..56b71ea 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java @@ -78,14 +78,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addStaticPart( new PppBuilder( WorldRenderProgram.getDefault(), - AbsFace.mapToFaces( - tailStartTexture, - tailStartTexture, - tailStartTexture, - tailStartTexture, - tailStartTexture, - tailStartTexture - ) + tailStartTexture ) .setOrigin(-60, -4, 14) .setDepth(32, 0, -16).setWidth(8).setHeight(8) @@ -97,14 +90,7 @@ public class TestEntityRenderJavapony extends EntityRender { b.addStaticPart( new PppBuilder( WorldRenderProgram.getDefault(), - AbsFace.mapToFaces( - neckTexture, - neckTexture, - neckTexture, - neckTexture, - neckTexture, - neckTexture - ) + neckTexture ) .setOrigin(0, -8, 8) .setWidth(16).setDepth(16).setHeight(2, 0, 16) diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index e2141d8..246c882 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockTickContext; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; @@ -34,12 +34,12 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile @Override public boolean canOccupyFace(TileTickContext context) { - return context.getFace() != AbsFace.NEG_Z && super.canOccupyFace(context); + return context.getFace() != RelFace.DOWN && super.canOccupyFace(context); } @Override - public boolean canOccupyFace(AbsFace face) { - return face != AbsFace.NEG_Z; + public boolean canOccupyFace(RelFace face) { + return face != RelFace.DOWN; } @Override @@ -50,7 +50,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile @Override public void tick(TileTickContext context) { if (!isLocationSuitable(context)) { - context.removeThisTile(); +// context.removeThisTile(); } } @@ -64,7 +64,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile } private boolean isBlockAboveTransparent(BlockTickContext context) { - return context.evalNeighbor(AbsFace.POS_Z, bctxt -> { + return context.evalNeighbor(RelFace.UP, bctxt -> { BlockLogic block = bctxt.getBlock(); if (block == null) return true; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileRenderGrass.java similarity index 70% rename from src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java rename to src/main/java/ru/windcorp/progressia/test/TestTileRenderGrass.java index 1845fa6..14b56c7 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileRenderGrass.java @@ -16,17 +16,18 @@ * along with this program. If not, see . */ -package ru.windcorp.progressia.client.world.tile; +package ru.windcorp.progressia.test; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.client.world.tile.TileRenderSurface; +import ru.windcorp.progressia.common.world.rels.RelFace; -public class TileRenderGrass extends TileRenderSurface { +public class TestTileRenderGrass extends TileRenderSurface { private final Texture topTexture; private final Texture sideTexture; - public TileRenderGrass( + public TestTileRenderGrass( String id, Texture top, Texture side @@ -37,13 +38,13 @@ public class TileRenderGrass extends TileRenderSurface { } @Override - public Texture getTexture(AbsFace face) { - return (face == AbsFace.POS_Z) ? topTexture : sideTexture; + public Texture getTexture(RelFace face) { + return (face == RelFace.UP) ? topTexture : sideTexture; } @Override - public boolean isOpaque(AbsFace face) { - return face == AbsFace.POS_Z; + public boolean isOpaque(RelFace face) { + return face == RelFace.UP; } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java index 24dbf2b..02bb12e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java @@ -30,14 +30,7 @@ public class TestGravityModel extends GravityModel { @Override protected void doGetGravity(Vec3 pos, Vec3 output) { - output.set(pos); - - if (output.length() < 10) { - output.set(0); - return; - } - - output.normalize().mul(-9.8f); + output.set(0, 0, -9.8f); } @Override From d438d2aa14f4679fb889ade4a3240b857bbfd7f8 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 7 Feb 2021 01:01:37 +0300 Subject: [PATCH 09/63] Linked GravityModel to a WorldGenerator and added GM comms transfer - WorldData no longer acquires a GravityModel automatically - On the server, GravityModel is specified by WorldGenerator - On the client, GravityModel is received from the server via a PacketSetGravityModel --- .../common/world/PacketSetGravityModel.java | 56 +++++++++++++++++++ .../progressia/common/world/WorldData.java | 17 ++++-- .../server/comms/ClientManager.java | 5 ++ .../progressia/server/world/WorldLogic.java | 2 + .../generation/AbstractWorldGenerator.java | 16 +++++- .../world/generation/WorldGenerator.java | 3 + .../test/gen/TestWorldGenerator.java | 2 +- 7 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java new file mode 100644 index 0000000..7e7f95e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java @@ -0,0 +1,56 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class PacketSetGravityModel extends PacketAffectWorld { + + private String gravityModelId; + + public PacketSetGravityModel() { + this("Core:SetGravityModel"); + } + + protected PacketSetGravityModel(String id) { + super(id); + } + + public void set(GravityModel model) { + this.gravityModelId = model.getId(); + } + + @Override + public void read(DataInput input) throws IOException, DecodingException { + gravityModelId = input.readUTF(); + } + + @Override + public void write(DataOutput output) throws IOException { + output.writeUTF(gravityModelId); + } + + @Override + public void apply(WorldData world) { + GravityModel model = GravityModelRegistry.getInstance().get(gravityModelId); + world.setGravityModel(model); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 6806c1b..625b8c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.util.ArrayList; @@ -51,8 +51,8 @@ public class WorldData private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); - - private GravityModel gravityModel = GravityModelRegistry.getInstance().get("Test:TheGravityModel"); + + private GravityModel gravityModel = null; private float time = 0; @@ -202,18 +202,25 @@ public class WorldData return null; return block.getCollisionModel(); } - + /** * @return the gravity model */ public GravityModel getGravityModel() { return gravityModel; } - + /** * @param gravityModel the gravity model to set */ public void setGravityModel(GravityModel gravityModel) { + if (!chunks.isEmpty()) { + throw new IllegalStateException( + "Attempted to change gravity model to " + gravityModel + " while " + chunks.size() + + " chunks were loaded" + ); + } + this.gravityModel = gravityModel; } diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java index cb4b80b..74c636d 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java @@ -28,6 +28,7 @@ import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.TIntObjectHashMap; import ru.windcorp.progressia.common.comms.CommsChannel.State; import ru.windcorp.progressia.common.comms.packets.Packet; +import ru.windcorp.progressia.common.world.PacketSetGravityModel; import ru.windcorp.progressia.common.world.PacketSetLocalPlayer; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.server.Player; @@ -73,6 +74,10 @@ public class ClientManager { private void addClientPlayer(ClientPlayer client) { String login = client.getLogin(); + + PacketSetGravityModel setGravityModelPacket = new PacketSetGravityModel(); + setGravityModelPacket.set(getServer().getWorld().getData().getGravityModel()); + client.sendPacket(setGravityModelPacket); EntityData entity = getServer().getPlayerManager().conjurePlayerEntity(login); Player player = new Player(entity, getServer(), client); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index ad255f0..5931e34 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -55,7 +55,9 @@ public class WorldLogic public WorldLogic(WorldData data, Server server, Function worldGeneratorConstructor) { this.data = data; this.server = server; + this.generator = worldGeneratorConstructor.apply(this); + data.setGravityModel(getGenerator().getGravityModel()); data.addListener(new WorldDataListener() { @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index ffb5c06..74583ff 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -25,14 +25,23 @@ import java.util.Objects; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.GravityModel; +import ru.windcorp.progressia.common.world.GravityModelRegistry; public abstract class AbstractWorldGenerator extends WorldGenerator { private final Class hintClass; + + private final GravityModel gravityModel; - public AbstractWorldGenerator(String id, Class hintClass) { + public AbstractWorldGenerator(String id, Class hintClass, String gravityModelId) { super(id); this.hintClass = Objects.requireNonNull(hintClass, "hintClass"); + this.gravityModel = GravityModelRegistry.getInstance().get(Objects.requireNonNull(gravityModelId, "gravityModelId")); + + if (this.gravityModel == null) { + throw new IllegalArgumentException("Gravity model with ID \"" + gravityModelId + "\" not found"); + } } @Override @@ -63,5 +72,10 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { protected void setHint(ChunkData chunk, H hint) { chunk.setGenerationHint(hint); } + + @Override + public GravityModel getGravityModel() { + return gravityModel; + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index afed281..6a85e45 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -26,6 +26,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.WorldData; public abstract class WorldGenerator extends Namespaced { @@ -42,5 +43,7 @@ public abstract class WorldGenerator extends Namespaced { public abstract void writeGenerationHint(DataOutputStream output, Object hint) throws IOException; public abstract boolean isChunkReady(Object hint); + + public abstract GravityModel getGravityModel(); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 6a2f1cb..9d4ff6e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -44,7 +44,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { private final TestTerrainGenerator terrainGen; public TestWorldGenerator(WorldLogic world) { - super("Test:WorldGenerator", Boolean.class); + super("Test:WorldGenerator", Boolean.class, "Test:TheGravityModel"); this.terrainGen = new TestTerrainGenerator(this, world); world.getData().addListener(new WorldDataListener() { From 2d55d4db51ae7a84cd4ecd36c1db0d88a88a06f1 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 22 Feb 2021 15:38:14 +0300 Subject: [PATCH 10/63] Added a cubic gravity model and fixed some stuff - Added TestPlanetGenerator and a corresponding gravity model - Fixed gravity-triggered camera rotation --- .../collision/colliders/AABBoidCollider.java | 67 ++++--- .../common/collision/colliders/Collider.java | 94 ++++----- .../progressia/common/world/ChunkData.java | 14 +- .../common/world/entity/EntityData.java | 6 +- .../ru/windcorp/progressia/server/Player.java | 2 +- .../ru/windcorp/progressia/server/Server.java | 6 +- .../windcorp/progressia/test/TestContent.java | 5 +- .../test/gen/TestPlanetGenerator.java | 181 ++++++++++++++++++ .../test/gen/TestPlanetGravityModel.java | 132 +++++++++++++ 9 files changed, 422 insertions(+), 85 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java index d6c31c1..ed42594 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java @@ -122,46 +122,51 @@ class AABBoidCollider { return output; } + // @formatter:off /* - * Here we determine whether a collision has actually happened, and if it - * did, at what moment. - * The basic idea is to compute the moment of collision and impact - * coordinates in wall coordinate space. - * Then, we can check impact coordinates to determine if we actually hit the - * wall or flew by and then - * check time to make sure the collision is not too far in the future and - * not in the past. + * Here we determine whether a collision has actually happened, and if it did, at what moment. + * + * The basic idea is to compute the moment of collision and impact coordinates in wall coordinate space. + * Then, we can check impact coordinates to determine if we actually hit the wall or flew by and then + * check time to make sure the collision is not too far in the future and not in the past. + * * DETAILED EXPLANATION: - * Consider a surface defined by an origin r_wall and two noncollinear - * nonzero vectors w and h. + * + * Consider a surface defined by an origin r_wall and two noncollinear nonzero vectors w and h. * Consider a line defined by an origin r_line and a nonzero vector v. + * * Then, a collision occurs if there exist x, y and t such that - * ______ _ - * r_line + v * t + * ______ _ + * r_line + v * t + * * and - * ______ _ _ - * r_wall + w * x + h * y - * describe the same location (indeed, this corresponds to a collision at - * moment t0 + t - * with a point on the wall with coordinates (x; y) in (w; h) coordinate - * system). + * ______ _ _ + * r_wall + w * x + h * y + * + * describe the same location (indeed, this corresponds to a collision at moment t0 + t + * with a point on the wall with coordinates (x; y) in (w; h) coordinate system). + * * Therefore, - * ______ _ ______ _ _ - * r_line + v*t = r_wall + w*x + h*y; - * _ ⎡w_x h_x -v_x⎤ ⎡x⎤ _ ______ ______ - * r = ⎢w_y h_y -v_y⎥ * ⎢y⎥, where r = r_line - r_wall; - * ⎣w_z h_z -v_z⎦ ⎣t⎦ - * ⎡x⎤ ⎡w_x h_x -v_x⎤ -1 _ - * ⎢y⎥ = ⎢w_y h_y -v_y⎥ * r, if the matrix is invertible. - * ⎣t⎦ ⎣w_z h_z -v_z⎦ + * ______ _ ______ _ _ + * r_line + v*t = r_wall + w*x + h*y; + * + * _ ⎡w_x h_x -v_x⎤ ⎡x⎤ _ ______ ______ + * r = ⎢w_y h_y -v_y⎥ * ⎢y⎥, where r = r_line - r_wall; + * ⎣w_z h_z -v_z⎦ ⎣t⎦ + * + * ⎡x⎤ ⎡w_x h_x -v_x⎤ -1 _ + * ⎢y⎥ = ⎢w_y h_y -v_y⎥ * r, if the matrix is invertible. + * ⎣t⎦ ⎣w_z h_z -v_z⎦ + * * Then, one only needs to ensure that: - * 0 < x < 1, - * 0 < y < 1, and - * 0 < t < T, where T is remaining tick time. - * If the matrix is not invertible or any of the conditions are not met, no - * collision happened. + * 0 < x < 1, + * 0 < y < 1, and + * 0 < t < T, where T is remaining tick time. + * + * If the matrix is not invertible or any of the conditions are not met, no collision happened. * If all conditions are satisfied, then the moment of impact is t0 + t. */ + // @formatter:on private static Collision computeWallCollision( Wall obstacleWall, AABBoid colliderModel, diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java index 56bc8ad..62a7808 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java @@ -212,66 +212,72 @@ public class Collider { handlePhysics(collision); } + // @formatter:off /* * Here we compute the change in body velocities due to a collision. + * * We make the following simplifications: - * 1) The bodies are perfectly rigid; - * 2) The collision is perfectly inelastic - * (no bouncing); - * 3) The bodies are spherical; - * 4) No tangential friction exists - * (bodies do not experience friction when sliding against each other); - * 5) Velocities are not relativistic. + * 1) The bodies are perfectly rigid; + * 2) The collision is perfectly inelastic + * (no bouncing); + * 3) The bodies are spherical; + * 4) No tangential friction exists + * (bodies do not experience friction when sliding against each other); + * 5) Velocities are not relativistic. + * * Angular momentum is ignored per 3) and 4), - * e.g. when something pushes an end of a long stick, the stick does not - * rotate. + * e.g. when something pushes an end of a long stick, the stick does not rotate. + * * DETAILED EXPLANATION: - * Two spherical (sic) bodies, a and b, experience a perfectly inelastic - * collision + * + * Two spherical (sic) bodies, a and b, experience a perfectly inelastic collision * along a unit vector - * _ _ _ _ _ - * n = (w ⨯ h) / (|w ⨯ h|), - * _ _ + * _ _ _ _ _ + * n = (w ⨯ h) / (|w ⨯ h|), + * _ _ * where w and h are two noncollinear nonzero vectors on the dividing plane. - * ___ ___ + * ___ ___ * Body masses and velocities are M_a, M_b and v_a, v_b, respectively. - * ___ ___ + * ___ ___ * After the collision desired velocities are u_a and u_b, respectively. - * _ - * (Notation convention: suffix 'n' denotes a vector projection onto vector - * n, + * _ + * (Notation convention: suffix 'n' denotes a vector projection onto vector n, * and suffix 't' denotes a vector projection onto the dividing plane.) - * Consider the law of conservation of momentum for axis n and the dividing - * plane: - * ____________ ____________ ________________ - * n: ⎧ p_a_before_n + p_b_before_n = p_common_after_n; - * ⎨ ___________ ____________ - * t: ⎩ p_i_after_t = p_i_before_t for any i in {a, b}. + * + * Consider the law of conservation of momentum for axis n and the dividing plane: + * ____________ ____________ ________________ + * n: ⎧ p_a_before_n + p_b_before_n = p_common_after_n; + * ⎨ ___________ ____________ + * t: ⎩ p_i_after_t = p_i_before_t for any i in {a, b}. + * * Expressing all p_* in given terms: - * ___ _ ___ _ ___ ___ ____ ____ - * n: ⎧ M_a * (v_a ⋅ n) + M_b * (v_b ⋅ n) = (M_a + M_b) * u_n, where u_n ≡ - * u_an = u_bn; - * ⎨ ____ ___ _ ___ _ - * t: ⎩ u_it = v_i - n * (v_i ⋅ n) for any i in {a, b}. + * ___ _ ___ _ ___ ___ ____ ____ + * n: ⎧ M_a * (v_a ⋅ n) + M_b * (v_b ⋅ n) = (M_a + M_b) * u_n, where u_n ≡ u_an = u_bn; + * ⎨ ____ ___ _ ___ _ + * t: ⎩ u_it = v_i - n * (v_i ⋅ n) for any i in {a, b}. + * * Therefore: - * ___ _ ___ _ ___ _ - * u_n = n * ( M_a/(M_a + M_b) * v_a ⋅ n + M_b/(M_a + M_b) * v_b ⋅ n ); + * ___ _ ___ _ ___ _ + * u_n = n * ( M_a/(M_a + M_b) * v_a ⋅ n + M_b/(M_a + M_b) * v_b ⋅ n ); + * * or, equivalently, - * ___ _ ___ _ ___ _ - * u_n = n * ( m_a * v_a ⋅ n + m_b * v_b ⋅ n ), + * ___ _ ___ _ ___ _ + * u_n = n * ( m_a * v_a ⋅ n + m_b * v_b ⋅ n ), + * * where m_a and m_b are relative masses (see below). + * * Finally, - * ___ ____ ___ - * u_i = u_it + u_n for any i in {a, b}. - * The usage of relative masses m_i permits a convenient generalization of - * the algorithm - * for infinite masses, signifying masses "significantly greater" than - * finite masses: - * 1) If both M_a and M_b are finite, let m_i = M_i / (M_a + M_b) for any i - * in {a, b}. - * 2) If M_i is finite but M_j is infinite, let m_i = 0 and m_j = 1. - * 3) If both M_a and M_b are infinite, let m_i = 1/2 for any i in {a, b}. + * ___ ____ ___ + * u_i = u_it + u_n for any i in {a, b}. + * + * The usage of relative masses m_i permits a convenient generalization of the algorithm + * for infinite masses, signifying masses "significantly greater" than finite masses: + * + * 1) If both M_a and M_b are finite, let m_i = M_i / (M_a + M_b) for any i in {a, b}. + * 2) If M_i is finite but M_j is infinite, let m_i = 0 and m_j = 1. + * 3) If both M_a and M_b are infinite, let m_i = 1/2 for any i in {a, b}. */ + // @formatter:on private static void handlePhysics(Collision collision) { // Fuck JGLM Vec3 n = Vectors.grab3(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index ac0fb93..5788053 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -30,6 +30,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; @@ -44,14 +45,16 @@ public class ChunkData implements GenericChunk { public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; + public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; private final Vec3i position = new Vec3i(); private final WorldData world; private final BlockData[] blocks = new BlockData[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; - private final TileDataStack[] tiles = new TileDataStack[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * - BLOCK_FACE_COUNT]; + private final TileDataStack[] tiles = new TileDataStack[ + BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCK_FACE_COUNT + ]; private final AbsFace up; @@ -91,6 +94,13 @@ public class ChunkData }); } } + + public void setBlockRel(Vec3i relativeBlockInChunk, BlockData block, boolean notify) { + Vec3i absoluteBlockInChunk = Vectors.grab3i(); + resolve(relativeBlockInChunk, absoluteBlockInChunk); + setBlock(absoluteBlockInChunk, block, notify); + Vectors.release(absoluteBlockInChunk); + } @Override public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index 344439a..e776e6a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -282,9 +282,9 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn // Don't format. @formatter:off matrix.set( - cos + (1 - cos)*x*x, (1 - cos)*x*y - sin*z, (1 - cos)*x*z + sin*y, - (1 - cos)*y*x + sin*z, cos + (1 - cos)*y*y, (1 - cos)*y*z - sin*x, - (1 - cos)*z*x - sin*y, (1 - cos)*z*y + sin*x, cos + (1 - cos)*z*z + cos + (1 - cos)*x*x, (1 - cos)*y*x + sin*z, (1 - cos)*z*x - sin*y, + (1 - cos)*x*y - sin*z, cos + (1 - cos)*y*y, (1 - cos)*z*y + sin*x, + (1 - cos)*x*z + sin*y, (1 - cos)*y*z - sin*x, cos + (1 - cos)*z*z ); // @formatter:on diff --git a/src/main/java/ru/windcorp/progressia/server/Player.java b/src/main/java/ru/windcorp/progressia/server/Player.java index ea373a8..734783f 100644 --- a/src/main/java/ru/windcorp/progressia/server/Player.java +++ b/src/main/java/ru/windcorp/progressia/server/Player.java @@ -63,7 +63,7 @@ public class Player extends PlayerData implements ChunkLoader { for (cursor.x = -iRadius; cursor.x <= +iRadius; ++cursor.x) { for (cursor.y = -iRadius; cursor.y <= +iRadius; ++cursor.y) { for (cursor.z = -iRadius; cursor.z <= +iRadius; ++cursor.z) { - if (cursor.x * cursor.x + cursor.y * cursor.y + (cursor.z * 2) * (cursor.z * 2) <= radiusSq) { + if (cursor.x * cursor.x + cursor.y * cursor.y + (cursor.z/* * 2*/) * (cursor.z/* * 2*/) <= radiusSq) { cursor.add(start); chunkConsumer.accept(cursor); diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index a46100a..40fdca6 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -31,7 +31,7 @@ import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; -import ru.windcorp.progressia.test.gen.TestWorldGenerator; +import ru.windcorp.progressia.test.gen.TestPlanetGenerator; public class Server { @@ -60,7 +60,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); public Server(WorldData world) { - this.world = new WorldLogic(world, this, TestWorldGenerator::new); + this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", Units.get("48 m"), w)); this.serverThread = new ServerThread(this); this.clientManager = new ClientManager(this); @@ -206,7 +206,7 @@ public class Server { } public float getLoadDistance(Player player) { - return Units.get(150.0f, "m"); + return Units.get(100.5f, "m"); } /** diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 2b0b90c..d34c3ba 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -59,13 +59,15 @@ import ru.windcorp.progressia.server.world.block.*; import ru.windcorp.progressia.server.world.entity.*; import ru.windcorp.progressia.server.world.tile.*; import ru.windcorp.progressia.test.gen.TestGravityModel; +import ru.windcorp.progressia.test.gen.TestPlanetGravityModel; public class TestContent { public static final String PLAYER_LOGIN = "Sasha"; public static final long PLAYER_ENTITY_ID = 0x42; public static final long STATIE_ENTITY_ID = 0xDEADBEEF; - public static final Vec3 SPAWN = new Vec3(8, 8, 880); +// public static final Vec3 SPAWN = new Vec3(8, 8, 880); + public static final Vec3 SPAWN = new Vec3(0, 0, 66); public static final List PLACEABLE_BLOCKS = new ArrayList<>(); public static final List PLACEABLE_TILES = new ArrayList<>(); @@ -424,6 +426,7 @@ public class TestContent { ChunkIO.registerCodec(new TestChunkCodec()); ChunkRenderOptimizerRegistry.getInstance().register("Core:SurfaceOptimizer", ChunkRenderOptimizerSurface::new); GravityModelRegistry.getInstance().register(new TestGravityModel()); + GravityModelRegistry.getInstance().register(new TestPlanetGravityModel()); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java new file mode 100644 index 0000000..bbcdbfd --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java @@ -0,0 +1,181 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileDataRegistry; +import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; + +public class TestPlanetGenerator extends AbstractWorldGenerator { + + private final int surfaceLevel; + + public TestPlanetGenerator(String id, float planetRadius, WorldLogic world) { + super(id, Boolean.class, "Test:PlanetGravityModel"); + + this.surfaceLevel = (int) (planetRadius / ChunkData.BLOCKS_PER_CHUNK); + if (surfaceLevel < 2) { + throw new IllegalArgumentException("planetRadius too small, must be at least 32 m"); + } + } + + @Override + protected Boolean doReadGenerationHint(DataInputStream input) throws IOException, DecodingException { + return input.readBoolean(); + } + + @Override + protected void doWriteGenerationHint(DataOutputStream output, Boolean hint) throws IOException { + output.writeBoolean(hint); + } + + @Override + protected boolean checkIsChunkReady(Boolean hint) { + return hint; + } + + @Override + public ChunkData generate(Vec3i chunkPos, WorldData world) { + ChunkData chunk = new ChunkData(chunkPos, world); + + generate(chunk); + chunk.setGenerationHint(true); + + world.addChunk(chunk); + return chunk; + } + + private enum ChunkType { + SURFACE, UNDERGROUND, EDGE_SURFACE, EDGE_UNDERGROUND, CORE, AIR; + } + + private void generate(ChunkData chunk) { + switch (getChunkType(chunk.getPosition())) { + case SURFACE: + fillSurface(chunk); + break; + case UNDERGROUND: + fillUndeground(chunk); + break; + case EDGE_SURFACE: + fillEdgeSurface(chunk); + break; + case EDGE_UNDERGROUND: + fillEdgeUnderground(chunk); + break; + case CORE: + fillCore(chunk); + break; + case AIR: + fillAir(chunk); + break; + } + } + + private void fillSurface(ChunkData chunk) { + final int bpc = ChunkData.BLOCKS_PER_CHUNK; + + BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); + BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); + + TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); + + chunk.forEachBiC(bic -> { + + BlockData block; + + if (bic.z > bpc - 4) { + block = dirt; + } else { + block = granite; + } + + chunk.setBlockRel(bic, block, false); + + }); + + VectorUtil.iterateCuboid(0, 0, bpc - 1, bpc, bpc, bpc, bic -> { + chunk.getTilesRel(bic, RelFace.UP).add(grass); + }); + } + + private void fillUndeground(ChunkData chunk) { + fill(chunk, BlockDataRegistry.getInstance().get("Test:GraniteMonolith")); + } + + private void fillEdgeSurface(ChunkData chunk) { + fill(chunk, BlockDataRegistry.getInstance().get("Test:Stone")); + } + + private void fillEdgeUnderground(ChunkData chunk) { + fill(chunk, BlockDataRegistry.getInstance().get("Test:Stone")); + } + + private void fillCore(ChunkData chunk) { + fill(chunk, BlockDataRegistry.getInstance().get("Test:Stone")); + } + + private void fillAir(ChunkData chunk) { + fill(chunk, BlockDataRegistry.getInstance().get("Test:Air")); + } + + private void fill(ChunkData chunk, BlockData block) { + chunk.forEachBiC(bic -> chunk.setBlock(bic, block, false)); + } + + private ChunkType getChunkType(Vec3i pos) { + int[] abs = pos.abs_().toIA_(); + Arrays.sort(abs); + + int medium = abs[1]; + int largest = abs[2]; + + int level = largest; + + if (level == 0) { + return ChunkType.CORE; + } + + if (largest > surfaceLevel) { + return ChunkType.AIR; + } + + boolean isSurface = largest == surfaceLevel; + + if (medium == largest) { + return isSurface ? ChunkType.EDGE_SURFACE : ChunkType.EDGE_UNDERGROUND; + } else { + return isSurface ? ChunkType.SURFACE : ChunkType.UNDERGROUND; + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java new file mode 100644 index 0000000..05d659a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java @@ -0,0 +1,132 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.GravityModel; +import ru.windcorp.progressia.common.world.rels.AbsFace; + +import static java.lang.Math.*; + +public class TestPlanetGravityModel extends GravityModel { + + private static final float GRAVITATIONAL_ACCELERATION = Units.get("9.8 m/s^2"); + private static final float ROUNDNESS = Units.get("16 m"); + private static final float INNER_RADIUS = Units.get("16 m"); + + public TestPlanetGravityModel() { + this("Test:PlanetGravityModel"); + } + + protected TestPlanetGravityModel(String id) { + super(id); + } + + @Override + protected void doGetGravity(Vec3 pos, Vec3 output) { + // Change to a CS where (0;0;0) is the center of the center chunk + float px = pos.x - ChunkData.CHUNK_RADIUS; + float py = pos.y - ChunkData.CHUNK_RADIUS; + float pz = pos.z - ChunkData.CHUNK_RADIUS; + + // Assume weightlessness when too close to center + if ((px*px + py*py + pz*pz) < INNER_RADIUS*INNER_RADIUS) { + output.set(0, 0, 0); + return; + } + + // Cache absolute coordinates + float ax = abs(px); + float ay = abs(py); + float az = abs(pz); + + // Determine maximum and middle coordinates by absolute value + final float maxAbs; + final float midAbs; + + // herptyderp + if (ax > ay) { + if (ax > az) { + maxAbs = ax; + midAbs = ay > az ? ay : az; + } else { + maxAbs = az; + midAbs = ax; + } + } else { + if (ay > az) { + maxAbs = ay; + midAbs = ax > az ? ax : az; + } else { + maxAbs = az; + midAbs = ay; + } + } + + output.x = maxAbs - ax < ROUNDNESS ? (px > 0 ? +1 : -1) : 0; + output.y = maxAbs - ay < ROUNDNESS ? (py > 0 ? +1 : -1) : 0; + output.z = maxAbs - az < ROUNDNESS ? (pz > 0 ? +1 : -1) : 0; + + if (maxAbs - midAbs < ROUNDNESS) { + output.normalize(); + computeEdgeGravity(output.x, output.y, output.z, px, py, pz, output); + } else { + assert output.dot(output) == 1 : "maxAbs - midAbs = " + maxAbs + " - " + midAbs + " > " + ROUNDNESS + " yet l*l != 1"; + } + + output.mul(-GRAVITATIONAL_ACCELERATION); + } + + private void computeEdgeGravity(float lx, float ly, float lz, float rx, float ry, float rz, Vec3 output) { + // da math is gud, no worry + // - Javapony + + if (lx == 0) rx = 0; + if (ly == 0) ry = 0; + if (lz == 0) rz = 0; + + float scalarProduct = rx*lx + ry*ly + rz*lz; + float rSquared = rx*rx + ry*ry + rz*rz; + + float distanceAlongEdge = scalarProduct - (float) sqrt( + scalarProduct*scalarProduct - rSquared + ROUNDNESS*ROUNDNESS + ); + + output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(ROUNDNESS); + + final float f = (float) sqrt(3.0/2); + + if (signum(lx) != signum(output.x)) { + computeEdgeGravity(0, ly*f, lz*f, rx, ry, rz, output); + } else if (signum(ly) != signum(output.y)) { + computeEdgeGravity(lx*f, 0, lz*f, rx, ry, rz, output); + } else if (signum(lz) != signum(output.z)) { + computeEdgeGravity(lx*f, ly*f, 0, rx, ry, rz, output); + } + } + + @Override + protected AbsFace doGetDiscreteUp(Vec3i chunkPos) { + AbsFace rounded = AbsFace.roundToFace(chunkPos.x, chunkPos.y, chunkPos.z); + return rounded == null ? AbsFace.POS_Z : rounded; + } + +} From bd5a1fa04e554aa7518eab4a50cf19df1cce81fd Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 28 Feb 2021 22:55:51 +0300 Subject: [PATCH 11/63] Added rotating AABBs through lots of pain and suffering - Collision models now rotate to match entity's general up direction - Extracted rotation logic from RelRelation into AxisRotations - Test:PlanetGravityModel is now properly centered - Fixed some small bugs --- .../client/world/ChunkRenderModel.java | 4 +- .../common/collision/AABBRotator.java | 134 ++++++++++++ .../common/world/entity/EntityData.java | 12 ++ .../common/world/generic/GenericChunk.java | 4 +- .../common/world/rels/AxisRotations.java | 193 ++++++++++++++++++ .../common/world/rels/BlockFaceResolver.java | 2 +- .../common/world/rels/RelRelation.java | 136 +----------- .../test/gen/TestPlanetGravityModel.java | 6 +- 8 files changed, 348 insertions(+), 143 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/collision/AABBRotator.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/rels/AxisRotations.java diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 471fb92..75857b8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -36,8 +36,8 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.rels.RelRelation; public class ChunkRenderModel implements Renderable { @@ -61,7 +61,7 @@ public class ChunkRenderModel implements Renderable { chunk.getY() * ChunkData.BLOCKS_PER_CHUNK, chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK ).translate(offset, offset, offset) - .mul(RelRelation.getResolutionMatrix4(chunk.getUp())) + .mul(AxisRotations.getResolutionMatrix4(chunk.getUp())) .translate(-offset, -offset, -offset); model.render(renderer); diff --git a/src/main/java/ru/windcorp/progressia/common/collision/AABBRotator.java b/src/main/java/ru/windcorp/progressia/common/collision/AABBRotator.java new file mode 100644 index 0000000..cbacb29 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/collision/AABBRotator.java @@ -0,0 +1,134 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.collision; + +import java.util.function.Supplier; + +import com.google.common.collect.ImmutableList; + +import glm.vec._3.Vec3; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.AxisRotations; + +public class AABBRotator implements AABBoid { + + private class AABBRotatorWall implements Wall { + + private final int id; + + public AABBRotatorWall(int id) { + this.id = id; + } + + @Override + public void getOrigin(Vec3 output) { + parent.getWall(id).getOrigin(output); + AxisRotations.resolve(output, upSupplier.get(), output); + } + + @Override + public void getWidth(Vec3 output) { + parent.getWall(id).getWidth(output); + AxisRotations.resolve(output, upSupplier.get(), output); + } + + @Override + public void getHeight(Vec3 output) { + parent.getWall(id).getHeight(output); + AxisRotations.resolve(output, upSupplier.get(), output); + } + + } + + private final Supplier upSupplier; + private final Supplier hingeSupplier; + private final AABBoid parent; + + private final AABBRotatorWall[] walls = new AABBRotatorWall[AbsFace.BLOCK_FACE_COUNT]; + + { + for (int id = 0; id < walls.length; ++id) { + walls[id] = new AABBRotatorWall(id); + } + } + + public AABBRotator(Supplier upSupplier, Supplier hingeSupplier, AABBoid parent) { + this.upSupplier = upSupplier; + this.hingeSupplier = hingeSupplier; + this.parent = parent; + } + + @Override + public void setOrigin(Vec3 origin) { + Vec3 relativeOrigin = Vectors.grab3(); + Vec3 hinge = hingeSupplier.get(); + + origin.sub(hinge, relativeOrigin); + AxisRotations.relativize(relativeOrigin, upSupplier.get(), relativeOrigin); + relativeOrigin.add(hinge); + + parent.setOrigin(relativeOrigin); + + Vectors.release(relativeOrigin); + } + + @Override + public void moveOrigin(Vec3 displacement) { + parent.moveOrigin(displacement); + } + + @Override + public void getOrigin(Vec3 output) { + parent.getOrigin(output); + Vec3 hinge = hingeSupplier.get(); + + output.sub(hinge); + AxisRotations.resolve(output, upSupplier.get(), output); + output.add(hinge); + } + + @Override + public void getSize(Vec3 output) { + parent.getSize(output); + AxisRotations.resolve(output, upSupplier.get(), output); + output.abs(); + } + + @Override + public Wall getWall(int faceId) { + return walls[faceId]; + } + + public static CollisionModel rotate(Supplier upSupplier, Supplier hingeSupplier, CollisionModel parent) { + if (parent instanceof AABBoid) { + return new AABBRotator(upSupplier, hingeSupplier, (AABBoid) parent); + } else if (parent instanceof CompoundCollisionModel) { + ImmutableList.Builder models = ImmutableList.builder(); + + for (CollisionModel original : ((CompoundCollisionModel) parent).getModels()) { + models.add(rotate(upSupplier, hingeSupplier, original)); + } + + return new CompoundCollisionModel(models.build()); + } else { + throw new RuntimeException("not supported"); + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index e776e6a..d54cca1 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -26,12 +26,14 @@ import java.util.Objects; import glm.mat._3.Mat3; import glm.vec._3.Vec3; import ru.windcorp.jputil.chars.StringUtil; +import ru.windcorp.progressia.common.collision.AABBRotator; import ru.windcorp.progressia.common.collision.Collideable; import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.util.Matrices; import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class EntityData extends StatefulObject implements Collideable, GenericEntity { @@ -51,6 +53,7 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn private long entityId; private CollisionModel collisionModel = null; + private CollisionModel rotatedCollisionModel = null; private double age = 0; @@ -107,11 +110,16 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn @Override public CollisionModel getCollisionModel() { + return rotatedCollisionModel; + } + + public CollisionModel getOriginalCollisionModel() { return collisionModel; } public void setCollisionModel(CollisionModel collisionModel) { this.collisionModel = collisionModel; + this.rotatedCollisionModel = AABBRotator.rotate(this::getUpFace, this::getPosition, collisionModel); } @Override @@ -164,6 +172,10 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn public Vec3 getUpVector() { return upVector; } + + public AbsFace getUpFace() { + return AbsFace.roundToFace(getUpVector()); + } /** * Sets this entity's up vector without updating looking at-vector. diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 1768119..95c18be 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -25,8 +25,8 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.common.world.rels.RelRelation; public interface GenericChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> { @@ -52,7 +52,7 @@ public interface GenericChunk, B exten output.set(relativeBlockInChunk.x, relativeBlockInChunk.y, relativeBlockInChunk.z); output.mul(2).sub(offset); - RelRelation.resolve(output, getUp(), output); + AxisRotations.resolve(output, getUp(), output); output.add(offset).div(2); diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/AxisRotations.java b/src/main/java/ru/windcorp/progressia/common/world/rels/AxisRotations.java new file mode 100644 index 0000000..2d13c19 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/AxisRotations.java @@ -0,0 +1,193 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.rels; + +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.NEG_X; +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.NEG_Y; +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.NEG_Z; +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.POS_X; +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.POS_Y; +import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.POS_Z; + +import java.util.Map; + +import glm.mat._3.Mat3; +import glm.mat._4.Mat4; +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.VectorUtil.SignedAxis; + +public class AxisRotations { + + private static class Rotation { + private static class MyMat3i { + private final int m00, m01, m02, m10, m11, m12, m20, m21, m22; + + public MyMat3i(Mat3 integerMatrix) { + this.m00 = (int) integerMatrix.m00; + this.m01 = (int) integerMatrix.m01; + this.m02 = (int) integerMatrix.m02; + this.m10 = (int) integerMatrix.m10; + this.m11 = (int) integerMatrix.m11; + this.m12 = (int) integerMatrix.m12; + this.m20 = (int) integerMatrix.m20; + this.m21 = (int) integerMatrix.m21; + this.m22 = (int) integerMatrix.m22; + } + + public Vec3i mul(Vec3i right, Vec3i res) { + res.set( + m00 * right.x + m10 * right.y + m20 * right.z, + m01 * right.x + m11 * right.y + m21 * right.z, + m02 * right.x + m12 * right.y + m22 * right.z + ); + return res; + } + } + + private final Mat3 resolutionMatrix3 = new Mat3(); + private final Mat4 resolutionMatrix4 = new Mat4(); + private final MyMat3i resolutionMatrix3i; + + private final Mat3 relativizationMatrix3 = new Mat3(); + private final Mat4 relativizationMatrix4 = new Mat4(); + private final MyMat3i relativizationMatrix3i; + + private Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) { + resolutionMatrix3.c0(computeUnitVectorAlong(northDestination)); + resolutionMatrix3.c1(computeUnitVectorAlong(westDestination)); + resolutionMatrix3.c2(computeUnitVectorAlong(upDestination)); + + resolutionMatrix3.toMat4(resolutionMatrix4); + resolutionMatrix3i = new MyMat3i(resolutionMatrix3); + + relativizationMatrix3.set(resolutionMatrix3).transpose(); + relativizationMatrix4.set(resolutionMatrix4).transpose(); + relativizationMatrix3i = new MyMat3i(relativizationMatrix3); + } + + private static Vec3 computeUnitVectorAlong(SignedAxis signedAxis) { + Vec3 result = new Vec3(0, 0, 0); + VectorUtil.set(result, signedAxis.getAxis(), signedAxis.getSign()); + return result; + } + + /** + * @return the resolutionMatrix3 + */ + public Mat3 getResolutionMatrix3() { + return resolutionMatrix3; + } + + /** + * @return the resolutionMatrix4 + */ + public Mat4 getResolutionMatrix4() { + return resolutionMatrix4; + } + + /** + * @return the relativizationMatrix3 + */ + public Mat3 getRelativizationMatrix3() { + return relativizationMatrix3; + } + + /** + * @return the relativizationMatrix4 + */ + public Mat4 getRelativizationMatrix4() { + return relativizationMatrix4; + } + + public Vec3i resolve(Vec3i output, Vec3i input) { + if (output == null) { + output = new Vec3i(); + } + resolutionMatrix3i.mul(input, output); + return output; + } + + public Vec3i relativize(Vec3i output, Vec3i input) { + if (output == null) { + output = new Vec3i(); + } + relativizationMatrix3i.mul(input, output); + return output; + } + + public Vec3 resolve(Vec3 output, Vec3 input) { + if (output == null) { + output = new Vec3(); + } + resolutionMatrix3.mul(input, output); + return output; + } + + public Vec3 relativize(Vec3 output, Vec3 input) { + if (output == null) { + output = new Vec3(); + } + relativizationMatrix3.mul(input, output); + return output; + } + } + + private final static Map TRANSFORMATIONS = AbsFace.mapToFaces( + new Rotation(POS_X, POS_Y, POS_Z), + new Rotation(POS_X, NEG_Y, NEG_Z), + new Rotation(POS_Z, NEG_Y, POS_X), + new Rotation(POS_Z, POS_Y, NEG_X), + new Rotation(POS_Z, NEG_X, NEG_Y), + new Rotation(POS_Z, POS_X, POS_Y) + ); + + public static Vec3i resolve(Vec3i relative, AbsFace up, Vec3i output) { + return TRANSFORMATIONS.get(up).resolve(output, relative); + } + + public static Vec3 resolve(Vec3 relative, AbsFace up, Vec3 output) { + return TRANSFORMATIONS.get(up).resolve(output, relative); + } + + public static Vec3i relativize(Vec3i absolute, AbsFace up, Vec3i output) { + return TRANSFORMATIONS.get(up).relativize(output, absolute); + } + + public static Vec3 relativize(Vec3 absolute, AbsFace up, Vec3 output) { + return TRANSFORMATIONS.get(up).relativize(output, absolute); + } + + public static Mat3 getResolutionMatrix3(AbsFace up) { + return TRANSFORMATIONS.get(up).getResolutionMatrix3(); + } + + public static Mat4 getResolutionMatrix4(AbsFace up) { + return TRANSFORMATIONS.get(up).getResolutionMatrix4(); + } + + public static Mat3 getRelativizationMatrix3(AbsFace up) { + return TRANSFORMATIONS.get(up).getRelativizationMatrix3(); + } + + public static Mat4 getRelativizationMatrix4(AbsFace up) { + return TRANSFORMATIONS.get(up).getRelativizationMatrix4(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java index 3e25e1b..e1f469e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/BlockFaceResolver.java @@ -37,7 +37,7 @@ public class BlockFaceResolver { for (AbsFace up : AbsFace.getFaces()) { for (RelFace relative : RelFace.getFaces()) { - AbsFace absolute = (AbsFace) AbsRelation.of(RelRelation.resolve(relative.getRelVector(), up, null)); + AbsFace absolute = (AbsFace) AbsRelation.of(AxisRotations.resolve(relative.getRelVector(), up, null)); RESOLUTION_TABLE[up.getId()][relative.getId()] = absolute; RELATIVIZATION_TABLE[up.getId()][absolute.getId()] = relative; diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java b/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java index 5268a26..6eec211 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/RelRelation.java @@ -17,122 +17,15 @@ */ package ru.windcorp.progressia.common.world.rels; -import java.util.Map; - -import glm.mat._3.Mat3; -import glm.mat._4.Mat4; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.util.VectorUtil.SignedAxis; - -import static ru.windcorp.progressia.common.util.VectorUtil.SignedAxis.*; /** * Name stands for Relative Relation */ public class RelRelation extends BlockRelation { - private static class Rotation { - private final SignedAxis northDestination; - private final SignedAxis westDestination; - private final SignedAxis upDestination; - - private final Mat3 resolutionMatrix3 = new Mat3(); - private final Mat4 resolutionMatrix4 = new Mat4(); - - private final Mat3 relativizationMatrix3 = new Mat3(); - private final Mat4 relativizationMatrix4 = new Mat4(); - - private Rotation(SignedAxis northDestination, SignedAxis westDestination, SignedAxis upDestination) { - this.northDestination = northDestination; - this.westDestination = westDestination; - this.upDestination = upDestination; - - resolutionMatrix3.c0(apply(null, new Vec3(1, 0, 0))); - resolutionMatrix3.c1(apply(null, new Vec3(0, 1, 0))); - resolutionMatrix3.c2(apply(null, new Vec3(0, 0, 1))); - resolutionMatrix3.toMat4(resolutionMatrix4); - - relativizationMatrix3.set(resolutionMatrix3).transpose(); - relativizationMatrix4.set(resolutionMatrix4).transpose(); - } - - /** - * @return the resolutionMatrix3 - */ - public Mat3 getResolutionMatrix3() { - return resolutionMatrix3; - } - - /** - * @return the resolutionMatrix4 - */ - public Mat4 getResolutionMatrix4() { - return resolutionMatrix4; - } - - /** - * @return the relativizationMatrix3 - */ - public Mat3 getRelativizationMatrix3() { - return relativizationMatrix3; - } - - /** - * @return the relativizationMatrix4 - */ - public Mat4 getRelativizationMatrix4() { - return relativizationMatrix4; - } - - public Vec3i apply(Vec3i output, Vec3i input) { - if (output == null) { - output = new Vec3i(); - } - - int inX = input.x, inY = input.y, inZ = input.z; - - set(output, inX, northDestination); - set(output, inY, westDestination); - set(output, inZ, upDestination); - - return output; - } - - private static void set(Vec3i output, int value, SignedAxis axis) { - VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value); - } - - public Vec3 apply(Vec3 output, Vec3 input) { - if (output == null) { - output = new Vec3(); - } - - float inX = input.x, inY = input.y, inZ = input.z; - - set(output, inX, northDestination); - set(output, inY, westDestination); - set(output, inZ, upDestination); - - return output; - } - - private static void set(Vec3 output, float value, SignedAxis axis) { - VectorUtil.set(output, axis.getAxis(), axis.isPositive() ? +value : -value); - } - } - - private final static Map TRANSFORMATIONS = AbsFace.mapToFaces( - new Rotation(POS_X, POS_Y, POS_Z), - new Rotation(POS_X, NEG_Y, NEG_Z), - new Rotation(POS_Z, NEG_Y, POS_X), - new Rotation(POS_Z, POS_Y, NEG_X), - new Rotation(POS_Z, NEG_X, NEG_Y), - new Rotation(POS_Z, POS_X, POS_Y) - ); - private final Vec3i vector = new Vec3i(); private final Vec3 floatVector = new Vec3(); private final Vec3 normalized = new Vec3(); @@ -242,38 +135,11 @@ public class RelRelation extends BlockRelation { private AbsRelation computeResolution(AbsFace up) { Vec3i resolution = Vectors.grab3i(); - resolve(vector, up, resolution); + AxisRotations.resolve(vector, up, resolution); AbsRelation result = AbsRelation.of(resolution); Vectors.release(resolution); return result; } - - public static Vec3i resolve(Vec3i relative, AbsFace up, Vec3i output) { - if (output == null) { - output = new Vec3i(); - } - - TRANSFORMATIONS.get(up).apply(output, relative); - - return output; - } - - public static Mat3 getResolutionMatrix3(AbsFace up) { - return TRANSFORMATIONS.get(up).getResolutionMatrix3(); - } - - public static Mat4 getResolutionMatrix4(AbsFace up) { - return TRANSFORMATIONS.get(up).getResolutionMatrix4(); - } - - - public static Mat3 getRelativizationMatrix3(AbsFace up) { - return TRANSFORMATIONS.get(up).getRelativizationMatrix3(); - } - - public static Mat4 getRelativizationMatrix4(AbsFace up) { - return TRANSFORMATIONS.get(up).getRelativizationMatrix4(); - } @Override protected Vec3i getSample() { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java index 05d659a..f3dc35f 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java @@ -43,9 +43,9 @@ public class TestPlanetGravityModel extends GravityModel { @Override protected void doGetGravity(Vec3 pos, Vec3 output) { // Change to a CS where (0;0;0) is the center of the center chunk - float px = pos.x - ChunkData.CHUNK_RADIUS; - float py = pos.y - ChunkData.CHUNK_RADIUS; - float pz = pos.z - ChunkData.CHUNK_RADIUS; + float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f; + float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f; + float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f; // Assume weightlessness when too close to center if ((px*px + py*py + pz*pz) < INNER_RADIUS*INNER_RADIUS) { From a9a21ce66476fc81b9fd9dee938fcb8e69adad47 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 28 Feb 2021 23:03:23 +0300 Subject: [PATCH 12/63] Moved planet generation code to its own package --- src/main/java/ru/windcorp/progressia/server/Server.java | 2 +- src/main/java/ru/windcorp/progressia/test/TestContent.java | 2 +- .../progressia/test/gen/{ => planet}/TestPlanetGenerator.java | 2 +- .../test/gen/{ => planet}/TestPlanetGravityModel.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/ru/windcorp/progressia/test/gen/{ => planet}/TestPlanetGenerator.java (99%) rename src/main/java/ru/windcorp/progressia/test/gen/{ => planet}/TestPlanetGravityModel.java (98%) diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 40fdca6..fcdee16 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -31,7 +31,7 @@ import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; -import ru.windcorp.progressia.test.gen.TestPlanetGenerator; +import ru.windcorp.progressia.test.gen.planet.TestPlanetGenerator; public class Server { diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index d34c3ba..464dc46 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -59,7 +59,7 @@ import ru.windcorp.progressia.server.world.block.*; import ru.windcorp.progressia.server.world.entity.*; import ru.windcorp.progressia.server.world.tile.*; import ru.windcorp.progressia.test.gen.TestGravityModel; -import ru.windcorp.progressia.test.gen.TestPlanetGravityModel; +import ru.windcorp.progressia.test.gen.planet.TestPlanetGravityModel; public class TestContent { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java similarity index 99% rename from src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java rename to src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index bbcdbfd..edc1811 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen; +package ru.windcorp.progressia.test.gen.planet; import java.io.DataInputStream; import java.io.DataOutputStream; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java rename to src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java index f3dc35f..309e0de 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestPlanetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen; +package ru.windcorp.progressia.test.gen.planet; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; From abd8d9eebbd52e2a40b196e98269d122ce337a57 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 28 Feb 2021 23:31:57 +0300 Subject: [PATCH 13/63] Moved some functionality into WorldGenerator - WorldGenerators now suggest a spawn location - WorldGenerators are no longer responsible for adding chunks --- .../ru/windcorp/progressia/server/PlayerManager.java | 2 +- .../windcorp/progressia/server/world/WorldLogic.java | 4 +++- .../server/world/generation/WorldGenerator.java | 3 +++ .../java/ru/windcorp/progressia/test/TestContent.java | 3 --- .../progressia/test/gen/TestWorldGenerator.java | 10 +++++++--- .../test/gen/planet/TestPlanetGenerator.java | 7 ++++++- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java index 8e34b49..60b07f1 100644 --- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -60,7 +60,7 @@ public class PlayerManager { EntityData player = EntityDataRegistry.getInstance().create("Test:Player"); player.setEntityId(TestContent.PLAYER_ENTITY_ID); - player.setPosition(TestContent.SPAWN); + player.setPosition(getServer().getWorld().getGenerator().suggestSpawnLocation()); player.setUpVector(new Vec3(0, 0, 1)); player.setLookingAt(new Vec3(2, 1, 0)); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 5931e34..bf5da5e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -106,7 +106,9 @@ public class WorldLogic } public ChunkData generate(Vec3i chunkPos) { - return getGenerator().generate(chunkPos, getData()); + ChunkData chunk = getGenerator().generate(chunkPos, getData()); + getData().addChunk(chunk); + return chunk; } public ChunkLogic getChunk(ChunkData chunkData) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index 6a85e45..f31cbc4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -22,6 +22,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; @@ -45,5 +46,7 @@ public abstract class WorldGenerator extends Namespaced { public abstract boolean isChunkReady(Object hint); public abstract GravityModel getGravityModel(); + + public abstract Vec3 suggestSpawnLocation(); } diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 464dc46..dd72aa8 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -30,7 +30,6 @@ import java.util.function.Consumer; import org.lwjgl.glfw.GLFW; -import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.audio.SoundEffect; @@ -66,8 +65,6 @@ public class TestContent { public static final String PLAYER_LOGIN = "Sasha"; public static final long PLAYER_ENTITY_ID = 0x42; public static final long STATIE_ENTITY_ID = 0xDEADBEEF; -// public static final Vec3 SPAWN = new Vec3(8, 8, 880); - public static final Vec3 SPAWN = new Vec3(0, 0, 66); public static final List PLACEABLE_BLOCKS = new ArrayList<>(); public static final List PLACEABLE_TILES = new ArrayList<>(); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 9d4ff6e..e66d9b7 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -23,6 +23,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Random; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; @@ -54,6 +55,11 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } }); } + + @Override + public Vec3 suggestSpawnLocation() { + return new Vec3(8, 8, 880); + } @Override protected Boolean doReadGenerationHint(DataInputStream input) throws IOException, DecodingException { @@ -72,9 +78,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public ChunkData generate(Vec3i chunkPos, WorldData world) { - ChunkData chunk = generateUnpopulated(chunkPos, world); - world.addChunk(chunk); - return chunk; + return generateUnpopulated(chunkPos, world); } private ChunkData generateUnpopulated(Vec3i chunkPos, WorldData world) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index edc1811..ea45d1e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -22,6 +22,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; @@ -47,6 +48,11 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { throw new IllegalArgumentException("planetRadius too small, must be at least 32 m"); } } + + @Override + public Vec3 suggestSpawnLocation() { + return new Vec3(0, 0, 66); + } @Override protected Boolean doReadGenerationHint(DataInputStream input) throws IOException, DecodingException { @@ -70,7 +76,6 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { generate(chunk); chunk.setGenerationHint(true); - world.addChunk(chunk); return chunk; } From f4311fb27c28fc81e3468c728bf1e925052058c0 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 15 Mar 2021 18:54:53 +0300 Subject: [PATCH 14/63] Created a bare-bones implementation of the final planet generator - Added Planet generator - Uses temporary generation algorithms - Added Surface generator - Added FloatRangeMap --- .../common/util/ArrayFloatRangeMap.java | 225 ++++++++++++++++++ .../progressia/common/util/FloatRangeMap.java | 36 +++ .../progressia/common/util/VectorUtil.java | 82 +++++++ .../progressia/common/world/BlockRay.java | 6 +- .../common/world/generic/GenericChunk.java | 59 +++++ .../progressia/server/ChunkManager.java | 17 +- .../ru/windcorp/progressia/server/Server.java | 3 +- .../progressia/test/gen/TerrainLayer.java | 30 +++ .../progressia/test/gen/planet/Planet.java | 82 +++++++ .../gen/planet/PlanetScatterGenerator.java | 41 ++++ .../gen/planet/PlanetTerrainGenerator.java | 107 +++++++++ .../test/gen/planet/TestHeightMap.java | 70 ++++++ .../test/gen/planet/TestPlanetGenerator.java | 142 ++--------- .../test/gen/surface/SurfaceFloatField.java | 27 +++ .../gen/surface/SurfaceScatterGenerator.java | 28 +++ .../gen/surface/SurfaceTerrainGenerator.java | 74 ++++++ 16 files changed, 896 insertions(+), 133 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/util/ArrayFloatRangeMap.java create mode 100644 src/main/java/ru/windcorp/progressia/common/util/FloatRangeMap.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java diff --git a/src/main/java/ru/windcorp/progressia/common/util/ArrayFloatRangeMap.java b/src/main/java/ru/windcorp/progressia/common/util/ArrayFloatRangeMap.java new file mode 100644 index 0000000..4eea3f6 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/ArrayFloatRangeMap.java @@ -0,0 +1,225 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Objects; + +public class ArrayFloatRangeMap implements FloatRangeMap { + + protected static class Node implements Comparable> { + public float pos; + public E value; + + public Node(float pos, E value) { + this.pos = pos; + this.value = value; + } + + @Override + public int compareTo(Node o) { + return Float.compare(pos, o.pos); + } + } + + /* + * Expects a random-access list + */ + protected final List> nodes; + protected int ranges = 0; + + protected static final int DEFAULT_CAPACITY = 16; + + public ArrayFloatRangeMap(int capacity) { + this.nodes = new ArrayList<>(2 * capacity); + } + + public ArrayFloatRangeMap() { + this(DEFAULT_CAPACITY); + } + + @Override + public int size() { + return this.ranges; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + private int nextIndex = 0; + + { + assert nodes.isEmpty() || nodes.get(nextIndex).value != null; + } + + private void findNext() { + while (nextIndex < nodes.size()) { + nextIndex++; + Node node = nodes.get(nextIndex); + if (node.value != null) return; + } + } + + @Override + public boolean hasNext() { + return nextIndex < nodes.size(); + } + + @Override + public E next() { + E result = nodes.get(nextIndex).value; + findNext(); + return result; + } + }; + } + + /** + * Returns an index of the smallest {@link Node} larger than or exactly at + * {@code position}. + * + * @param position the position to look up + * @return an index in the {@link #nodes} list containing the first + * {@link Node} whose {@link Node#pos} is not smaller than + * {@code position}, or {@code nodes.size()} if no such index exists + */ + protected int findCeiling(float position) { + + /* + * Implementation based on OpenJDK's + * Collections.indexedBinarySearch(List, Comparator) + */ + + int low = 0; + int high = nodes.size() - 1; + + while (low <= high) { + int mid = (low + high) >>> 1; + float midVal = nodes.get(mid).pos; + int cmp = Float.compare(midVal, position); + + if (cmp < 0) + low = mid + 1; + else if (cmp > 0) + high = mid - 1; + else + return mid; // key found + } + + return low; // the insertion point is the desired index + } + + /** + * Returns an index of the largest {@link Node} smaller than or exactly at + * {@code position}. + * + * @param position the position to look up + * @return an index in the {@link #nodes} list containing the last + * {@link Node} whose {@link Node#pos} is not greater than + * {@code position}, or {@code -1} if no such index exists + */ + protected int findFloor(float position) { + + /* + * Implementation based on OpenJDK's + * Collections.indexedBinarySearch(List, Comparator) + */ + + int low = 0; + int high = nodes.size() - 1; + + while (low <= high) { + int mid = (low + high) >>> 1; + float midVal = nodes.get(mid).pos; + int cmp = Float.compare(midVal, position); + + if (cmp < 0) + low = mid + 1; + else if (cmp > 0) + high = mid - 1; + else + return mid; // key found + } + + return low - 1; // the insertion point immediately follows the desired index + } + + protected Node getEffectiveNode(float at) { + int effectiveNodeIndex = findFloor(at); + if (effectiveNodeIndex < 0) return null; + return nodes.get(effectiveNodeIndex); + } + + @Override + public E get(float at) { + Node effectiveNode = getEffectiveNode(at); + return effectiveNode == null ? null : effectiveNode.value; + } + + @Override + public void put(float min, float max, E element) { + Objects.requireNonNull(element, "element"); + + if (!(max > min)) // This funky construction also deals with NaNs since NaNs always fail any comparison + { + throw new IllegalArgumentException(max + " is not greater than " + min); + } + + int indexOfInsertionOfMin = findCeiling(min); + + nodes.add(indexOfInsertionOfMin, new Node(min, element)); + ranges++; + + ListIterator> it = nodes.listIterator(indexOfInsertionOfMin + 1); + E elementEffectiveImmediatelyAfterInsertedRange = null; + + if (indexOfInsertionOfMin > 0) { + elementEffectiveImmediatelyAfterInsertedRange = nodes.get(indexOfInsertionOfMin - 1).value; + } + + while (it.hasNext()) { + Node node = it.next(); + + if (node.pos >= max) { + break; + } + + elementEffectiveImmediatelyAfterInsertedRange = node.value; + if (elementEffectiveImmediatelyAfterInsertedRange != null) { + // Removing an actual range + ranges--; + } + it.remove(); + } + + if (max != Float.POSITIVE_INFINITY) { + nodes.add(indexOfInsertionOfMin + 1, new Node(max, elementEffectiveImmediatelyAfterInsertedRange)); + + if (elementEffectiveImmediatelyAfterInsertedRange != null) { + // We might have added one right back + ranges++; + } + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/util/FloatRangeMap.java b/src/main/java/ru/windcorp/progressia/common/util/FloatRangeMap.java new file mode 100644 index 0000000..303d6a8 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/FloatRangeMap.java @@ -0,0 +1,36 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.util; + +public interface FloatRangeMap extends Iterable { + + void put(float min, float max, E element); + E get(float at); + + int size(); + + default boolean defines(float position) { + return get(position) != null; + } + + default E getOrDefault(float at, E def) { + E result = get(at); + return result == null ? def : result; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java index 6bef350..f25368f 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java @@ -290,6 +290,88 @@ public class VectorUtil { ); return output; } + + public static Vec3i sort(Vec3i input, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + int ax = input.x, ay = input.y, az = input.z; + + if (ax > ay) { + if (ax > az) { + output.x = ax; + output.y = ay > az ? ay : az; + output.z = ay > az ? az : ay; + } else { + output.x = az; + output.y = ax; + output.z = ay; + } + } else { + if (ay > az) { + output.x = ay; + output.y = ax > az ? ax : az; + output.z = ax > az ? az : ax; + } else { + output.x = az; + output.y = ay; + output.z = ax; + } + } + + return output; + } + + public static Vec3 sort(Vec3 input, Vec3 output) { + if (output == null) { + output = new Vec3(); + } + + float ax = input.x, ay = input.y, az = input.z; + + if (ax > ay) { + if (ax > az) { + output.x = ax; + output.y = ay > az ? ay : az; + output.z = ay > az ? az : ay; + } else { + output.x = az; + output.y = ax; + output.z = ay; + } + } else { + if (ay > az) { + output.x = ay; + output.y = ax > az ? ax : az; + output.z = ax > az ? az : ax; + } else { + output.x = az; + output.y = ay; + output.z = ax; + } + } + + return output; + } + + public static Vec3i sortAfterAbs(Vec3i input, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + input.abs(output); + return sort(output, output); + } + + public static Vec3 sortAfterAbs(Vec3 input, Vec3 output) { + if (output == null) { + output = new Vec3(); + } + + input.abs(output); + return sort(output, output); + } public static float get(Vec2 v, Axis a) { switch (a) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java index 9f35d4c..d7dffc1 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java +++ b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java @@ -90,11 +90,7 @@ public class BlockRay { VectorUtil.set(block, axis, VectorUtil.get(block, axis) + (int) signum(VectorUtil.get(direction, axis))); // position += direction * tMin - VectorUtil.linearCombination(position, 1, direction, tMin, position); // position - // += - // direction - // * - // tMin + VectorUtil.linearCombination(position, 1, direction, tMin, position); distance += tMin; // position.(axis) = round(position.(axis)) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 95c18be..fa80269 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -20,6 +20,7 @@ package ru.windcorp.progressia.common.world.generic; import java.util.function.Consumer; +import glm.Glm; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; @@ -118,6 +119,64 @@ public interface GenericChunk, B exten default int getMaxZ() { return Coordinates.getInWorld(getZ(), BLOCKS_PER_CHUNK - 1); } + + default Vec3i getMinBIW(Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + output.set(getMinX(), getMinY(), getMinZ()); + + return output; + } + + default Vec3i getMaxBIW(Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + output.set(getMaxX(), getMaxY(), getMaxZ()); + + return output; + } + + default Vec3i getMinBIWRel(Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + Vec3i absMin = getMinBIW(Vectors.grab3i()); + Vec3i absMax = getMaxBIW(Vectors.grab3i()); + + AxisRotations.relativize(absMin, getUp(), absMin); + AxisRotations.relativize(absMax, getUp(), absMax); + + Glm.min(absMin, absMax, output); + + Vectors.release(absMax); + Vectors.release(absMin); + + return output; + } + + default Vec3i getMaxBIWRel(Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + Vec3i absMin = getMinBIW(Vectors.grab3i()); + Vec3i absMax = getMaxBIW(Vectors.grab3i()); + + AxisRotations.relativize(absMin, getUp(), absMin); + AxisRotations.relativize(absMax, getUp(), absMax); + + Glm.max(absMin, absMax, output); + + Vectors.release(absMax); + Vectors.release(absMin); + + return output; + } default boolean containsBiC(Vec3i blockInChunk) { return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK && diff --git a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java index b0b0777..ede6d70 100644 --- a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java @@ -128,7 +128,7 @@ public class ChunkManager { private void processQueues() { toUnload.forEach(this::unloadChunk); toUnload.clear(); - toLoad.forEach(this::loadChunk); + toLoad.forEach(this::loadOrGenerateChunk); toLoad.clear(); visions.forEach((p, v) -> { @@ -140,15 +140,26 @@ public class ChunkManager { return createIfMissing ? visions.computeIfAbsent(player, k -> new PlayerVision()) : visions.get(player); } - public void loadChunk(Vec3i chunkPos) { + public void loadOrGenerateChunk(Vec3i chunkPos) { + + boolean chunkLoadedFromDisk = loadChunk(chunkPos); + + if (!chunkLoadedFromDisk) { + getServer().getWorld().generate(chunkPos); + } + + } + + public boolean loadChunk(Vec3i chunkPos) { WorldData world = getServer().getWorld().getData(); ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); if (chunk != null) { world.addChunk(chunk); + return true; } else { - getServer().getWorld().generate(chunkPos); + return false; } } diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index fcdee16..ceafa47 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -31,6 +31,7 @@ import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; +import ru.windcorp.progressia.test.gen.planet.Planet; import ru.windcorp.progressia.test.gen.planet.TestPlanetGenerator; public class Server { @@ -60,7 +61,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); public Server(WorldData world) { - this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", Units.get("48 m"), w)); + this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 16f, 9.8f, 16f), w)); this.serverThread = new ServerThread(this); this.clientManager = new ClientManager(this); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java new file mode 100644 index 0000000..74e3335 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java @@ -0,0 +1,30 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import java.util.Random; + +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockData; + +@FunctionalInterface +public interface TerrainLayer { + + BlockData get(float north, float west, float depth, Random random, ChunkData chunk); + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java new file mode 100644 index 0000000..795c85f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java @@ -0,0 +1,82 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.planet; + +import ru.windcorp.progressia.common.world.ChunkData; + +public class Planet { + + private final int radiusInChunks; + + private final float curvature; + private final float surfaceGravitationalAcceleration; + private final float innerGravityRadius; + + public Planet( + int radiusInChunks, + float curvature, + float surfaceGravitationalAcceleration, + float innerGravityRadius + ) { + this.radiusInChunks = radiusInChunks; + this.curvature = curvature; + this.surfaceGravitationalAcceleration = surfaceGravitationalAcceleration; + this.innerGravityRadius = innerGravityRadius; + } + + /** + * @return the radiusInChunks + */ + public int getRadiusInChunks() { + return radiusInChunks; + } + + public float getRadius() { + return radiusInChunks * ChunkData.BLOCKS_PER_CHUNK + ChunkData.CHUNK_RADIUS; + } + + public int getDiameterInChunks() { + return radiusInChunks * 2 + 1; + } + + public float getDiameter() { + return getDiameterInChunks() * ChunkData.BLOCKS_PER_CHUNK; + } + + /** + * @return the curvature + */ + public float getCurvature() { + return curvature; + } + + /** + * @return the innerGravityRadius + */ + public float getInnerGravityRadius() { + return innerGravityRadius; + } + + /** + * @return the surfaceGravitationalAcceleration + */ + public float getSurfaceGravitationalAcceleration() { + return surfaceGravitationalAcceleration; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java new file mode 100644 index 0000000..da0f8d3 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java @@ -0,0 +1,41 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.planet; + +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.test.gen.surface.SurfaceScatterGenerator; + +public class PlanetScatterGenerator { + + private final TestPlanetGenerator parent; + private final SurfaceScatterGenerator surfaceGenerator; + + public PlanetScatterGenerator(TestPlanetGenerator generator) { + this.parent = generator; + this.surfaceGenerator = new SurfaceScatterGenerator(); + } + + public TestPlanetGenerator getGenerator() { + return parent; + } + + public void generateScatter(ChunkData chunk) { + surfaceGenerator.generateScatter(chunk); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java new file mode 100644 index 0000000..d59984a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -0,0 +1,107 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.planet; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; +import ru.windcorp.progressia.common.util.FloatRangeMap; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.test.gen.TerrainLayer; +import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField; +import ru.windcorp.progressia.test.gen.surface.SurfaceTerrainGenerator; + +class PlanetTerrainGenerator { + + private final TestPlanetGenerator parent; + private final SurfaceTerrainGenerator surfaceGenerator; + + public PlanetTerrainGenerator(TestPlanetGenerator generator) { + this.parent = generator; + + SurfaceFloatField heightMap = new TestHeightMap( + generator.getPlanet().getRadius() - ChunkData.BLOCKS_PER_CHUNK, + generator.getPlanet().getRadius() / 4, + 5, + 6 + ); + + FloatRangeMap layers = new ArrayFloatRangeMap<>(); + BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); + BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); + layers.put(Float.NEGATIVE_INFINITY, 0, (n, w, d, r, c) -> air); + layers.put(0, Float.POSITIVE_INFINITY, (n, w, d, r, c) -> granite); + + this.surfaceGenerator = new SurfaceTerrainGenerator((f, n, w) -> heightMap.get(f, n, w) + generator.getPlanet().getRadius(), layers); + } + + public TestPlanetGenerator getGenerator() { + return parent; + } + + public ChunkData generateTerrain(Vec3i chunkPos, WorldData world) { + ChunkData chunk = new ChunkData(chunkPos, world); + + if (isOrdinaryChunk(chunkPos)) { + generateOrdinaryTerrain(chunk); + } else { + generateBorderTerrain(chunk); + } + + return chunk; + } + + private boolean isOrdinaryChunk(Vec3i chunkPos) { + Vec3i sorted = VectorUtil.sortAfterAbs(chunkPos, null); + return sorted.x != sorted.y; + } + + private void generateOrdinaryTerrain(ChunkData chunk) { + surfaceGenerator.generateTerrain(chunk); + } + + private void generateBorderTerrain(ChunkData chunk) { + BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); + BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); + + float radius = parent.getPlanet().getRadius(); + + Vec3 biw = new Vec3(); + + chunk.forEachBiC(bic -> { + + biw.set( + Coordinates.getInWorld(chunk.getX(), bic.x), + Coordinates.getInWorld(chunk.getY(), bic.y), + Coordinates.getInWorld(chunk.getZ(), bic.z) + ); + + biw.sub(ChunkData.CHUNK_RADIUS - 0.5f); + VectorUtil.sortAfterAbs(biw, biw); + + chunk.setBlock(bic, biw.x <= radius ? stone : air, false); + + }); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java new file mode 100644 index 0000000..2141c63 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java @@ -0,0 +1,70 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.planet; + +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField; + +public class TestHeightMap implements SurfaceFloatField { + + private final float cutoffPoint; + private final float cutoffDistance; + private final float amplitude; + private final float characteristicSize; + + public TestHeightMap( + float cutoffPoint, + float cutoffDistance, + float amplitude, + float characteristicSize + ) { + this.cutoffPoint = cutoffPoint; + this.cutoffDistance = cutoffDistance; + this.amplitude = amplitude; + this.characteristicSize = characteristicSize; + } + + @Override + public float get(AbsFace face, float north, float west) { + double cutoffCoefficient = 1; + cutoffCoefficient *= cutoffFunction(cutoffPoint - north); + cutoffCoefficient *= cutoffFunction(cutoffPoint + north); + cutoffCoefficient *= cutoffFunction(cutoffPoint - west); + cutoffCoefficient *= cutoffFunction(cutoffPoint + west); + + if (cutoffCoefficient == 0) { + return 0; + } + + double base = Math.sin(north / characteristicSize) * Math.sin(west / characteristicSize); + base *= amplitude; + + return (float) (base * cutoffCoefficient); + } + + private double cutoffFunction(float distanceToCutoffPoint) { + if (distanceToCutoffPoint < 0) { + return 0; + } else if (distanceToCutoffPoint < cutoffDistance) { + return (1 - Math.cos(Math.PI * distanceToCutoffPoint / cutoffDistance)) / 2; + } else { + return 1; + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index ea45d1e..b21d985 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -20,38 +20,39 @@ package ru.windcorp.progressia.test.gen.planet; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.util.Arrays; - import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; public class TestPlanetGenerator extends AbstractWorldGenerator { - private final int surfaceLevel; + private final Planet planet; + + private final PlanetTerrainGenerator terrainGenerator; + private final PlanetScatterGenerator scatterGenerator; - public TestPlanetGenerator(String id, float planetRadius, WorldLogic world) { + public TestPlanetGenerator(String id, Planet planet, WorldLogic world) { super(id, Boolean.class, "Test:PlanetGravityModel"); + this.planet = planet; - this.surfaceLevel = (int) (planetRadius / ChunkData.BLOCKS_PER_CHUNK); - if (surfaceLevel < 2) { - throw new IllegalArgumentException("planetRadius too small, must be at least 32 m"); - } + this.terrainGenerator = new PlanetTerrainGenerator(this); + this.scatterGenerator = new PlanetScatterGenerator(this); + } + + /** + * @return the planet + */ + public Planet getPlanet() { + return planet; } @Override public Vec3 suggestSpawnLocation() { - return new Vec3(0, 0, 66); + return new Vec3(7f, 7f, getPlanet().getRadius() + 10); } @Override @@ -71,116 +72,9 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { @Override public ChunkData generate(Vec3i chunkPos, WorldData world) { - ChunkData chunk = new ChunkData(chunkPos, world); - - generate(chunk); - chunk.setGenerationHint(true); - + ChunkData chunk = terrainGenerator.generateTerrain(chunkPos, world); + scatterGenerator.generateScatter(chunk); return chunk; } - - private enum ChunkType { - SURFACE, UNDERGROUND, EDGE_SURFACE, EDGE_UNDERGROUND, CORE, AIR; - } - - private void generate(ChunkData chunk) { - switch (getChunkType(chunk.getPosition())) { - case SURFACE: - fillSurface(chunk); - break; - case UNDERGROUND: - fillUndeground(chunk); - break; - case EDGE_SURFACE: - fillEdgeSurface(chunk); - break; - case EDGE_UNDERGROUND: - fillEdgeUnderground(chunk); - break; - case CORE: - fillCore(chunk); - break; - case AIR: - fillAir(chunk); - break; - } - } - - private void fillSurface(ChunkData chunk) { - final int bpc = ChunkData.BLOCKS_PER_CHUNK; - - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); - BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); - - TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); - - chunk.forEachBiC(bic -> { - - BlockData block; - - if (bic.z > bpc - 4) { - block = dirt; - } else { - block = granite; - } - - chunk.setBlockRel(bic, block, false); - - }); - - VectorUtil.iterateCuboid(0, 0, bpc - 1, bpc, bpc, bpc, bic -> { - chunk.getTilesRel(bic, RelFace.UP).add(grass); - }); - } - - private void fillUndeground(ChunkData chunk) { - fill(chunk, BlockDataRegistry.getInstance().get("Test:GraniteMonolith")); - } - - private void fillEdgeSurface(ChunkData chunk) { - fill(chunk, BlockDataRegistry.getInstance().get("Test:Stone")); - } - - private void fillEdgeUnderground(ChunkData chunk) { - fill(chunk, BlockDataRegistry.getInstance().get("Test:Stone")); - } - - private void fillCore(ChunkData chunk) { - fill(chunk, BlockDataRegistry.getInstance().get("Test:Stone")); - } - - private void fillAir(ChunkData chunk) { - fill(chunk, BlockDataRegistry.getInstance().get("Test:Air")); - } - - private void fill(ChunkData chunk, BlockData block) { - chunk.forEachBiC(bic -> chunk.setBlock(bic, block, false)); - } - - private ChunkType getChunkType(Vec3i pos) { - int[] abs = pos.abs_().toIA_(); - Arrays.sort(abs); - - int medium = abs[1]; - int largest = abs[2]; - - int level = largest; - - if (level == 0) { - return ChunkType.CORE; - } - - if (largest > surfaceLevel) { - return ChunkType.AIR; - } - - boolean isSurface = largest == surfaceLevel; - - if (medium == largest) { - return isSurface ? ChunkType.EDGE_SURFACE : ChunkType.EDGE_UNDERGROUND; - } else { - return isSurface ? ChunkType.SURFACE : ChunkType.UNDERGROUND; - } - } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java new file mode 100644 index 0000000..4b368d4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java @@ -0,0 +1,27 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import ru.windcorp.progressia.common.world.rels.AbsFace; + +@FunctionalInterface +public interface SurfaceFloatField { + + float get(AbsFace face, float north, float west); + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java new file mode 100644 index 0000000..a9f08d9 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java @@ -0,0 +1,28 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import ru.windcorp.progressia.common.world.ChunkData; + +public class SurfaceScatterGenerator { + + public void generateScatter(ChunkData chunk) { + chunk.setGenerationHint(true); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java new file mode 100644 index 0000000..b05df5a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java @@ -0,0 +1,74 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import java.util.Random; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.CoordinatePacker; +import ru.windcorp.progressia.common.util.FloatRangeMap; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.rels.AxisRotations; +import ru.windcorp.progressia.test.gen.TerrainLayer; + +public class SurfaceTerrainGenerator { + + private final SurfaceFloatField heightMap; + private final FloatRangeMap layers; + + public SurfaceTerrainGenerator(SurfaceFloatField heightMap, FloatRangeMap layers) { + this.heightMap = heightMap; + this.layers = layers; + } + + public void generateTerrain(ChunkData chunk) { + + Vec3i relBIC = new Vec3i(); + + Vec3 offset = new Vec3(chunk.getMinX(), chunk.getMinY(), chunk.getMinZ()); + AxisRotations.relativize(offset, chunk.getUp(), offset); + offset.sub(ChunkData.CHUNK_RADIUS - 0.5f); + + Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); + + for (relBIC.x = 0; relBIC.x < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.x) { + for (relBIC.y = 0; relBIC.y < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.y) { + generateColumn(chunk, relBIC, offset, random); + } + } + + } + + public void generateColumn(ChunkData chunk, Vec3i relBIC, Vec3 offset, Random random) { + + float north = relBIC.x + offset.x; + float west = relBIC.y + offset.y; + + float relSurface = heightMap.get(chunk.getUp(), north, west) - offset.z; + + for (relBIC.z = 0; relBIC.z < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { + float depth = relSurface - relBIC.z; + BlockData block = layers.get(depth).get(north, west, depth, random, chunk); + chunk.setBlockRel(relBIC, block, false); + } + + } + +} From f28c765e3ff95582fe3aabb875c265356af2be4f Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 15 Mar 2021 21:02:33 +0300 Subject: [PATCH 15/63] Made Gravity Models configurable with packets --- .../progressia/common/world/GravityModel.java | 61 ++++++++++++ .../common/world/GravityModelRegistry.java | 4 +- .../common/world/PacketSetGravityModel.java | 22 ++++- .../ru/windcorp/progressia/server/Server.java | 2 +- .../generation/AbstractWorldGenerator.java | 2 +- .../windcorp/progressia/test/TestContent.java | 4 +- .../progressia/test/gen/TestGravityModel.java | 19 +++- .../progressia/test/gen/planet/Planet.java | 27 ++++-- .../test/gen/planet/TestPlanetGenerator.java | 4 + .../gen/planet/TestPlanetGravityModel.java | 96 +++++++++++++++---- .../gen/surface/SurfaceCachingFloatField.java | 77 +++++++++++++++ .../gen/surface/SurfaceFieldRegistry.java | 29 ++++++ .../test/gen/surface/SurfaceNodeStorage.java | 57 +++++++++++ 13 files changed, 368 insertions(+), 36 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java index 14f61e9..917d45f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModel.java @@ -17,6 +17,9 @@ */ package ru.windcorp.progressia.common.world; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; import java.util.Objects; import glm.vec._3.Vec3; @@ -165,5 +168,63 @@ public abstract class GravityModel extends Namespaced { * specified chunk. Never {@code null}. */ protected abstract AbsFace doGetDiscreteUp(Vec3i chunkPos); + + /** + * Parses the settings from the provided {@link DataInput} and configures this object appropriately. This method will not necessarily exhaust the input. + * @param input a stream to read the settings from + * @throws IOException if an I/O error occurs + * @throws DecodingException if the settings could not be parsed from input + */ + public void readSettings(DataInput input) throws IOException, DecodingException { + Objects.requireNonNull(input, "input"); + + try { + doReadSettings(input); + } catch (IOException | DecodingException e) { + throw e; + } catch (Exception e) { + throw CrashReports.report( + e, + "%s failed to read its settings", + this + ); + } + } + + /** + * Encodes the settings of this model into the provided {@link DataOutput}. + * @param output a stream to write the settings into + * @throws IOException if an I/O error occurs + */ + public void writeSettings(DataOutput output) throws IOException { + Objects.requireNonNull(output, "output"); + + try { + doWriteSettings(output); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw CrashReports.report( + e, + "%s failed to write its settings", + this + ); + } + } + + /** + * Parses the settings from the provided {@link DataInput} and configures this object appropriately. This method will not necessarily exhaust the input. + * @param input a stream to read the settings from + * @throws IOException if an I/O error occurs + * @throws DecodingException if the settings could not be parsed from input + */ + protected abstract void doReadSettings(DataInput input) throws IOException, DecodingException; + + /** + * Encodes the settings of this model into the provided {@link DataOutput}. + * @param output a stream to write the settings into + * @throws IOException if an I/O error occurs + */ + protected abstract void doWriteSettings(DataOutput output) throws IOException; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java b/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java index b48cd0c..776e04f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/world/GravityModelRegistry.java @@ -17,9 +17,9 @@ */ package ru.windcorp.progressia.common.world; -import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; +import ru.windcorp.progressia.common.util.namespaces.NamespacedFactoryRegistry; -public class GravityModelRegistry extends NamespacedInstanceRegistry { +public class GravityModelRegistry extends NamespacedFactoryRegistry { public static final GravityModelRegistry INSTANCE = new GravityModelRegistry(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java index 7e7f95e..2fd30a6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java @@ -21,9 +21,13 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import ru.windcorp.progressia.common.util.DataBuffer; +import ru.windcorp.progressia.common.util.crash.CrashReports; + public class PacketSetGravityModel extends PacketAffectWorld { private String gravityModelId; + private final DataBuffer settings = new DataBuffer(); public PacketSetGravityModel() { this("Core:SetGravityModel"); @@ -35,22 +39,38 @@ public class PacketSetGravityModel extends PacketAffectWorld { public void set(GravityModel model) { this.gravityModelId = model.getId(); + + try { + model.writeSettings(settings.getWriter()); + } catch (IOException e) { + throw CrashReports.report(e, "%s has errored when writing its settings", model); + } } @Override public void read(DataInput input) throws IOException, DecodingException { gravityModelId = input.readUTF(); + settings.fill(input, input.readInt()); } @Override public void write(DataOutput output) throws IOException { output.writeUTF(gravityModelId); + output.writeInt(settings.getSize()); + settings.flush(output); } @Override public void apply(WorldData world) { - GravityModel model = GravityModelRegistry.getInstance().get(gravityModelId); + GravityModel model = GravityModelRegistry.getInstance().create(gravityModelId); world.setGravityModel(model); + try { + model.readSettings(settings.getReader()); + } catch (IOException e) { + throw CrashReports.report(e, "%s has errored when reading its settings", model); + } catch (DecodingException e) { + throw CrashReports.report(e, "%s has failed to parse its settings", model); + } } } diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index ceafa47..8ca9383 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -61,7 +61,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); public Server(WorldData world) { - this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 16f, 9.8f, 16f), w)); + this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 9.8f, 16f, 16f), w)); this.serverThread = new ServerThread(this); this.clientManager = new ClientManager(this); diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index 74583ff..6856887 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -37,7 +37,7 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { public AbstractWorldGenerator(String id, Class hintClass, String gravityModelId) { super(id); this.hintClass = Objects.requireNonNull(hintClass, "hintClass"); - this.gravityModel = GravityModelRegistry.getInstance().get(Objects.requireNonNull(gravityModelId, "gravityModelId")); + this.gravityModel = GravityModelRegistry.getInstance().create(Objects.requireNonNull(gravityModelId, "gravityModelId")); if (this.gravityModel == null) { throw new IllegalArgumentException("Gravity model with ID \"" + gravityModelId + "\" not found"); diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index dd72aa8..e65ae68 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -422,8 +422,8 @@ public class TestContent { private static void registerMisc() { ChunkIO.registerCodec(new TestChunkCodec()); ChunkRenderOptimizerRegistry.getInstance().register("Core:SurfaceOptimizer", ChunkRenderOptimizerSurface::new); - GravityModelRegistry.getInstance().register(new TestGravityModel()); - GravityModelRegistry.getInstance().register(new TestPlanetGravityModel()); + GravityModelRegistry.getInstance().register("Test:TheGravityModel", TestGravityModel::new); + GravityModelRegistry.getInstance().register("Test:PlanetGravityModel", TestPlanetGravityModel::new); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java index 02bb12e..a2a8a8d 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGravityModel.java @@ -17,15 +17,20 @@ */ package ru.windcorp.progressia.test.gen; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.rels.AbsFace; public class TestGravityModel extends GravityModel { - public TestGravityModel() { - super("Test:TheGravityModel"); + public TestGravityModel(String id) { + super(id); } @Override @@ -39,4 +44,14 @@ public class TestGravityModel extends GravityModel { return rounded == null ? AbsFace.POS_Z : rounded; } + @Override + protected void doReadSettings(DataInput input) throws IOException, DecodingException { + // Do nothing + } + + @Override + protected void doWriteSettings(DataOutput output) throws IOException { + // Do nothing + } + } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java index 795c85f..38b9d94 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java @@ -23,20 +23,20 @@ public class Planet { private final int radiusInChunks; - private final float curvature; - private final float surfaceGravitationalAcceleration; - private final float innerGravityRadius; + private final TestPlanetGravityModel.Settings gravityModelSettings; public Planet( int radiusInChunks, - float curvature, float surfaceGravitationalAcceleration, + float curvature, float innerGravityRadius ) { this.radiusInChunks = radiusInChunks; - this.curvature = curvature; - this.surfaceGravitationalAcceleration = surfaceGravitationalAcceleration; - this.innerGravityRadius = innerGravityRadius; + this.gravityModelSettings = new TestPlanetGravityModel.Settings( + surfaceGravitationalAcceleration, + curvature, + innerGravityRadius + ); } /** @@ -62,21 +62,28 @@ public class Planet { * @return the curvature */ public float getCurvature() { - return curvature; + return gravityModelSettings.curvature; } /** * @return the innerGravityRadius */ public float getInnerGravityRadius() { - return innerGravityRadius; + return gravityModelSettings.innerRadius; } /** * @return the surfaceGravitationalAcceleration */ public float getSurfaceGravitationalAcceleration() { - return surfaceGravitationalAcceleration; + return gravityModelSettings.surfaceGravitationalAcceleration; + } + + /** + * @return the gravityModelSettings + */ + public TestPlanetGravityModel.Settings getGravityModelSettings() { + return gravityModelSettings; } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index b21d985..3012715 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -37,8 +37,12 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { public TestPlanetGenerator(String id, Planet planet, WorldLogic world) { super(id, Boolean.class, "Test:PlanetGravityModel"); + this.planet = planet; + TestPlanetGravityModel model = (TestPlanetGravityModel) this.getGravityModel(); + model.configure(planet.getGravityModelSettings()); + this.terrainGenerator = new PlanetTerrainGenerator(this); this.scatterGenerator = new PlanetScatterGenerator(this); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java index 309e0de..cb5fc34 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java @@ -19,36 +19,86 @@ package ru.windcorp.progressia.test.gen.planet; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.rels.AbsFace; import static java.lang.Math.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + public class TestPlanetGravityModel extends GravityModel { - private static final float GRAVITATIONAL_ACCELERATION = Units.get("9.8 m/s^2"); - private static final float ROUNDNESS = Units.get("16 m"); - private static final float INNER_RADIUS = Units.get("16 m"); + public static class Settings { + public float surfaceGravitationalAcceleration; + public float curvature; + public float innerRadius; + + public Settings() {} + + public Settings(float surfaceGravitationalAcceleration, float curvature, float innerRadius) { + this.surfaceGravitationalAcceleration = surfaceGravitationalAcceleration; + this.curvature = curvature; + this.innerRadius = innerRadius; + } + + public void copyFrom(Settings copyFrom) { + this.surfaceGravitationalAcceleration = copyFrom.surfaceGravitationalAcceleration; + this.curvature = copyFrom.curvature; + this.innerRadius = copyFrom.innerRadius; + } + + public void read(DataInput input) throws IOException, DecodingException { + surfaceGravitationalAcceleration = input.readFloat(); + curvature = input.readFloat(); + innerRadius = input.readFloat(); + } + + public void write(DataOutput output) throws IOException { + output.writeFloat(surfaceGravitationalAcceleration); + output.writeFloat(curvature); + output.writeFloat(innerRadius); + } + } - public TestPlanetGravityModel() { - this("Test:PlanetGravityModel"); + private Settings settings = new Settings(); + + public TestPlanetGravityModel(String id) { + super(id); } - protected TestPlanetGravityModel(String id) { - super(id); + public float getSurfaceGravitationalAcceleration() { + return settings.surfaceGravitationalAcceleration; + } + + public float getCurvature() { + return settings.curvature; + } + + public float getInnerRadius() { + return settings.innerRadius; + } + + public void configure(Settings settings) { + this.settings = settings; } @Override protected void doGetGravity(Vec3 pos, Vec3 output) { + float r = getInnerRadius(); + float c = getCurvature(); + float g = getSurfaceGravitationalAcceleration(); + // Change to a CS where (0;0;0) is the center of the center chunk float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f; float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f; float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f; // Assume weightlessness when too close to center - if ((px*px + py*py + pz*pz) < INNER_RADIUS*INNER_RADIUS) { + if ((px*px + py*py + pz*pz) < r*r) { output.set(0, 0, 0); return; } @@ -81,24 +131,26 @@ public class TestPlanetGravityModel extends GravityModel { } } - output.x = maxAbs - ax < ROUNDNESS ? (px > 0 ? +1 : -1) : 0; - output.y = maxAbs - ay < ROUNDNESS ? (py > 0 ? +1 : -1) : 0; - output.z = maxAbs - az < ROUNDNESS ? (pz > 0 ? +1 : -1) : 0; + output.x = maxAbs - ax < c ? (px > 0 ? +1 : -1) : 0; + output.y = maxAbs - ay < c ? (py > 0 ? +1 : -1) : 0; + output.z = maxAbs - az < c ? (pz > 0 ? +1 : -1) : 0; - if (maxAbs - midAbs < ROUNDNESS) { + if (maxAbs - midAbs < c) { output.normalize(); computeEdgeGravity(output.x, output.y, output.z, px, py, pz, output); } else { - assert output.dot(output) == 1 : "maxAbs - midAbs = " + maxAbs + " - " + midAbs + " > " + ROUNDNESS + " yet l*l != 1"; + assert output.dot(output) == 1 : "maxAbs - midAbs = " + maxAbs + " - " + midAbs + " > " + c + " yet l*l != 1"; } - output.mul(-GRAVITATIONAL_ACCELERATION); + output.mul(-g); } private void computeEdgeGravity(float lx, float ly, float lz, float rx, float ry, float rz, Vec3 output) { // da math is gud, no worry // - Javapony + float r = getInnerRadius(); + if (lx == 0) rx = 0; if (ly == 0) ry = 0; if (lz == 0) rz = 0; @@ -107,10 +159,10 @@ public class TestPlanetGravityModel extends GravityModel { float rSquared = rx*rx + ry*ry + rz*rz; float distanceAlongEdge = scalarProduct - (float) sqrt( - scalarProduct*scalarProduct - rSquared + ROUNDNESS*ROUNDNESS + scalarProduct*scalarProduct - rSquared + r*r ); - output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(ROUNDNESS); + output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(r); final float f = (float) sqrt(3.0/2); @@ -128,5 +180,15 @@ public class TestPlanetGravityModel extends GravityModel { AbsFace rounded = AbsFace.roundToFace(chunkPos.x, chunkPos.y, chunkPos.z); return rounded == null ? AbsFace.POS_Z : rounded; } + + @Override + protected void doReadSettings(DataInput input) throws IOException, DecodingException { + this.settings.read(input); + } + + @Override + protected void doWriteSettings(DataOutput output) throws IOException { + this.settings.write(output); + } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java new file mode 100644 index 0000000..01a98f0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java @@ -0,0 +1,77 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import ru.windcorp.progressia.common.util.namespaces.Namespaced; +import ru.windcorp.progressia.common.world.rels.AbsFace; + +/** + * A scalar field defined on a plane. For each pair of {@code float}s (north; west) a single {@code float} is defined by this object. + */ +public abstract class SurfaceCachingFloatField extends Namespaced implements SurfaceFloatField { + + private final int levels; + + private SurfaceFieldRegistry registry = null; + private int index; + + public SurfaceCachingFloatField(String id, int levels) { + super(id); + this.levels = levels; + } + + int getIndex() { + if (getRegistry() == null) { + throw new IllegalStateException("No registry assigned to field " + this); + } + return index; + } + + void setIndex(int index) { + if (getRegistry() == null) { + throw new IllegalStateException("No registry assigned to field " + this); + } + this.index = index; + } + + SurfaceFieldRegistry getRegistry() { + return registry; + } + + void setRegistry(SurfaceFieldRegistry registry) { + this.registry = registry; + } + + public int getLevels() { + return levels; + } + + protected abstract float computeDetailAt(AbsFace surface, int level, float north, float west); + + @Override + public float get(AbsFace surface, float north, float west) { + float result = 0; + + for (int level = 0; level < getLevels(); ++level) { + result += computeDetailAt(surface, level, north, west); + } + + return result; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java new file mode 100644 index 0000000..f1decd4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java @@ -0,0 +1,29 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +public class SurfaceFieldRegistry { + + private int nextIndex = 0; + + public void register(SurfaceCachingFloatField field) { + field.setIndex(nextIndex); + nextIndex++; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java new file mode 100644 index 0000000..ad1ec39 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java @@ -0,0 +1,57 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import gnu.trove.map.TLongObjectMap; +import gnu.trove.map.hash.TLongObjectHashMap; +import ru.windcorp.progressia.common.util.CoordinatePacker; +import ru.windcorp.progressia.common.world.DecodingException; + +public class SurfaceNodeStorage { + + public static class Node { +// private float[] floats; + } + + private final TLongObjectMap map = new TLongObjectHashMap<>(); + + public Node getNode(int north, int west) { + return map.get(CoordinatePacker.pack2IntsIntoLong(north, west)); + } + + public boolean hasNode(int north, int west) { + return map.containsKey(CoordinatePacker.pack2IntsIntoLong(north, west)); + } + + public void put(int north, int west, Node node) { + map.put(CoordinatePacker.pack2IntsIntoLong(north, west), node); + } + + public void read(DataInput input) throws IOException, DecodingException { + System.err.println("PlaneNodeMap.read did nothing because nobody implemented it yet"); + } + + public void write(DataOutput output) throws IOException { + System.err.println("PlaneNodeMap.write did nothing because nobody implemented it yet"); + } + +} From ef572c43c7948988214df0363c1e6084265dd6fe Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 25 Mar 2021 17:15:03 +0300 Subject: [PATCH 16/63] Updated documentation for GuavaEventBusHijacker and ReportingEventBus --- .../common/hacks/GuavaEventBusHijacker.java | 19 +++++++++---------- .../common/util/crash/ReportingEventBus.java | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java b/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java index 6bc7901..8ee2c60 100644 --- a/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java +++ b/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.hacks; import java.lang.reflect.Constructor; @@ -29,15 +29,14 @@ import com.google.common.util.concurrent.MoreExecutors; import ru.windcorp.progressia.common.util.crash.CrashReports; /** - * This class had to be written because there is not legal way to instantiate a - * non-async - * {@link EventBus} with both a custom identifier and a custom exception - * handler. Which - * is a shame. Guava maintainers know about the issue but have rejected - * solutions multiple - * times without a clearly stated reason; looks like some dirty - * reflection will - * have to do. + * This class had to be written because there is no legal way to instantiate a + * non-async {@link EventBus} with both a custom identifier and a custom + * exception handler. Which is a shame. Guava maintainers know about the issue + * but have rejected solutions multiple times without a clearly stated + * reason; looks like some dirty reflection will have to do. + *

    + * When explicitly referencing this class, please mention its usage in + * implementation notes because it is unreliable long-term. * * @author javapony */ diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java b/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java index 141efa9..a95365e 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java @@ -15,18 +15,34 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash; import com.google.common.eventbus.EventBus; import ru.windcorp.progressia.common.hacks.GuavaEventBusHijacker; +/** + * A utility for creating Guava's {@link EventBus}es that + * {@linkplain CrashReports report} exceptions instead of suppressing them. + * + * @author javapony + */ public class ReportingEventBus { private ReportingEventBus() { } + /** + * Instantiates a new {@link EventBus} with the provided identifier that + * reports any unhandled exceptions with {@link CrashReports}. + * + * @param identifier the identifier of the new bus + * @return the created event bus + * @implNote This implementation relies on {@link GuavaEventBusHijacker} for + * creating buses with custom identifiers and uncaught exception + * handlers. It may break suddenly with a Guava update. + */ public static EventBus create(String identifier) { return GuavaEventBusHijacker.newEventBus( identifier, From 4332a782214e05ed64f662c717e6da1ab5c9e661 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 26 Mar 2021 20:26:12 +0300 Subject: [PATCH 17/63] Refactored ChunkManager and EntityManager, added server event bus --- .../common/world/generic/ChunkMaps.java | 261 ++++++++++++++++++ .../progressia/server/ChunkManager.java | 245 ---------------- .../progressia/server/EntityManager.java | 197 ------------- .../progressia/server/PlayerManager.java | 7 + .../ru/windcorp/progressia/server/Server.java | 89 +++--- .../server/comms/ClientManager.java | 2 +- .../progressia/server/comms/ClientPlayer.java | 4 +- .../progressia/server/events/ClientEvent.java | 46 +++ .../progressia/server/events/PlayerEvent.java | 49 ++++ .../server/events/PlayerJoinedEvent.java | 33 +++ .../server/events/PlayerLeftEvent.java | 33 +++ .../progressia/server/events/ServerEvent.java | 68 +++++ .../server/management/load/ChunkManager.java | 192 +++++++++++++ .../management/load/ChunkRequestDaemon.java | 206 ++++++++++++++ .../server/management/load/EntityManager.java | 97 +++++++ .../management/load/EntityRequestDaemon.java | 121 ++++++++ .../server/management/load/LoadManager.java | 65 +++++ .../server/management/load/PlayerVision.java | 85 ++++++ .../server/management/load/VisionManager.java | 108 ++++++++ 19 files changed, 1429 insertions(+), 479 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/ChunkManager.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/EntityManager.java create mode 100644 src/main/java/ru/windcorp/progressia/server/events/ClientEvent.java create mode 100644 src/main/java/ru/windcorp/progressia/server/events/PlayerEvent.java create mode 100644 src/main/java/ru/windcorp/progressia/server/events/PlayerJoinedEvent.java create mode 100644 src/main/java/ru/windcorp/progressia/server/events/PlayerLeftEvent.java create mode 100644 src/main/java/ru/windcorp/progressia/server/events/ServerEvent.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/EntityManager.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/EntityRequestDaemon.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/LoadManager.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/PlayerVision.java create mode 100644 src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java new file mode 100644 index 0000000..e67f67e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java @@ -0,0 +1,261 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic; + +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import glm.vec._3.i.Vec3i; +import gnu.trove.map.hash.TLongObjectHashMap; + +public class ChunkMaps { + + public static ChunkMap newHashMap() { + return new LongBasedChunkMap(new TLongObjectHashMap()); + } + + public static ChunkMap newSyncHashMap(Object mutex) { + return new SynchronizedChunkMap(new LongBasedChunkMap(new TLongObjectHashMap()), mutex); + } + + public static ChunkMap newSyncHashMap() { + return newSyncHashMap(null); + } + + @SuppressWarnings("unchecked") + public static ChunkMap empty() { + return (ChunkMap) EMPTY_MAP; + } + + private ChunkMaps() { + } + + private final static ChunkMap EMPTY_MAP = new ChunkMap() { + + @Override + public int size() { + return 0; + } + + @Override + public boolean containsKey(Vec3i pos) { + return false; + } + + @Override + public Object get(Vec3i pos) { + return null; + } + + @Override + public Object put(Vec3i pos, Object obj) { + throw new UnsupportedOperationException(); + } + + @Override + public Object remove(Vec3i pos) { + throw new UnsupportedOperationException(); + } + + @Override + public Collection values() { + return Collections.emptyList(); + } + + @Override + public ChunkSet keys() { + return ChunkSets.empty(); + } + + @Override + public boolean removeIf(BiPredicate condition) { + return false; + } + + @Override + public void forEach(BiConsumer action) { + // Do nothing + } + + }; + + private static class SynchronizedChunkMap implements ChunkMap { + + private final ChunkMap parent; + private final Object mutex; + + public SynchronizedChunkMap(ChunkMap parent, Object mutex) { + Objects.requireNonNull(parent, "parent"); + this.parent = parent; + + this.mutex = mutex == null ? this : mutex; + } + + @Override + public int size() { + synchronized (mutex) { + return parent.size(); + } + } + + @Override + public boolean isEmpty() { + synchronized (mutex) { + return parent.isEmpty(); + } + } + + @Override + public boolean containsKey(Vec3i pos) { + synchronized (mutex) { + return parent.containsKey(pos); + } + } + + @Override + public V get(Vec3i pos) { + synchronized (mutex) { + return parent.get(pos); + } + } + + @Override + public V put(Vec3i pos, V obj) { + synchronized (mutex) { + return parent.put(pos, obj); + } + } + + @Override + public V remove(Vec3i pos) { + synchronized (mutex) { + return parent.remove(pos); + } + } + + @Override + public boolean containsValue(V value) { + synchronized (mutex) { + return parent.containsValue(value); + } + } + + @Override + public V getOrDefault(Vec3i pos, V def) { + synchronized (mutex) { + return parent.getOrDefault(pos, def); + } + } + + @Override + public V compute(Vec3i pos, BiFunction remappingFunction) { + synchronized (mutex) { + return parent.compute(pos, remappingFunction); + } + } + + @Override + public boolean containsChunk(GenericChunk chunk) { + synchronized (mutex) { + return parent.containsChunk(chunk); + } + } + + @Override + public V get(GenericChunk chunk) { + synchronized (mutex) { + return parent.get(chunk); + } + } + + @Override + public V put(GenericChunk chunk, V obj) { + synchronized (mutex) { + return parent.put(chunk, obj); + } + } + + @Override + public V remove(GenericChunk chunk) { + synchronized (mutex) { + return parent.remove(chunk); + } + } + + @Override + public V getOrDefault(GenericChunk chunk, V def) { + synchronized (mutex) { + return parent.getOrDefault(chunk, def); + } + } + + @Override + public > V compute( + C chunk, + BiFunction remappingFunction + ) { + synchronized (mutex) { + return parent.compute(chunk, remappingFunction); + } + } + + @Override + public Collection values() { + synchronized (mutex) { + return parent.values(); + } + } + + @Override + public ChunkSet keys() { + synchronized (mutex) { + return parent.keys(); + } + } + + @Override + public boolean removeIf(BiPredicate condition) { + synchronized (mutex) { + return parent.removeIf(condition); + } + } + + @Override + public void forEach(BiConsumer action) { + synchronized (mutex) { + parent.forEach(action); + } + } + + @Override + public > void forEachIn( + GenericWorld world, + BiConsumer action + ) { + synchronized (mutex) { + parent.forEachIn(world, action); + } + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java deleted file mode 100644 index ede6d70..0000000 --- a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server; - -import java.util.Collections; -import java.util.Map; -import java.util.WeakHashMap; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.PacketRevokeChunk; -import ru.windcorp.progressia.common.world.PacketSendChunk; -import ru.windcorp.progressia.common.world.WorldData; -import ru.windcorp.progressia.common.world.generic.ChunkSet; -import ru.windcorp.progressia.common.world.generic.ChunkSets; -import ru.windcorp.progressia.test.TestWorldDiskIO; - -public class ChunkManager { - - private class PlayerVision { - - private final ChunkSet visible = ChunkSets.newSyncHashSet(); - private final ChunkSet requested = ChunkSets.newHashSet(); - private final ChunkSet toSend = ChunkSets.newHashSet(); - private final ChunkSet toRevoke = ChunkSets.newHashSet(); - - public boolean isChunkVisible(Vec3i chunkPos) { - return visible.contains(chunkPos); - } - - public void gatherRequests(Player player) { - requested.clear(); - player.requestChunksToLoad(requested::add); - } - - public void updateQueues(Player player) { - toSend.clear(); - - requested.forEachIn(server.getWorld(), chunk -> { - if (!chunk.isReady()) - return; - if (visible.contains(chunk)) - return; - toSend.add(chunk); - }); - - toRevoke.clear(); - toRevoke.addAll(visible); - toRevoke.removeIf(v -> loaded.contains(v) && requested.contains(v)); - } - - public void processQueues(Player player) { - toRevoke.forEach(chunkPos -> revokeChunk(player, chunkPos)); - toRevoke.clear(); - - toSend.forEach(chunkPos -> sendChunk(player, chunkPos)); - toSend.clear(); - } - - } - - private final Server server; - - private final ChunkSet loaded; - private final ChunkSet requested = ChunkSets.newHashSet(); - private final ChunkSet toLoad = ChunkSets.newHashSet(); - private final ChunkSet toUnload = ChunkSets.newHashSet(); - - // TODO replace with a normal Map managed by some sort of PlayerListener, - // weak maps are weak - private final Map visions = Collections.synchronizedMap(new WeakHashMap<>()); - - public ChunkManager(Server server) { - this.server = server; - this.loaded = server.getWorld().getData().getLoadedChunks(); - } - - public void tick() { - synchronized (getServer().getWorld().getData()) { - synchronized (visions) { - gatherRequests(); - updateQueues(); - processQueues(); - } - } - } - - private void gatherRequests() { - requested.clear(); - - server.getPlayerManager().getPlayers().forEach(p -> { - PlayerVision vision = getVision(p, true); - vision.gatherRequests(p); - requested.addAll(vision.requested); - }); - } - - private void updateQueues() { - toLoad.clear(); - toLoad.addAll(requested); - toLoad.removeAll(loaded); - - toUnload.clear(); - toUnload.addAll(loaded); - toUnload.removeAll(requested); - - visions.forEach((p, v) -> { - v.updateQueues(p); - }); - } - - private void processQueues() { - toUnload.forEach(this::unloadChunk); - toUnload.clear(); - toLoad.forEach(this::loadOrGenerateChunk); - toLoad.clear(); - - visions.forEach((p, v) -> { - v.processQueues(p); - }); - } - - private PlayerVision getVision(Player player, boolean createIfMissing) { - return createIfMissing ? visions.computeIfAbsent(player, k -> new PlayerVision()) : visions.get(player); - } - - public void loadOrGenerateChunk(Vec3i chunkPos) { - - boolean chunkLoadedFromDisk = loadChunk(chunkPos); - - if (!chunkLoadedFromDisk) { - getServer().getWorld().generate(chunkPos); - } - - } - - public boolean loadChunk(Vec3i chunkPos) { - - WorldData world = getServer().getWorld().getData(); - - ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); - if (chunk != null) { - world.addChunk(chunk); - return true; - } else { - return false; - } - - } - - public void unloadChunk(Vec3i chunkPos) { - - WorldData world = getServer().getWorld().getData(); - - ChunkData chunk = world.getChunk(chunkPos); - if (chunk == null) { - throw new IllegalStateException( - String.format( - "Chunk (%d; %d; %d) not loaded, cannot unload", - chunkPos.x, - chunkPos.y, - chunkPos.z - ) - ); - } - - world.removeChunk(chunk); - - TestWorldDiskIO.saveChunk(chunk, getServer()); - - } - - public void sendChunk(Player player, Vec3i chunkPos) { - ChunkData chunk = server.getWorld().getData().getChunk(chunkPos); - - if (chunk == null) { - throw new IllegalStateException( - String.format( - "Chunk (%d; %d; %d) is not loaded, cannot send", - chunkPos.x, - chunkPos.y, - chunkPos.z - ) - ); - } - - PacketSendChunk packet = new PacketSendChunk(); - packet.set(chunk); - player.getClient().sendPacket(packet); - - getVision(player, true).visible.add(chunkPos); - } - - public void revokeChunk(Player player, Vec3i chunkPos) { - PacketRevokeChunk packet = new PacketRevokeChunk(); - packet.set(chunkPos); - player.getClient().sendPacket(packet); - - PlayerVision vision = getVision(player, false); - if (vision != null) { - vision.visible.remove(chunkPos); - } - } - - public boolean isChunkVisible(Vec3i chunkPos, Player player) { - PlayerVision vision = getVision(player, false); - - if (vision == null) { - return false; - } - - return vision.isChunkVisible(chunkPos); - } - - public ChunkSet getVisibleChunks(Player player) { - PlayerVision vision = getVision(player, false); - - if (vision == null) { - return ChunkSets.empty(); - } - - return vision.visible; - } - - public Server getServer() { - return server; - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/EntityManager.java b/src/main/java/ru/windcorp/progressia/server/EntityManager.java deleted file mode 100644 index d904c83..0000000 --- a/src/main/java/ru/windcorp/progressia/server/EntityManager.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server; - -import java.util.Collections; -import java.util.Map; -import java.util.WeakHashMap; - -import glm.vec._3.i.Vec3i; -import gnu.trove.TCollections; -import gnu.trove.iterator.TLongIterator; -import gnu.trove.set.TLongSet; -import gnu.trove.set.hash.TLongHashSet; -import ru.windcorp.jputil.chars.StringUtil; -import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.entity.PacketRevokeEntity; -import ru.windcorp.progressia.common.world.entity.PacketSendEntity; -import ru.windcorp.progressia.common.world.generic.ChunkSet; - -public class EntityManager { - - private class PlayerVision { - - private final TLongSet visible = TCollections.synchronizedSet(new TLongHashSet()); - private final TLongSet requested = new TLongHashSet(); - private final TLongSet toSend = new TLongHashSet(); - private final TLongSet toRevoke = new TLongHashSet(); - - public boolean isEntityVisible(long entityId) { - return visible.contains(entityId); - } - - public void gatherRequests(Player player) { - requested.clear(); - - ChunkSet visibleChunks = player.getClient().getVisibleChunks(); - Vec3i v = Vectors.grab3i(); - - getServer().getWorld().forEachEntity(entity -> { - if (visibleChunks.contains(entity.getChunkCoords(v))) { - requested.add(entity.getEntityId()); - } - }); - - Vectors.release(v); - } - - public void updateQueues(Player player) { - toSend.clear(); - toSend.addAll(requested); - toSend.removeAll(visible); - toSend.retainAll(loaded); - - toRevoke.clear(); - - for (TLongIterator it = visible.iterator(); it.hasNext();) { - long entityId = it.next(); - if (!loaded.contains(entityId) || !requested.contains(entityId)) { - toRevoke.add(entityId); - } - } - } - - public void processQueues(Player player) { - toRevoke.forEach(entityId -> { - revokeEntity(player, entityId); - return true; - }); - toRevoke.clear(); - - toSend.forEach(entityId -> { - sendEntity(player, entityId); - return true; - }); - toSend.clear(); - } - - } - - private final Server server; - - private final TLongSet loaded; - - // TODO replace with a normal Map managed by some sort of PlayerListener, - // weak maps are weak - private final Map visions = Collections.synchronizedMap(new WeakHashMap<>()); - - public EntityManager(Server server) { - this.server = server; - this.loaded = server.getWorld().getData().getLoadedEntities(); - } - - public void tick() { - synchronized (getServer().getWorld().getData()) { - synchronized (visions) { - gatherRequests(); - updateQueues(); - processQueues(); - } - } - } - - private void gatherRequests() { - server.getPlayerManager().getPlayers().forEach(p -> { - PlayerVision vision = getVision(p, true); - vision.gatherRequests(p); - }); - } - - private void updateQueues() { - visions.forEach((p, v) -> { - v.updateQueues(p); - }); - } - - private void processQueues() { - visions.forEach((p, v) -> { - v.processQueues(p); - }); - } - - private PlayerVision getVision(Player player, boolean createIfMissing) { - return createIfMissing ? visions.computeIfAbsent(player, k -> new PlayerVision()) : visions.get(player); - } - - public void sendEntity(Player player, long entityId) { - - EntityData entity = server.getWorld().getData().getEntity(entityId); - - if (entity == null) { - throw new IllegalStateException( - "Entity with entity ID " + new String(StringUtil.toFullHex(entityId)) + " is not loaded, cannot send" - ); - } - - PacketSendEntity packet = new PacketSendEntity(); - packet.set(entity); - player.getClient().sendPacket(packet); - - getVision(player, true).visible.add(entityId); - } - - public void revokeEntity(Player player, long entityId) { - PacketRevokeEntity packet = new PacketRevokeEntity(); - packet.set(entityId); - player.getClient().sendPacket(packet); - - PlayerVision vision = getVision(player, false); - if (vision != null) { - vision.visible.remove(entityId); - } - } - - public boolean isEntityVisible(long entityId, Player player) { - PlayerVision vision = getVision(player, false); - - if (vision == null) { - return false; - } - - return vision.isEntityVisible(entityId); - } - - private static final TLongSet EMPTY_LONG_SET = TCollections.unmodifiableSet(new TLongHashSet()); - - public TLongSet getVisibleEntities(Player player) { - PlayerVision vision = getVision(player, false); - - if (vision == null) { - return EMPTY_LONG_SET; - } - - return vision.visible; - } - - public Server getServer() { - return server; - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java index 60b07f1..10799e0 100644 --- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -26,6 +26,7 @@ import glm.vec._3.Vec3; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityDataRegistry; +import ru.windcorp.progressia.server.events.PlayerJoinedEvent; import ru.windcorp.progressia.test.TestContent; public class PlayerManager { @@ -44,6 +45,8 @@ public class PlayerManager { public void addPlayer(Player player) { this.players.add(player); + System.out.println("PlayerManager.addPlayer()"); + getServer().postEvent(new PlayerJoinedEvent.Immutable(getServer(), player)); } public EntityData conjurePlayerEntity(String login) { @@ -69,6 +72,10 @@ public class PlayerManager { return player; } + + public Object getMutex() { + return players; + } public Server getServer() { return server; diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 8ca9383..d4d1883 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -15,18 +15,25 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.function.Consumer; import org.apache.logging.log4j.LogManager; +import com.google.common.eventbus.EventBus; + import ru.windcorp.jputil.functions.ThrowingRunnable; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.TaskQueue; +import ru.windcorp.progressia.common.util.crash.ReportingEventBus; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.server.comms.ClientManager; +import ru.windcorp.progressia.server.events.ServerEvent; +import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon; +import ru.windcorp.progressia.server.management.load.EntityRequestDaemon; +import ru.windcorp.progressia.server.management.load.LoadManager; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; @@ -53,25 +60,32 @@ public class Server { private final ClientManager clientManager; private final PlayerManager playerManager; - private final ChunkManager chunkManager; - private final EntityManager entityManager; + private final LoadManager loadManager; private final TaskQueue taskQueue = new TaskQueue(this::isServerThread); + private final EventBus eventBus = ReportingEventBus.create("ServerEvents"); + private final TickingSettings tickingSettings = new TickingSettings(); public Server(WorldData world) { - this.world = new WorldLogic(world, this, w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 9.8f, 16f, 16f), w)); + this.world = new WorldLogic( + world, + this, + w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 9.8f, 16f, 16f), w) + ); this.serverThread = new ServerThread(this); this.clientManager = new ClientManager(this); this.playerManager = new PlayerManager(this); - this.chunkManager = new ChunkManager(this); - this.entityManager = new EntityManager(this); + this.loadManager = new LoadManager(this); - schedule(chunkManager::tick); - schedule(entityManager::tick); - schedule(this::scheduleWorldTicks); // Must run after chunkManager so it only schedules chunks that hadn't unloaded + schedule(new ChunkRequestDaemon(loadManager.getChunkManager())::tick); + schedule(new EntityRequestDaemon(loadManager.getEntityManager())::tick); + + // Must run after request daemons so it only schedules chunks that + // hadn't unloaded + schedule(this::scheduleWorldTicks); } /** @@ -84,8 +98,8 @@ public class Server { } /** - * Returns this server's {@link ClientManager}. - * Use this to deal with communications, e.g. send packets. + * Returns this server's {@link ClientManager}. Use this to deal with + * communications, e.g. send packets. * * @return the {@link ClientManager} that handles this server */ @@ -97,8 +111,8 @@ public class Server { return playerManager; } - public ChunkManager getChunkManager() { - return chunkManager; + public LoadManager getLoadManager() { + return loadManager; } /** @@ -111,9 +125,9 @@ public class Server { } /** - * Requests that the provided task is executed once on next server tick. - * The task will be run in the main server thread. The task object is - * discarded after execution. + * Requests that the provided task is executed once on next server tick. The + * task will be run in the main server thread. The task object is discarded + * after execution. *

    * Use this method to request a one-time (rare) action that must necessarily * happen in the main server thread, such as initialization tasks or @@ -130,13 +144,12 @@ public class Server { /** * Executes the tasks in the server main thread as soon as possible. *

    - * If this method is invoked in the server main thread, then the task is - * run immediately (the method blocks until the task finishes). Otherwise - * this method behaves exactly like {@link #invokeLater(Runnable)}. + * If this method is invoked in the server main thread, then the task is run + * immediately (the method blocks until the task finishes). Otherwise this + * method behaves exactly like {@link #invokeLater(Runnable)}. *

    * Use this method to make sure that a piece of code is run in the main - * server - * thread. + * server thread. * * @param task the task to run * @see #invokeLater(Runnable) @@ -146,11 +159,7 @@ public class Server { taskQueue.invokeNow(task); } - public void waitAndInvoke( - ThrowingRunnable task - ) - throws InterruptedException, - E { + public void waitAndInvoke(ThrowingRunnable task) throws InterruptedException, E { taskQueue.waitAndInvoke(task); } @@ -170,6 +179,20 @@ public class Server { serverThread.getTicker().requestEvaluation(evaluation); } + public void subscribe(Object object) { + eventBus.register(object); + } + + public void unsubscribe(Object object) { + eventBus.unregister(object); + } + + public void postEvent(ServerEvent event) { + event.setServer(this); + eventBus.post(event); + event.setServer(null); + } + /** * Returns the duration of the last server tick. Server logic should assume * that this much in-world time has passed. @@ -186,8 +209,8 @@ public class Server { /** * Returns the {@link WorldAccessor} object for this server. Use the - * provided accessor to - * request common {@link Evaluation}s and {@link Change}s. + * provided accessor to request common {@link Evaluation}s and + * {@link Change}s. * * @return a {@link WorldAccessor} * @see #requestChange(Change) @@ -227,8 +250,7 @@ public class Server { /** * Shuts the server down, disconnecting the clients with the provided - * message. - * This method blocks until the shutdown is complete. + * message. This method blocks until the shutdown is complete. * * @param message the message to send to the clients as the disconnect * reason @@ -245,10 +267,9 @@ public class Server { /** * Returns an instance of {@link java.util.Random Random} that can be used - * as a source of indeterministic - * randomness. World generation and other algorithms that must have random - * but reproducible results should - * not use this. + * as a source of indeterministic randomness. World generation and other + * algorithms that must have random but reproducible results should not use + * this. * * @return a thread-safe indeterministic instance of * {@link java.util.Random}. diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java index 74c636d..dfa631a 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java @@ -81,7 +81,7 @@ public class ClientManager { EntityData entity = getServer().getPlayerManager().conjurePlayerEntity(login); Player player = new Player(entity, getServer(), client); - getServer().getPlayerManager().getPlayers().add(player); + getServer().getPlayerManager().addPlayer(player); PacketSetLocalPlayer packet = new PacketSetLocalPlayer(); packet.set(entity.getEntityId()); diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java index c455b8e..c05d952 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java @@ -44,13 +44,13 @@ public abstract class ClientPlayer extends ClientChat { public boolean isChunkVisible(Vec3i chunkPos) { if (player == null) return false; - return player.getServer().getChunkManager().isChunkVisible(chunkPos, player); + return player.getServer().getLoadManager().getVisionManager().isChunkVisible(chunkPos, player); } public ChunkSet getVisibleChunks() { if (player == null) return ChunkSets.empty(); - return player.getServer().getChunkManager().getVisibleChunks(player); + return player.getServer().getLoadManager().getVisionManager().getVisibleChunks(player); } public boolean isChunkVisible(long entityId) { diff --git a/src/main/java/ru/windcorp/progressia/server/events/ClientEvent.java b/src/main/java/ru/windcorp/progressia/server/events/ClientEvent.java new file mode 100644 index 0000000..c795fa8 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/events/ClientEvent.java @@ -0,0 +1,46 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.events; + +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.comms.Client; + +public interface ClientEvent extends ServerEvent { + + Client getClient(); + + public static abstract class Immutable extends ServerEvent.Default implements ClientEvent { + + private final Client client; + + public Immutable(Server server, Client client) { + super(server); + this.client = client; + } + + /** + * @return the client + */ + @Override + public Client getClient() { + return client; + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/events/PlayerEvent.java b/src/main/java/ru/windcorp/progressia/server/events/PlayerEvent.java new file mode 100644 index 0000000..544418e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/events/PlayerEvent.java @@ -0,0 +1,49 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.events; + +import ru.windcorp.progressia.server.Player; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.comms.Client; + +public interface PlayerEvent extends ClientEvent { + + Player getPlayer(); + + public static abstract class Immutable extends ServerEvent.Default implements PlayerEvent { + + private final Player player; + + public Immutable(Server server, Player player) { + super(server); + this.player = player; + } + + @Override + public Player getPlayer() { + return player; + } + + @Override + public Client getClient() { + return player.getClient(); + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/events/PlayerJoinedEvent.java b/src/main/java/ru/windcorp/progressia/server/events/PlayerJoinedEvent.java new file mode 100644 index 0000000..eed2a90 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/events/PlayerJoinedEvent.java @@ -0,0 +1,33 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.events; + +import ru.windcorp.progressia.server.Player; +import ru.windcorp.progressia.server.Server; + +public interface PlayerJoinedEvent extends PlayerEvent { + + public static class Immutable extends PlayerEvent.Immutable implements PlayerJoinedEvent { + + public Immutable(Server server, Player player) { + super(server, player); + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/events/PlayerLeftEvent.java b/src/main/java/ru/windcorp/progressia/server/events/PlayerLeftEvent.java new file mode 100644 index 0000000..d6e4417 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/events/PlayerLeftEvent.java @@ -0,0 +1,33 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.events; + +import ru.windcorp.progressia.server.Player; +import ru.windcorp.progressia.server.Server; + +public interface PlayerLeftEvent extends PlayerEvent { + + public static class Immutable extends PlayerEvent.Immutable implements PlayerLeftEvent { + + public Immutable(Server server, Player player) { + super(server, player); + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/events/ServerEvent.java b/src/main/java/ru/windcorp/progressia/server/events/ServerEvent.java new file mode 100644 index 0000000..b63f727 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/events/ServerEvent.java @@ -0,0 +1,68 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.events; + +import ru.windcorp.progressia.server.Server; + +/** + * An interface for all events issued by a {@link Server}. + */ +public interface ServerEvent { + + /** + * Returns the server instance that this event happened on. + * + * @return the relevant server + */ + Server getServer(); + + /** + * Sets the server instance that the event is posted on. The value provided + * to this method must be returned by subsequent calls to + * {@link #getServer()}. Do not call this method when handling the event. + * + * @param server the server dispatching the event or {@code null} to unbind + * any previously bound server + */ + void setServer(Server server); + + /** + * A default implementation of {@link ServerEvent}. This is not necessarily + * extended by server events. + */ + public static abstract class Default implements ServerEvent { + + private Server server; + + public Default(Server server) { + this.server = server; + } + + @Override + public Server getServer() { + return server; + } + + @Override + public void setServer(Server server) { + this.server = server; + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java new file mode 100644 index 0000000..a31a9cd --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java @@ -0,0 +1,192 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.management.load; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.PacketRevokeChunk; +import ru.windcorp.progressia.common.world.PacketSendChunk; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.server.Player; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.test.TestWorldDiskIO; + +/** + * Chunk manager provides facilities to load, unload and generate chunks for a + * {@link Server} on demand. + */ +public class ChunkManager { + + private final LoadManager loadManager; + + public ChunkManager(LoadManager loadManager) { + this.loadManager = loadManager; + } + + /** + * @return the loadManager + */ + public LoadManager getLoadManager() { + return loadManager; + } + + /** + * @return the server + */ + public Server getServer() { + return getLoadManager().getServer(); + } + + /** + * Describes the result of an attempt to load a chunk. + */ + public static enum LoadResult { + /** + * A chunk has successfully been read from disk and is now loaded. + */ + LOADED_FROM_DISK, + + /** + * A chunk has successfully been generated and is now loaded. + */ + GENERATED, + + /** + * A chunk has already been loaded and so no action has been taken. + */ + ALREADY_LOADED, + + /** + * A chunk has not been loaded previously and the operation has failed + * to load it. It is not currently loaded. + */ + NOT_LOADED + } + + /** + * Loads or generates the chunk at the given location unless it is already + * loaded. The chunk is loaded after this method completes normally. + * + * @param chunkPos the position of the chunk + * @return one of {@link LoadResult#LOADED_FROM_DISK LOADED_FROM_DISK}, + * {@link LoadResult#GENERATED GENERATED} or + * {@link LoadResult#ALREADY_LOADED ALREADY_LOADED} + */ + public LoadResult loadOrGenerateChunk(Vec3i chunkPos) { + LoadResult loadResult = loadChunk(chunkPos); + + if (loadResult == LoadResult.NOT_LOADED) { + getServer().getWorld().generate(chunkPos); + return LoadResult.GENERATED; + } else { + return loadResult; + } + } + + /** + * Attempts to load the chunk from disk unless it is already loaded. If the + * chunk is not currently loaded and it is not available on the disk this + * method does nothing. + * + * @param chunkPos the position of the chunk + * @return one of {@link LoadResult#LOADED_FROM_DISK LOADED_FROM_DISK}, + * {@link LoadResult#NOT_LOADED NOT_LOADED} or + * {@link LoadResult#ALREADY_LOADED ALREADY_LOADED} + */ + public LoadResult loadChunk(Vec3i chunkPos) { + if (isChunkLoaded(chunkPos)) { + return LoadResult.ALREADY_LOADED; + } + + WorldData world = getServer().getWorld().getData(); + + ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); + if (chunk != null) { + world.addChunk(chunk); + return LoadResult.LOADED_FROM_DISK; + } else { + return LoadResult.NOT_LOADED; + } + } + + /** + * Unloads the chunk and saves it to disk if the chunk is loaded, otherwise + * does nothing. + * + * @param chunkPos the position of the chunk + * @return {@code true} iff the chunk had been loaded and was unloaded by + * this method + */ + public boolean unloadChunk(Vec3i chunkPos) { + WorldData world = getServer().getWorld().getData(); + ChunkData chunk = world.getChunk(chunkPos); + + if (chunk == null) { + return false; + } + + world.removeChunk(chunk); + TestWorldDiskIO.saveChunk(chunk, getServer()); + + return true; + } + + public void sendChunk(Player player, Vec3i chunkPos) { + ChunkData chunk = getServer().getWorld().getData().getChunk(chunkPos); + + if (chunk == null) { + throw new IllegalStateException( + String.format( + "Chunk (%d; %d; %d) is not loaded, cannot send", + chunkPos.x, + chunkPos.y, + chunkPos.z + ) + ); + } + + PacketSendChunk packet = new PacketSendChunk(); + packet.set(chunk); + player.getClient().sendPacket(packet); + + getLoadManager().getVisionManager().getVision(player, true).getVisibleChunks().add(chunkPos); + } + + public void revokeChunk(Player player, Vec3i chunkPos) { + PacketRevokeChunk packet = new PacketRevokeChunk(); + packet.set(chunkPos); + player.getClient().sendPacket(packet); + + PlayerVision vision = getLoadManager().getVisionManager().getVision(player, false); + if (vision != null) { + vision.getVisibleChunks().remove(chunkPos); + } + } + + /** + * Checks whether or not the chunk at the specified location is loaded. A + * loaded chunk is accessible through the server's {@link WorldData} object. + * + * @param chunkPos the position of the chunk + * @return {@code true} iff the chunk is loaded + */ + public boolean isChunkLoaded(Vec3i chunkPos) { + return getServer().getWorld().isChunkLoaded(chunkPos); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java new file mode 100644 index 0000000..ff3c7e0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java @@ -0,0 +1,206 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.management.load; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.world.generic.ChunkMap; +import ru.windcorp.progressia.common.world.generic.ChunkMaps; +import ru.windcorp.progressia.common.world.generic.ChunkSet; +import ru.windcorp.progressia.common.world.generic.ChunkSets; +import ru.windcorp.progressia.server.Server; + +/** + * Chunk request daemon gathers chunk requests from players (via {@link VisionManager}) and loads or unloads chunks appropriately. + */ +public class ChunkRequestDaemon { + + private static final float CHUNK_UNLOAD_DELAY = Units.get(5, "s"); + + private final ChunkManager chunkManager; + + private final ChunkSet loaded; + private final ChunkSet requested = ChunkSets.newHashSet(); + private final ChunkSet toLoad = ChunkSets.newHashSet(); + private final ChunkSet toRequestUnload = ChunkSets.newHashSet(); + + private final Collection buffer = new ArrayList<>(); + + private static class ChunkUnloadRequest { + private final Vec3i chunkPos; + private final long unloadAt; + + public ChunkUnloadRequest(Vec3i chunkPos, long unloadAt) { + this.chunkPos = chunkPos; + this.unloadAt = unloadAt; + } + + /** + * @return the chunk position + */ + public Vec3i getChunkPos() { + return chunkPos; + } + + /** + * @return the moment when the chunks becomes eligible for unloading + */ + public long getUnloadAt() { + return unloadAt; + } + } + + private final ChunkMap unloadSchedule = ChunkMaps.newHashMap(); + + public ChunkRequestDaemon(ChunkManager chunkManager) { + this.chunkManager = chunkManager; + this.loaded = getServer().getWorld().getData().getLoadedChunks(); + } + + public void tick() { + synchronized (getServer().getWorld().getData()) { + synchronized (getServer().getPlayerManager().getMutex()) { + loadAndUnloadChunks(); + sendAndRevokeChunks(); + } + } + } + + private void loadAndUnloadChunks() { + gatherLoadRequests(); + updateLoadQueues(); + processLoadQueues(); + } + + private void gatherLoadRequests() { + requested.clear(); + + getChunkManager().getLoadManager().getVisionManager().forEachVision(vision -> { + vision.getRequestedChunks().clear(); + vision.getPlayer().requestChunksToLoad(vision.getRequestedChunks()::add); + requested.addAll(vision.getRequestedChunks()); + }); + } + + private void updateLoadQueues() { + toLoad.clear(); + toLoad.addAll(requested); + toLoad.removeAll(loaded); + + toRequestUnload.clear(); + toRequestUnload.addAll(loaded); + toRequestUnload.removeAll(requested); + } + + private void processLoadQueues() { + toRequestUnload.forEach(this::scheduleUnload); + toRequestUnload.clear(); + + toLoad.forEach(getChunkManager()::loadOrGenerateChunk); + toLoad.clear(); + + unloadScheduledChunks(); + } + + private void scheduleUnload(Vec3i chunkPos) { + if (unloadSchedule.containsKey(chunkPos)) { + // Unload already requested, skip + return; + } + + long unloadAt = System.currentTimeMillis() + (long) (getUnloadDelay() * 1000); + Vec3i chunkPosCopy = new Vec3i(chunkPos); + + unloadSchedule.put(chunkPosCopy, new ChunkUnloadRequest(chunkPosCopy, unloadAt)); + } + + private void unloadScheduledChunks() { + long now = System.currentTimeMillis(); + + for (Iterator it = unloadSchedule.values().iterator(); it.hasNext();) { + ChunkUnloadRequest request = it.next(); + + if (request.getUnloadAt() < now) { + it.remove(); + getChunkManager().unloadChunk(request.getChunkPos()); + } + } + } + + private void sendAndRevokeChunks() { + getChunkManager().getLoadManager().getVisionManager().forEachVision(vision -> { + revokeChunks(vision); + sendChunks(vision); + }); + } + + private void sendChunks(PlayerVision vision) { + vision.getRequestedChunks().forEachIn(getServer().getWorld(), chunk -> { + if (!chunk.isReady()) + return; + if (vision.isChunkVisible(chunk.getPosition())) + return; + buffer.add(chunk.getPosition()); + }); + + if (buffer.isEmpty()) return; + for (Vec3i chunkPos : buffer) { + getChunkManager().sendChunk(vision.getPlayer(), chunkPos); + } + + buffer.clear(); + } + + private void revokeChunks(PlayerVision vision) { + vision.getVisibleChunks().forEach(chunkPos -> { + if (getChunkManager().isChunkLoaded(chunkPos) && vision.getRequestedChunks().contains(chunkPos)) + return; + buffer.add(new Vec3i(chunkPos)); + }); + + if (buffer.isEmpty()) return; + for (Vec3i chunkPos : buffer) { + getChunkManager().revokeChunk(vision.getPlayer(), chunkPos); + } + + buffer.clear(); + } + + /** + * @return the minimum amount of time a chunk will spend in the unload queue + */ + public float getUnloadDelay() { + return CHUNK_UNLOAD_DELAY; + } + + /** + * @return the manager + */ + public ChunkManager getChunkManager() { + return chunkManager; + } + + public Server getServer() { + return getChunkManager().getServer(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/EntityManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/EntityManager.java new file mode 100644 index 0000000..6aa3853 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/EntityManager.java @@ -0,0 +1,97 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.server.management.load; + +import gnu.trove.set.TLongSet; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.entity.PacketRevokeEntity; +import ru.windcorp.progressia.common.world.entity.PacketSendEntity; +import ru.windcorp.progressia.server.Player; +import ru.windcorp.progressia.server.Server; + +public class EntityManager { + + private final LoadManager loadManager; + + private final TLongSet loaded; + + public EntityManager(LoadManager loadManager) { + this.loadManager = loadManager; + this.loaded = getServer().getWorld().getData().getLoadedEntities(); + } + + public void sendEntity(Player player, long entityId) { + PlayerVision vision = getLoadManager().getVisionManager().getVision(player, true); + if (!vision.getVisibleEntities().add(entityId)) { + return; + } + + EntityData entity = getServer().getWorld().getData().getEntity(entityId); + + if (entity == null) { + throw new IllegalStateException( + "Entity with entity ID " + EntityData.formatEntityId(entityId) + " is not loaded, cannot send" + ); + } + + PacketSendEntity packet = new PacketSendEntity(); + packet.set(entity); + player.getClient().sendPacket(packet); + } + + public void revokeEntity(Player player, long entityId) { + PlayerVision vision = getLoadManager().getVisionManager().getVision(player, false); + if (vision == null) { + return; + } + if (!vision.getVisibleEntities().remove(entityId)) { + return; + } + + PacketRevokeEntity packet = new PacketRevokeEntity(); + packet.set(entityId); + player.getClient().sendPacket(packet); + } + + public boolean isEntityVisible(Player player, long entityId) { + PlayerVision vision = getLoadManager().getVisionManager().getVision(player, false); + + if (vision == null) { + return false; + } + + return vision.isEntityVisible(entityId); + } + + public boolean isEntityLoaded(long entityId) { + return loaded.contains(entityId); + } + + /** + * @return the loadManager + */ + public LoadManager getLoadManager() { + return loadManager; + } + + public Server getServer() { + return getLoadManager().getServer(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/EntityRequestDaemon.java b/src/main/java/ru/windcorp/progressia/server/management/load/EntityRequestDaemon.java new file mode 100644 index 0000000..9605ffe --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/EntityRequestDaemon.java @@ -0,0 +1,121 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.management.load; + +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import gnu.trove.TLongCollection; +import gnu.trove.iterator.TLongIterator; +import gnu.trove.list.array.TLongArrayList; +import gnu.trove.set.TLongSet; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.generic.ChunkSet; +import ru.windcorp.progressia.server.Server; + +public class EntityRequestDaemon { + + private final EntityManager entityManager; + + private final TLongCollection buffer = new TLongArrayList(); + + public EntityRequestDaemon(EntityManager entityManager) { + this.entityManager = entityManager; + } + + public void tick() { + synchronized (getServer().getWorld().getData()) { + synchronized (getServer().getPlayerManager().getMutex()) { + gatherRequests(); + revokeEntities(); + sendEntities(); + } + } + } + + private void gatherRequests() { + Vec3i v = Vectors.grab3i(); + + forEachVision(vision -> { + + TLongSet requestedEntities = vision.getRequestedEntities(); + requestedEntities.clear(); + + ChunkSet visibleChunks = vision.getVisibleChunks(); + getServer().getWorld().forEachEntity(entity -> { + if (visibleChunks.contains(entity.getChunkCoords(v))) { + requestedEntities.add(entity.getEntityId()); + } + }); + }); + + Vectors.release(v); + } + + private void sendEntities() { + forEachVision(vision -> { + for (TLongIterator it = vision.getRequestedEntities().iterator(); it.hasNext();) { + long entityId = it.next(); + if (getEntityManager().isEntityLoaded(entityId) && !vision.getVisibleEntities().contains(entityId)) { + buffer.add(entityId); + } + } + + if (buffer.isEmpty()) return; + for (TLongIterator it = buffer.iterator(); it.hasNext();) { + getEntityManager().sendEntity(vision.getPlayer(), it.next()); + } + + buffer.clear(); + }); + } + + private void revokeEntities() { + forEachVision(vision -> { + for (TLongIterator it = vision.getVisibleEntities().iterator(); it.hasNext();) { + long entityId = it.next(); + if (!getEntityManager().isEntityLoaded(entityId) || !vision.getRequestedEntities().contains(entityId)) { + buffer.add(entityId); + } + } + + if (buffer.isEmpty()) return; + for (TLongIterator it = buffer.iterator(); it.hasNext();) { + getEntityManager().revokeEntity(vision.getPlayer(), it.next()); + } + + buffer.clear(); + }); + } + + /** + * @return the entityManager + */ + public EntityManager getEntityManager() { + return entityManager; + } + + public Server getServer() { + return getEntityManager().getServer(); + } + + private void forEachVision(Consumer action) { + getEntityManager().getLoadManager().getVisionManager().forEachVision(action); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/LoadManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/LoadManager.java new file mode 100644 index 0000000..3670116 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/LoadManager.java @@ -0,0 +1,65 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.management.load; + +import ru.windcorp.progressia.server.Server; + +public class LoadManager { + + private final Server server; + private final ChunkManager chunkManager; + private final EntityManager entityManager; + private final VisionManager visionManager; + + public LoadManager(Server server) { + this.server = server; + + this.chunkManager = new ChunkManager(this); + this.entityManager = new EntityManager(this); + this.visionManager = new VisionManager(this); + } + + /** + * @return the chunkManager + */ + public ChunkManager getChunkManager() { + return chunkManager; + } + + /** + * @return the entityManager + */ + public EntityManager getEntityManager() { + return entityManager; + } + + /** + * @return the visionManager + */ + public VisionManager getVisionManager() { + return visionManager; + } + + /** + * @return the server + */ + public Server getServer() { + return server; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/PlayerVision.java b/src/main/java/ru/windcorp/progressia/server/management/load/PlayerVision.java new file mode 100644 index 0000000..bb8e474 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/PlayerVision.java @@ -0,0 +1,85 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.management.load; + +import glm.vec._3.i.Vec3i; +import gnu.trove.TCollections; +import gnu.trove.set.TLongSet; +import gnu.trove.set.hash.TLongHashSet; +import ru.windcorp.progressia.common.world.generic.ChunkSet; +import ru.windcorp.progressia.common.world.generic.ChunkSets; +import ru.windcorp.progressia.server.Player; + +public class PlayerVision { + + private final Player player; + + private final ChunkSet visibleChunks = ChunkSets.newSyncHashSet(); + private final ChunkSet requestedChunks = ChunkSets.newHashSet(); + + private final TLongSet visibleEntities = TCollections.synchronizedSet(new TLongHashSet()); + private final TLongSet requestedEntities = new TLongHashSet(); + + public PlayerVision(Player player) { + this.player = player; + } + + public boolean isChunkVisible(Vec3i chunkPos) { + return visibleChunks.contains(chunkPos); + } + + public boolean isEntityVisible(long entityId) { + return visibleEntities.contains(entityId); + } + + /** + * @return the requestedChunks + */ + public ChunkSet getRequestedChunks() { + return requestedChunks; + } + + /** + * @return the visibleChunks + */ + public ChunkSet getVisibleChunks() { + return visibleChunks; + } + + /** + * @return the requestedEntities + */ + public TLongSet getRequestedEntities() { + return requestedEntities; + } + + /** + * @return the visibleEntities + */ + public TLongSet getVisibleEntities() { + return visibleEntities; + } + + /** + * @return the player + */ + public Player getPlayer() { + return player; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java new file mode 100644 index 0000000..cdf2d8e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java @@ -0,0 +1,108 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.management.load; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +import com.google.common.eventbus.Subscribe; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.generic.ChunkSet; +import ru.windcorp.progressia.common.world.generic.ChunkSets; +import ru.windcorp.progressia.server.Player; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.events.PlayerJoinedEvent; +import ru.windcorp.progressia.server.events.PlayerLeftEvent; + +public class VisionManager { + + private final LoadManager loadManager; + + private final Map visions = Collections.synchronizedMap(new HashMap<>()); + + public VisionManager(LoadManager loadManager) { + this.loadManager = loadManager; + getServer().subscribe(this); + } + + @Subscribe + private void onPlayerJoined(PlayerJoinedEvent event) { + System.out.println("VisionManager.onPlayerJoined()"); + getVision(event.getPlayer(), true); + } + + @Subscribe + private void onPlayerLeft(PlayerLeftEvent event) { + System.out.println("VisionManager.onPlayerLeft()"); + visions.remove(event.getPlayer()); + } + + public PlayerVision getVision(Player player, boolean createIfMissing) { + if (createIfMissing) { + return visions.computeIfAbsent(player, PlayerVision::new); + } else { + return visions.get(player); + } + } + + public void forEachVision(Consumer action) { + visions.values().forEach(action); + } + + public boolean isChunkVisible(Vec3i chunkPos, Player player) { + PlayerVision vision = getVision(player, false); + + if (vision == null) { + return false; + } + + return vision.isChunkVisible(chunkPos); + } + + public ChunkSet getVisibleChunks(Player player) { + PlayerVision vision = getVision(player, false); + + if (vision == null) { + return ChunkSets.empty(); + } + + return vision.getVisibleChunks(); + } + + /** + * @return the loadManager + */ + public LoadManager getLoadManager() { + return loadManager; + } + + /** + * @return the chunkManager + */ + public ChunkManager getChunkManager() { + return getLoadManager().getChunkManager(); + } + + public Server getServer() { + return getLoadManager().getServer(); + } + +} From 7ecdfdfb4dfd508648405adf33e96089d0d537c0 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 26 Mar 2021 21:26:05 +0300 Subject: [PATCH 18/63] Added scatter generation logic to TestPlanetGenerator - Scatter generation is now triggered properly in TestPlanetGenerator - WorldGenerators are now required to call addChunk() themselves (again) - ChunkManager now generates loaded chunks that are not ready - Chunks scheduled for unloading no longer unload if they become requested while in queue --- .../server/management/load/ChunkManager.java | 2 +- .../management/load/ChunkRequestDaemon.java | 6 ++++ .../progressia/server/world/WorldLogic.java | 4 +-- .../test/gen/TestWorldGenerator.java | 4 ++- .../gen/planet/PlanetScatterGenerator.java | 3 ++ .../gen/planet/PlanetTerrainGenerator.java | 4 ++- .../test/gen/planet/TestPlanetGenerator.java | 31 +++++++++++++++++-- 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java index a31a9cd..baf68f6 100644 --- a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java @@ -90,7 +90,7 @@ public class ChunkManager { public LoadResult loadOrGenerateChunk(Vec3i chunkPos) { LoadResult loadResult = loadChunk(chunkPos); - if (loadResult == LoadResult.NOT_LOADED) { + if (loadResult == LoadResult.NOT_LOADED || !getServer().getWorld().getChunk(chunkPos).isReady()) { getServer().getWorld().generate(chunkPos); return LoadResult.GENERATED; } else { diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java index ff3c7e0..502f68f 100644 --- a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java @@ -140,7 +140,13 @@ public class ChunkRequestDaemon { ChunkUnloadRequest request = it.next(); if (request.getUnloadAt() < now) { + it.remove(); + + if (requested.contains(request.getChunkPos())) { + continue; // do not unload chunks that became requested + } + getChunkManager().unloadChunk(request.getChunkPos()); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index bf5da5e..5931e34 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -106,9 +106,7 @@ public class WorldLogic } public ChunkData generate(Vec3i chunkPos) { - ChunkData chunk = getGenerator().generate(chunkPos, getData()); - getData().addChunk(chunk); - return chunk; + return getGenerator().generate(chunkPos, getData()); } public ChunkLogic getChunk(ChunkData chunkData) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index e66d9b7..8e0195a 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -78,7 +78,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public ChunkData generate(Vec3i chunkPos, WorldData world) { - return generateUnpopulated(chunkPos, world); + ChunkData chunk = generateUnpopulated(chunkPos, world); + world.addChunk(chunk); + return chunk; } private ChunkData generateUnpopulated(Vec3i chunkPos, WorldData world) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java index da0f8d3..a2af1d4 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java @@ -17,7 +17,9 @@ */ package ru.windcorp.progressia.test.gen.planet; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.test.gen.surface.SurfaceScatterGenerator; public class PlanetScatterGenerator { @@ -35,6 +37,7 @@ public class PlanetScatterGenerator { } public void generateScatter(ChunkData chunk) { + chunk.setBlock(new Vec3i(8, 8, 8), BlockDataRegistry.getInstance().get("Test:Log"), false); surfaceGenerator.generateScatter(chunk); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index d59984a..5948b92 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -48,9 +48,11 @@ class PlanetTerrainGenerator { FloatRangeMap layers = new ArrayFloatRangeMap<>(); BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); + BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); layers.put(Float.NEGATIVE_INFINITY, 0, (n, w, d, r, c) -> air); - layers.put(0, Float.POSITIVE_INFINITY, (n, w, d, r, c) -> granite); + layers.put(0, 4, (n, w, d, r, c) -> dirt); + layers.put(4, Float.POSITIVE_INFINITY, (n, w, d, r, c) -> granite); this.surfaceGenerator = new SurfaceTerrainGenerator((f, n, w) -> heightMap.get(f, n, w) + generator.getPlanet().getRadius(), layers); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 3012715..3f548e9 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -20,16 +20,21 @@ package ru.windcorp.progressia.test.gen.planet; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; + import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; public class TestPlanetGenerator extends AbstractWorldGenerator { + private final Server server; + private final Planet planet; private final PlanetTerrainGenerator terrainGenerator; @@ -38,6 +43,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { public TestPlanetGenerator(String id, Planet planet, WorldLogic world) { super(id, Boolean.class, "Test:PlanetGravityModel"); + this.server = world.getServer(); this.planet = planet; TestPlanetGravityModel model = (TestPlanetGravityModel) this.getGravityModel(); @@ -71,14 +77,33 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { @Override protected boolean checkIsChunkReady(Boolean hint) { - return hint; + return hint == Boolean.TRUE; // Avoid NPE } @Override public ChunkData generate(Vec3i chunkPos, WorldData world) { - ChunkData chunk = terrainGenerator.generateTerrain(chunkPos, world); - scatterGenerator.generateScatter(chunk); + VectorUtil.iterateCuboidAround(chunkPos, 3, r -> conjureTerrain(r, world)); + ChunkData chunk = world.getChunk(chunkPos); + + if (!isChunkReady(chunk.getGenerationHint())) { + scatterGenerator.generateScatter(chunk); + } + return chunk; } + + private void conjureTerrain(Vec3i chunkPos, WorldData world) { + ChunkData chunk = world.getChunk(chunkPos); + + if (chunk == null) { + server.getLoadManager().getChunkManager().loadChunk(chunkPos); + chunk = world.getChunk(chunkPos); + } + + if (chunk == null) { + chunk = terrainGenerator.generateTerrain(chunkPos, world); + world.addChunk(chunk); + } + } } From 2d3d250f92efecea018b66f4d913fe511ae433f6 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 2 Apr 2021 21:29:09 +0300 Subject: [PATCH 19/63] Renamed Scatter to Feature and added a generation feature interface - Renamed SurfaceScatterGenerator to SurfaceFeatureGenerator - Renamed PlanetScatterGenerator to PlanetFeatureGenerator - Added a very basic interface for adding generation features - Removed debug leftovers from PlayerManager and VisionManager --- .../progressia/server/PlayerManager.java | 1 - .../server/management/load/VisionManager.java | 2 - .../gen/planet/PlanetFeatureGenerator.java | 78 +++++++++++++++++++ .../test/gen/planet/TestPlanetGenerator.java | 6 +- ...tterGenerator.java => SurfaceFeature.java} | 13 +++- .../SurfaceFeatureGenerator.java} | 37 ++++----- 6 files changed, 109 insertions(+), 28 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java rename src/main/java/ru/windcorp/progressia/test/gen/surface/{SurfaceScatterGenerator.java => SurfaceFeature.java} (76%) rename src/main/java/ru/windcorp/progressia/test/gen/{planet/PlanetScatterGenerator.java => surface/SurfaceFeatureGenerator.java} (51%) diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java index 10799e0..f762778 100644 --- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -45,7 +45,6 @@ public class PlayerManager { public void addPlayer(Player player) { this.players.add(player); - System.out.println("PlayerManager.addPlayer()"); getServer().postEvent(new PlayerJoinedEvent.Immutable(getServer(), player)); } diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java index cdf2d8e..b4d2a93 100644 --- a/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java +++ b/src/main/java/ru/windcorp/progressia/server/management/load/VisionManager.java @@ -45,13 +45,11 @@ public class VisionManager { @Subscribe private void onPlayerJoined(PlayerJoinedEvent event) { - System.out.println("VisionManager.onPlayerJoined()"); getVision(event.getPlayer(), true); } @Subscribe private void onPlayerLeft(PlayerLeftEvent event) { - System.out.println("VisionManager.onPlayerLeft()"); visions.remove(event.getPlayer()); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java new file mode 100644 index 0000000..79f0593 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java @@ -0,0 +1,78 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.planet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.test.gen.surface.SurfaceFeature; +import ru.windcorp.progressia.test.gen.surface.SurfaceFeatureGenerator; + +public class PlanetFeatureGenerator { + + private final TestPlanetGenerator parent; + private final SurfaceFeatureGenerator surfaceGenerator; + + public PlanetFeatureGenerator(TestPlanetGenerator generator) { + this.parent = generator; + + Collection features = new ArrayList<>(); + features.add(new SurfaceFeature("Test:GlassFeature") { + @Override + public void process(ChunkData chunk, Random random) { + + chunk.setBlockRel(new Vec3i(8, 8, 8), BlockDataRegistry.getInstance().get("Test:Glass"), true); + + } + }); + + this.surfaceGenerator = new SurfaceFeatureGenerator(features); + } + + public TestPlanetGenerator getGenerator() { + return parent; + } + + public void generateFeatures(ChunkData chunk) { + if (isOrdinaryChunk(chunk.getPosition())) { + generateOrdinaryFeatures(chunk); + } else { + generateBorderFeatures(chunk); + } + } + + private boolean isOrdinaryChunk(Vec3i chunkPos) { + Vec3i sorted = VectorUtil.sortAfterAbs(chunkPos, null); + return sorted.x != sorted.y; + } + + private void generateOrdinaryFeatures(ChunkData chunk) { + surfaceGenerator.generateFeatures(chunk); + } + + private void generateBorderFeatures(ChunkData chunk) { + // Do nothing + chunk.setGenerationHint(true); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 3f548e9..7206edc 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -38,7 +38,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { private final Planet planet; private final PlanetTerrainGenerator terrainGenerator; - private final PlanetScatterGenerator scatterGenerator; + private final PlanetFeatureGenerator featureGenerator; public TestPlanetGenerator(String id, Planet planet, WorldLogic world) { super(id, Boolean.class, "Test:PlanetGravityModel"); @@ -50,7 +50,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { model.configure(planet.getGravityModelSettings()); this.terrainGenerator = new PlanetTerrainGenerator(this); - this.scatterGenerator = new PlanetScatterGenerator(this); + this.featureGenerator = new PlanetFeatureGenerator(this); } /** @@ -86,7 +86,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { ChunkData chunk = world.getChunk(chunkPos); if (!isChunkReady(chunk.getGenerationHint())) { - scatterGenerator.generateScatter(chunk); + featureGenerator.generateFeatures(chunk); } return chunk; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java similarity index 76% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java rename to src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index a9f08d9..649b414 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceScatterGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -17,12 +17,17 @@ */ package ru.windcorp.progressia.test.gen.surface; +import java.util.Random; + +import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; -public class SurfaceScatterGenerator { - - public void generateScatter(ChunkData chunk) { - chunk.setGenerationHint(true); +public abstract class SurfaceFeature extends Namespaced { + + public SurfaceFeature(String id) { + super(id); } + + public abstract void process(ChunkData chunk, Random random); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java similarity index 51% rename from src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java rename to src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java index a2af1d4..753256a 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetScatterGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java @@ -15,30 +15,31 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.planet; +package ru.windcorp.progressia.test.gen.surface; -import glm.vec._3.i.Vec3i; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; + +import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.test.gen.surface.SurfaceScatterGenerator; -public class PlanetScatterGenerator { +public class SurfaceFeatureGenerator { - private final TestPlanetGenerator parent; - private final SurfaceScatterGenerator surfaceGenerator; - - public PlanetScatterGenerator(TestPlanetGenerator generator) { - this.parent = generator; - this.surfaceGenerator = new SurfaceScatterGenerator(); + private final Collection features; // TODO make ordered + + public SurfaceFeatureGenerator(Collection features) { + this.features = new ArrayList<>(features); } - public TestPlanetGenerator getGenerator() { - return parent; - } - - public void generateScatter(ChunkData chunk) { - chunk.setBlock(new Vec3i(8, 8, 8), BlockDataRegistry.getInstance().get("Test:Log"), false); - surfaceGenerator.generateScatter(chunk); + public void generateFeatures(ChunkData chunk) { + Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); + + for (SurfaceFeature feature : features) { + feature.process(chunk, random); + } + + chunk.setGenerationHint(true); } } From 3c3f3816df85b4dc214b1c871f1d30e7a65aeceb Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 2 Apr 2021 21:51:52 +0300 Subject: [PATCH 20/63] Fixed a generation issue and refactored some code around WorldGenerators - ChunkRequestDaemon now attempts to generate requested loaded non-ready chunks upon discovery - The server is now only specified once for WorldGenerator - WorldLogic now actively checks the generation contract --- .../ru/windcorp/progressia/server/Server.java | 2 +- .../management/load/ChunkRequestDaemon.java | 13 +++++- .../progressia/server/world/WorldLogic.java | 40 +++++++++++++++++-- .../generation/AbstractWorldGenerator.java | 23 ++++++++++- .../world/generation/WorldGenerator.java | 8 +++- .../test/gen/TestWorldGenerator.java | 16 ++++---- .../gen/planet/PlanetTerrainGenerator.java | 5 +-- .../test/gen/planet/TestPlanetGenerator.java | 27 +++++-------- 8 files changed, 98 insertions(+), 36 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index d4d1883..63435a1 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -72,7 +72,7 @@ public class Server { this.world = new WorldLogic( world, this, - w -> new TestPlanetGenerator("Test:PlanetGenerator", new Planet(4, 9.8f, 16f, 16f), w) + new TestPlanetGenerator("Test:PlanetGenerator", this, new Planet(4, 9.8f, 16f, 16f)) ); this.serverThread = new ServerThread(this); diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java index 502f68f..f720c7f 100644 --- a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkRequestDaemon.java @@ -41,6 +41,7 @@ public class ChunkRequestDaemon { private final ChunkSet loaded; private final ChunkSet requested = ChunkSets.newHashSet(); private final ChunkSet toLoad = ChunkSets.newHashSet(); + private final ChunkSet toGenerate = ChunkSets.newHashSet(); private final ChunkSet toRequestUnload = ChunkSets.newHashSet(); private final Collection buffer = new ArrayList<>(); @@ -118,6 +119,9 @@ public class ChunkRequestDaemon { toLoad.forEach(getChunkManager()::loadOrGenerateChunk); toLoad.clear(); + toGenerate.forEach(getChunkManager()::loadOrGenerateChunk); + toGenerate.clear(); + unloadScheduledChunks(); } @@ -161,10 +165,15 @@ public class ChunkRequestDaemon { private void sendChunks(PlayerVision vision) { vision.getRequestedChunks().forEachIn(getServer().getWorld(), chunk -> { - if (!chunk.isReady()) + if (!chunk.isReady()) { + toGenerate.add(chunk); return; - if (vision.isChunkVisible(chunk.getPosition())) + } + + if (vision.isChunkVisible(chunk.getPosition())) { return; + } + buffer.add(chunk.getPosition()); }); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 5931e34..4111646 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -21,9 +21,10 @@ package ru.windcorp.progressia.server.world; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.function.Function; +import glm.Glm; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.ChunkDataListeners; import ru.windcorp.progressia.common.world.WorldData; @@ -52,11 +53,11 @@ public class WorldLogic private final Evaluation tickEntitiesTask = new TickEntitiesTask(); - public WorldLogic(WorldData data, Server server, Function worldGeneratorConstructor) { + public WorldLogic(WorldData data, Server server, WorldGenerator generator) { this.data = data; this.server = server; - this.generator = worldGeneratorConstructor.apply(this); + this.generator = generator; data.setGravityModel(getGenerator().getGravityModel()); data.addListener(new WorldDataListener() { @@ -106,7 +107,38 @@ public class WorldLogic } public ChunkData generate(Vec3i chunkPos) { - return getGenerator().generate(chunkPos, getData()); + ChunkData chunk = getGenerator().generate(chunkPos); + + if (!Glm.equals(chunkPos, chunk.getPosition())) { + throw CrashReports.report(null, "Generator %s has generated a chunk at (%d; %d; %d) when requested to generate a chunk at (%d; %d; %d)", + getGenerator(), + chunk.getX(), chunk.getY(), chunk.getZ(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } + + if (getData().getChunk(chunk.getPosition()) != chunk) { + if (isChunkLoaded(chunkPos)) { + throw CrashReports.report(null, "Generator %s has returned a chunk different to the chunk that is located at (%d; %d; %d)", + getGenerator(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } else { + throw CrashReports.report(null, "Generator %s has returned a chunk that is not loaded when requested to generate a chunk at (%d; %d; %d)", + getGenerator(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } + } + + if (!getChunk(chunk).isReady()) { + throw CrashReports.report(null, "Generator %s has returned a chunk that is not ready when requested to generate a chunk at (%d; %d; %d)", + getGenerator(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } + + return chunk; } public ChunkLogic getChunk(ChunkData chunkData) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index 6856887..e765d85 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -27,17 +27,23 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.GravityModelRegistry; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.WorldLogic; public abstract class AbstractWorldGenerator extends WorldGenerator { private final Class hintClass; private final GravityModel gravityModel; + + private final Server server; - public AbstractWorldGenerator(String id, Class hintClass, String gravityModelId) { + public AbstractWorldGenerator(String id, Server server, Class hintClass, String gravityModelId) { super(id); this.hintClass = Objects.requireNonNull(hintClass, "hintClass"); this.gravityModel = GravityModelRegistry.getInstance().create(Objects.requireNonNull(gravityModelId, "gravityModelId")); + this.server = server; if (this.gravityModel == null) { throw new IllegalArgumentException("Gravity model with ID \"" + gravityModelId + "\" not found"); @@ -77,5 +83,20 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { public GravityModel getGravityModel() { return gravityModel; } + + @Override + public Server getServer() { + return server; + } + + @Override + public WorldLogic getWorldLogic() { + return server.getWorld(); + } + + @Override + public WorldData getWorldData() { + return server.getWorld().getData(); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index f31cbc4..f05674d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -29,6 +29,8 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.WorldLogic; public abstract class WorldGenerator extends Namespaced { @@ -37,7 +39,7 @@ public abstract class WorldGenerator extends Namespaced { // package-private constructor; extend AbstractWorldGeneration } - public abstract ChunkData generate(Vec3i chunkPos, WorldData world); + public abstract ChunkData generate(Vec3i chunkPos); public abstract Object readGenerationHint(DataInputStream input) throws IOException, DecodingException; @@ -48,5 +50,9 @@ public abstract class WorldGenerator extends Namespaced { public abstract GravityModel getGravityModel(); public abstract Vec3 suggestSpawnLocation(); + + public abstract Server getServer(); + public abstract WorldLogic getWorldLogic(); + public abstract WorldData getWorldData(); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 8e0195a..e8c8641 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -37,18 +37,18 @@ import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; public class TestWorldGenerator extends AbstractWorldGenerator { private final TestTerrainGenerator terrainGen; - public TestWorldGenerator(WorldLogic world) { - super("Test:WorldGenerator", Boolean.class, "Test:TheGravityModel"); - this.terrainGen = new TestTerrainGenerator(this, world); + public TestWorldGenerator(Server server) { + super("Test:WorldGenerator", server, Boolean.class, "Test:TheGravityModel"); + this.terrainGen = new TestTerrainGenerator(this, server.getWorld()); - world.getData().addListener(new WorldDataListener() { + getWorldData().addListener(new WorldDataListener() { @Override public void onChunkLoaded(WorldData world, ChunkData chunk) { findAndPopulate(chunk.getPosition(), world); @@ -77,9 +77,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } @Override - public ChunkData generate(Vec3i chunkPos, WorldData world) { - ChunkData chunk = generateUnpopulated(chunkPos, world); - world.addChunk(chunk); + public ChunkData generate(Vec3i chunkPos) { + ChunkData chunk = generateUnpopulated(chunkPos, getWorldData()); + getWorldData().addChunk(chunk); return chunk; } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index 5948b92..bd144a9 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -24,7 +24,6 @@ import ru.windcorp.progressia.common.util.FloatRangeMap; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.test.gen.TerrainLayer; @@ -61,8 +60,8 @@ class PlanetTerrainGenerator { return parent; } - public ChunkData generateTerrain(Vec3i chunkPos, WorldData world) { - ChunkData chunk = new ChunkData(chunkPos, world); + public ChunkData generateTerrain(Vec3i chunkPos) { + ChunkData chunk = new ChunkData(chunkPos, getGenerator().getWorldData()); if (isOrdinaryChunk(chunkPos)) { generateOrdinaryTerrain(chunk); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 7206edc..82f0f55 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -26,24 +26,19 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; public class TestPlanetGenerator extends AbstractWorldGenerator { - private final Server server; - private final Planet planet; private final PlanetTerrainGenerator terrainGenerator; private final PlanetFeatureGenerator featureGenerator; - public TestPlanetGenerator(String id, Planet planet, WorldLogic world) { - super(id, Boolean.class, "Test:PlanetGravityModel"); + public TestPlanetGenerator(String id, Server server, Planet planet) { + super(id, server, Boolean.class, "Test:PlanetGravityModel"); - this.server = world.getServer(); this.planet = planet; TestPlanetGravityModel model = (TestPlanetGravityModel) this.getGravityModel(); @@ -81,9 +76,9 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { } @Override - public ChunkData generate(Vec3i chunkPos, WorldData world) { - VectorUtil.iterateCuboidAround(chunkPos, 3, r -> conjureTerrain(r, world)); - ChunkData chunk = world.getChunk(chunkPos); + public ChunkData generate(Vec3i chunkPos) { + VectorUtil.iterateCuboidAround(chunkPos, 3, r -> conjureTerrain(r)); + ChunkData chunk = getWorldData().getChunk(chunkPos); if (!isChunkReady(chunk.getGenerationHint())) { featureGenerator.generateFeatures(chunk); @@ -92,17 +87,17 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { return chunk; } - private void conjureTerrain(Vec3i chunkPos, WorldData world) { - ChunkData chunk = world.getChunk(chunkPos); + private void conjureTerrain(Vec3i chunkPos) { + ChunkData chunk = getWorldData().getChunk(chunkPos); if (chunk == null) { - server.getLoadManager().getChunkManager().loadChunk(chunkPos); - chunk = world.getChunk(chunkPos); + getServer().getLoadManager().getChunkManager().loadChunk(chunkPos); + chunk = getWorldData().getChunk(chunkPos); } if (chunk == null) { - chunk = terrainGenerator.generateTerrain(chunkPos, world); - world.addChunk(chunk); + chunk = terrainGenerator.generateTerrain(chunkPos); + getWorldData().addChunk(chunk); } } From 2532e80f6a56d9a1daa2fe5760003ccfb614e7b2 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 5 Apr 2021 17:30:37 +0300 Subject: [PATCH 21/63] Moved some methods from ChunkData to GenericChunk - Moved some method definitions from ChunkData to GenericChunk - Moved some method definitions from ChunkData to GenericWritableChunk - Refactored GenericChunk including changing some method signatures - Added some documentation for GenericChunk --- .../client/world/ChunkRenderModel.java | 3 +- .../cro/ChunkRenderOptimizerSurface.java | 5 +- .../progressia/common/world/ChunkData.java | 61 +---- .../common/world/generic/GenericChunk.java | 236 ++++++++++-------- .../world/generic/GenericWritableChunk.java | 31 +++ .../progressia/common/world/generic/Util.java | 53 ++++ .../server/world/ChunkTickContext.java | 3 +- .../progressia/test/TestChunkCodec.java | 7 +- .../gen/planet/PlanetTerrainGenerator.java | 3 +- 9 files changed, 233 insertions(+), 169 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/Util.java diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 75857b8..46a3f28 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -36,6 +36,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -76,7 +77,7 @@ public class ChunkRenderModel implements Renderable { optimizers.forEach(ChunkRenderOptimizer::startRender); - chunk.forEachBiC(relBlockInChunk -> { + GenericChunk.forEachBiC(relBlockInChunk -> { processBlockAndTiles(relBlockInChunk, sink); }); diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index f30b91c..5ede1ef 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -38,6 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.RelFace; public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @@ -216,7 +217,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { Consumer consumer = shapeParts::add; - chunk.forEachBiC(relBlockInChunk -> { + GenericChunk.forEachBiC(relBlockInChunk -> { processInnerFaces(relBlockInChunk, consumer); processOuterFaces(relBlockInChunk, consumer); }); @@ -315,7 +316,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } private boolean shouldRenderWhenFacing(Vec3i relBlockInChunk, RelFace face) { - if (chunk.containsBiC(relBlockInChunk)) { + if (GenericChunk.containsBiC(relBlockInChunk)) { return shouldRenderWhenFacingLocal(relBlockInChunk, face); } else { return shouldRenderWhenFacingNeighbor(relBlockInChunk, face); diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 5788053..54b922d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -25,14 +25,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Objects; -import java.util.function.BiConsumer; -import java.util.function.Consumer; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; + import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericWritableChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -42,7 +41,7 @@ import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; public class ChunkData - implements GenericChunk { + implements GenericWritableChunk { public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; @@ -83,6 +82,7 @@ public class ChunkData return blocks[getBlockIndex(posInChunk)]; } + @Override public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) { BlockData previous = blocks[getBlockIndex(posInChunk)]; blocks[getBlockIndex(posInChunk)] = block; @@ -95,6 +95,7 @@ public class ChunkData } } + @Override public void setBlockRel(Vec3i relativeBlockInChunk, BlockData block, boolean notify) { Vec3i absoluteBlockInChunk = Vectors.grab3i(); resolve(relativeBlockInChunk, absoluteBlockInChunk); @@ -168,7 +169,7 @@ public class ChunkData } private static void checkLocalCoordinates(Vec3i posInChunk) { - if (!isInBounds(posInChunk)) { + if (!GenericChunk.containsBiC(posInChunk)) { throw new IllegalCoordinatesException( "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " + "are not legal chunk coordinates" @@ -176,56 +177,6 @@ public class ChunkData } } - public static boolean isInBounds(Vec3i posInChunk) { - return posInChunk.x >= 0 && posInChunk.x < BLOCKS_PER_CHUNK && - posInChunk.y >= 0 && posInChunk.y < BLOCKS_PER_CHUNK && - posInChunk.z >= 0 && posInChunk.z < BLOCKS_PER_CHUNK; - } - - public boolean isBorder(Vec3i blockInChunk, BlockFace face) { - final int min = 0, max = BLOCKS_PER_CHUNK - 1; - AbsFace absFace = face.resolve(getUp()); - return (blockInChunk.x == min && absFace == AbsFace.NEG_X) || - (blockInChunk.x == max && absFace == AbsFace.POS_X) || - (blockInChunk.y == min && absFace == AbsFace.NEG_Y) || - (blockInChunk.y == max && absFace == AbsFace.POS_Y) || - (blockInChunk.z == min && absFace == AbsFace.NEG_Z) || - (blockInChunk.z == max && absFace == AbsFace.POS_Z); - } - - public void forEachBlock(Consumer action) { - VectorUtil.iterateCuboid( - 0, - 0, - 0, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - action - ); - } - - public void forEachTileStack(Consumer action) { - forEachBlock(blockInChunk -> { - for (AbsFace face : AbsFace.getFaces()) { - TileDataStack stack = getTilesOrNull(blockInChunk, face); - if (stack == null) - continue; - action.accept(stack); - } - }); - } - - /** - * Iterates over all tiles in this chunk. - * - * @param action the action to perform. {@code TileLocation} refers to each - * tile using its primary block - */ - public void forEachTile(BiConsumer action) { - forEachTileStack(stack -> stack.forEach(tileData -> action.accept(stack, tileData))); - } - public WorldData getWorld() { return world; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index fa80269..e51ac02 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -15,9 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; +import java.util.function.BiConsumer; import java.util.function.Consumer; import glm.Glm; @@ -29,37 +30,90 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.BlockFace; +/** + * An unmodifiable chunk representation. Per default, it is usually one of + * {@link ru.windcorp.progressia.common.world.ChunkData ChunkData}, + * {@link ru.windcorp.progressia.client.world.ChunkRender ChunkRender} or + * {@link ru.windcorp.progressia.server.world.ChunkLogic ChunkLogic}, but this + * interface may be implemented differently for various reasons. + *

    + * A generic chunk contains {@linkplain GenericBlock blocks} and + * {@linkplain GenericTileStack tile stacks} and is characterized by its + * location. It also bears a discrete up direction. Note that no + * {@linkplain GenericWorld world} object is directly accessible through this + * interface. + *

    + * This interface defines the most common methods for examining a chunk and + * implements many of them as default methods. It also contains several static + * methods useful when dealing with chunks. {@code GenericChunk} does not + * provide a way to modify a chunk; use {@link GenericWritableChunk} methods + * when applicable. + * + * @param a reference to itself (required to properly reference a + * {@link GenericTileStack}) + * @param block type + * @param tile type + * @param tile stack type + * @author javapony + */ public interface GenericChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> { + /** + * The count of blocks in a side of a chunk. This is guaranteed to be a + * power of two. This is always equal to {@link Coordinates#CHUNK_SIZE}. + */ public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; + /* + * Abstract methods + */ + + /** + * Returns the position of this chunk in {@linkplain Coordinates#chunk + * coordinates of chunk}. The returned object must not be modified. + * + * @return this chunk's position + */ Vec3i getPosition(); - + + /** + * Returns the discrete up direction for this chunk. + * + * @return this chunk's discrete up direction + */ AbsFace getUp(); + /** + * Retrieves the block at the location specified by its + * {@linkplain Coordinates#blockInChunk chunk coordinates}. During chunk + * generation it may be {@code null}. + * + * @param blockInChunk local coordinates of the block to fetch + * @return the block at the requested location or {@code null}. + */ B getBlock(Vec3i blockInChunk); TS getTiles(Vec3i blockInChunk, BlockFace face); boolean hasTiles(Vec3i blockInChunk, BlockFace face); - + default Vec3i resolve(Vec3i relativeBlockInChunk, Vec3i output) { if (output == null) { output = new Vec3i(); } - + final int offset = BLOCKS_PER_CHUNK - 1; - + output.set(relativeBlockInChunk.x, relativeBlockInChunk.y, relativeBlockInChunk.z); output.mul(2).sub(offset); - + AxisRotations.resolve(output, getUp(), output); - + output.add(offset).div(2); - + return output; } - + default B getBlockRel(Vec3i relativeBlockInChunk) { Vec3i absoluteBlockInChunk = Vectors.grab3i(); resolve(relativeBlockInChunk, absoluteBlockInChunk); @@ -67,7 +121,7 @@ public interface GenericChunk, B exten Vectors.release(absoluteBlockInChunk); return result; } - + default TS getTilesRel(Vec3i relativeBlockInChunk, BlockFace face) { Vec3i absoluteBlockInChunk = Vectors.grab3i(); resolve(relativeBlockInChunk, absoluteBlockInChunk); @@ -75,7 +129,7 @@ public interface GenericChunk, B exten Vectors.release(absoluteBlockInChunk); return result; } - + default boolean hasTilesRel(Vec3i relativeBlockInChunk, BlockFace face) { Vec3i absoluteBlockInChunk = Vectors.grab3i(); resolve(relativeBlockInChunk, absoluteBlockInChunk); @@ -83,7 +137,7 @@ public interface GenericChunk, B exten Vectors.release(absoluteBlockInChunk); return result; } - + default int getX() { return getPosition().x; } @@ -119,150 +173,100 @@ public interface GenericChunk, B exten default int getMaxZ() { return Coordinates.getInWorld(getZ(), BLOCKS_PER_CHUNK - 1); } - + default Vec3i getMinBIW(Vec3i output) { if (output == null) { output = new Vec3i(); } - + output.set(getMinX(), getMinY(), getMinZ()); - + return output; } - + default Vec3i getMaxBIW(Vec3i output) { if (output == null) { output = new Vec3i(); } - + output.set(getMaxX(), getMaxY(), getMaxZ()); - + return output; } - + default Vec3i getMinBIWRel(Vec3i output) { if (output == null) { output = new Vec3i(); } - + Vec3i absMin = getMinBIW(Vectors.grab3i()); Vec3i absMax = getMaxBIW(Vectors.grab3i()); - + AxisRotations.relativize(absMin, getUp(), absMin); AxisRotations.relativize(absMax, getUp(), absMax); - + Glm.min(absMin, absMax, output); - + Vectors.release(absMax); Vectors.release(absMin); - + return output; } - + default Vec3i getMaxBIWRel(Vec3i output) { if (output == null) { output = new Vec3i(); } - + Vec3i absMin = getMinBIW(Vectors.grab3i()); Vec3i absMax = getMaxBIW(Vectors.grab3i()); - + AxisRotations.relativize(absMin, getUp(), absMin); AxisRotations.relativize(absMax, getUp(), absMax); - + Glm.max(absMin, absMax, output); - + Vectors.release(absMax); Vectors.release(absMin); - + return output; } - default boolean containsBiC(Vec3i blockInChunk) { + public static boolean containsBiC(Vec3i blockInChunk) { return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK && blockInChunk.y >= 0 && blockInChunk.y < BLOCKS_PER_CHUNK && blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK; } + public static boolean isSurfaceBiC(Vec3i blockInChunk) { + return Util.getBorderHits(blockInChunk) >= 1; + } + + public static boolean isEdgeBiC(Vec3i blockInChunk) { + return Util.getBorderHits(blockInChunk) >= 2; + } + + public static boolean isVertexBiC(Vec3i blockInChunk) { + return Util.getBorderHits(blockInChunk) == 3; + } + default boolean containsBiW(Vec3i blockInWorld) { - Vec3i v = Vectors.grab3i(); - - v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v); - v = blockInWorld.sub(v, v); - - boolean result = containsBiC(v); - - Vectors.release(v); - return result; + return Util.testBiC(blockInWorld, this, GenericChunk::containsBiC); } - - default boolean isSurfaceBiC(Vec3i blockInChunk) { - int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - - return hits >= 1; - } - + default boolean isSurfaceBiW(Vec3i blockInWorld) { - Vec3i v = Vectors.grab3i(); - - v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v); - v = blockInWorld.sub(v, v); - - boolean result = isSurfaceBiC(v); - - Vectors.release(v); - return result; + return Util.testBiC(blockInWorld, this, GenericChunk::isSurfaceBiC); } - - default boolean isEdgeBiC(Vec3i blockInChunk) { - int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - - return hits >= 2; - } - + default boolean isEdgeBiW(Vec3i blockInWorld) { - Vec3i v = Vectors.grab3i(); - - v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v); - v = blockInWorld.sub(v, v); - - boolean result = isEdgeBiC(v); - - Vectors.release(v); - return result; + return Util.testBiC(blockInWorld, this, GenericChunk::isEdgeBiC); } - - default boolean isVertexBiC(Vec3i blockInChunk) { - int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - - return hits == 3; - } - + default boolean isVertexBiW(Vec3i blockInWorld) { - Vec3i v = Vectors.grab3i(); - - v = Coordinates.getInWorld(getPosition(), Vectors.ZERO_3i, v); - v = blockInWorld.sub(v, v); - - boolean result = isVertexBiC(v); - - Vectors.release(v); - return result; + return Util.testBiC(blockInWorld, this, GenericChunk::isVertexBiC); } - default void forEachBiC(Consumer action) { + public static void forEachBiC(Consumer action) { VectorUtil.iterateCuboid( 0, 0, @@ -293,22 +297,42 @@ public interface GenericChunk, B exten return null; } - + default TS getTilesOrNullRel(Vec3i relativeBlockInChunk, BlockFace face) { Vec3i absoluteBlockInChunk = Vectors.grab3i(); resolve(relativeBlockInChunk, absoluteBlockInChunk); - + TS result; - + if (hasTiles(absoluteBlockInChunk, face)) { result = getTiles(absoluteBlockInChunk, face); } else { result = null; } - + Vectors.release(absoluteBlockInChunk); - + return result; } + default void forEachTileStack(Consumer action) { + forEachBiC(blockInChunk -> { + for (AbsFace face : AbsFace.getFaces()) { + TS stack = getTilesOrNull(blockInChunk, face); + if (stack == null) + continue; + action.accept(stack); + } + }); + } + + /** + * Iterates over all tiles in this chunk. + * + * @param action the action to perform + */ + default void forEachTile(BiConsumer action) { + forEachTileStack(stack -> stack.forEach(tileData -> action.accept(stack, tileData))); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java new file mode 100644 index 0000000..9dc1557 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java @@ -0,0 +1,31 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic; + +import glm.vec._3.i.Vec3i; + +import ru.windcorp.progressia.common.world.block.BlockData; + +public interface GenericWritableChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> + extends GenericChunk { + + void setBlock(Vec3i posInChunk, BlockData block, boolean notify); + + void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java b/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java new file mode 100644 index 0000000..8f6f79f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java @@ -0,0 +1,53 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic; + +import java.util.function.Predicate; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.Coordinates; + +class Util { + + public static int getBorderHits(Vec3i blockInChunk) { + int hits = 0; + + if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; + + return hits; + } + + public static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { + Vec3i v = Vectors.grab3i(); + + v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v); + v = blockInWorld.sub(v, v); + + boolean result = test.test(v); + + Vectors.release(v); + + return result; + } + + + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java index d32503d..0480a6e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java @@ -22,6 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.world.block.BlockTickContext; @@ -45,7 +46,7 @@ public interface ChunkTickContext extends TickContext { default void forEachBlock(Consumer action) { TickContextMutable context = TickContextMutable.uninitialized(); - getChunkData().forEachBlock(blockInChunk -> { + GenericChunk.forEachBiC(blockInChunk -> { context.rebuild().withServer(getServer()).withChunk(getChunk()).withBlockInChunk(blockInChunk).build(); action.accept(context); }); diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index 9e94d64..050b94e 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -38,6 +38,7 @@ import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.io.ChunkCodec; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; @@ -124,7 +125,7 @@ public class TestChunkCodec extends ChunkCodec { private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException { try { - chunk.forEachBiC(guard(v -> { + GenericChunk.forEachBiC(guard(v -> { chunk.setBlock(v, blockPalette[input.readInt()], false); })); } catch (UncheckedIOException e) { @@ -171,7 +172,7 @@ public class TestChunkCodec extends ChunkCodec { private Palette createBlockPalette(ChunkData chunk) { Palette blockPalette = new Palette<>(); - chunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); + GenericChunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); return blockPalette; } @@ -199,7 +200,7 @@ public class TestChunkCodec extends ChunkCodec { private void writeBlocks(ChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { try { - chunk.forEachBiC(guard(v -> { + GenericChunk.forEachBiC(guard(v -> { output.writeInt(blockPalette.getNid(chunk.getBlock(v))); })); } catch (UncheckedIOException e) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index bd144a9..a5b086f 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -26,6 +26,7 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.test.gen.TerrainLayer; import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField; import ru.windcorp.progressia.test.gen.surface.SurfaceTerrainGenerator; @@ -89,7 +90,7 @@ class PlanetTerrainGenerator { Vec3 biw = new Vec3(); - chunk.forEachBiC(bic -> { + GenericChunk.forEachBiC(bic -> { biw.set( Coordinates.getInWorld(chunk.getX(), bic.x), From e0a03cad1d2725a086178e780da9ae8bc0ac229f Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Tue, 6 Apr 2021 00:36:38 +0300 Subject: [PATCH 22/63] More refactoring of GenericChunk and pals - Genericized TileReference - Unified template arguments --- .../progressia/client/world/ChunkRender.java | 41 ++++- .../progressia/client/world/WorldRender.java | 3 +- .../world/tile/TileRenderReference.java | 27 +++ .../client/world/tile/TileRenderStack.java | 3 +- .../progressia/common/world/ChunkData.java | 16 +- .../progressia/common/world/WorldData.java | 3 +- .../common/world/generic/ChunkMap.java | 16 +- .../common/world/generic/ChunkMaps.java | 16 +- .../common/world/generic/ChunkSet.java | 18 +- .../common/world/generic/ChunkSets.java | 18 +- .../common/world/generic/GenericChunk.java | 10 +- .../world/generic/GenericTileReference.java | 41 +++++ .../world/generic/GenericTileStack.java | 22 ++- .../common/world/generic/GenericWorld.java | 11 +- .../world/generic/GenericWritableChunk.java | 16 +- .../generic/GenericWritableTileStack.java | 160 ++++++++++++++++++ .../world/generic/LongBasedChunkSet.java | 2 +- .../progressia/common/world/generic/Util.java | 2 +- ...eReference.java => TileDataReference.java} | 14 +- .../common/world/tile/TileDataStack.java | 142 +--------------- .../progressia/server/world/ChunkLogic.java | 46 ++++- .../server/world/TickContextMutable.java | 8 +- .../progressia/server/world/WorldLogic.java | 3 +- .../server/world/tile/TileLogicReference.java | 27 +++ .../server/world/tile/TileLogicStack.java | 3 +- .../server/world/tile/TileTickContext.java | 4 +- 26 files changed, 452 insertions(+), 220 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java rename src/main/java/ru/windcorp/progressia/common/world/tile/{TileReference.java => TileDataReference.java} (71%) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index ca58bf7..c69fcf3 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -27,6 +27,7 @@ import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.block.BlockRenderRegistry; import ru.windcorp.progressia.client.world.tile.TileRender; +import ru.windcorp.progressia.client.world.tile.TileRenderReference; import ru.windcorp.progressia.client.world.tile.TileRenderRegistry; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; @@ -34,10 +35,11 @@ import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileDataReference; import ru.windcorp.progressia.common.world.tile.TileDataStack; public class ChunkRender - implements GenericChunk { + implements GenericChunk { private final WorldRender world; private final ChunkData data; @@ -108,6 +110,28 @@ public class ChunkRender } private class TileRenderStackImpl extends TileRenderStack { + private class TileRenderReferenceImpl implements TileRenderReference { + private final TileDataReference parent; + + public TileRenderReferenceImpl(TileDataReference parent) { + this.parent = parent; + } + + @Override + public TileRender get() { + return TileRenderRegistry.getInstance().get(parent.get().getId()); + } + + @Override + public int getIndex() { + return parent.getIndex(); + } + + @Override + public TileRenderStack getStack() { + return TileRenderStackImpl.this; + } + } private final TileDataStack parent; @@ -129,6 +153,21 @@ public class ChunkRender public RelFace getFace() { return parent.getFace(); } + + @Override + public TileRenderReference getReference(int index) { + return new TileRenderReferenceImpl(parent.getReference(index)); + } + + @Override + public int getIndexByTag(int tag) { + return parent.getIndexByTag(tag); + } + + @Override + public int getTagByIndex(int index) { + return parent.getTagByIndex(index); + } @Override public TileRender get(int index) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java index 8be08c2..2e674f0 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java @@ -34,6 +34,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry; import ru.windcorp.progressia.client.world.entity.EntityRenderable; import ru.windcorp.progressia.client.world.tile.TileRender; +import ru.windcorp.progressia.client.world.tile.TileRenderReference; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; @@ -47,7 +48,7 @@ import ru.windcorp.progressia.common.world.generic.ChunkSets; import ru.windcorp.progressia.common.world.generic.GenericWorld; public class WorldRender - implements GenericWorld { + implements GenericWorld { private final WorldData data; private final Client client; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java new file mode 100644 index 0000000..3def556 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java @@ -0,0 +1,27 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.client.world.tile; + +import ru.windcorp.progressia.client.world.ChunkRender; +import ru.windcorp.progressia.client.world.block.BlockRender; +import ru.windcorp.progressia.common.world.generic.GenericTileReference; + +public interface TileRenderReference + extends GenericTileReference { + +} diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java index 6bb8fb0..ca95cd2 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java @@ -19,11 +19,12 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.world.ChunkRender; +import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.common.world.generic.GenericTileStack; import ru.windcorp.progressia.common.world.tile.TileDataStack; public abstract class TileRenderStack - extends GenericTileStack { + extends GenericTileStack { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 54b922d..9a00e25 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -36,12 +36,12 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileDataReference; import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; public class ChunkData - implements GenericWritableChunk { + implements GenericWritableChunk { public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; @@ -219,10 +219,10 @@ public class ChunkData * @author javapony */ private class TileDataStackImpl extends TileDataStack { - private class TileReferenceImpl implements TileReference { + private class TileDataReferenceImpl implements TileDataReference { private int index; - public TileReferenceImpl(int index) { + public TileDataReferenceImpl(int index) { this.index = index; } @@ -264,7 +264,7 @@ public class ChunkData private final TileData[] tiles = new TileData[TILES_PER_FACE]; private int size = 0; - private final TileReferenceImpl[] references = new TileReferenceImpl[tiles.length]; + private final TileDataReferenceImpl[] references = new TileDataReferenceImpl[tiles.length]; private final int[] indicesByTag = new int[tiles.length]; private final int[] tagsByIndex = new int[tiles.length]; @@ -437,11 +437,11 @@ public class ChunkData } @Override - public TileReference getReference(int index) { + public TileDataReference getReference(int index) { checkIndex(index, false); if (references[index] == null) { - references[index] = new TileReferenceImpl(index); + references[index] = new TileDataReferenceImpl(index); } return references[index]; @@ -500,7 +500,7 @@ public class ChunkData throw new AssertionError("get(index) is null"); if (references[index] != null) { - TileReference ref = getReference(index); + TileDataReference ref = getReference(index); if (ref == null) throw new AssertionError("references[index] is not null but getReference(index) is"); if (!ref.isValid()) diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 625b8c2..7fec468 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -38,9 +38,10 @@ import ru.windcorp.progressia.common.world.generic.GenericWorld; import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.tile.TileDataReference; public class WorldData - implements GenericWorld { + implements GenericWorld { private final ChunkMap chunksByPos = new LongBasedChunkMap<>( TCollections.synchronizedMap(new TLongObjectHashMap<>()) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java index 6c35781..5b4f6f6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java @@ -77,27 +77,27 @@ public interface ChunkMap { // TODO implement (int, int, int) and GenericChunk versions of all of the // above - default boolean containsChunk(GenericChunk chunk) { + default boolean containsChunk(GenericChunk chunk) { return containsKey(chunk.getPosition()); } - default V get(GenericChunk chunk) { + default V get(GenericChunk chunk) { return get(chunk.getPosition()); } - default V put(GenericChunk chunk, V obj) { + default V put(GenericChunk chunk, V obj) { return put(chunk.getPosition(), obj); } - default V remove(GenericChunk chunk) { + default V remove(GenericChunk chunk) { return remove(chunk.getPosition()); } - default V getOrDefault(GenericChunk chunk, V def) { + default V getOrDefault(GenericChunk chunk, V def) { return containsChunk(chunk) ? def : get(chunk); } - default > V compute( + default > V compute( C chunk, BiFunction remappingFunction ) { @@ -128,8 +128,8 @@ public interface ChunkMap { void forEach(BiConsumer action); - default > void forEachIn( - GenericWorld world, + default > void forEachIn( + GenericWorld world, BiConsumer action ) { forEach((pos, value) -> { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java index e67f67e..c194351 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java @@ -174,42 +174,42 @@ public class ChunkMaps { } @Override - public boolean containsChunk(GenericChunk chunk) { + public boolean containsChunk(GenericChunk chunk) { synchronized (mutex) { return parent.containsChunk(chunk); } } @Override - public V get(GenericChunk chunk) { + public V get(GenericChunk chunk) { synchronized (mutex) { return parent.get(chunk); } } @Override - public V put(GenericChunk chunk, V obj) { + public V put(GenericChunk chunk, V obj) { synchronized (mutex) { return parent.put(chunk, obj); } } @Override - public V remove(GenericChunk chunk) { + public V remove(GenericChunk chunk) { synchronized (mutex) { return parent.remove(chunk); } } @Override - public V getOrDefault(GenericChunk chunk, V def) { + public V getOrDefault(GenericChunk chunk, V def) { synchronized (mutex) { return parent.getOrDefault(chunk, def); } } @Override - public > V compute( + public > V compute( C chunk, BiFunction remappingFunction ) { @@ -247,8 +247,8 @@ public class ChunkMaps { } @Override - public > void forEachIn( - GenericWorld world, + public > void forEachIn( + GenericWorld world, BiConsumer action ) { synchronized (mutex) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java index 73c2267..6f26ef0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java @@ -75,20 +75,20 @@ public interface ChunkSet extends Iterable { return result; } - default boolean contains(GenericChunk chunk) { + default boolean contains(GenericChunk chunk) { return contains(chunk.getPosition()); } - default boolean add(GenericChunk chunk) { + default boolean add(GenericChunk chunk) { return add(chunk.getPosition()); } - default boolean remove(GenericChunk chunk) { + default boolean remove(GenericChunk chunk) { return remove(chunk.getPosition()); } - default > void forEachIn( - GenericWorld world, + default > void forEachIn( + GenericWorld world, Consumer action ) { forEach(position -> { @@ -207,7 +207,7 @@ public interface ChunkSet extends Iterable { } } - default boolean containsAllChunks(Iterable> chunks) { + default boolean containsAllChunks(Iterable> chunks) { boolean[] hasMissing = new boolean[] { false }; chunks.forEach(c -> { @@ -219,7 +219,7 @@ public interface ChunkSet extends Iterable { return hasMissing[0]; } - default boolean containsAnyChunks(Iterable> chunks) { + default boolean containsAnyChunks(Iterable> chunks) { boolean[] hasPresent = new boolean[] { false }; chunks.forEach(c -> { @@ -231,11 +231,11 @@ public interface ChunkSet extends Iterable { return hasPresent[0]; } - default void addAllChunks(Iterable> chunks) { + default void addAllChunks(Iterable> chunks) { chunks.forEach(this::add); } - default void removeAllChunks(Iterable> chunks) { + default void removeAllChunks(Iterable> chunks) { chunks.forEach(this::remove); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java index 93413e4..4ee643b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java @@ -198,29 +198,29 @@ public class ChunkSets { } @Override - public boolean contains(GenericChunk chunk) { + public boolean contains(GenericChunk chunk) { synchronized (mutex) { return parent.contains(chunk); } } @Override - public boolean add(GenericChunk chunk) { + public boolean add(GenericChunk chunk) { synchronized (mutex) { return parent.add(chunk); } } @Override - public boolean remove(GenericChunk chunk) { + public boolean remove(GenericChunk chunk) { synchronized (mutex) { return parent.remove(chunk); } } @Override - public > void forEachIn( - GenericWorld world, + public > void forEachIn( + GenericWorld world, Consumer action ) { synchronized (mutex) { @@ -320,28 +320,28 @@ public class ChunkSets { } @Override - public boolean containsAllChunks(Iterable> chunks) { + public boolean containsAllChunks(Iterable> chunks) { synchronized (mutex) { return parent.containsAllChunks(chunks); } } @Override - public boolean containsAnyChunks(Iterable> chunks) { + public boolean containsAnyChunks(Iterable> chunks) { synchronized (mutex) { return parent.containsAnyChunks(chunks); } } @Override - public void addAllChunks(Iterable> chunks) { + public void addAllChunks(Iterable> chunks) { synchronized (mutex) { parent.addAllChunks(chunks); } } @Override - public void removeAllChunks(Iterable> chunks) { + public void removeAllChunks(Iterable> chunks) { synchronized (mutex) { parent.removeAllChunks(chunks); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index e51ac02..281b697 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -56,7 +56,15 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * @param tile stack type * @author javapony */ -public interface GenericChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> { +// @formatter:off +public interface GenericChunk< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericTileStack , + TR extends GenericTileReference , + C extends GenericChunk +> { +// @formatter:on /** * The count of blocks in a side of a chunk. This is guaranteed to be a diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java new file mode 100644 index 0000000..b3e7289 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java @@ -0,0 +1,41 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic; + +// @formatter:off +public interface GenericTileReference< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericTileStack , + TR extends GenericTileReference , + C extends GenericChunk +> { +// @formatter:on + + T get(); + + int getIndex(); + + TS getStack(); + + default boolean isValid() { + return get() != null; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java index a2e8a4d..ddf7e00 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java @@ -27,9 +27,15 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.RelFace; -public abstract class GenericTileStack, T extends GenericTile, C extends GenericChunk> - extends AbstractList - implements RandomAccess { +// @formatter:off +public abstract class GenericTileStack< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericTileStack , + TR extends GenericTileReference , + C extends GenericChunk +> extends AbstractList implements RandomAccess { +// @formatter:on public static interface TSConsumer { void accept(int layer, T tile); @@ -43,6 +49,12 @@ public abstract class GenericTileStack public abstract RelFace getFace(); + public abstract TR getReference(int index); + + public abstract int getIndexByTag(int tag); + + public abstract int getTagByIndex(int index); + public Vec3i getBlockInWorld(Vec3i output) { // This is safe return Coordinates.getInWorld(getChunk().getPosition(), getBlockInChunk(output), output); @@ -105,4 +117,8 @@ public abstract class GenericTileStack return findClosest(id) != null; } + public B getHost() { + return getChunk().getBlock(getBlockInChunk(null)); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java index c71ef54..c945461 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java @@ -29,7 +29,16 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; -public interface GenericWorld, C extends GenericChunk, E extends GenericEntity> { +// @formatter:off +public interface GenericWorld< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericTileStack , + TR extends GenericTileReference , + C extends GenericChunk , + E extends GenericEntity +> { +// @formatter:on Collection getChunks(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java index 9dc1557..baf6cc2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java @@ -19,12 +19,18 @@ package ru.windcorp.progressia.common.world.generic; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.block.BlockData; +// @formatter:off +public interface GenericWritableChunk< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericWritableTileStack , + TR extends GenericTileReference , + C extends GenericWritableChunk +> + extends GenericChunk { +// @formatter:on -public interface GenericWritableChunk, B extends GenericBlock, T extends GenericTile, TS extends GenericTileStack> - extends GenericChunk { - - void setBlock(Vec3i posInChunk, BlockData block, boolean notify); + void setBlock(Vec3i posInChunk, B block, boolean notify); void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java new file mode 100644 index 0000000..b2363e3 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java @@ -0,0 +1,160 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic; + +// @formatter:off +public abstract class GenericWritableTileStack< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericWritableTileStack, + TR extends GenericTileReference, + C extends GenericWritableChunk +> + extends GenericTileStack { +// @formatter:on + + /** + * Inserts the specified tile at the specified position in this stack. + * Shifts the tile currently at that position (if any) and any tiles above + * to + * the top (adds one to their indices). + * + * @param index index at which the specified tile is to be inserted + * @param tile tile to be inserted + * @throws TileStackIsFullException if this stack is {@linkplain #isFull() + * full} + */ + /* + * Impl note: AbstractList provides a useless implementation of this method, + * make sure to override it in subclass + */ + @Override + public abstract void add(int index, T tile); + + /** + * Adds the specified tile at the end of this stack assigning it the + * provided tag. + * This method is useful for copying stacks when preserving tags is + * necessary. + * + * @param tile the tile to add + * @param tag the tag to assign the new tile + * @throws IllegalArgumentException if this stack already contains a tile + * with the + * provided tag + */ + public abstract void load(T tile, int tag); + + /** + * Replaces the tile at the specified position in this stack with the + * specified tile. + * + * @param index index of the tile to replace + * @param tile tile to be stored at the specified position + * @return the tile previously at the specified position + */ + /* + * Impl note: AbstractList provides a useless implementation of this method, + * make sure to override it in subclass + */ + @Override + public abstract T set(int index, T tile); + + /** + * Removes the tile at the specified position in this list. Shifts any + * subsequent tiles + * to the left (subtracts one from their indices). Returns the tile that was + * removed + * from the list. + * + * @param index the index of the tile to be removed + * @return the tile previously at the specified position + */ + /* + * Impl note: AbstractList provides a useless implementation of this method, + * make sure to override it in subclass + */ + @Override + public abstract T remove(int index); + + /* + * Aliases and overloads + */ + + public void addClosest(T tile) { + add(0, tile); + } + + public void addFarthest(T tile) { + add(size(), tile); + } + + /** + * Attempts to {@link #add(int, TileData) add} the provided {@code tile} + * at {@code index}. If the stack is {@linkplain #isFull() full}, does + * nothing. + * + * @param index the index to insert the tile at + * @param tile the tile to try to add + * @return {@code true} iff this stack has changed + */ + public boolean offer(int index, T tile) { + if (isFull()) + return false; + add(index, tile); + return true; + } + + public boolean offerClosest(T tile) { + return offer(0, tile); + } + + public boolean offerFarthest(T tile) { + return offer(size(), tile); + } + + public T removeClosest() { + return remove(0); + } + + public T removeFarthest() { + return remove(size() - 1); + } + + public T poll(int index) { + if (size() <= index) + return null; + return remove(index); + } + + public T pollClosest() { + return poll(0); + } + + public T pollFarthest() { + return poll(size() - 1); + } + + @Override + public boolean add(T tile) { + addFarthest(tile); + return true; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java index cd5a755..11559ca 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java @@ -45,7 +45,7 @@ public class LongBasedChunkSet implements ChunkSet { addAll(copyFrom); } - public LongBasedChunkSet(TLongSet impl, GenericWorld copyFrom) { + public LongBasedChunkSet(TLongSet impl, GenericWorld copyFrom) { this(impl); addAllChunks(copyFrom.getChunks()); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java b/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java index 8f6f79f..f3765d7 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java @@ -35,7 +35,7 @@ class Util { return hits; } - public static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { + public static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { Vec3i v = Vectors.grab3i(); v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java similarity index 71% rename from src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java rename to src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java index 75fde58..b9699c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java @@ -18,16 +18,10 @@ package ru.windcorp.progressia.common.world.tile; -public interface TileReference { +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.GenericTileReference; - TileData get(); - - int getIndex(); - - TileDataStack getStack(); - - default boolean isValid() { - return get() != null; - } +public interface TileDataReference extends GenericTileReference { } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java index 80f0ba4..7e88402 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java @@ -20,147 +20,9 @@ package ru.windcorp.progressia.common.world.tile; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericTileStack; +import ru.windcorp.progressia.common.world.generic.GenericWritableTileStack; public abstract class TileDataStack - extends GenericTileStack { - - /** - * Inserts the specified tile at the specified position in this stack. - * Shifts the tile currently at that position (if any) and any tiles above - * to - * the top (adds one to their indices). - * - * @param index index at which the specified tile is to be inserted - * @param tile tile to be inserted - * @throws TileStackIsFullException if this stack is {@linkplain #isFull() - * full} - */ - /* - * Impl note: AbstractList provides a useless implementation of this method, - * make sure to override it in subclass - */ - @Override - public abstract void add(int index, TileData tile); - - /** - * Adds the specified tile at the end of this stack assigning it the - * provided tag. - * This method is useful for copying stacks when preserving tags is - * necessary. - * - * @param tile the tile to add - * @param tag the tag to assign the new tile - * @throws IllegalArgumentException if this stack already contains a tile - * with the - * provided tag - */ - public abstract void load(TileData tile, int tag); - - /** - * Replaces the tile at the specified position in this stack with the - * specified tile. - * - * @param index index of the tile to replace - * @param tile tile to be stored at the specified position - * @return the tile previously at the specified position - */ - /* - * Impl note: AbstractList provides a useless implementation of this method, - * make sure to override it in subclass - */ - @Override - public abstract TileData set(int index, TileData tile); - - /** - * Removes the tile at the specified position in this list. Shifts any - * subsequent tiles - * to the left (subtracts one from their indices). Returns the tile that was - * removed - * from the list. - * - * @param index the index of the tile to be removed - * @return the tile previously at the specified position - */ - /* - * Impl note: AbstractList provides a useless implementation of this method, - * make sure to override it in subclass - */ - @Override - public abstract TileData remove(int index); - - public abstract TileReference getReference(int index); - - public abstract int getIndexByTag(int tag); - - public abstract int getTagByIndex(int index); - - /* - * Aliases and overloads - */ - - public void addClosest(TileData tile) { - add(0, tile); - } - - public void addFarthest(TileData tile) { - add(size(), tile); - } - - /** - * Attempts to {@link #add(int, TileData) add} the provided {@code tile} - * at {@code index}. If the stack is {@linkplain #isFull() full}, does - * nothing. - * - * @param index the index to insert the tile at - * @param tile the tile to try to add - * @return {@code true} iff this stack has changed - */ - public boolean offer(int index, TileData tile) { - if (isFull()) - return false; - add(index, tile); - return true; - } - - public boolean offerClosest(TileData tile) { - return offer(0, tile); - } - - public boolean offerFarthest(TileData tile) { - return offer(size(), tile); - } - - public TileData removeClosest() { - return remove(0); - } - - public TileData removeFarthest() { - return remove(size() - 1); - } - - public TileData poll(int index) { - if (size() <= index) - return null; - return remove(index); - } - - public TileData pollClosest() { - return poll(0); - } - - public TileData pollFarthest() { - return poll(size() - 1); - } - - @Override - public boolean add(TileData tile) { - addFarthest(tile); - return true; - } - - public BlockData getHost() { - return getChunk().getBlock(getBlockInChunk(null)); - } + extends GenericWritableTileStack { } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index 2ee89d6..a5177fe 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -33,7 +33,7 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileReference; +import ru.windcorp.progressia.common.world.tile.TileDataReference; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.server.world.block.TickableBlock; @@ -41,16 +41,17 @@ import ru.windcorp.progressia.server.world.tasks.TickChunk; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; import ru.windcorp.progressia.server.world.tile.TickableTile; import ru.windcorp.progressia.server.world.tile.TileLogic; +import ru.windcorp.progressia.server.world.tile.TileLogicReference; import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; import ru.windcorp.progressia.server.world.tile.TileLogicStack; -public class ChunkLogic implements GenericChunk { +public class ChunkLogic implements GenericChunk { private final WorldLogic world; private final ChunkData data; private final Collection tickingBlocks = new ArrayList<>(); - private final Collection tickingTiles = new ArrayList<>(); + private final Collection tickingTiles = new ArrayList<>(); private final TickChunk tickTask = new TickChunk(this); @@ -124,7 +125,7 @@ public class ChunkLogic implements GenericChunk action) { + public void forEachTickingTile(BiConsumer action) { tickingTiles.forEach(ref -> { action.accept( ref, @@ -138,7 +139,29 @@ public class ChunkLogic implements GenericChunk tileStack); + TileStack withTS(GenericTileStack tileStack); default Builder.Chunk withChunk(ChunkData chunk) { Objects.requireNonNull(chunk, "chunk"); return withChunk(chunk.getPosition()); } - default TileTickContext withTile(TileReference ref) { + default TileTickContext withTile(TileDataReference ref) { Objects.requireNonNull(ref, "ref"); return withTS(ref.getStack()).withLayer(ref.getIndex()); } @@ -259,7 +259,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public TileStack withTS(GenericTileStack tileStack) { + public TileStack withTS(GenericTileStack tileStack) { Objects.requireNonNull(tileStack, "tileStack"); return withBlock( diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 4111646..0b80b89 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -37,10 +37,11 @@ import ru.windcorp.progressia.server.world.generation.WorldGenerator; import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask; import ru.windcorp.progressia.server.world.ticking.Evaluation; import ru.windcorp.progressia.server.world.tile.TileLogic; +import ru.windcorp.progressia.server.world.tile.TileLogicReference; import ru.windcorp.progressia.server.world.tile.TileLogicStack; public class WorldLogic - implements GenericWorld { diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java new file mode 100644 index 0000000..97bf35c --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java @@ -0,0 +1,27 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.tile; + +import ru.windcorp.progressia.common.world.generic.GenericTileReference; +import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.server.world.block.BlockLogic; + +public interface TileLogicReference + extends GenericTileReference { + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java index 5e91963..b38a6f6 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java @@ -21,9 +21,10 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.generic.GenericTileStack; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.server.world.block.BlockLogic; public abstract class TileLogicStack - extends GenericTileStack { + extends GenericTileStack { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java index 45f41ec..7e7ae88 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileReference; +import ru.windcorp.progressia.common.world.tile.TileDataReference; public interface TileTickContext extends TSTickContext { @@ -53,7 +53,7 @@ public interface TileTickContext extends TSTickContext { return stack.get(getLayer()); } - default TileReference getReference() { + default TileDataReference getReference() { return getTDS().getReference(getLayer()); } From a95bdf1efe2c36a85ca2a6325c6dfd4d309b8574 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 9 Apr 2021 20:15:07 +0300 Subject: [PATCH 23/63] Moved .setBlockRel(...) implementation to GenericWritableChunk --- .../ru/windcorp/progressia/common/world/ChunkData.java | 9 --------- .../progressia/common/world/generic/GenericChunk.java | 4 ++-- .../common/world/generic/GenericWritableChunk.java | 8 +++++++- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 9a00e25..2202f99 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -28,7 +28,6 @@ import java.util.Objects; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.generic.GenericWritableChunk; @@ -94,14 +93,6 @@ public class ChunkData }); } } - - @Override - public void setBlockRel(Vec3i relativeBlockInChunk, BlockData block, boolean notify) { - Vec3i absoluteBlockInChunk = Vectors.grab3i(); - resolve(relativeBlockInChunk, absoluteBlockInChunk); - setBlock(absoluteBlockInChunk, block, notify); - Vectors.release(absoluteBlockInChunk); - } @Override public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 281b697..6c15195 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -105,14 +105,14 @@ public interface GenericChunk< boolean hasTiles(Vec3i blockInChunk, BlockFace face); - default Vec3i resolve(Vec3i relativeBlockInChunk, Vec3i output) { + default Vec3i resolve(Vec3i relativeCoords, Vec3i output) { if (output == null) { output = new Vec3i(); } final int offset = BLOCKS_PER_CHUNK - 1; - output.set(relativeBlockInChunk.x, relativeBlockInChunk.y, relativeBlockInChunk.z); + output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z); output.mul(2).sub(offset); AxisRotations.resolve(output, getUp(), output); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java index baf6cc2..40fb010 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java @@ -18,6 +18,7 @@ package ru.windcorp.progressia.common.world.generic; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.Vectors; // @formatter:off public interface GenericWritableChunk< @@ -32,6 +33,11 @@ public interface GenericWritableChunk< void setBlock(Vec3i posInChunk, B block, boolean notify); - void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify); + default void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify) { + Vec3i absoluteBlockInChunk = Vectors.grab3i(); + resolve(relativeBlockInChunk, absoluteBlockInChunk); + setBlock(absoluteBlockInChunk, block, notify); + Vectors.release(absoluteBlockInChunk); + } } From 20dccf3d12f4d0fb148bd86f569ec8a81e26bc13 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 9 Apr 2021 23:13:21 +0300 Subject: [PATCH 24/63] Some more refactoring of generic world-related classes. May not compile. - Added GenericWritableWorld - Moved static methods from GenericChunk to GenericChunks - GenericEntity now declares getEntityId() - GenericWorld now declares getEntity(long) - Added a lambda-based mapToFaces variations for AbsFace and RelFace --- .../client/world/ChunkRenderModel.java | 4 +- .../progressia/client/world/WorldRender.java | 7 ++ .../cro/ChunkRenderOptimizerSurface.java | 6 +- .../client/world/entity/EntityRenderable.java | 5 + .../progressia/common/world/ChunkData.java | 4 +- .../progressia/common/world/WorldData.java | 9 +- .../common/world/entity/EntityData.java | 1 + .../common/world/generic/GenericChunk.java | 55 ++-------- .../common/world/generic/GenericChunks.java | 102 ++++++++++++++++++ .../common/world/generic/GenericEntity.java | 2 + .../common/world/generic/GenericWorld.java | 2 + .../{Util.java => GenericWritableWorld.java} | 50 ++++----- .../progressia/common/world/rels/AbsFace.java | 12 +++ .../progressia/common/world/rels/RelFace.java | 13 +++ .../server/world/ChunkTickContext.java | 4 +- .../progressia/server/world/WorldLogic.java | 5 + .../progressia/test/TestChunkCodec.java | 8 +- 17 files changed, 196 insertions(+), 93 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java rename src/main/java/ru/windcorp/progressia/common/world/generic/{Util.java => GenericWritableWorld.java} (52%) diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 46a3f28..832a7ee 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -36,7 +36,7 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -77,7 +77,7 @@ public class ChunkRenderModel implements Renderable { optimizers.forEach(ChunkRenderOptimizer::startRender); - GenericChunk.forEachBiC(relBlockInChunk -> { + GenericChunks.forEachBiC(relBlockInChunk -> { processBlockAndTiles(relBlockInChunk, sink); }); diff --git a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java index 2e674f0..7ff4df6 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java @@ -111,6 +111,13 @@ public class WorldRender public Collection getEntities() { return entityModels.values(); } + + @Override + public EntityRenderable getEntity(long entityId) { + EntityData entityData = getData().getEntity(entityId); + if (entityData == null) return null; + return getEntityRenderable(entityData); + } public void render(ShapeRenderHelper renderer) { updateChunks(); diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index 5ede1ef..26ee23c 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -38,7 +38,7 @@ import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.RelFace; public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @@ -217,7 +217,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { Consumer consumer = shapeParts::add; - GenericChunk.forEachBiC(relBlockInChunk -> { + GenericChunks.forEachBiC(relBlockInChunk -> { processInnerFaces(relBlockInChunk, consumer); processOuterFaces(relBlockInChunk, consumer); }); @@ -316,7 +316,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } private boolean shouldRenderWhenFacing(Vec3i relBlockInChunk, RelFace face) { - if (GenericChunk.containsBiC(relBlockInChunk)) { + if (GenericChunks.containsBiC(relBlockInChunk)) { return shouldRenderWhenFacingLocal(relBlockInChunk, face); } else { return shouldRenderWhenFacingNeighbor(relBlockInChunk, face); diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java index 24ea147..fcd50f6 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java @@ -71,6 +71,11 @@ public abstract class EntityRenderable implements Renderable, GenericEntity { public String getId() { return getData().getId(); } + + @Override + public long getEntityId() { + return getData().getEntityId(); + } public final Vec3 getLookingAt(Vec3 output) { if (output == null) output = new Vec3(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 2202f99..728bc80 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -29,7 +29,7 @@ import java.util.Objects; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.generic.GenericWritableChunk; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; @@ -160,7 +160,7 @@ public class ChunkData } private static void checkLocalCoordinates(Vec3i posInChunk) { - if (!GenericChunk.containsBiC(posInChunk)) { + if (!GenericChunks.containsBiC(posInChunk)) { throw new IllegalCoordinatesException( "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " + "are not legal chunk coordinates" diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 7fec468..13138c5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -34,14 +34,14 @@ import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.ChunkMap; import ru.windcorp.progressia.common.world.generic.ChunkSet; -import ru.windcorp.progressia.common.world.generic.GenericWorld; +import ru.windcorp.progressia.common.world.generic.GenericWritableWorld; import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileDataReference; public class WorldData - implements GenericWorld { + implements GenericWritableWorld { private final ChunkMap chunksByPos = new LongBasedChunkMap<>( TCollections.synchronizedMap(new TLongObjectHashMap<>()) @@ -128,6 +128,7 @@ public class WorldData chunksByPos.remove(chunk); } + @Override public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { ChunkData chunk = getChunkByBlock(blockInWorld); if (chunk == null) @@ -140,10 +141,12 @@ public class WorldData chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify); } + @Override public EntityData getEntity(long entityId) { return entitiesById.get(entityId); } + @Override public void addEntity(EntityData entity) { Objects.requireNonNull(entity, "entity"); @@ -164,6 +167,7 @@ public class WorldData getListeners().forEach(l -> l.onEntityAdded(this, entity)); } + @Override public void removeEntity(long entityId) { synchronized (entitiesById) { EntityData entity = entitiesById.get(entityId); @@ -178,6 +182,7 @@ public class WorldData } } + @Override public void removeEntity(EntityData entity) { Objects.requireNonNull(entity, "entity"); diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index d54cca1..ed6876d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -85,6 +85,7 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn this.velocity.set(velocity); } + @Override public long getEntityId() { return entityId; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 6c15195..f9401d8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -106,20 +106,7 @@ public interface GenericChunk< boolean hasTiles(Vec3i blockInChunk, BlockFace face); default Vec3i resolve(Vec3i relativeCoords, Vec3i output) { - if (output == null) { - output = new Vec3i(); - } - - final int offset = BLOCKS_PER_CHUNK - 1; - - output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z); - output.mul(2).sub(offset); - - AxisRotations.resolve(output, getUp(), output); - - output.add(offset).div(2); - - return output; + return GenericChunks.resolve(relativeCoords, output, getUp()); } default B getBlockRel(Vec3i relativeBlockInChunk) { @@ -240,50 +227,20 @@ public interface GenericChunk< return output; } - public static boolean containsBiC(Vec3i blockInChunk) { - return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK && - blockInChunk.y >= 0 && blockInChunk.y < BLOCKS_PER_CHUNK && - blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK; - } - - public static boolean isSurfaceBiC(Vec3i blockInChunk) { - return Util.getBorderHits(blockInChunk) >= 1; - } - - public static boolean isEdgeBiC(Vec3i blockInChunk) { - return Util.getBorderHits(blockInChunk) >= 2; - } - - public static boolean isVertexBiC(Vec3i blockInChunk) { - return Util.getBorderHits(blockInChunk) == 3; - } - default boolean containsBiW(Vec3i blockInWorld) { - return Util.testBiC(blockInWorld, this, GenericChunk::containsBiC); + return GenericChunks.testBiC(blockInWorld, this, GenericChunks::containsBiC); } default boolean isSurfaceBiW(Vec3i blockInWorld) { - return Util.testBiC(blockInWorld, this, GenericChunk::isSurfaceBiC); + return GenericChunks.testBiC(blockInWorld, this, GenericChunks::isSurfaceBiC); } default boolean isEdgeBiW(Vec3i blockInWorld) { - return Util.testBiC(blockInWorld, this, GenericChunk::isEdgeBiC); + return GenericChunks.testBiC(blockInWorld, this, GenericChunks::isEdgeBiC); } default boolean isVertexBiW(Vec3i blockInWorld) { - return Util.testBiC(blockInWorld, this, GenericChunk::isVertexBiC); - } - - public static void forEachBiC(Consumer action) { - VectorUtil.iterateCuboid( - 0, - 0, - 0, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - action - ); + return GenericChunks.testBiC(blockInWorld, this, GenericChunks::isVertexBiC); } default void forEachBiW(Consumer action) { @@ -324,7 +281,7 @@ public interface GenericChunk< } default void forEachTileStack(Consumer action) { - forEachBiC(blockInChunk -> { + GenericChunks.forEachBiC(blockInChunk -> { for (AbsFace face : AbsFace.getFaces()) { TS stack = getTilesOrNull(blockInChunk, face); if (stack == null) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java new file mode 100644 index 0000000..ac97578 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java @@ -0,0 +1,102 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.AxisRotations; + +public class GenericChunks { + + public static Vec3i resolve(Vec3i relativeCoords, Vec3i output, AbsFace up) { + if (output == null) { + output = new Vec3i(); + } + + final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1; + + output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z); + output.mul(2).sub(offset); + + AxisRotations.resolve(output, up, output); + + output.add(offset).div(2); + + return output; + } + + private static int getBorderHits(Vec3i blockInChunk) { + int hits = 0; + + if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; + + return hits; + } + + static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { + Vec3i v = Vectors.grab3i(); + + v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v); + v = blockInWorld.sub(v, v); + + boolean result = test.test(v); + + Vectors.release(v); + + return result; + } + + public static boolean containsBiC(Vec3i blockInChunk) { + return blockInChunk.x >= 0 && blockInChunk.x < GenericChunk.BLOCKS_PER_CHUNK && + blockInChunk.y >= 0 && blockInChunk.y < GenericChunk.BLOCKS_PER_CHUNK && + blockInChunk.z >= 0 && blockInChunk.z < GenericChunk.BLOCKS_PER_CHUNK; + } + + public static boolean isSurfaceBiC(Vec3i blockInChunk) { + return GenericChunks.getBorderHits(blockInChunk) >= 1; + } + + public static boolean isEdgeBiC(Vec3i blockInChunk) { + return GenericChunks.getBorderHits(blockInChunk) >= 2; + } + + public static boolean isVertexBiC(Vec3i blockInChunk) { + return GenericChunks.getBorderHits(blockInChunk) == 3; + } + + public static void forEachBiC(Consumer action) { + VectorUtil.iterateCuboid( + 0, + 0, + 0, + GenericChunk.BLOCKS_PER_CHUNK, + GenericChunk.BLOCKS_PER_CHUNK, + GenericChunk.BLOCKS_PER_CHUNK, + action + ); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java index c15bd39..3acfc23 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java @@ -25,6 +25,8 @@ import ru.windcorp.progressia.common.world.Coordinates; public interface GenericEntity { String getId(); + + long getEntityId(); Vec3 getPosition(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java index c945461..e17cf66 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java @@ -46,6 +46,8 @@ public interface GenericWorld< Collection getEntities(); + E getEntity(long entityId); + /* * Chunks */ diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java similarity index 52% rename from src/main/java/ru/windcorp/progressia/common/world/generic/Util.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java index f3765d7..b970f89 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/Util.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java @@ -17,37 +17,29 @@ */ package ru.windcorp.progressia.common.world.generic; -import java.util.function.Predicate; - import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.block.BlockData; -class Util { - - public static int getBorderHits(Vec3i blockInChunk) { - int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - - return hits; +//@formatter:off +public interface GenericWritableWorld< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericWritableTileStack , + TR extends GenericTileReference , + C extends GenericWritableChunk , + E extends GenericEntity +> + extends GenericWorld { +//@formatter:on + + void setBlock(Vec3i blockInWorld, BlockData block, boolean notify); + + void addEntity(E entity); + + void removeEntity(long entityId); + + default void removeEntity(E entity) { + removeEntity(entity.getEntityId()); } - - public static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { - Vec3i v = Vectors.grab3i(); - - v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v); - v = blockInWorld.sub(v, v); - - boolean result = test.test(v); - - Vectors.release(v); - - return result; - } - - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java index 9ffb5e9..d741bac 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/AbsFace.java @@ -19,6 +19,7 @@ package ru.windcorp.progressia.common.world.rels; import java.util.Objects; +import java.util.function.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -90,6 +91,17 @@ public final class AbsFace extends AbsRelation implements BlockFace { .build(); } + public static ImmutableMap mapToFaces(Function generator) { + return mapToFaces( + generator.apply(POS_Z), + generator.apply(NEG_Z), + generator.apply(POS_X), + generator.apply(NEG_X), + generator.apply(NEG_Y), + generator.apply(POS_Y) + ); + } + /** * Rounds the provided vector to one of {@link AbsFace}s. The returned face * is pointing in the same general direction as the provided vector. The diff --git a/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java b/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java index 7f3ddb7..99e97fb 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/rels/RelFace.java @@ -17,6 +17,8 @@ */ package ru.windcorp.progressia.common.world.rels; +import java.util.function.Function; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -68,6 +70,17 @@ public class RelFace extends RelRelation implements BlockFace { .put(EAST, east) .build(); } + + public static ImmutableMap mapToFaces(Function generator) { + return mapToFaces( + generator.apply(UP), + generator.apply(DOWN), + generator.apply(NORTH), + generator.apply(SOUTH), + generator.apply(WEST), + generator.apply(EAST) + ); + } private static int nextId = 0; diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java index 0480a6e..64778cd 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.world.block.BlockTickContext; @@ -46,7 +46,7 @@ public interface ChunkTickContext extends TickContext { default void forEachBlock(Consumer action) { TickContextMutable context = TickContextMutable.uninitialized(); - GenericChunk.forEachBiC(blockInChunk -> { + GenericChunks.forEachBiC(blockInChunk -> { context.rebuild().withServer(getServer()).withChunk(getChunk()).withBlockInChunk(blockInChunk).build(); action.accept(context); }); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 0b80b89..d080551 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -90,6 +90,11 @@ public class WorldLogic public Collection getEntities() { return getData().getEntities(); } + + @Override + public EntityData getEntity(long entityId) { + return getData().getEntity(entityId); + } public Evaluation getTickEntitiesTask() { return tickEntitiesTask; diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index 050b94e..0f4dcd2 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -38,7 +38,7 @@ import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.io.ChunkCodec; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; @@ -125,7 +125,7 @@ public class TestChunkCodec extends ChunkCodec { private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException { try { - GenericChunk.forEachBiC(guard(v -> { + GenericChunks.forEachBiC(guard(v -> { chunk.setBlock(v, blockPalette[input.readInt()], false); })); } catch (UncheckedIOException e) { @@ -172,7 +172,7 @@ public class TestChunkCodec extends ChunkCodec { private Palette createBlockPalette(ChunkData chunk) { Palette blockPalette = new Palette<>(); - GenericChunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); + GenericChunks.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); return blockPalette; } @@ -200,7 +200,7 @@ public class TestChunkCodec extends ChunkCodec { private void writeBlocks(ChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { try { - GenericChunk.forEachBiC(guard(v -> { + GenericChunks.forEachBiC(guard(v -> { output.writeInt(blockPalette.getNid(chunk.getBlock(v))); })); } catch (UncheckedIOException e) { From 6fb7e7fc04ff4f6c3dfa9195c5d574a64db6f9ab Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Tue, 13 Apr 2021 15:18:15 +0300 Subject: [PATCH 25/63] Added SurfaceWorld to facilitate surface feature generation --- .../common/world/generic/GenericChunk.java | 16 +- .../progressia/test/TestBushFeature.java | 45 +++++ .../gen/planet/PlanetFeatureGenerator.java | 34 ++-- .../gen/planet/PlanetTerrainGenerator.java | 4 +- .../progressia/test/gen/surface/Surface.java | 46 +++++ .../test/gen/surface/SurfaceFeature.java | 125 ++++++++++++- .../gen/surface/SurfaceFeatureGenerator.java | 17 +- .../test/gen/surface/SurfaceWorld.java | 168 ++++++++++++++++++ 8 files changed, 426 insertions(+), 29 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/TestBushFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index f9401d8..0748a34 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -244,13 +244,17 @@ public interface GenericChunk< } default void forEachBiW(Consumer action) { + int minX = Coordinates.getInWorld(getX(), 0); + int minY = Coordinates.getInWorld(getY(), 0); + int minZ = Coordinates.getInWorld(getZ(), 0); + VectorUtil.iterateCuboid( - Coordinates.getInWorld(getX(), 0), - Coordinates.getInWorld(getY(), 0), - Coordinates.getInWorld(getZ(), 0), - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, + minX, + minY, + minZ, + minX + BLOCKS_PER_CHUNK, + minY + BLOCKS_PER_CHUNK, + minZ + BLOCKS_PER_CHUNK, action ); } diff --git a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java new file mode 100644 index 0000000..9e99314 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java @@ -0,0 +1,45 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.test.gen.surface.SurfaceFeature; +import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; + +public class TestBushFeature extends SurfaceFeature { + + public TestBushFeature(String id) { + super(id); + } + + @Override + public void process(SurfaceWorld world, Request request) { + BlockData block = BlockDataRegistry.getInstance().get("Test:Log"); + + Vec3i location = new Vec3i(request.getRandom().nextInt(ChunkData.BLOCKS_PER_CHUNK), request.getRandom().nextInt(ChunkData.BLOCKS_PER_CHUNK), request.getRandom().nextInt(ChunkData.BLOCKS_PER_CHUNK)).add(request.getMin()); + if (world.getBlockSfc(location) == BlockDataRegistry.getInstance().get("Test:Air")) { + + world.setBlockSfc(location, block, false); + + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java index 79f0593..1f69e00 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java @@ -19,40 +19,40 @@ package ru.windcorp.progressia.test.gen.planet; import java.util.ArrayList; import java.util.Collection; -import java.util.Random; +import java.util.Map; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.test.TestBushFeature; +import ru.windcorp.progressia.test.gen.surface.Surface; import ru.windcorp.progressia.test.gen.surface.SurfaceFeature; import ru.windcorp.progressia.test.gen.surface.SurfaceFeatureGenerator; public class PlanetFeatureGenerator { - + private final TestPlanetGenerator parent; - private final SurfaceFeatureGenerator surfaceGenerator; + + private final Map surfaceGenerators; public PlanetFeatureGenerator(TestPlanetGenerator generator) { this.parent = generator; - + Collection features = new ArrayList<>(); - features.add(new SurfaceFeature("Test:GlassFeature") { - @Override - public void process(ChunkData chunk, Random random) { - - chunk.setBlockRel(new Vec3i(8, 8, 8), BlockDataRegistry.getInstance().get("Test:Glass"), true); - - } - }); + features.add(new TestBushFeature("Test:BushFeature")); - this.surfaceGenerator = new SurfaceFeatureGenerator(features); + int seaLevel = (int) parent.getPlanet().getRadius(); + this.surfaceGenerators = AbsFace.mapToFaces(face -> new SurfaceFeatureGenerator( + new Surface(face, seaLevel), + features + )); } - + public TestPlanetGenerator getGenerator() { return parent; } - + public void generateFeatures(ChunkData chunk) { if (isOrdinaryChunk(chunk.getPosition())) { generateOrdinaryFeatures(chunk); @@ -67,7 +67,7 @@ public class PlanetFeatureGenerator { } private void generateOrdinaryFeatures(ChunkData chunk) { - surfaceGenerator.generateFeatures(chunk); + surfaceGenerators.get(chunk.getUp()).generateFeatures(chunk); } private void generateBorderFeatures(ChunkData chunk) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index a5b086f..649a6e9 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -26,7 +26,7 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.test.gen.TerrainLayer; import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField; import ru.windcorp.progressia.test.gen.surface.SurfaceTerrainGenerator; @@ -90,7 +90,7 @@ class PlanetTerrainGenerator { Vec3 biw = new Vec3(); - GenericChunk.forEachBiC(bic -> { + GenericChunks.forEachBiC(bic -> { biw.set( Coordinates.getInWorld(chunk.getX(), bic.x), diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java new file mode 100644 index 0000000..0baa6f0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java @@ -0,0 +1,46 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import ru.windcorp.progressia.common.world.rels.AbsFace; + +public class Surface { + + private final AbsFace up; + private final int seaLevel; + + public Surface(AbsFace up, int seaLevel) { + this.up = up; + this.seaLevel = seaLevel; + } + + /** + * @return the up + */ + public AbsFace getUp() { + return up; + } + + /** + * @return the seaLevel + */ + public int getSeaLevel() { + return seaLevel; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index 649b414..aa0ef6c 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -18,16 +18,137 @@ package ru.windcorp.progressia.test.gen.surface; import java.util.Random; +import java.util.function.Consumer; +import glm.Glm; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.generic.GenericChunks; +import ru.windcorp.progressia.common.world.rels.AxisRotations; public abstract class SurfaceFeature extends Namespaced { + public static class Request { + + private final ChunkData chunk; + private final Vec3i minSfc = new Vec3i(); + private final Vec3i maxSfc = new Vec3i(); + + private final Random random; + + public Request(ChunkData chunk, Random random) { + this.chunk = chunk; + this.random = random; + + Vec3i absMin = chunk.getMinBIW(null); + Vec3i absMax = chunk.getMaxBIW(null); + + AxisRotations.relativize(absMin, chunk.getUp(), absMin); + AxisRotations.relativize(absMax, chunk.getUp(), absMax); + + Glm.min(absMin, absMax, minSfc); + Glm.max(absMin, absMax, maxSfc); + } + + public ChunkData getChunk() { + return chunk; + } + + public Random getRandom() { + return random; + } + + public int getMinX() { + return minSfc.x; + } + + public int getMaxX() { + return maxSfc.x; + } + + public int getMinY() { + return minSfc.y; + } + + public int getMaxY() { + return maxSfc.y; + } + + public int getMinZ() { + return minSfc.z; + } + + public int getMaxZ() { + return maxSfc.z; + } + + public Vec3i getMin() { + return minSfc; + } + + public Vec3i getMax() { + return maxSfc; + } + + public boolean contains(Vec3i surfaceBlockInWorld) { + Vec3i bic = Vectors.grab3i(); + bic.set(surfaceBlockInWorld.x, surfaceBlockInWorld.y, surfaceBlockInWorld.z); + bic.sub(minSfc); + boolean result = GenericChunks.containsBiC(bic); + Vectors.release(bic); + return result; + } + + public void forEach(Consumer action) { + VectorUtil.iterateCuboid( + minSfc.x, + minSfc.y, + minSfc.z, + maxSfc.x + 1, + maxSfc.y + 1, + maxSfc.z + 1, + action + ); + } + + /** + * Provided vectors have z set to {@link #getMinZ()}. + */ + public void forEachOnFloor(Consumer action) { + forEachOnLayer(action, getMinZ()); + } + + /** + * Provided vectors have z set to {@link #getMaxZ()}. + */ + public void forEachOnCeiling(Consumer action) { + forEachOnLayer(action, getMaxZ()); + } + + /** + * Provided vectors have z set to layer. + */ + public void forEachOnLayer(Consumer action, int layer) { + VectorUtil.iterateCuboid( + minSfc.x, + minSfc.y, + layer, + maxSfc.x + 1, + maxSfc.y + 1, + layer + 1, + action + ); + } + + } + public SurfaceFeature(String id) { super(id); } - - public abstract void process(ChunkData chunk, Random random); + + public abstract void process(SurfaceWorld world, Request request); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java index 753256a..ade7869 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java @@ -26,17 +26,30 @@ import ru.windcorp.progressia.common.world.ChunkData; public class SurfaceFeatureGenerator { + private final Surface surface; + private final Collection features; // TODO make ordered - public SurfaceFeatureGenerator(Collection features) { + public SurfaceFeatureGenerator(Surface surface, Collection features) { + this.surface = surface; this.features = new ArrayList<>(features); } + /** + * @return the surface + */ + public Surface getSurface() { + return surface; + } + public void generateFeatures(ChunkData chunk) { + SurfaceWorld world = new SurfaceWorld(surface, chunk.getWorld()); + Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); + SurfaceFeature.Request request = new SurfaceFeature.Request(chunk, random); for (SurfaceFeature feature : features) { - feature.process(chunk, random); + feature.process(world, request); } chunk.setGenerationHint(true); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java new file mode 100644 index 0000000..740cc50 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java @@ -0,0 +1,168 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import java.util.Collection; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.GenericChunks; +import ru.windcorp.progressia.common.world.generic.GenericWritableWorld; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileDataReference; +import ru.windcorp.progressia.common.world.tile.TileDataStack; + +public class SurfaceWorld implements GenericWritableWorld { + + private final Surface surface; + private final GenericWritableWorld parent; + + public SurfaceWorld( + Surface surface, + GenericWritableWorld parent + ) { + this.surface = surface; + this.parent = parent; + } + + /** + * @return the surface + */ + public Surface getSurface() { + return surface; + } + + /** + * @return the parent + */ + public GenericWritableWorld getParent() { + return parent; + } + + /* + * Delegate methods + */ + + @Override + public Collection getChunks() { + return parent.getChunks(); + } + + @Override + public ChunkData getChunk(Vec3i pos) { + return parent.getChunk(pos); + } + + @Override + public Collection getEntities() { + return parent.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return parent.getEntity(entityId); + } + + @Override + public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { + parent.setBlock(blockInWorld, block, notify); + } + + @Override + public void addEntity(EntityData entity) { + parent.addEntity(entity); + } + + @Override + public void removeEntity(long entityId) { + parent.removeEntity(entityId); + } + + public Vec3i resolve(Vec3i surfacePosition, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + output.set(surfacePosition.x, surfacePosition.y, surfacePosition.z); + output.z -= getSurface().getSeaLevel(); + + GenericChunks.resolve(surfacePosition, output, getSurface().getUp()); + + return output; + } + + public BlockData getBlockSfc(Vec3i surfaceBlockInWorld) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + BlockData result = parent.getBlock(blockInWorld); + Vectors.release(blockInWorld); + return result; + } + + public void setBlockSfc(Vec3i surfaceBlockInWorld, BlockData block, boolean notify) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + parent.setBlock(blockInWorld, block, notify); + Vectors.release(blockInWorld); + } + + public TileDataStack getTilesSfc(Vec3i surfaceBlockInWorld, BlockFace face) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + TileDataStack result = parent.getTiles(blockInWorld, face); + Vectors.release(blockInWorld); + return result; + } + + public TileDataStack getTilesOrNullSfc(Vec3i surfaceBlockInWorld, BlockFace face) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + TileDataStack result = parent.getTilesOrNull(blockInWorld, face); + Vectors.release(blockInWorld); + return result; + } + + public boolean hasTilesSfc(Vec3i surfaceBlockInWorld, BlockFace face) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + boolean result = parent.hasTiles(blockInWorld, face); + Vectors.release(blockInWorld); + return result; + } + + public TileData getTileSfc(Vec3i surfaceBlockInWorld, BlockFace face, int layer) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + TileData result = parent.getTile(blockInWorld, face, layer); + Vectors.release(blockInWorld); + return result; + } + + public boolean isBlockLoadedSfc(Vec3i surfaceBlockInWorld) { + Vec3i blockInWorld = Vectors.grab3i(); + resolve(surfaceBlockInWorld, blockInWorld); + boolean result = parent.isBlockLoaded(blockInWorld); + Vectors.release(blockInWorld); + return result; + } + +} From b374e9a7368b81231e2512798b355debaea08630 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Tue, 4 May 2021 20:29:06 -0400 Subject: [PATCH 26/63] Added FallingBlock Classes -Added TestEntityDataFallingBlock class -Right now only supports Test:Sand -Kinda just copied from Statie -Added TestEntityRenderFallingBlock -Used BlockRenderTexturedCube and TestEntityRenderStatie for this one -Has a setTexture method, but it needs improving -Added TestEntityLogicFallingBlock class -Allows for a falling block to return to being a block. -The coordinates of the entity never move, even if it does ingame. -In TestContent -Registers Test:FallingBlock -In TestWorldGenerator -Adds listener for a sand block being placed -Listener replaces the block with a FallingBlock entity -It should also replace the block with air but it hasn't been working for me. --- .../windcorp/progressia/test/TestContent.java | 4 + .../test/TestEntityDataFallingBlock.java | 30 +++++ .../test/TestEntityLogicFallingBlock.java | 51 +++++++++ .../test/TestEntityRenderFallingBlock.java | 55 +++++++++ .../test/gen/TestWorldGenerator.java | 104 ++++++++++-------- 5 files changed, 197 insertions(+), 47 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java create mode 100644 src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java create mode 100644 src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index dad5496..7f4ed7e 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -245,6 +245,10 @@ public class TestContent { register("Test:Statie", TestEntityDataStatie::new); register(new TestEntityRenderStatie("Test:Statie")); register(new TestEntityLogicStatie("Test:Statie")); + + register("Test:FallingBlock", TestEntityDataFallingBlock::new); + register(new TestEntityRenderFallingBlock("Test:FallingBlock")); + register(new TestEntityLogicFallingBlock("Test:FallingBlock")); } private static void regsiterControls() { diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java new file mode 100644 index 0000000..cdb5060 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java @@ -0,0 +1,30 @@ +package ru.windcorp.progressia.test; + +import ru.windcorp.progressia.common.collision.AABB; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; + +/** + * Data for Test:FallingBlock + * @author opfromthestart + * + */ +public class TestEntityDataFallingBlock extends EntityData { + + private BlockData block; + + public TestEntityDataFallingBlock() { + this("Test:FallingBlock",new BlockData("Test:Sand")); + } + + protected TestEntityDataFallingBlock(String id, BlockData blockInput) { + super(id); + setCollisionModel(new AABB(0,0,0,1,1,1)); + block = blockInput; + } + + public BlockData getBlock() + { + return block; + } +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java new file mode 100644 index 0000000..1b8b600 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -0,0 +1,51 @@ +package ru.windcorp.progressia.test; + +import org.apache.logging.log4j.LogManager; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.server.world.TickContext; +import ru.windcorp.progressia.server.world.entity.EntityLogic; + +/** + * Logic for Test:FallingBlock + * @author opfromthestart + * + */ +public class TestEntityLogicFallingBlock extends EntityLogic { + + public TestEntityLogicFallingBlock(String id) { + super(id); + } + + @Override + public void tick(EntityData entity, TickContext context) { + super.tick(entity, context); + + //friction + Vec3 vel = entity.getVelocity(); + float friction = .8f; + vel = new Vec3(vel.x*friction,vel.y*friction,vel.z); + entity.setVelocity(vel); + + + TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) context.getServer().getWorld().getData().getEntity(entity.getEntityId());; + + Vec3i occupiedBlock = entity.getBlockInWorld(null); + Vec3i underBlock = occupiedBlock.sub_(0, 0, 1); + + Vec3i chunkCoords = underBlock.div_(16); + Vec3i inChunkCoords = underBlock.mod_(new Vec3i(16)); + + LogManager.getLogger().info("FallingBlock is at "+String.valueOf(occupiedBlock.x)+" "+String.valueOf(occupiedBlock.y)+" "+String.valueOf(occupiedBlock.z)); + LogManager.getLogger().info("Block is of type " + context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); + + if (context.getServer().getWorld().getData().getChunk(chunkCoords).getBlock(inChunkCoords) + .getId() != "Test:Air") { + LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); + context.getServer().getWorldAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); + context.getServer().getWorld().getData().removeEntity(entity); + } + } +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java new file mode 100644 index 0000000..7fe07da --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java @@ -0,0 +1,55 @@ +package ru.windcorp.progressia.test; + +import ru.windcorp.progressia.client.graphics.model.Renderable; +import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; +import ru.windcorp.progressia.client.graphics.model.Shapes; +import ru.windcorp.progressia.client.graphics.texture.Atlases; +import ru.windcorp.progressia.client.graphics.texture.SimpleTexture; +import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.client.graphics.texture.Atlases.AtlasGroup; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.world.entity.EntityRender; +import ru.windcorp.progressia.client.world.entity.EntityRenderable; +import ru.windcorp.progressia.common.resource.ResourceManager; +import ru.windcorp.progressia.common.world.entity.EntityData; + +/** + * Renderer for Test:FallingBlock + * @author opfromthestart + * + */ +public class TestEntityRenderFallingBlock extends EntityRender { + private Renderable cube; + + public TestEntityRenderFallingBlock(String id) { + super(id); + cube = new Shapes.PppBuilder( + WorldRenderProgram.getDefault(), + new SimpleTexture( + Atlases.getSprite( + ResourceManager.getTextureResource("blocks/Sand"), new AtlasGroup("Blocks", 1 << 12) + ) + ) + ).create(); + } + + public void setTexture(Texture texture) { // There has to be a better way. + cube = new Shapes.PppBuilder( + WorldRenderProgram.getDefault(), + texture + ) + .create(); + } + + @Override + public EntityRenderable createRenderable(EntityData entity) { + return new EntityRenderable(entity) { + @Override + public void render(ShapeRenderHelper renderer) { + //LogManager.getLogger().info("Rendering FallingBlock"); + cube.render(renderer); + } + }; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 1b35ffc..5898fe3 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test.gen; import java.io.DataInputStream; @@ -23,10 +23,14 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Random; +import org.apache.logging.log4j.LogManager; + +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; @@ -38,6 +42,7 @@ import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; +import ru.windcorp.progressia.test.TestEntityDataFallingBlock; public class TestWorldGenerator extends AbstractWorldGenerator { @@ -51,6 +56,41 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public void onChunkLoaded(WorldData world, ChunkData chunk) { findAndPopulate(chunk.getPosition(), world); + chunk.addListener(new ChunkDataListener() { + @Override + public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, + BlockData current) { + if (current.getId() != "Test:Sand") { // Replace with + // proper check + // for all + // gravity + // blocks + return; + } + if (chunk.getBlock(blockInChunk.add_(0, 0, -1)).getId() == "Test:Air")// TODO + // Won't + // work + // on + // z + // chunk + // boundaries + { + LogManager.getLogger().info("Inserting FallingBlock"); + + TestEntityDataFallingBlock fallingBlock = new TestEntityDataFallingBlock(); + + Vec3i worldPos = chunk.getPosition().mul_(16).add_(blockInChunk); + Vec3 floatWorldPos = new Vec3(worldPos.x, worldPos.y, worldPos.z); + fallingBlock.setPosition(floatWorldPos); + + fallingBlock.setEntityId(("Test:FallingBlock" + floatWorldPos.toString() + + String.valueOf(new Random().nextFloat())).hashCode()); + + chunk.getWorld().addEntity(fallingBlock); + chunk.setBlock(blockInChunk, BlockDataRegistry.getInstance().get("Test:Air"), true); + } + } + }); } }); } @@ -88,12 +128,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - BlockData[] granites = new BlockData[] { - BlockDataRegistry.getInstance().get("Test:GraniteGravel"), - BlockDataRegistry.getInstance().get("Test:GraniteGravel"), - BlockDataRegistry.getInstance().get("Test:GraniteCracked"), - BlockDataRegistry.getInstance().get("Test:GraniteMonolith") - }; + BlockData[] granites = new BlockData[] { BlockDataRegistry.getInstance().get("Test:GraniteGravel"), + BlockDataRegistry.getInstance().get("Test:GraniteGravel"), + BlockDataRegistry.getInstance().get("Test:GraniteCracked"), + BlockDataRegistry.getInstance().get("Test:GraniteMonolith") }; double[][] heightMap = new double[bpc][bpc]; double[][] gradMap = new double[bpc][bpc]; @@ -168,7 +206,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { ChunkData chunk = world.getChunk(chunkPos); assert chunk != null : "Something went wrong when populating chunk at (" + chunkPos.x + "; " + chunkPos.y + "; " - + chunkPos.z + ")"; + + chunkPos.z + ")"; BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); @@ -203,15 +241,8 @@ public class TestWorldGenerator extends AbstractWorldGenerator { int xic = Coordinates.convertInWorldToInChunk(biw.x); int yic = Coordinates.convertInWorldToInChunk(biw.y); - addTiles( - chunk, - biw, - world, - random, - world.getBlock(biw) == dirt, - heightMap[xic][yic], - gradMap[xic][yic] - ); + addTiles(chunk, biw, world, random, world.getBlock(biw) == dirt, heightMap[xic][yic], + gradMap[xic][yic]); } } @@ -219,15 +250,8 @@ public class TestWorldGenerator extends AbstractWorldGenerator { chunk.setGenerationHint(true); } - private void addTiles( - ChunkData chunk, - Vec3i biw, - WorldData world, - Random random, - boolean isDirt, - double height, - double grad - ) { + private void addTiles(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt, double height, + double grad) { if (isDirt) addGrass(chunk, biw, world, random); addDecor(chunk, biw, world, random, isDirt); @@ -257,40 +281,26 @@ public class TestWorldGenerator extends AbstractWorldGenerator { private void addDecor(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt) { if (isDirt) { if (random.nextInt(8) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( - TileDataRegistry.getInstance().get("Test:Sand") - ); + world.getTiles(biw, BlockFace.TOP).addFarthest(TileDataRegistry.getInstance().get("Test:Sand")); } if (random.nextInt(8) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( - TileDataRegistry.getInstance().get("Test:Stones") - ); + world.getTiles(biw, BlockFace.TOP).addFarthest(TileDataRegistry.getInstance().get("Test:Stones")); } if (random.nextInt(8) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( - TileDataRegistry.getInstance().get("Test:YellowFlowers") - ); + world.getTiles(biw, BlockFace.TOP) + .addFarthest(TileDataRegistry.getInstance().get("Test:YellowFlowers")); } } else { if (random.nextInt(2) == 0) { - world.getTiles(biw, BlockFace.TOP).addFarthest( - TileDataRegistry.getInstance().get("Test:Stones") - ); + world.getTiles(biw, BlockFace.TOP).addFarthest(TileDataRegistry.getInstance().get("Test:Stones")); } } } - private void addSnow( - ChunkData chunk, - Vec3i biw, - WorldData world, - Random random, - boolean isDirt, - double height, - double grad - ) { + private void addSnow(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt, double height, + double grad) { if (height < 1500) return; From b3ae82938327f3cff4ec86e091a1f5a877319c87 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Sun, 9 May 2021 15:57:38 -0400 Subject: [PATCH 27/63] Almost All Works -Added Set in TestEntityLogicFallingBlock to keep track of gravity blocks -Used this set in listener in TestWorldGenerator -setInvisible and isDone() methods in TestEntityDataFallingBlock -Used to determine if the entity should be rendered/cared about in TestEntityRenderFallingBlock and TestEntityLogicFallingBlock -Added more accurate Vec3i mod and div methods in TestEntityLogicFallingBlock *Change this to a better place -TestEntityLogicFallingBlock actually places the block when the entity lands -Better air block detection in TestWorldGenerator *Still cannot erase the original placed block, not sure why. --- .../test/TestEntityDataFallingBlock.java | 13 +++++ .../test/TestEntityLogicFallingBlock.java | 58 +++++++++++++++---- .../test/TestEntityRenderFallingBlock.java | 29 +++++----- .../test/gen/TestWorldGenerator.java | 21 +++---- 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java index cdb5060..cf47a29 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java @@ -12,6 +12,7 @@ import ru.windcorp.progressia.common.world.entity.EntityData; public class TestEntityDataFallingBlock extends EntityData { private BlockData block; + private boolean isDone = false; public TestEntityDataFallingBlock() { this("Test:FallingBlock",new BlockData("Test:Sand")); @@ -27,4 +28,16 @@ public class TestEntityDataFallingBlock extends EntityData { { return block; } + + public void setInvisible() + { + //block = new BlockData("Test:Log"); + isDone = true; + setCollisionModel(new AABB(0,0,0,.5f,0.5f,0.5f)); + } + + public boolean isDone() + { + return isDone; + } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index 1b8b600..2c52c73 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -1,9 +1,13 @@ package ru.windcorp.progressia.test; +import java.util.HashSet; +import java.util.Set; + import org.apache.logging.log4j.LogManager; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.server.world.TickContext; import ru.windcorp.progressia.server.world.entity.EntityLogic; @@ -15,12 +19,37 @@ import ru.windcorp.progressia.server.world.entity.EntityLogic; */ public class TestEntityLogicFallingBlock extends EntityLogic { + public static Set FallingBlocks = new HashSet(); + + public void addFallables() + { + FallingBlocks.add("Test:Sand"); + } + public TestEntityLogicFallingBlock(String id) { super(id); + addFallables(); + } + + private Vec3i trueMod(Vec3i input,Vec3i modulus) //Move this to a class in Vec or something + { + return input.mod_(modulus).add_(modulus).mod_(modulus); + } + + private Vec3i trueDiv(Vec3i input,Vec3i divisor) //Move this to a class in Vec or something + { + Vec3i temp = input.div_(divisor); + temp.add(new Vec3i(input.x<0 ? -1 : 0,input.y<0 ? -1 : 0,input.z<0 ? -1 : 0)); + return temp; } @Override public void tick(EntityData entity, TickContext context) { + if (entity == null) + { + return; + } + //LogManager.getLogger().info("NotNull "+entity.toString() + " " + context.toString()); super.tick(entity, context); //friction @@ -28,24 +57,31 @@ public class TestEntityLogicFallingBlock extends EntityLogic { float friction = .8f; vel = new Vec3(vel.x*friction,vel.y*friction,vel.z); entity.setVelocity(vel); - - TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) context.getServer().getWorld().getData().getEntity(entity.getEntityId());; - - Vec3i occupiedBlock = entity.getBlockInWorld(null); + TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); + //fallBlock = (TestEntityDataFallingBlock) entity; + + if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) + { + return; + } + + Vec3i occupiedBlock = fallBlock.getBlockInWorld(null); Vec3i underBlock = occupiedBlock.sub_(0, 0, 1); - Vec3i chunkCoords = underBlock.div_(16); - Vec3i inChunkCoords = underBlock.mod_(new Vec3i(16)); + Vec3i chunkCoords = trueDiv(underBlock, new Vec3i(16)); + Vec3i inChunkCoords = trueMod(underBlock, new Vec3i(16)); - LogManager.getLogger().info("FallingBlock is at "+String.valueOf(occupiedBlock.x)+" "+String.valueOf(occupiedBlock.y)+" "+String.valueOf(occupiedBlock.z)); - LogManager.getLogger().info("Block is of type " + context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); + //LogManager.getLogger().info("InChunk "+String.valueOf(chunkCoords.x)+" "+String.valueOf(chunkCoords.y)+" "+String.valueOf(chunkCoords.z)+" "+String.valueOf(inChunkCoords.x)+" "+String.valueOf(inChunkCoords.y)+" "+String.valueOf(inChunkCoords.z)); + //LogManager.getLogger().info("FallingBlock is at "+String.valueOf(occupiedBlock.x)+" "+String.valueOf(occupiedBlock.y)+" "+String.valueOf(occupiedBlock.z)); + //LogManager.getLogger().info("Block is of type " + context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - if (context.getServer().getWorld().getData().getChunk(chunkCoords).getBlock(inChunkCoords) + if (ClientState.getInstance().getWorld().getData().getChunk(chunkCoords).getBlock(inChunkCoords) .getId() != "Test:Air") { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); - context.getServer().getWorldAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); - context.getServer().getWorld().getData().removeEntity(entity); + ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, fallBlock.getBlock(),true); + fallBlock.setInvisible(); //Until I know how to properly delete it. + //ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId()); } } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java index 7fe07da..fccb704 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java @@ -15,6 +15,7 @@ import ru.windcorp.progressia.common.world.entity.EntityData; /** * Renderer for Test:FallingBlock + * * @author opfromthestart * */ @@ -23,22 +24,13 @@ public class TestEntityRenderFallingBlock extends EntityRender { public TestEntityRenderFallingBlock(String id) { super(id); - cube = new Shapes.PppBuilder( - WorldRenderProgram.getDefault(), - new SimpleTexture( - Atlases.getSprite( - ResourceManager.getTextureResource("blocks/Sand"), new AtlasGroup("Blocks", 1 << 12) - ) - ) - ).create(); + cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), new SimpleTexture(Atlases + .getSprite(ResourceManager.getTextureResource("blocks/Sand"), new AtlasGroup("Blocks", 1 << 12)))) + .create(); } - + public void setTexture(Texture texture) { // There has to be a better way. - cube = new Shapes.PppBuilder( - WorldRenderProgram.getDefault(), - texture - ) - .create(); + cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), texture).create(); } @Override @@ -46,7 +38,14 @@ public class TestEntityRenderFallingBlock extends EntityRender { return new EntityRenderable(entity) { @Override public void render(ShapeRenderHelper renderer) { - //LogManager.getLogger().info("Rendering FallingBlock"); + // LogManager.getLogger().info("Rendering FallingBlock"); + if (((TestEntityDataFallingBlock) entity).isDone()) { + return; + //setTexture(new SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/LogSide"), + // new AtlasGroup("Blocks", 1 << 12)))); + } + //setTexture(new SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/Sand"), + // new AtlasGroup("Blocks", 1 << 12)))); cube.render(renderer); } }; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 5898fe3..6ec975f 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -27,6 +27,7 @@ import org.apache.logging.log4j.LogManager; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; @@ -43,6 +44,7 @@ import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; import ru.windcorp.progressia.test.TestEntityDataFallingBlock; +import ru.windcorp.progressia.test.TestEntityLogicFallingBlock; public class TestWorldGenerator extends AbstractWorldGenerator { @@ -60,20 +62,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { - if (current.getId() != "Test:Sand") { // Replace with - // proper check - // for all - // gravity - // blocks + if (!TestEntityLogicFallingBlock.FallingBlocks.contains(current.getId())) { return; } - if (chunk.getBlock(blockInChunk.add_(0, 0, -1)).getId() == "Test:Air")// TODO - // Won't - // work - // on - // z - // chunk - // boundaries + if (chunk.getWorld().getBlock(chunk.getPosition().mul_(16).add_(blockInChunk.add_(0, 0, -1))).getId() == "Test:Air") { LogManager.getLogger().info("Inserting FallingBlock"); @@ -87,7 +79,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { + String.valueOf(new Random().nextFloat())).hashCode()); chunk.getWorld().addEntity(fallingBlock); - chunk.setBlock(blockInChunk, BlockDataRegistry.getInstance().get("Test:Air"), true); + chunk.setBlock(blockInChunk, previous, true); + Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); + LogManager.getLogger().info(String.valueOf(chunkWorldPos.x)+" "+String.valueOf(chunkWorldPos.y)+" "+String.valueOf(chunkWorldPos.z)); + ClientState.getInstance().getWorld().getData().setBlock(chunkWorldPos, BlockDataRegistry.getInstance().get("Test:Glass"), true); } } }); From bf49687ab66557aa65429861d3edbb09a70a3009 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Thu, 10 Jun 2021 12:50:51 -0400 Subject: [PATCH 28/63] Better performance maybe? -Changed as many of the ClientState statements to context as I could. -Only looks for a sand based update once per block update(I think it was twice before) --- .../test/TestEntityLogicFallingBlock.java | 13 +++++++------ .../progressia/test/gen/TestWorldGenerator.java | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index 2c52c73..cff6b24 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -44,7 +44,7 @@ public class TestEntityLogicFallingBlock extends EntityLogic { } @Override - public void tick(EntityData entity, TickContext context) { + public void tick(EntityData entity, TickContext context) { //context.getWorldData() ClientState.getInstance().getWorld().getData() if (entity == null) { return; @@ -58,7 +58,7 @@ public class TestEntityLogicFallingBlock extends EntityLogic { vel = new Vec3(vel.x*friction,vel.y*friction,vel.z); entity.setVelocity(vel); - TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); + TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); //ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); //fallBlock = (TestEntityDataFallingBlock) entity; if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) @@ -76,12 +76,13 @@ public class TestEntityLogicFallingBlock extends EntityLogic { //LogManager.getLogger().info("FallingBlock is at "+String.valueOf(occupiedBlock.x)+" "+String.valueOf(occupiedBlock.y)+" "+String.valueOf(occupiedBlock.z)); //LogManager.getLogger().info("Block is of type " + context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - if (ClientState.getInstance().getWorld().getData().getChunk(chunkCoords).getBlock(inChunkCoords) + if (context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords) .getId() != "Test:Air") { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); - ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, fallBlock.getBlock(),true); - fallBlock.setInvisible(); //Until I know how to properly delete it. - //ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId()); + //ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, fallBlock.getBlock(),true); + context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); + //fallBlock.setInvisible(); //Until I know how to properly delete it. + context.getWorldData().removeEntity(entity.getEntityId()); } } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 6ec975f..6702856 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -27,7 +27,6 @@ import org.apache.logging.log4j.LogManager; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; @@ -58,7 +57,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public void onChunkLoaded(WorldData world, ChunkData chunk) { findAndPopulate(chunk.getPosition(), world); - chunk.addListener(new ChunkDataListener() { + chunk.addListener(new ChunkDataListener() { //Falling Block spawning logic @Override public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { @@ -79,10 +78,11 @@ public class TestWorldGenerator extends AbstractWorldGenerator { + String.valueOf(new Random().nextFloat())).hashCode()); chunk.getWorld().addEntity(fallingBlock); - chunk.setBlock(blockInChunk, previous, true); + + chunk.setBlock(blockInChunk, previous, false); Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); LogManager.getLogger().info(String.valueOf(chunkWorldPos.x)+" "+String.valueOf(chunkWorldPos.y)+" "+String.valueOf(chunkWorldPos.z)); - ClientState.getInstance().getWorld().getData().setBlock(chunkWorldPos, BlockDataRegistry.getInstance().get("Test:Glass"), true); + world.setBlock(chunkWorldPos, BlockDataRegistry.getInstance().get("Test:Glass"), false); } } }); From 47eb9fa5af9edc9066bd3d63c31c7b946ec2423d Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Thu, 10 Jun 2021 14:08:35 -0400 Subject: [PATCH 29/63] Conservation of Matter -Placing a Test:Sand block now deletes the block and summons a Test:FallingBlock in its place. --- .../test/TestEntityDataFallingBlock.java | 11 +++++++++++ .../test/TestEntityLogicFallingBlock.java | 15 ++++++++++++--- .../progressia/test/gen/TestWorldGenerator.java | 1 - 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java index cf47a29..0b1e1e1 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java @@ -13,6 +13,7 @@ public class TestEntityDataFallingBlock extends EntityData { private BlockData block; private boolean isDone = false; + private boolean hasDeleted = false; public TestEntityDataFallingBlock() { this("Test:FallingBlock",new BlockData("Test:Sand")); @@ -24,6 +25,16 @@ public class TestEntityDataFallingBlock extends EntityData { block = blockInput; } + public void setDestroyed() + { + hasDeleted = true; + } + + public boolean hasDestroyed() + { + return hasDeleted; + } + public BlockData getBlock() { return block; diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index cff6b24..62b8337 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.ClientState; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.server.world.TickContext; import ru.windcorp.progressia.server.world.entity.EntityLogic; @@ -49,12 +50,13 @@ public class TestEntityLogicFallingBlock extends EntityLogic { { return; } + //LogManager.getLogger().info("NotNull "+entity.toString() + " " + context.toString()); super.tick(entity, context); //friction Vec3 vel = entity.getVelocity(); - float friction = .8f; + float friction = 0f; vel = new Vec3(vel.x*friction,vel.y*friction,vel.z); entity.setVelocity(vel); @@ -66,6 +68,13 @@ public class TestEntityLogicFallingBlock extends EntityLogic { return; } + if (!fallBlock.hasDestroyed()) + { + //LogManager.getLogger().info(fallBlock.getStartPos()); + context.getAccessor().setBlock(fallBlock.getBlockInWorld(null), BlockDataRegistry.getInstance().get("Test:Air")); + fallBlock.setDestroyed(); + } + Vec3i occupiedBlock = fallBlock.getBlockInWorld(null); Vec3i underBlock = occupiedBlock.sub_(0, 0, 1); @@ -81,8 +90,8 @@ public class TestEntityLogicFallingBlock extends EntityLogic { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); //ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, fallBlock.getBlock(),true); context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); - //fallBlock.setInvisible(); //Until I know how to properly delete it. - context.getWorldData().removeEntity(entity.getEntityId()); + fallBlock.setInvisible(); //Until I know how to properly delete it. + //context.getWorldData().removeEntity(entity.getEntityId()); } } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 6702856..bb3acc9 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -82,7 +82,6 @@ public class TestWorldGenerator extends AbstractWorldGenerator { chunk.setBlock(blockInChunk, previous, false); Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); LogManager.getLogger().info(String.valueOf(chunkWorldPos.x)+" "+String.valueOf(chunkWorldPos.y)+" "+String.valueOf(chunkWorldPos.z)); - world.setBlock(chunkWorldPos, BlockDataRegistry.getInstance().get("Test:Glass"), false); } } }); From 3879e5ffac06df6b4fda80d9a532a72ddd4f5196 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Thu, 10 Jun 2021 15:56:15 -0400 Subject: [PATCH 30/63] Sand Towers Fall -The listener in TestWorldGenerator updates any block above it if that block is a block that can be affected by gravity. -Format happened(I forgot) --- .../test/CollisionModelRenderer.java | 11 +- .../test/ControlBreakBlockData.java | 2 +- .../test/ControlPlaceBlockData.java | 2 +- .../progressia/test/ControlPlaceTileData.java | 2 +- .../windcorp/progressia/test/LayerAbout.java | 25 +- .../progressia/test/LayerTestGUI.java | 367 ++++++----------- .../windcorp/progressia/test/LayerTestUI.java | 51 +-- .../progressia/test/TestBlockLogicAir.java | 2 +- .../progressia/test/TestBlockLogicGlass.java | 2 +- .../progressia/test/TestChunkCodec.java | 5 +- .../windcorp/progressia/test/TestContent.java | 103 ++--- .../test/TestEntityDataFallingBlock.java | 38 +- .../progressia/test/TestEntityDataStatie.java | 2 +- .../test/TestEntityLogicFallingBlock.java | 89 ++-- .../test/TestEntityLogicStatie.java | 2 +- .../test/TestEntityRenderFallingBlock.java | 10 +- .../test/TestEntityRenderHuman.java | 162 ++------ .../test/TestEntityRenderJavapony.java | 387 ++++-------------- .../test/TestEntityRenderStatie.java | 14 +- .../progressia/test/TestMusicPlayer.java | 55 +-- .../progressia/test/TestPlayerControls.java | 26 +- .../progressia/test/TestTileLogicGrass.java | 2 +- .../progressia/test/TestWorldDiskIO.java | 72 +--- .../test/gen/TestWorldGenerator.java | 20 +- 24 files changed, 433 insertions(+), 1018 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/CollisionModelRenderer.java b/src/main/java/ru/windcorp/progressia/test/CollisionModelRenderer.java index 4c7ca68..345e7f8 100644 --- a/src/main/java/ru/windcorp/progressia/test/CollisionModelRenderer.java +++ b/src/main/java/ru/windcorp/progressia/test/CollisionModelRenderer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import glm.mat._4.Mat4; @@ -33,9 +33,9 @@ import ru.windcorp.progressia.common.collision.CompoundCollisionModel; public class CollisionModelRenderer { private static final Shape CUBE = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null) - .setColorMultiplier(1.0f, 0.7f, 0.2f).create(); + .setColorMultiplier(1.0f, 0.7f, 0.2f).create(); private static final Shape CUBE_GRAY = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null) - .setColorMultiplier(0.5f, 0.5f, 0.5f).create(); + .setColorMultiplier(0.5f, 0.5f, 0.5f).create(); public static void renderCollisionModel(CollisionModel model, ShapeRenderHelper helper) { if (model instanceof AABBoid) { @@ -60,10 +60,7 @@ public class CollisionModelRenderer { helper.popTransform(); } - private static void renderCompound( - CompoundCollisionModel model, - ShapeRenderHelper helper - ) { + private static void renderCompound(CompoundCollisionModel model, ShapeRenderHelper helper) { for (CollisionModel part : model.getModels()) { renderCollisionModel(part, helper); } diff --git a/src/main/java/ru/windcorp/progressia/test/ControlBreakBlockData.java b/src/main/java/ru/windcorp/progressia/test/ControlBreakBlockData.java index a9df57a..d7e8a36 100644 --- a/src/main/java/ru/windcorp/progressia/test/ControlBreakBlockData.java +++ b/src/main/java/ru/windcorp/progressia/test/ControlBreakBlockData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/test/ControlPlaceBlockData.java b/src/main/java/ru/windcorp/progressia/test/ControlPlaceBlockData.java index f3e45e2..f83a0cc 100644 --- a/src/main/java/ru/windcorp/progressia/test/ControlPlaceBlockData.java +++ b/src/main/java/ru/windcorp/progressia/test/ControlPlaceBlockData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java b/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java index 5a37b6f..5835d7b 100644 --- a/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java +++ b/src/main/java/ru/windcorp/progressia/test/ControlPlaceTileData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/test/LayerAbout.java b/src/main/java/ru/windcorp/progressia/test/LayerAbout.java index 3eaff87..20260b0 100644 --- a/src/main/java/ru/windcorp/progressia/test/LayerAbout.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerAbout.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.client.graphics.Colors; @@ -38,29 +38,12 @@ public class LayerAbout extends GUILayer { Font font = new Font().withColor(Colors.WHITE).deriveOutlined().withAlign(Typeface.ALIGN_RIGHT); Font aboutFont = font.withColor(0xFF37A3E6).deriveBold(); - panel.addChild( - new Label( - "About", - aboutFont, - new MutableStringLocalized("LayerAbout.Title") - ) - ); + panel.addChild(new Label("About", aboutFont, new MutableStringLocalized("LayerAbout.Title"))); panel.addChild( - new Label( - "Version", - font, - new MutableStringLocalized("LayerAbout.Version").format("pre-alpha 1") - ) - ); + new Label("Version", font, new MutableStringLocalized("LayerAbout.Version").format("pre-alpha 1"))); - panel.addChild( - new Label( - "DebugHint", - font, - new MutableStringLocalized("LayerAbout.DebugHint") - ) - ); + panel.addChild(new Label("DebugHint", font, new MutableStringLocalized("LayerAbout.DebugHint"))); getRoot().addChild(panel); diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java index ca02ed8..db42176 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import glm.vec._3.Vec3; @@ -58,146 +58,51 @@ public class LayerTestGUI extends GUILayer { TestPlayerControls tpc = TestPlayerControls.getInstance(); panel.addChild( - new Label( - "IsFlyingDisplay", - font, - tmp_dynFormat("LayerTestGUI.IsFlyingDisplay", tpc::isFlying) - ) - ); + new Label("IsFlyingDisplay", font, tmp_dynFormat("LayerTestGUI.IsFlyingDisplay", tpc::isFlying))); + + panel.addChild(new Label("IsSprintingDisplay", font, + tmp_dynFormat("LayerTestGUI.IsSprintingDisplay", tpc::isSprinting))); + + panel.addChild(new Label("IsMouseCapturedDisplay", font, + tmp_dynFormat("LayerTestGUI.IsMouseCapturedDisplay", tpc::isMouseCaptured))); + + panel.addChild(new Label("CameraModeDisplay", font, tmp_dynFormat("LayerTestGUI.CameraModeDisplay", + ClientState.getInstance().getCamera()::getCurrentModeIndex))); + + panel.addChild(new Label("GravityModeDisplay", font, tmp_dynFormat("LayerTestGUI.GravityModeDisplay", + () -> tpc.useMinecraftGravity() ? "Minecraft" : "Realistic"))); + + panel.addChild(new Label("LanguageDisplay", font, + tmp_dynFormat("LayerTestGUI.LanguageDisplay", Localizer.getInstance()::getLanguage))); + + panel.addChild(new Label("FullscreenDisplay", font, + tmp_dynFormat("LayerTestGUI.IsFullscreen", GraphicsBackend::isFullscreen))); + + panel.addChild(new Label("VSyncDisplay", font, + tmp_dynFormat("LayerTestGUI.IsVSync", GraphicsBackend::isVSyncEnabled))); panel.addChild( - new Label( - "IsSprintingDisplay", - font, - tmp_dynFormat("LayerTestGUI.IsSprintingDisplay", tpc::isSprinting) - ) - ); + new DynamicLabel("FPSDisplay", font, + DynamicStrings.builder().addDyn(new MutableStringLocalized("LayerTestGUI.FPSDisplay")) + .addDyn(() -> FPS_RECORD.update(GraphicsInterface.getFPS()), 5, 1).buildSupplier(), + 128)); + + panel.addChild(new DynamicLabel("TPSDisplay", font, LayerTestGUI::getTPS, 128)); panel.addChild( - new Label( - "IsMouseCapturedDisplay", - font, - tmp_dynFormat("LayerTestGUI.IsMouseCapturedDisplay", tpc::isMouseCaptured) - ) - ); + new DynamicLabel("ChunkUpdatesDisplay", font, + DynamicStrings.builder().addDyn(new MutableStringLocalized("LayerTestGUI.ChunkUpdatesDisplay")) + .addDyn(ClientState.getInstance().getWorld()::getPendingChunkUpdates).buildSupplier(), + 128)); - panel.addChild( - new Label( - "CameraModeDisplay", - font, - tmp_dynFormat( - "LayerTestGUI.CameraModeDisplay", - ClientState.getInstance().getCamera()::getCurrentModeIndex - ) - ) - ); + panel.addChild(new DynamicLabel("PosDisplay", font, LayerTestGUI::getPos, 128)); - panel.addChild( - new Label( - "GravityModeDisplay", - font, - tmp_dynFormat( - "LayerTestGUI.GravityModeDisplay", - () -> tpc.useMinecraftGravity() ? "Minecraft" : "Realistic" - ) - ) - ); - - panel.addChild( - new Label( - "LanguageDisplay", - font, - tmp_dynFormat("LayerTestGUI.LanguageDisplay", Localizer.getInstance()::getLanguage) - ) - ); - - panel.addChild( - new Label( - "FullscreenDisplay", - font, - tmp_dynFormat("LayerTestGUI.IsFullscreen", GraphicsBackend::isFullscreen) - ) - ); - - panel.addChild( - new Label( - "VSyncDisplay", - font, - tmp_dynFormat("LayerTestGUI.IsVSync", GraphicsBackend::isVSyncEnabled) - ) - ); - - panel.addChild( - new DynamicLabel( - "FPSDisplay", - font, - DynamicStrings.builder() - .addDyn(new MutableStringLocalized("LayerTestGUI.FPSDisplay")) - .addDyn(() -> FPS_RECORD.update(GraphicsInterface.getFPS()), 5, 1) - .buildSupplier(), - 128 - ) - ); - - panel.addChild( - new DynamicLabel( - "TPSDisplay", - font, - LayerTestGUI::getTPS, - 128 - ) - ); - - panel.addChild( - new DynamicLabel( - "ChunkUpdatesDisplay", - font, - DynamicStrings.builder() - .addDyn(new MutableStringLocalized("LayerTestGUI.ChunkUpdatesDisplay")) - .addDyn(ClientState.getInstance().getWorld()::getPendingChunkUpdates) - .buildSupplier(), - 128 - ) - ); - - panel.addChild( - new DynamicLabel( - "PosDisplay", - font, - LayerTestGUI::getPos, - 128 - ) - ); - - panel.addChild( - new Label( - "SelectedBlockDisplay", - font, - tmp_dynFormat( - "LayerTestGUI.SelectedBlockDisplay", - () -> tpc.isBlockSelected() ? ">" : " ", - () -> tpc.getSelectedBlock().getId() - ) - ) - ); - panel.addChild( - new Label( - "SelectedTileDisplay", - font, - tmp_dynFormat( - "LayerTestGUI.SelectedTileDisplay", - () -> tpc.isBlockSelected() ? " " : ">", - () -> tpc.getSelectedTile().getId() - ) - ) - ); - panel.addChild( - new Label( - "PlacementModeHint", - font, - new MutableStringLocalized("LayerTestGUI.PlacementModeHint").format("\u2B04") - ) - ); + panel.addChild(new Label("SelectedBlockDisplay", font, tmp_dynFormat("LayerTestGUI.SelectedBlockDisplay", + () -> tpc.isBlockSelected() ? ">" : " ", () -> tpc.getSelectedBlock().getId()))); + panel.addChild(new Label("SelectedTileDisplay", font, tmp_dynFormat("LayerTestGUI.SelectedTileDisplay", + () -> tpc.isBlockSelected() ? " " : ">", () -> tpc.getSelectedTile().getId()))); + panel.addChild(new Label("PlacementModeHint", font, + new MutableStringLocalized("LayerTestGUI.PlacementModeHint").format("\u2B04"))); getRoot().addChild(panel); } @@ -265,16 +170,14 @@ public class LayerTestGUI extends GUILayer { private static final Averager TPS_RECORD = new Averager(); private static final Supplier TPS_STRING = DynamicStrings.builder() - .addDyn(new MutableStringLocalized("LayerTestGUI.TPSDisplay")) - .addDyn(() -> TPS_RECORD.update(ServerState.getInstance().getTPS()), 5, 1) - .buildSupplier(); + .addDyn(new MutableStringLocalized("LayerTestGUI.TPSDisplay")) + .addDyn(() -> TPS_RECORD.update(ServerState.getInstance().getTPS()), 5, 1).buildSupplier(); private static final Supplier POS_STRING = DynamicStrings.builder() - .addDyn(new MutableStringLocalized("LayerTestGUI.PosDisplay")) - .addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().x, 7, 1) - .addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().y, 7, 1) - .addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().z, 7, 1) - .buildSupplier(); + .addDyn(new MutableStringLocalized("LayerTestGUI.PosDisplay")) + .addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().x, 7, 1) + .addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().y, 7, 1) + .addDyn(() -> ClientState.getInstance().getCamera().getLastAnchorPosition().z, 7, 1).buildSupplier(); private static CharSequence getTPS() { Server server = ServerState.getInstance(); @@ -316,93 +219,95 @@ public class LayerTestGUI extends GUILayer { }); } -// private static class DebugComponent extends Component { -// private final int color; -// -// public DebugComponent(String name, Vec2i size, int color) { -// super(name); -// this.color = color; -// -// setPreferredSize(size); -// -// addListener(new Object() { -// @Subscribe -// public void onHoverChanged(HoverEvent e) { -// requestReassembly(); -// } -// }); -// -// addListener(KeyEvent.class, this::onClicked); -// } -// -// private boolean onClicked(KeyEvent event) { -// if (!event.isMouse()) { -// return false; -// } else if (event.isPress() && event.isLeftMouseButton()) { -// System.out.println("You pressed a Component!"); -// } -// return true; -// } -// -// @Override -// protected void assembleSelf(RenderTarget target) { -// target.fill(getX(), getY(), getWidth(), getHeight(), Colors.BLACK); -// -// target.fill( -// getX() + 2, getY() + 2, -// getWidth() - 4, getHeight() - 4, -// isHovered() ? Colors.DEBUG_YELLOW : color -// ); -// } -// } -// -// public LayerTestGUI() { -// super("LayerTestGui", new LayoutAlign(1, 0.75, 5)); -// -// Panel panel = new Panel("Alex", new LayoutVertical(5)); -// -// panel.addChild(new DebugComponent("Bravo", new Vec2i(200, 100), 0x44FF44)); -// -// Component charlie = new DebugComponent("Charlie", null, 0x222222); -// charlie.setLayout(new LayoutVertical(5)); -// -// //Debug -// Localizer.getInstance().setLanguage("ru-RU"); -// MutableString epsilon = new MutableStringLocalized("Epsilon") -// .addListener(() -> ((Label)charlie.getChild(0)).update()).format(34, "thirty-four"); -// // These two are swapped in code due to a bug in layouts, fixing ATM -// charlie.addChild( -// new Label( -// "Delta", -// new Font().withColor(0xCCBB44).deriveShadow().deriveBold(), -// "Пре-альфа!" -// ) -// ); -// charlie.addChild( -// new Label( -// "Epsilon", -// new Font().withColor(0x4444BB).deriveItalic(), -// () -> epsilon.get().concat("\u269b") -// ) -// ); -// panel.addChild(charlie); -// -// -// charlie.addListener(KeyEvent.class, e -> { -// if(e.isPress() && e.getKey() == GLFW.GLFW_KEY_L) { -// Localizer localizer = Localizer.getInstance(); -// if (localizer.getLanguage().equals("ru-RU")) { -// localizer.setLanguage("en-US"); -// } else { -// localizer.setLanguage("ru-RU"); -// } -// return true; -// } return false; -// }); -// charlie.setFocusable(true); -// charlie.takeFocus(); -// -// getRoot().addChild(panel); -// } + // private static class DebugComponent extends Component { + // private final int color; + // + // public DebugComponent(String name, Vec2i size, int color) { + // super(name); + // this.color = color; + // + // setPreferredSize(size); + // + // addListener(new Object() { + // @Subscribe + // public void onHoverChanged(HoverEvent e) { + // requestReassembly(); + // } + // }); + // + // addListener(KeyEvent.class, this::onClicked); + // } + // + // private boolean onClicked(KeyEvent event) { + // if (!event.isMouse()) { + // return false; + // } else if (event.isPress() && event.isLeftMouseButton()) { + // System.out.println("You pressed a Component!"); + // } + // return true; + // } + // + // @Override + // protected void assembleSelf(RenderTarget target) { + // target.fill(getX(), getY(), getWidth(), getHeight(), Colors.BLACK); + // + // target.fill( + // getX() + 2, getY() + 2, + // getWidth() - 4, getHeight() - 4, + // isHovered() ? Colors.DEBUG_YELLOW : color + // ); + // } + // } + // + // public LayerTestGUI() { + // super("LayerTestGui", new LayoutAlign(1, 0.75, 5)); + // + // Panel panel = new Panel("Alex", new LayoutVertical(5)); + // + // panel.addChild(new DebugComponent("Bravo", new Vec2i(200, 100), + // 0x44FF44)); + // + // Component charlie = new DebugComponent("Charlie", null, 0x222222); + // charlie.setLayout(new LayoutVertical(5)); + // + // //Debug + // Localizer.getInstance().setLanguage("ru-RU"); + // MutableString epsilon = new MutableStringLocalized("Epsilon") + // .addListener(() -> ((Label)charlie.getChild(0)).update()).format(34, + // "thirty-four"); + // // These two are swapped in code due to a bug in layouts, fixing ATM + // charlie.addChild( + // new Label( + // "Delta", + // new Font().withColor(0xCCBB44).deriveShadow().deriveBold(), + // "Пре-альфа!" + // ) + // ); + // charlie.addChild( + // new Label( + // "Epsilon", + // new Font().withColor(0x4444BB).deriveItalic(), + // () -> epsilon.get().concat("\u269b") + // ) + // ); + // panel.addChild(charlie); + // + // + // charlie.addListener(KeyEvent.class, e -> { + // if(e.isPress() && e.getKey() == GLFW.GLFW_KEY_L) { + // Localizer localizer = Localizer.getInstance(); + // if (localizer.getLanguage().equals("ru-RU")) { + // localizer.setLanguage("en-US"); + // } else { + // localizer.setLanguage("ru-RU"); + // } + // return true; + // } return false; + // }); + // charlie.setFocusable(true); + // charlie.takeFocus(); + // + // getRoot().addChild(panel); + // } } diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java index c93a055..892df0f 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import org.lwjgl.glfw.GLFW; @@ -75,17 +75,10 @@ public class LayerTestUI extends AssembledFlatLayer { target.drawTexture(texShadow, -texShadow, texSize, texSize, Colors.BLACK, compassBg); target.drawTexture(0, 0, texSize, texSize, compassBg); - target.addCustomRenderer( - new LambdaModel( - LambdaModel.lambdaBuilder() - .addDynamicPart( - target.createRectagle(0, 0, texSize, texSize, Colors.WHITE, compassFg), - mat -> mat.translate(texSize / 2, texSize / 2, 0) - .rotateZ(getCompassRotation()) - .translate(-texSize / 2, -texSize / 2, 0) - ) - ) - ); + target.addCustomRenderer(new LambdaModel(LambdaModel.lambdaBuilder().addDynamicPart( + target.createRectagle(0, 0, texSize, texSize, Colors.WHITE, compassFg), + mat -> mat.translate(texSize / 2, texSize / 2, 0).rotateZ(getCompassRotation()).translate(-texSize / 2, + -texSize / 2, 0)))); target.popTransform(); drawCross(target); @@ -110,37 +103,15 @@ public class LayerTestUI extends AssembledFlatLayer { final Vec4 borderColor = Colors.BLACK; final Vec4 fillColor = Colors.WHITE; - target.fill( - cx - length - thickness / 2, - cy - thickness / 2, - 2 * length + thickness, - thickness, - borderColor - ); + target.fill(cx - length - thickness / 2, cy - thickness / 2, 2 * length + thickness, thickness, borderColor); - target.fill( - cx - thickness / 2, - cy - length - thickness / 2, - thickness, - 2 * length + thickness, - borderColor - ); + target.fill(cx - thickness / 2, cy - length - thickness / 2, thickness, 2 * length + thickness, borderColor); - target.fill( - cx - length - thickness / 2 + borderSize, - cy - thickness / 2 + borderSize, - 2 * length + thickness - 2 * borderSize, - thickness - 2 * borderSize, - fillColor - ); + target.fill(cx - length - thickness / 2 + borderSize, cy - thickness / 2 + borderSize, + 2 * length + thickness - 2 * borderSize, thickness - 2 * borderSize, fillColor); - target.fill( - cx - thickness / 2 + borderSize, - cy - length - thickness / 2 + borderSize, - thickness - 2 * borderSize, - 2 * length + thickness - 2 * borderSize, - fillColor - ); + target.fill(cx - thickness / 2 + borderSize, cy - length - thickness / 2 + borderSize, + thickness - 2 * borderSize, 2 * length + thickness - 2 * borderSize, fillColor); } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java index e378dbf..e9877e9 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicAir.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.world.block.BlockFace; diff --git a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java index eca9e5c..e58cc3d 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBlockLogicGlass.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.world.block.BlockFace; diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index a4f891b..a9298a1 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import java.io.DataInput; @@ -85,8 +85,7 @@ public class TestChunkCodec extends ChunkCodec { @Override public ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) - throws DecodingException, - IOException { + throws DecodingException, IOException { BlockData[] blockPalette = readBlockPalette(input); TileData[] tilePalette = readTilePalette(input); diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 7f4ed7e..573fd1f 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import static ru.windcorp.progressia.client.world.block.BlockRenderRegistry.getBlockTexture; @@ -129,17 +129,9 @@ public class TestContent { register(new BlockLogic("Test:Concrete")); register(new BlockData("Test:Log")); - register( - new BlockRenderOpaqueCube( - "Test:Log", - getBlockTexture("LogTop"), - getBlockTexture("LogTop"), - getBlockTexture("LogSide"), - getBlockTexture("LogSide"), - getBlockTexture("LogSide"), - getBlockTexture("LogSide") - ) - ); + register(new BlockRenderOpaqueCube("Test:Log", getBlockTexture("LogTop"), getBlockTexture("LogTop"), + getBlockTexture("LogSide"), getBlockTexture("LogSide"), getBlockTexture("LogSide"), + getBlockTexture("LogSide"))); register(new BlockLogic("Test:Log")); register(new BlockData("Test:WoodenPlank")); @@ -257,49 +249,24 @@ public class TestContent { ControlLogicRegistry logic = ControlLogicRegistry.getInstance(); data.register("Test:BreakBlock", ControlBreakBlockData::new); - triggers.register( - ControlTriggers.of( - "Test:BreakBlock", - KeyEvent.class, - TestContent::onBlockBreakTrigger, - KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_LEFT).matcher(), - i -> isAnythingSelected() - ) - ); + triggers.register(ControlTriggers.of("Test:BreakBlock", KeyEvent.class, TestContent::onBlockBreakTrigger, + KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_LEFT).matcher(), i -> isAnythingSelected())); logic.register(ControlLogic.of("Test:BreakBlock", TestContent::onBlockBreakReceived)); data.register("Test:PlaceBlock", ControlPlaceBlockData::new); - triggers.register( - ControlTriggers.of( - "Test:PlaceBlock", - KeyEvent.class, - TestContent::onBlockPlaceTrigger, + triggers.register(ControlTriggers.of("Test:PlaceBlock", KeyEvent.class, TestContent::onBlockPlaceTrigger, KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_RIGHT).matcher(), - i -> isAnythingSelected() && TestPlayerControls.getInstance().isBlockSelected() - ) - ); + i -> isAnythingSelected() && TestPlayerControls.getInstance().isBlockSelected())); logic.register(ControlLogic.of("Test:PlaceBlock", TestContent::onBlockPlaceReceived)); data.register("Test:PlaceTile", ControlPlaceTileData::new); - triggers.register( - ControlTriggers.of( - "Test:PlaceTile", - KeyEvent.class, - TestContent::onTilePlaceTrigger, + triggers.register(ControlTriggers.of("Test:PlaceTile", KeyEvent.class, TestContent::onTilePlaceTrigger, KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_RIGHT).matcher(), - i -> isAnythingSelected() && !TestPlayerControls.getInstance().isBlockSelected() - ) - ); + i -> isAnythingSelected() && !TestPlayerControls.getInstance().isBlockSelected())); logic.register(ControlLogic.of("Test:PlaceTile", TestContent::onTilePlaceReceived)); - - triggers.register( - ControlTriggers.localOf( - "Test:StartNextMusic", - KeyEvent.class, - TestMusicPlayer::startNextNow, - KeyMatcher.of(GLFW.GLFW_KEY_M).matcher() - ) - ); + + triggers.register(ControlTriggers.localOf("Test:StartNextMusic", KeyEvent.class, TestMusicPlayer::startNextNow, + KeyMatcher.of(GLFW.GLFW_KEY_M).matcher())); } private static void register(BlockData x) { @@ -310,17 +277,11 @@ public class TestContent { TileDataRegistry.getInstance().register(x); } - private static void register( - String id, - Factory factory - ) { + private static void register(String id, Factory factory) { EntityDataRegistry.getInstance().register(id, factory); } - private static void registerEntityData( - String id, - Consumer transform - ) { + private static void registerEntityData(String id, Consumer transform) { EntityDataRegistry.getInstance().register(id, new Factory() { @Override public EntityData build() { @@ -379,27 +340,19 @@ public class TestContent { sfx.play(false); } - private static void onBlockBreakReceived( - Server server, - PacketControl packet, - ru.windcorp.progressia.server.comms.Client client - ) { + private static void onBlockBreakReceived(Server server, PacketControl packet, + ru.windcorp.progressia.server.comms.Client client) { Vec3i blockInWorld = ((ControlBreakBlockData) packet.getControl()).getBlockInWorld(); server.getWorldAccessor().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air")); } private static void onBlockPlaceTrigger(ControlData control) { - ((ControlPlaceBlockData) control).set( - TestPlayerControls.getInstance().getSelectedBlock(), - getSelection().getBlock().add_(getSelection().getSurface().getVector()) - ); + ((ControlPlaceBlockData) control).set(TestPlayerControls.getInstance().getSelectedBlock(), + getSelection().getBlock().add_(getSelection().getSurface().getVector())); } - private static void onBlockPlaceReceived( - Server server, - PacketControl packet, - ru.windcorp.progressia.server.comms.Client client - ) { + private static void onBlockPlaceReceived(Server server, PacketControl packet, + ru.windcorp.progressia.server.comms.Client client) { ControlPlaceBlockData controlData = ((ControlPlaceBlockData) packet.getControl()); BlockData block = controlData.getBlock(); Vec3i blockInWorld = controlData.getBlockInWorld(); @@ -409,18 +362,12 @@ public class TestContent { } private static void onTilePlaceTrigger(ControlData control) { - ((ControlPlaceTileData) control).set( - TestPlayerControls.getInstance().getSelectedTile(), - getSelection().getBlock(), - getSelection().getSurface() - ); + ((ControlPlaceTileData) control).set(TestPlayerControls.getInstance().getSelectedTile(), + getSelection().getBlock(), getSelection().getSurface()); } - private static void onTilePlaceReceived( - Server server, - PacketControl packet, - ru.windcorp.progressia.server.comms.Client client - ) { + private static void onTilePlaceReceived(Server server, PacketControl packet, + ru.windcorp.progressia.server.comms.Client client) { ControlPlaceTileData controlData = ((ControlPlaceTileData) packet.getControl()); TileData tile = controlData.getTile(); Vec3i blockInWorld = controlData.getBlockInWorld(); diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java index 0b1e1e1..7d11bb6 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java @@ -6,49 +6,45 @@ import ru.windcorp.progressia.common.world.entity.EntityData; /** * Data for Test:FallingBlock + * * @author opfromthestart * */ public class TestEntityDataFallingBlock extends EntityData { - + private BlockData block; private boolean isDone = false; private boolean hasDeleted = false; public TestEntityDataFallingBlock() { - this("Test:FallingBlock",new BlockData("Test:Sand")); + this("Test:FallingBlock", new BlockData("Test:Sand")); } - + protected TestEntityDataFallingBlock(String id, BlockData blockInput) { super(id); - setCollisionModel(new AABB(0,0,0,1,1,1)); + setCollisionModel(new AABB(0, 0, 0, 1, 1, 1)); block = blockInput; } - - public void setDestroyed() - { + + public void setDestroyed() { hasDeleted = true; } - - public boolean hasDestroyed() - { + + public boolean hasDestroyed() { return hasDeleted; } - - public BlockData getBlock() - { + + public BlockData getBlock() { return block; } - - public void setInvisible() - { - //block = new BlockData("Test:Log"); + + public void setInvisible() { + // block = new BlockData("Test:Log"); isDone = true; - setCollisionModel(new AABB(0,0,0,.5f,0.5f,0.5f)); + setCollisionModel(new AABB(0, 0, 0, .5f, 0.5f, 0.5f)); } - - public boolean isDone() - { + + public boolean isDone() { return isDone; } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java index 94f5043..6bbee70 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataStatie.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.collision.AABB; diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index 62b8337..ccbb37a 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -15,83 +15,94 @@ import ru.windcorp.progressia.server.world.entity.EntityLogic; /** * Logic for Test:FallingBlock + * * @author opfromthestart * */ public class TestEntityLogicFallingBlock extends EntityLogic { public static Set FallingBlocks = new HashSet(); - - public void addFallables() - { + + public void addFallables() { FallingBlocks.add("Test:Sand"); } - + public TestEntityLogicFallingBlock(String id) { super(id); addFallables(); } - - private Vec3i trueMod(Vec3i input,Vec3i modulus) //Move this to a class in Vec or something + + private Vec3i trueMod(Vec3i input, Vec3i modulus) // Move this to a class in + // Vec or something { return input.mod_(modulus).add_(modulus).mod_(modulus); } - - private Vec3i trueDiv(Vec3i input,Vec3i divisor) //Move this to a class in Vec or something + + private Vec3i trueDiv(Vec3i input, Vec3i divisor) // Move this to a class in + // Vec or something { Vec3i temp = input.div_(divisor); - temp.add(new Vec3i(input.x<0 ? -1 : 0,input.y<0 ? -1 : 0,input.z<0 ? -1 : 0)); + temp.add(new Vec3i(input.x < 0 ? -1 : 0, input.y < 0 ? -1 : 0, input.z < 0 ? -1 : 0)); return temp; } @Override - public void tick(EntityData entity, TickContext context) { //context.getWorldData() ClientState.getInstance().getWorld().getData() - if (entity == null) - { + public void tick(EntityData entity, TickContext context) { // context.getWorldData() + // ClientState.getInstance().getWorld().getData() + if (entity == null) { return; } - - //LogManager.getLogger().info("NotNull "+entity.toString() + " " + context.toString()); + + // LogManager.getLogger().info("NotNull "+entity.toString() + " " + + // context.toString()); super.tick(entity, context); - - //friction + + // friction Vec3 vel = entity.getVelocity(); float friction = 0f; - vel = new Vec3(vel.x*friction,vel.y*friction,vel.z); + vel = new Vec3(vel.x * friction, vel.y * friction, vel.z); entity.setVelocity(vel); - - TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); //ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); - //fallBlock = (TestEntityDataFallingBlock) entity; - - if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) - { + + TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld() + .getData().getEntity(entity.getEntityId()); // ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); + // fallBlock = (TestEntityDataFallingBlock) entity; + + if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) { return; } - - if (!fallBlock.hasDestroyed()) - { - //LogManager.getLogger().info(fallBlock.getStartPos()); - context.getAccessor().setBlock(fallBlock.getBlockInWorld(null), BlockDataRegistry.getInstance().get("Test:Air")); + + if (!fallBlock.hasDestroyed()) { + // LogManager.getLogger().info(fallBlock.getStartPos()); + context.getAccessor().setBlock(fallBlock.getBlockInWorld(null), + BlockDataRegistry.getInstance().get("Test:Air")); fallBlock.setDestroyed(); } - + Vec3i occupiedBlock = fallBlock.getBlockInWorld(null); Vec3i underBlock = occupiedBlock.sub_(0, 0, 1); - + Vec3i chunkCoords = trueDiv(underBlock, new Vec3i(16)); Vec3i inChunkCoords = trueMod(underBlock, new Vec3i(16)); - - //LogManager.getLogger().info("InChunk "+String.valueOf(chunkCoords.x)+" "+String.valueOf(chunkCoords.y)+" "+String.valueOf(chunkCoords.z)+" "+String.valueOf(inChunkCoords.x)+" "+String.valueOf(inChunkCoords.y)+" "+String.valueOf(inChunkCoords.z)); - //LogManager.getLogger().info("FallingBlock is at "+String.valueOf(occupiedBlock.x)+" "+String.valueOf(occupiedBlock.y)+" "+String.valueOf(occupiedBlock.z)); - //LogManager.getLogger().info("Block is of type " + context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - if (context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords) - .getId() != "Test:Air") { + // LogManager.getLogger().info("InChunk + // "+String.valueOf(chunkCoords.x)+" "+String.valueOf(chunkCoords.y)+" + // "+String.valueOf(chunkCoords.z)+" "+String.valueOf(inChunkCoords.x)+" + // "+String.valueOf(inChunkCoords.y)+" + // "+String.valueOf(inChunkCoords.z)); + // LogManager.getLogger().info("FallingBlock is at + // "+String.valueOf(occupiedBlock.x)+" + // "+String.valueOf(occupiedBlock.y)+" + // "+String.valueOf(occupiedBlock.z)); + // LogManager.getLogger().info("Block is of type " + + // context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); + + if (context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); - //ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, fallBlock.getBlock(),true); + // ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, + // fallBlock.getBlock(),true); context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); - fallBlock.setInvisible(); //Until I know how to properly delete it. - //context.getWorldData().removeEntity(entity.getEntityId()); + fallBlock.setInvisible(); // Until I know how to properly delete it. + // context.getWorldData().removeEntity(entity.getEntityId()); } } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java index 5fa66fb..f27abfe 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.world.entity.EntityData; diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java index fccb704..0adaa34 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java @@ -41,11 +41,13 @@ public class TestEntityRenderFallingBlock extends EntityRender { // LogManager.getLogger().info("Rendering FallingBlock"); if (((TestEntityDataFallingBlock) entity).isDone()) { return; - //setTexture(new SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/LogSide"), - // new AtlasGroup("Blocks", 1 << 12)))); + // setTexture(new + // SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/LogSide"), + // new AtlasGroup("Blocks", 1 << 12)))); } - //setTexture(new SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/Sand"), - // new AtlasGroup("Blocks", 1 << 12)))); + // setTexture(new + // SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/Sand"), + // new AtlasGroup("Blocks", 1 << 12)))); cube.render(renderer); } }; diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderHuman.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderHuman.java index 388d89c..31b73ca 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderHuman.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderHuman.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import static java.lang.Math.toRadians; @@ -56,11 +56,7 @@ public class TestEntityRenderHuman extends EntityRender { this.skin = fetchSkin(); - ComplexTexture texture = new ComplexTexture( - this.skin, - 16, - 16 - ); + ComplexTexture texture = new ComplexTexture(this.skin, 16, 16); this.body = createBody(texture); this.head = createHead(texture); @@ -80,109 +76,37 @@ public class TestEntityRenderHuman extends EntityRender { } private Renderable createBody(ComplexTexture texture) { - return createLayeredCuboid( - texture, - 4, - 8, - 4, - 4, - 2, - 3, - 1, - -0.5f, - -1, - 3, - 1, - 2, - 3 - ); + return createLayeredCuboid(texture, 4, 8, 4, 4, 2, 3, 1, -0.5f, -1, 3, 1, 2, 3); } private Renderable createHead(ComplexTexture texture) { - return createLayeredCuboid( - texture, - 0, - 12, - 8, - 12, - 2, - 2, - 2, - -1, - -1, - 0, - 2, - 2, - 2 - ); + return createLayeredCuboid(texture, 0, 12, 8, 12, 2, 2, 2, -1, -1, 0, 2, 2, 2); } - private Renderable createLimb( - ComplexTexture texture, - int tx, - int ty, - int tx2, - int ty2, - boolean isArm, - boolean isLeft - ) { - Renderable model = createLayeredCuboid( - texture, - tx, - ty, - tx2, - ty2, - 1, - 3, - 1, - -0.5f, - -0.5f, - isArm ? -2.5f : -3f, - 1, - 1, - 3 - ); + private Renderable createLimb(ComplexTexture texture, int tx, int ty, int tx2, int ty2, boolean isArm, + boolean isLeft) { + Renderable model = createLayeredCuboid(texture, tx, ty, tx2, ty2, 1, 3, 1, -0.5f, -0.5f, isArm ? -2.5f : -3f, 1, + 1, 3); if (isArm) { - return LambdaModel.animate( - model, - mat -> { - double phase = GraphicsInterface.getTime() + (isLeft ? 0 : Math.PI / 3); - mat.rotateX((isLeft ? +1 : -1) * 1 / 40f * (sin(phase) + 1)); - mat.rotateY(1 / 20f * sin(Math.PI / 3 * phase)); - } - ); + return LambdaModel.animate(model, mat -> { + double phase = GraphicsInterface.getTime() + (isLeft ? 0 : Math.PI / 3); + mat.rotateX((isLeft ? +1 : -1) * 1 / 40f * (sin(phase) + 1)); + mat.rotateY(1 / 20f * sin(Math.PI / 3 * phase)); + }); } else { return model; } } - private Renderable createLayeredCuboid( - ComplexTexture texture, - int tx, - int ty, - int tx2, - int ty2, - int tw, - int th, - int td, - float ox, - float oy, - float oz, - float sx, - float sy, - float sz - ) { + private Renderable createLayeredCuboid(ComplexTexture texture, int tx, int ty, int tx2, int ty2, int tw, int th, + int td, float ox, float oy, float oz, float sx, float sy, float sz) { WorldRenderProgram program = WorldRenderProgram.getDefault(); StaticModel.Builder b = StaticModel.builder(); // First layer - b.addPart( - new PppBuilder( - program, - texture.getCuboidTextures(tx, ty, tw, th, td) - ).setOrigin(ox, oy, oz).setSize(sx, sy, sz).create() - ); + b.addPart(new PppBuilder(program, texture.getCuboidTextures(tx, ty, tw, th, td)).setOrigin(ox, oy, oz) + .setSize(sx, sy, sz).create()); ox -= SECOND_LAYER_OFFSET; oy -= SECOND_LAYER_OFFSET; @@ -193,55 +117,25 @@ public class TestEntityRenderHuman extends EntityRender { sz += SECOND_LAYER_OFFSET * 2; // Second layer - b.addPart( - new PppBuilder( - program, - texture.getCuboidTextures(tx2, ty2, tw, th, td) - ).setOrigin(ox, oy, oz).setSize(sx, sy, sz).create() - ); + b.addPart(new PppBuilder(program, texture.getCuboidTextures(tx2, ty2, tw, th, td)).setOrigin(ox, oy, oz) + .setSize(sx, sy, sz).create()); return b.build(); } @Override public EntityRenderable createRenderable(EntityData entity) { - return new HumanoidModel( - entity, + return new HumanoidModel(entity, - new HumanoidModel.Body(body), - new HumanoidModel.Head( - head, - new Vec3(0, 0, 6), - 70, - 25, - new Vec3(1.2f, 0, 1.5f) - ), - new HumanoidModel.Arm( - leftArm, - new Vec3(0, +1.5f, 3 + 3 - 0.5f), - 0.0f - ), - new HumanoidModel.Arm( - rightArm, - new Vec3(0, -1.5f, 3 + 3 - 0.5f), - FloatMathUtil.PI_F - ), - new HumanoidModel.Leg( - leftLeg, - new Vec3(0, +0.5f, 3), - FloatMathUtil.PI_F - ), - new HumanoidModel.Leg( - rightLeg, - new Vec3(0, -0.5f, 3), - 0.0f - ), + new HumanoidModel.Body(body), + new HumanoidModel.Head(head, new Vec3(0, 0, 6), 70, 25, new Vec3(1.2f, 0, 1.5f)), + new HumanoidModel.Arm(leftArm, new Vec3(0, +1.5f, 3 + 3 - 0.5f), 0.0f), + new HumanoidModel.Arm(rightArm, new Vec3(0, -1.5f, 3 + 3 - 0.5f), FloatMathUtil.PI_F), + new HumanoidModel.Leg(leftLeg, new Vec3(0, +0.5f, 3), FloatMathUtil.PI_F), + new HumanoidModel.Leg(rightLeg, new Vec3(0, -0.5f, 3), 0.0f), - 1.8f / (3 + 3 + 2) - ) - .setWalkingArmSwing((float) toRadians(30)) - .setWalkingLegSwing((float) toRadians(50)) - .setWalkingFrequency(0.15f / 60.0f); + 1.8f / (3 + 3 + 2)).setWalkingArmSwing((float) toRadians(30)).setWalkingLegSwing((float) toRadians(50)) + .setWalkingFrequency(0.15f / 60.0f); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java index aefa1c6..aa3ad1b 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import java.util.ArrayList; @@ -54,11 +54,7 @@ public class TestEntityRenderJavapony extends EntityRender { public TestEntityRenderJavapony(String id) { super(id); - ComplexTexture texture = new ComplexTexture( - EntityRenderRegistry.getEntityTexture("javapony"), - 256, - 128 - ); + ComplexTexture texture = new ComplexTexture(EntityRenderRegistry.getEntityTexture("javapony"), 256, 128); this.body = createBody(texture); this.head = createHead(texture); @@ -75,49 +71,20 @@ public class TestEntityRenderJavapony extends EntityRender { Texture tailStartTexture = texture.get(128, 96, 8, 32); - b.addStaticPart( - new PppBuilder( - WorldRenderProgram.getDefault(), - BlockFace.mapToFaces( - tailStartTexture, - tailStartTexture, - tailStartTexture, - tailStartTexture, - tailStartTexture, - tailStartTexture - ) - ) - .setOrigin(-60, -4, 14) - .setDepth(32, 0, -16).setWidth(8).setHeight(8) - .create() - ); + b.addStaticPart(new PppBuilder(WorldRenderProgram.getDefault(), + BlockFace.mapToFaces(tailStartTexture, tailStartTexture, tailStartTexture, tailStartTexture, + tailStartTexture, tailStartTexture)).setOrigin(-60, -4, 14).setDepth(32, 0, -16).setWidth(8) + .setHeight(8).create()); Texture neckTexture = texture.get(0, 48, 16, 16); - b.addStaticPart( - new PppBuilder( - WorldRenderProgram.getDefault(), - BlockFace.mapToFaces( - neckTexture, - neckTexture, - neckTexture, - neckTexture, - neckTexture, - neckTexture - ) - ) - .setOrigin(0, -8, 8) - .setWidth(16).setDepth(16).setHeight(2, 0, 16) - .create() - ); + b.addStaticPart(new PppBuilder(WorldRenderProgram.getDefault(), + BlockFace.mapToFaces(neckTexture, neckTexture, neckTexture, neckTexture, neckTexture, neckTexture)) + .setOrigin(0, -8, 8).setWidth(16).setDepth(16).setHeight(2, 0, 16).create()); - b.addDynamicPart( - createTail(texture), - m -> m - .translate(-60, 0, 24) - .rotateX(0.05f * Math.sin(GraphicsInterface.getTime())) - .rotateY(0.05f * Math.sin(Math.PI / 3 * GraphicsInterface.getTime())) - ); + b.addDynamicPart(createTail(texture), + m -> m.translate(-60, 0, 24).rotateX(0.05f * Math.sin(GraphicsInterface.getTime())) + .rotateY(0.05f * Math.sin(Math.PI / 3 * GraphicsInterface.getTime()))); return new LambdaModel(b); } @@ -127,192 +94,62 @@ public class TestEntityRenderJavapony extends EntityRender { List faces = new ArrayList<>(); // F BODY - faces.add( - Faces.createRectangle( - program, - texture.get(80, 16, 32, 32), - Colors.WHITE, - new Vec3(+16, -16, -16), - new Vec3(0, +32, 0), - new Vec3(0, 0, +32), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(80, 16, 32, 32), Colors.WHITE, new Vec3(+16, -16, -16), + new Vec3(0, +32, 0), new Vec3(0, 0, +32), false)); // NECK BASE - faces.add( - Faces.createRectangle( - program, - texture.get(80, 48, 32, 16), - Colors.WHITE, - new Vec3(+16, -16, +16), - new Vec3(0, +32, 0), - new Vec3(-16, 0, 0), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(80, 48, 32, 16), Colors.WHITE, new Vec3(+16, -16, +16), + new Vec3(0, +32, 0), new Vec3(-16, 0, 0), false)); // T BODY (BACK) - faces.add( - Faces.createRectangle( - program, - texture.get(128, 0, 32, 48), - Colors.WHITE, - new Vec3(0, -16, +16), - new Vec3(0, +32, 0), - new Vec3(-48, 0, 0), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(128, 0, 32, 48), Colors.WHITE, new Vec3(0, -16, +16), + new Vec3(0, +32, 0), new Vec3(-48, 0, 0), false)); // BOTTOM B (upper) - faces.add( - Faces.createRectangle( - program, - texture.get(144, 48, 32, 16), - Colors.WHITE, - new Vec3(-48, -16, 0), - new Vec3(0, 32, 0), - new Vec3(0, 0, 16), - true - ) - ); + faces.add(Faces.createRectangle(program, texture.get(144, 48, 32, 16), Colors.WHITE, new Vec3(-48, -16, 0), + new Vec3(0, 32, 0), new Vec3(0, 0, 16), true)); // BOTTOM B (lower) - faces.add( - Faces.createRectangle( - program, - texture.get(144, 48, 32, 16), - Colors.WHITE, - new Vec3(-48, -16, -16), - new Vec3(0, 32, 0), - new Vec3(0, 0, 16), - true - ) - ); + faces.add(Faces.createRectangle(program, texture.get(144, 48, 32, 16), Colors.WHITE, new Vec3(-48, -16, -16), + new Vec3(0, 32, 0), new Vec3(0, 0, 16), true)); // BOTTOM B (stomach) - faces.add( - Faces.createRectangle( - program, - texture.get(144, 48, 32, 16), - Colors.WHITE, - new Vec3(-48, -16, -16), - new Vec3(0, 32, 0), - new Vec3(16, 0, 0), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(144, 48, 32, 16), Colors.WHITE, new Vec3(-48, -16, -16), + new Vec3(0, 32, 0), new Vec3(16, 0, 0), false)); // STOMACH - faces.add( - Faces.createRectangle( - program, - texture.get(224, 96, 32, 32), - Colors.WHITE, - new Vec3(-32, -16, -16), - new Vec3(0, 32, 0), - new Vec3(32, 0, 0), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(224, 96, 32, 32), Colors.WHITE, new Vec3(-32, -16, -16), + new Vec3(0, 32, 0), new Vec3(32, 0, 0), false)); // BOTTOM F - faces.add( - Faces.createRectangle( - program, - texture.get(112, 48, 32, 16), - Colors.WHITE, - new Vec3(+16, -16, -16), - new Vec3(0, 32, 0), - new Vec3(-16, 0, 0), - true - ) - ); + faces.add(Faces.createRectangle(program, texture.get(112, 48, 32, 16), Colors.WHITE, new Vec3(+16, -16, -16), + new Vec3(0, 32, 0), new Vec3(-16, 0, 0), true)); // BODY L - faces.add( - Faces.createRectangle( - program, - texture.get(112, 16, 16, 32), - Colors.WHITE, - new Vec3(+16, +16, -16), - new Vec3(-16, 0, 0), - new Vec3(0, 0, +32), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(112, 16, 16, 32), Colors.WHITE, new Vec3(+16, +16, -16), + new Vec3(-16, 0, 0), new Vec3(0, 0, +32), false)); // BODY SIDES (left) - faces.add( - Faces.createRectangle( - program, - texture.get(96, 96, 32, 32), - Colors.WHITE, - new Vec3(0, +16, -16), - new Vec3(-32, 0, 0), - new Vec3(0, 0, +32), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(96, 96, 32, 32), Colors.WHITE, new Vec3(0, +16, -16), + new Vec3(-32, 0, 0), new Vec3(0, 0, +32), false)); // QT MARK (left) - faces.add( - Faces.createRectangle( - program, - texture.get(16, 96, 16, 32), - Colors.WHITE, - new Vec3(-32, +16, -16), - new Vec3(-16, 0, 0), - new Vec3(0, 0, +32), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(16, 96, 16, 32), Colors.WHITE, new Vec3(-32, +16, -16), + new Vec3(-16, 0, 0), new Vec3(0, 0, +32), false)); // BODY R - faces.add( - Faces.createRectangle( - program, - texture.get(64, 16, 16, 32), - Colors.WHITE, - new Vec3(0, -16, -16), - new Vec3(+16, 0, 0), - new Vec3(0, 0, +32), - false - ) - ); + faces.add(Faces.createRectangle(program, texture.get(64, 16, 16, 32), Colors.WHITE, new Vec3(0, -16, -16), + new Vec3(+16, 0, 0), new Vec3(0, 0, +32), false)); // BODY SIDES (right) - faces.add( - Faces.createRectangle( - program, - texture.get(96, 96, 32, 32), - Colors.WHITE, - new Vec3(0, -16, -16), - new Vec3(-32, 0, 0), - new Vec3(0, 0, +32), - true - ) - ); + faces.add(Faces.createRectangle(program, texture.get(96, 96, 32, 32), Colors.WHITE, new Vec3(0, -16, -16), + new Vec3(-32, 0, 0), new Vec3(0, 0, +32), true)); // QT MARK (right) - faces.add( - Faces.createRectangle( - program, - texture.get(16, 96, 16, 32), - Colors.WHITE, - new Vec3(-32, -16, -16), - new Vec3(-16, 0, 0), - new Vec3(0, 0, +32), - true - ) - ); + faces.add(Faces.createRectangle(program, texture.get(16, 96, 16, 32), Colors.WHITE, new Vec3(-32, -16, -16), + new Vec3(-16, 0, 0), new Vec3(0, 0, +32), true)); - return new Shape( - Usage.STATIC, - program, - faces.toArray(new Face[faces.size()]) - ); + return new Shape(Usage.STATIC, program, faces.toArray(new Face[faces.size()])); } private static Renderable createHead(ComplexTexture texture) { @@ -320,87 +157,42 @@ public class TestEntityRenderJavapony extends EntityRender { StaticModel.Builder b = StaticModel.builder(); // Head - b.addPart( - new PppBuilder( - program, - texture.getCuboidTextures(0, 64, 32) - ).setOrigin(-16, -16, 0).setSize(32).create() - ); + b.addPart(new PppBuilder(program, texture.getCuboidTextures(0, 64, 32)).setOrigin(-16, -16, 0).setSize(32) + .create()); final float hairOffset = 1f; // Hair - b.addPart( - new PppBuilder( - program, - texture.getCuboidTextures(128, 64, 32) - ) - .setOrigin(-16 - hairOffset, -16 - hairOffset, -hairOffset) - .setSize(32 + 2 * hairOffset) - .create() - ); + b.addPart(new PppBuilder(program, texture.getCuboidTextures(128, 64, 32)) + .setOrigin(-16 - hairOffset, -16 - hairOffset, -hairOffset).setSize(32 + 2 * hairOffset).create()); // Right ear - b.addPart( - new PppBuilder( - program, - texture.getCuboidTextures(48, 128 - 80, 8) - ).setOrigin(-16 + 3, -16, 32).setSize(8).create() - ); + b.addPart(new PppBuilder(program, texture.getCuboidTextures(48, 128 - 80, 8)).setOrigin(-16 + 3, -16, 32) + .setSize(8).create()); // Left ear - b.addPart( - new PppBuilder( - program, - texture.getCuboidTextures(48, 128 - 80, 8) - ).setOrigin(-16 + 3, +16, 32).setSize(8, -8, 8).flip().create() - ); + b.addPart(new PppBuilder(program, texture.getCuboidTextures(48, 128 - 80, 8)).setOrigin(-16 + 3, +16, 32) + .setSize(8, -8, 8).flip().create()); // Muzzle - b.addPart( - new PppBuilder( - program, - BlockFace.mapToFaces( - texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0), - texture.get(32 + 8, 64, 16, 8), - texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0) - ) - ).setOrigin(16, -8, 0).setSize(4, 16, 8).create() - ); + b.addPart(new PppBuilder(program, + BlockFace.mapToFaces(texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), + texture.get(32 + 8, 64, 16, 8), texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0))).setOrigin(16, -8, 0).setSize(4, 16, 8).create()); // Nose - b.addPart( - new PppBuilder( - program, - BlockFace.mapToFaces( - texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0), - texture.get(32 + 12, 64 + 8, 8, 4), - texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0) - ) - ).setOrigin(16, -4, 8).setSize(4, 8, 4).create() - ); + b.addPart(new PppBuilder(program, + BlockFace.mapToFaces(texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), + texture.get(32 + 12, 64 + 8, 8, 4), texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0))).setOrigin(16, -4, 8).setSize(4, 8, 4).create()); return b.build(); } - private static Renderable createLeg( - ComplexTexture texture, - int textureX, - int textureY, - boolean isLeft - ) { - PppBuilder b = new PppBuilder( - WorldRenderProgram.getDefault(), - texture.getCuboidTextures(textureX, textureY, 16, 48, 16) - ) - .setOrigin(-8, isLeft ? +8 : -8, -48) - .setSize(16, isLeft ? -16 : +16, 48); + private static Renderable createLeg(ComplexTexture texture, int textureX, int textureY, boolean isLeft) { + PppBuilder b = new PppBuilder(WorldRenderProgram.getDefault(), + texture.getCuboidTextures(textureX, textureY, 16, 48, 16)).setOrigin(-8, isLeft ? +8 : -8, -48) + .setSize(16, isLeft ? -16 : +16, 48); if (isLeft) b.flip(); @@ -413,59 +205,26 @@ public class TestEntityRenderJavapony extends EntityRender { StaticModel.Builder b = StaticModel.builder(); // Main tail - b.addPart( - new PppBuilder( - program, - BlockFace.mapToFaces( - texture.get(128, 96, 16, 16), - texture.get(128, 96, 16, 16), - texture.get(128, 96, 16, 32), - texture.get(128, 96, 16, 32), - texture.get(144, 96, 16, 32), - texture.get(144, 96, 16, 32) - ) - ).setOrigin(-8, -8, -32).setSize(16, 16, 32).create() - ); + b.addPart(new PppBuilder(program, + BlockFace.mapToFaces(texture.get(128, 96, 16, 16), texture.get(128, 96, 16, 16), + texture.get(128, 96, 16, 32), texture.get(128, 96, 16, 32), texture.get(144, 96, 16, 32), + texture.get(144, 96, 16, 32))).setOrigin(-8, -8, -32).setSize(16, 16, 32).create()); return b.build(); } @Override public EntityRenderable createRenderable(EntityData entity) { - return new QuadripedModel( - entity, + return new QuadripedModel(entity, - new QuadripedModel.Body(body), - new QuadripedModel.Head( - head, - new Vec3(12, 0, 20), - 120, - 45, - new Vec3(16, 0, 20) - ), - new QuadripedModel.Leg( - leftForeLeg, - new Vec3(6, +8.1f, -16), - 0.0f - ), - new QuadripedModel.Leg( - rightForeLeg, - new Vec3(6, -8.1f, -16), - 2.5f - ), - new QuadripedModel.Leg( - leftHindLeg, - new Vec3(-36, +8.2f, -16), - 2.5f - ), - new QuadripedModel.Leg( - rightHindLeg, - new Vec3(-36, -8.2f, -16), - 0.0f - ), + new QuadripedModel.Body(body), + new QuadripedModel.Head(head, new Vec3(12, 0, 20), 120, 45, new Vec3(16, 0, 20)), + new QuadripedModel.Leg(leftForeLeg, new Vec3(6, +8.1f, -16), 0.0f), + new QuadripedModel.Leg(rightForeLeg, new Vec3(6, -8.1f, -16), 2.5f), + new QuadripedModel.Leg(leftHindLeg, new Vec3(-36, +8.2f, -16), 2.5f), + new QuadripedModel.Leg(rightHindLeg, new Vec3(-36, -8.2f, -16), 0.0f), - 1 / 96f - ); + 1 / 96f); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java index 47990fd..af5ed11 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderStatie.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.client.graphics.model.Renderable; @@ -29,12 +29,8 @@ import ru.windcorp.progressia.common.world.entity.EntityData; public class TestEntityRenderStatie extends EntityRender { - private final Renderable cube = new Shapes.PppBuilder( - WorldRenderProgram.getDefault(), - (Texture) null - ) - .setColorMultiplier(1, 1, 0) - .create(); + private final Renderable cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), (Texture) null) + .setColorMultiplier(1, 1, 0).create(); public TestEntityRenderStatie(String id) { super(id); @@ -45,9 +41,7 @@ public class TestEntityRenderStatie extends EntityRender { return new EntityRenderable(entity) { @Override public void render(ShapeRenderHelper renderer) { - renderer.pushTransform().scale( - ((TestEntityDataStatie) entity).getSize() / 24.0f - ); + renderer.pushTransform().scale(((TestEntityDataStatie) entity).getSize() / 24.0f); cube.render(renderer); diff --git a/src/main/java/ru/windcorp/progressia/test/TestMusicPlayer.java b/src/main/java/ru/windcorp/progressia/test/TestMusicPlayer.java index 1674d5b..ac221d8 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestMusicPlayer.java +++ b/src/main/java/ru/windcorp/progressia/test/TestMusicPlayer.java @@ -38,41 +38,41 @@ import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.util.crash.CrashReports; public class TestMusicPlayer implements Runnable { - + private static final int MIN_SILENCE = 15 * 1000; // 15 seconds private static final int MAX_SILENCE = 60 * 1000; // one minute - + private static TestMusicPlayer instance = null; - + private final List compositions = new ArrayList<>(); - + private final Random random = new Random(); private long nextStart; private Sound lastStarted = null; - + public TestMusicPlayer() { this.nextStart = System.currentTimeMillis(); - + instance = this; } - + public static void start() { Thread thread = new Thread(new TestMusicPlayer(), "Music Thread"); thread.setDaemon(true); thread.start(); } - + @Override public void run() { loadCompositions(); - + if (compositions.isEmpty()) { LogManager.getLogger().warn("No music found"); return; } - + while (true) { - + try { synchronized (this) { while (true) { @@ -88,39 +88,39 @@ public class TestMusicPlayer implements Runnable { LogManager.getLogger().warn("Received interrupt in music thread, terminating thread..."); return; } - + startNextComposition(); - + } } private void loadCompositions() { try { - + Path directory = Paths.get("music"); - + if (!Files.isDirectory(directory)) { Files.createDirectories(directory); } - + Iterator it = Files.walk(directory).filter(Files::isRegularFile).iterator(); int i = 0; - + while (it.hasNext()) { String file = it.next().toString(); if (!file.endsWith(".ogg") && !file.endsWith(".oga")) { LogManager.getLogger().warn("Skipping " + file + ": not .ogg nor .oga"); } - + String id = "Progressia:Music" + (i++); - + AudioManager.loadSound(ResourceManager.getFileResource(file.toString()), id, AudioFormat.STEREO); SoundType composition = AudioRegistry.getInstance().get(id); compositions.add(composition); - + LogManager.getLogger().info("Loaded " + file); } - + } catch (IOException e) { throw CrashReports.report(e, "Could not load music"); } @@ -129,20 +129,21 @@ public class TestMusicPlayer implements Runnable { private synchronized void startNextComposition() { int index = random.nextInt(compositions.size()); SoundType composition = compositions.get(index); - + long now = System.currentTimeMillis(); long durationInMs = (long) (composition.getDuration() * 1000); long silence = random.nextInt(MAX_SILENCE - MIN_SILENCE) + MIN_SILENCE; - + nextStart = now + durationInMs + silence; - + lastStarted = new Music(composition); lastStarted.play(false); } - + public static void startNextNow() { - if (instance == null) return; - + if (instance == null) + return; + synchronized (instance) { instance.nextStart = System.currentTimeMillis(); instance.notifyAll(); diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java index f129255..f9b4439 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java +++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import glm.Glm; @@ -119,12 +119,8 @@ public class TestPlayerControls { desiredVelocity.z = movementUp; desiredVelocity.mul(speed); - Vec3 change = new Vec3() - .set(desiredVelocity) - .sub(player.getVelocity()) - .mul((float) Math.exp(-authority * GraphicsInterface.getFrameLength())) - .negate() - .add(desiredVelocity); + Vec3 change = new Vec3().set(desiredVelocity).sub(player.getVelocity()) + .mul((float) Math.exp(-authority * GraphicsInterface.getFrameLength())).negate().add(desiredVelocity); if (!isFlying) { change.z = player.getVelocity().z; @@ -134,7 +130,7 @@ public class TestPlayerControls { // THIS IS TERRIBLE TEST EntityData serverEntity = ServerState.getInstance().getWorld().getData() - .getEntity(TestContent.PLAYER_ENTITY_ID); + .getEntity(TestContent.PLAYER_ENTITY_ID); if (serverEntity != null) { serverEntity.setPosition(player.getPosition()); } @@ -356,12 +352,8 @@ public class TestPlayerControls { EntityData player = getEntity(); - normalizeAngles( - player.getDirection().add( - (float) (event.getChangeX() * yawScale), - (float) (event.getChangeY() * pitchScale) - ) - ); + normalizeAngles(player.getDirection().add((float) (event.getChangeX() * yawScale), + (float) (event.getChangeY() * pitchScale))); } private void normalizeAngles(Vec2 dir) { @@ -369,11 +361,7 @@ public class TestPlayerControls { dir.x = FloatMathUtil.normalizeAngle(dir.x); // Clamp pitch - dir.y = Glm.clamp( - dir.y, - -FloatMathUtil.PI_F / 2, - +FloatMathUtil.PI_F / 2 - ); + dir.y = Glm.clamp(dir.y, -FloatMathUtil.PI_F / 2, +FloatMathUtil.PI_F / 2); } private void onWheelScroll(WheelScrollEvent event) { diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index 06afc77..e6514ca 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.world.block.BlockFace; diff --git a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java index 97a0d99..7d10013 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java +++ b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import java.io.BufferedInputStream; @@ -52,29 +52,15 @@ public class TestWorldDiskIO { return; try { - LOG.debug( - "Saving {} {} {}", - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ); + LOG.debug("Saving {} {} {}", chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z); Files.createDirectories(SAVE_DIR); - Path path = SAVE_DIR.resolve( - String.format( - "chunk_%+d_%+d_%+d.progressia_chunk", - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ) - ); + Path path = SAVE_DIR.resolve(String.format("chunk_%+d_%+d_%+d.progressia_chunk", chunk.getPosition().x, + chunk.getPosition().y, chunk.getPosition().z)); - try ( - DataOutputStream output = new DataOutputStream( - new DeflaterOutputStream(new BufferedOutputStream(Files.newOutputStream(path))) - ) - ) { + try (DataOutputStream output = new DataOutputStream( + new DeflaterOutputStream(new BufferedOutputStream(Files.newOutputStream(path))))) { ChunkIO.save(chunk, output, IOContext.SAVE); writeGenerationHint(chunk, output, server); } @@ -84,7 +70,7 @@ public class TestWorldDiskIO { } private static void writeGenerationHint(ChunkData chunk, DataOutputStream output, Server server) - throws IOException { + throws IOException { server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint()); } @@ -92,22 +78,11 @@ public class TestWorldDiskIO { if (!ENABLE) return null; - Path path = SAVE_DIR.resolve( - String.format( - "chunk_%+d_%+d_%+d.progressia_chunk", - chunkPos.x, - chunkPos.y, - chunkPos.z - ) - ); + Path path = SAVE_DIR + .resolve(String.format("chunk_%+d_%+d_%+d.progressia_chunk", chunkPos.x, chunkPos.y, chunkPos.z)); if (!Files.exists(path)) { - LOG.debug( - "Not found {} {} {}", - chunkPos.x, - chunkPos.y, - chunkPos.z - ); + LOG.debug("Not found {} {} {}", chunkPos.x, chunkPos.y, chunkPos.z); return null; } @@ -115,34 +90,20 @@ public class TestWorldDiskIO { try { ChunkData result = load(path, chunkPos, world, server); - LOG.debug( - "Loaded {} {} {}", - chunkPos.x, - chunkPos.y, - chunkPos.z - ); + LOG.debug("Loaded {} {} {}", chunkPos.x, chunkPos.y, chunkPos.z); return result; } catch (Exception e) { e.printStackTrace(); - LOG.debug( - "Could not load {} {} {}", - chunkPos.x, - chunkPos.y, - chunkPos.z - ); + LOG.debug("Could not load {} {} {}", chunkPos.x, chunkPos.y, chunkPos.z); return null; } } private static ChunkData load(Path path, Vec3i chunkPos, WorldData world, Server server) - throws IOException, - DecodingException { - try ( - DataInputStream input = new DataInputStream( - new InflaterInputStream(new BufferedInputStream(Files.newInputStream(path))) - ) - ) { + throws IOException, DecodingException { + try (DataInputStream input = new DataInputStream( + new InflaterInputStream(new BufferedInputStream(Files.newInputStream(path))))) { ChunkData chunk = ChunkIO.load(world, chunkPos, input, IOContext.SAVE); readGenerationHint(chunk, input, server); return chunk; @@ -150,8 +111,7 @@ public class TestWorldDiskIO { } private static void readGenerationHint(ChunkData chunk, DataInputStream input, Server server) - throws IOException, - DecodingException { + throws IOException, DecodingException { chunk.setGenerationHint(server.getWorld().getGenerator().readGenerationHint(input)); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index bb3acc9..8ce6e45 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -57,15 +57,22 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public void onChunkLoaded(WorldData world, ChunkData chunk) { findAndPopulate(chunk.getPosition(), world); - chunk.addListener(new ChunkDataListener() { //Falling Block spawning logic + chunk.addListener(new ChunkDataListener() { // Falling Block + // spawning logic @Override public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { + Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); + + if (TestEntityLogicFallingBlock.FallingBlocks.contains(chunk.getWorld() + .getBlock(chunkWorldPos.add_(0, 0, 1)).getId())) { + chunk.getWorld().setBlock(chunkWorldPos.add_(0, 0, 1), BlockDataRegistry.getInstance().get(chunk.getWorld().getBlock(chunkWorldPos.add_(0,0,1)).getId()), true); + } if (!TestEntityLogicFallingBlock.FallingBlocks.contains(current.getId())) { return; } - if (chunk.getWorld().getBlock(chunk.getPosition().mul_(16).add_(blockInChunk.add_(0, 0, -1))).getId() == "Test:Air") - { + if (chunk.getWorld().getBlock(chunkWorldPos.add_(0, 0, -1)) + .getId() == "Test:Air") { LogManager.getLogger().info("Inserting FallingBlock"); TestEntityDataFallingBlock fallingBlock = new TestEntityDataFallingBlock(); @@ -78,10 +85,11 @@ public class TestWorldGenerator extends AbstractWorldGenerator { + String.valueOf(new Random().nextFloat())).hashCode()); chunk.getWorld().addEntity(fallingBlock); - + chunk.setBlock(blockInChunk, previous, false); - Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); - LogManager.getLogger().info(String.valueOf(chunkWorldPos.x)+" "+String.valueOf(chunkWorldPos.y)+" "+String.valueOf(chunkWorldPos.z)); + + LogManager.getLogger().info(String.valueOf(chunkWorldPos.x) + " " + + String.valueOf(chunkWorldPos.y) + " " + String.valueOf(chunkWorldPos.z)); } } }); From ae2980c9de3a93ba3745120853895cccf2c07f9f Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Thu, 10 Jun 2021 17:00:09 -0400 Subject: [PATCH 31/63] Bug Fixing and Performance -Multiple null checks(It doesn't work without them) -Checks to make sure entities are within loaded chunks -Actual entity removal --- .../test/TestEntityLogicFallingBlock.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index ccbb37a..3cc0e9c 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -53,8 +53,8 @@ public class TestEntityLogicFallingBlock extends EntityLogic { return; } - // LogManager.getLogger().info("NotNull "+entity.toString() + " " + - // context.toString()); + //LogManager.getLogger().info("NotNull "+entity.toString()+" "+String.valueOf(entity!=null) + " " + + //context.toString()); super.tick(entity, context); // friction @@ -66,7 +66,13 @@ public class TestEntityLogicFallingBlock extends EntityLogic { TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld() .getData().getEntity(entity.getEntityId()); // ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); // fallBlock = (TestEntityDataFallingBlock) entity; - + + //LogManager.getLogger().info("NotNull FB "+String.valueOf(fallBlock!=null)); + if (fallBlock==null) + { + return; + } + if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) { return; } @@ -95,14 +101,14 @@ public class TestEntityLogicFallingBlock extends EntityLogic { // "+String.valueOf(occupiedBlock.z)); // LogManager.getLogger().info("Block is of type " + // context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - - if (context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { + + if (context.getWorldData().isBlockLoaded(occupiedBlock) && context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); // ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, // fallBlock.getBlock(),true); context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); fallBlock.setInvisible(); // Until I know how to properly delete it. - // context.getWorldData().removeEntity(entity.getEntityId()); + ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId());//context.getWorldData().removeEntity(entity.getEntityId()); } } } From e58007ea1112142621773f8cd2892106846a5c34 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Thu, 10 Jun 2021 17:09:24 -0400 Subject: [PATCH 32/63] Format Format --- .../opensimplex2/areagen/OpenSimplex2S.java | 863 ++++++++++-------- .../java/ru/windcorp/jputil/ArrayUtil.java | 8 +- .../java/ru/windcorp/jputil/CSVWriter.java | 2 +- .../ru/windcorp/jputil/PrimitiveUtil.java | 16 +- .../java/ru/windcorp/jputil/SyncStreams.java | 140 ++- .../ru/windcorp/jputil/SyntaxException.java | 2 +- .../jputil/chars/CharArrayIterator.java | 4 +- .../windcorp/jputil/chars/CharConsumer.java | 2 +- .../windcorp/jputil/chars/CharConsumers.java | 2 +- .../windcorp/jputil/chars/CharPredicate.java | 2 +- .../windcorp/jputil/chars/CharSupplier.java | 2 +- .../jputil/chars/EscapeException.java | 2 +- .../ru/windcorp/jputil/chars/Escaper.java | 61 +- .../jputil/chars/FancyCharacterIterator.java | 4 +- .../jputil/chars/IndentedStringBuilder.java | 2 +- .../ru/windcorp/jputil/chars/StringUtil.java | 167 ++-- .../chars/UncheckedEscapeException.java | 2 +- .../ru/windcorp/jputil/chars/WordReader.java | 2 +- .../chars/reader/AbstractCharReader.java | 9 +- .../jputil/chars/reader/ArrayCharReader.java | 2 +- .../chars/reader/BufferedCharReader.java | 11 +- .../jputil/chars/reader/CharReader.java | 7 +- .../jputil/chars/reader/CharReaders.java | 2 +- .../jputil/chars/reader/ReaderCharReader.java | 2 +- .../jputil/chars/reader/StringCharReader.java | 5 +- .../jputil/functions/FloatSupplier.java | 2 +- .../jputil/functions/ThrowingBiConsumer.java | 29 +- .../jputil/functions/ThrowingConsumer.java | 20 +- .../jputil/functions/ThrowingFunction.java | 29 +- .../jputil/functions/ThrowingRunnable.java | 8 +- .../jputil/functions/ThrowingSupplier.java | 2 +- .../jputil/iterators/ArrayIterator.java | 2 +- .../jputil/iterators/FunctionIterator.java | 2 +- .../jputil/iterators/PeekingIterator.java | 2 +- .../jputil/iterators/RangeIterator.java | 8 +- .../windcorp/jputil/iterators/Reiterator.java | 2 +- .../selectors/AbstractSelectorOperator.java | 2 +- .../selectors/NamedParameterizedSelector.java | 2 +- .../jputil/selectors/NamedSelector.java | 2 +- .../jputil/selectors/OperatorAnd.java | 2 +- .../jputil/selectors/OperatorExclude.java | 2 +- .../jputil/selectors/OperatorNot.java | 2 +- .../windcorp/jputil/selectors/OperatorOr.java | 2 +- .../jputil/selectors/OperatorXor.java | 2 +- .../jputil/selectors/PredicateWrapper.java | 2 +- .../windcorp/jputil/selectors/Selector.java | 2 +- .../jputil/selectors/SelectorOperator.java | 2 +- .../jputil/selectors/SelectorSystem.java | 4 +- .../ru/windcorp/progressia/Progressia.java | 2 +- .../progressia/ProgressiaLauncher.java | 2 +- .../java/ru/windcorp/progressia/Proxy.java | 2 +- .../ru/windcorp/progressia/client/Client.java | 8 +- .../progressia/client/ClientProxy.java | 10 +- .../progressia/client/ClientState.java | 6 +- .../client/ProgressiaClientMain.java | 2 +- .../progressia/client/audio/AudioFormat.java | 2 +- .../progressia/client/audio/AudioManager.java | 12 +- .../client/audio/AudioRegistry.java | 4 +- .../progressia/client/audio/AudioSystem.java | 9 +- .../progressia/client/audio/Music.java | 11 +- .../progressia/client/audio/Sound.java | 32 +- .../client/audio/backend/AudioReader.java | 21 +- .../client/audio/backend/Listener.java | 25 +- .../client/audio/backend/SoundType.java | 11 +- .../client/audio/backend/Speaker.java | 21 +- .../comms/DefaultClientCommsListener.java | 6 +- .../client/comms/ServerCommsChannel.java | 2 +- .../client/comms/controls/ControlTrigger.java | 2 +- .../controls/ControlTriggerInputBased.java | 2 +- .../comms/controls/ControlTriggerLambda.java | 20 +- .../controls/ControlTriggerLocalLambda.java | 8 +- .../controls/ControlTriggerRegistry.java | 2 +- .../comms/controls/ControlTriggers.java | 219 ++--- .../comms/controls/InputBasedControls.java | 5 +- .../client/comms/localhost/LocalClient.java | 2 +- .../localhost/LocalServerCommsChannel.java | 8 +- .../progressia/client/graphics/Colors.java | 18 +- .../progressia/client/graphics/GUI.java | 4 +- .../progressia/client/graphics/Layer.java | 2 +- .../client/graphics/backend/FaceCulling.java | 2 +- .../graphics/backend/GraphicsBackend.java | 23 +- .../graphics/backend/GraphicsInterface.java | 2 +- .../client/graphics/backend/InputHandler.java | 34 +- .../client/graphics/backend/InputTracker.java | 7 +- .../graphics/backend/LWJGLInitializer.java | 14 +- .../graphics/backend/OpenGLObjectTracker.java | 34 +- .../graphics/backend/RenderTaskQueue.java | 8 +- .../client/graphics/backend/RenderThread.java | 2 +- .../client/graphics/backend/Usage.java | 6 +- .../graphics/backend/VertexBufferObject.java | 5 +- .../backend/shaders/CombinedShader.java | 24 +- .../graphics/backend/shaders/Program.java | 2 +- .../graphics/backend/shaders/Shader.java | 12 +- .../backend/shaders/attributes/Attribute.java | 2 +- .../attributes/AttributeVertexArray.java | 101 +- .../backend/shaders/uniforms/Uniform.java | 2 +- .../shaders/uniforms/Uniform1Float.java | 2 +- .../backend/shaders/uniforms/Uniform1Int.java | 2 +- .../shaders/uniforms/Uniform2Float.java | 2 +- .../backend/shaders/uniforms/Uniform2Int.java | 2 +- .../shaders/uniforms/Uniform2Matrix.java | 2 +- .../shaders/uniforms/Uniform3Float.java | 2 +- .../backend/shaders/uniforms/Uniform3Int.java | 2 +- .../shaders/uniforms/Uniform3Matrix.java | 2 +- .../shaders/uniforms/Uniform4Float.java | 2 +- .../backend/shaders/uniforms/Uniform4Int.java | 2 +- .../shaders/uniforms/Uniform4Matrix.java | 2 +- .../graphics/flat/AssembledFlatLayer.java | 2 +- .../flat/AssembledFlatRenderHelper.java | 2 +- .../flat/DefaultFlatRenderHelper.java | 2 +- .../client/graphics/flat/FlatGraphics.java | 2 +- .../graphics/flat/FlatRenderHelper.java | 7 +- .../graphics/flat/FlatRenderProgram.java | 21 +- .../progressia/client/graphics/flat/Mask.java | 5 +- .../client/graphics/flat/MaskStack.java | 7 +- .../client/graphics/flat/RenderTarget.java | 160 +--- .../client/graphics/flat/TransformedMask.java | 52 +- .../progressia/client/graphics/font/Font.java | 15 +- .../client/graphics/font/GNUUnifont.java | 2 +- .../graphics/font/GNUUnifontLoader.java | 35 +- .../client/graphics/font/SpriteTypeface.java | 101 +- .../client/graphics/font/Typeface.java | 49 +- .../client/graphics/font/Typefaces.java | 2 +- .../client/graphics/gui/Component.java | 9 +- .../client/graphics/gui/DynamicLabel.java | 2 +- .../client/graphics/gui/GUILayer.java | 2 +- .../progressia/client/graphics/gui/Label.java | 16 +- .../client/graphics/gui/Layout.java | 2 +- .../progressia/client/graphics/gui/Panel.java | 2 +- .../graphics/gui/event/ChildAddedEvent.java | 2 +- .../client/graphics/gui/event/ChildEvent.java | 2 +- .../graphics/gui/event/ChildRemovedEvent.java | 2 +- .../graphics/gui/event/ComponentEvent.java | 2 +- .../client/graphics/gui/event/FocusEvent.java | 2 +- .../graphics/gui/event/HierarchyEvent.java | 2 +- .../client/graphics/gui/event/HoverEvent.java | 2 +- .../gui/event/ParentChangedEvent.java | 2 +- .../graphics/gui/layout/LayoutAlign.java | 21 +- .../gui/layout/LayoutBorderHorizontal.java | 27 +- .../gui/layout/LayoutBorderVertical.java | 27 +- .../graphics/gui/layout/LayoutGrid.java | 15 +- .../graphics/gui/layout/LayoutHorizontal.java | 5 +- .../graphics/gui/layout/LayoutVertical.java | 5 +- .../client/graphics/input/CursorEvent.java | 2 +- .../graphics/input/CursorMoveEvent.java | 14 +- .../graphics/input/FrameResizeEvent.java | 8 +- .../client/graphics/input/InputEvent.java | 2 +- .../client/graphics/input/KeyEvent.java | 10 +- .../client/graphics/input/KeyMatcher.java | 2 +- .../client/graphics/input/Keys.java | 29 +- .../client/graphics/input/WheelEvent.java | 2 +- .../graphics/input/WheelScrollEvent.java | 2 +- .../client/graphics/input/bus/Input.java | 2 +- .../client/graphics/input/bus/InputBus.java | 27 +- .../graphics/input/bus/InputListener.java | 2 +- .../graphics/model/BlockFaceVectors.java | 57 +- .../client/graphics/model/DynamicModel.java | 33 +- .../client/graphics/model/EmptyModel.java | 2 +- .../client/graphics/model/Face.java | 39 +- .../client/graphics/model/FaceGroup.java | 7 +- .../client/graphics/model/Faces.java | 82 +- .../client/graphics/model/LambdaModel.java | 44 +- .../client/graphics/model/Model.java | 2 +- .../client/graphics/model/Renderable.java | 2 +- .../client/graphics/model/Shape.java | 2 +- .../graphics/model/ShapeRenderHelper.java | 13 +- .../graphics/model/ShapeRenderProgram.java | 189 +--- .../client/graphics/model/Shapes.java | 145 +-- .../client/graphics/model/StaticModel.java | 18 +- .../client/graphics/texture/Atlases.java | 9 +- .../graphics/texture/ComplexTexture.java | 64 +- .../graphics/texture/SimpleTexture.java | 2 +- .../graphics/texture/SimpleTextures.java | 6 +- .../client/graphics/texture/Sprite.java | 12 +- .../client/graphics/texture/Texture.java | 2 +- .../client/graphics/texture/TextureData.java | 31 +- .../graphics/texture/TextureDataEditor.java | 126 +-- .../graphics/texture/TextureLoader.java | 54 +- .../graphics/texture/TexturePrimitive.java | 2 +- .../graphics/texture/TextureSettings.java | 2 +- .../client/graphics/texture/TextureUtil.java | 68 +- .../client/graphics/world/Camera.java | 63 +- .../client/graphics/world/EntityAnchor.java | 25 +- .../client/graphics/world/LayerWorld.java | 34 +- .../client/graphics/world/LocalPlayer.java | 2 +- .../client/graphics/world/Selection.java | 2 +- .../graphics/world/WorldRenderHelper.java | 7 +- .../graphics/world/WorldRenderProgram.java | 138 +-- .../client/localization/LocaleListener.java | 2 +- .../client/localization/Localizer.java | 4 +- .../client/localization/MutableString.java | 4 +- .../localization/MutableStringConcat.java | 2 +- .../localization/MutableStringFormatter.java | 2 +- .../localization/MutableStringFunc.java | 2 +- .../localization/MutableStringLocalized.java | 2 +- .../localization/MutableStringParented.java | 2 +- .../client/localization/Parser.java | 16 +- .../progressia/client/world/ChunkRender.java | 16 +- .../client/world/ChunkRenderModel.java | 60 +- .../client/world/ChunkUpdateListener.java | 27 +- .../progressia/client/world/WorldRender.java | 12 +- .../client/world/block/BlockRender.java | 6 +- .../client/world/block/BlockRenderNone.java | 2 +- .../world/block/BlockRenderOpaqueCube.java | 33 +- .../world/block/BlockRenderRegistry.java | 8 +- .../world/block/BlockRenderTexturedCube.java | 56 +- .../block/BlockRenderTransparentCube.java | 33 +- .../world/cro/ChunkRenderOptimizer.java | 31 +- .../cro/ChunkRenderOptimizerRegistry.java | 6 +- .../cro/ChunkRenderOptimizerSurface.java | 83 +- .../client/world/entity/EntityRender.java | 2 +- .../world/entity/EntityRenderRegistry.java | 13 +- .../client/world/entity/EntityRenderable.java | 2 +- .../client/world/entity/HumanoidModel.java | 33 +- .../client/world/entity/NPedModel.java | 43 +- .../client/world/entity/QuadripedModel.java | 21 +- .../client/world/tile/TileRender.java | 6 +- .../client/world/tile/TileRenderGrass.java | 8 +- .../client/world/tile/TileRenderNone.java | 4 +- .../world/tile/TileRenderOpaqueSurface.java | 2 +- .../client/world/tile/TileRenderRegistry.java | 8 +- .../client/world/tile/TileRenderStack.java | 5 +- .../client/world/tile/TileRenderSurface.java | 45 +- .../tile/TileRenderTransparentSurface.java | 2 +- .../ru/windcorp/progressia/common/Units.java | 32 +- .../progressia/common/collision/AABB.java | 39 +- .../progressia/common/collision/AABBoid.java | 2 +- .../common/collision/Collideable.java | 13 +- .../common/collision/CollisionModel.java | 2 +- .../collision/CollisionPathComputer.java | 36 +- .../collision/CompoundCollisionModel.java | 2 +- .../collision/TransformedCollisionModel.java | 2 +- .../common/collision/TranslatedAABB.java | 2 +- .../progressia/common/collision/Wall.java | 2 +- .../collision/WorldCollisionHelper.java | 25 +- .../collision/colliders/AABBoidCollider.java | 97 +- .../AnythingWithCompoundCollider.java | 21 +- .../common/collision/colliders/Collider.java | 225 ++--- .../progressia/common/comms/CommsChannel.java | 30 +- .../common/comms/CommsListener.java | 2 +- .../common/comms/controls/ControlData.java | 2 +- .../comms/controls/ControlDataRegistry.java | 2 +- .../common/comms/controls/PacketControl.java | 2 +- .../common/comms/packets/Packet.java | 2 +- .../common/hacks/GuavaEventBusHijacker.java | 34 +- .../progressia/common/resource/Resource.java | 6 +- .../common/resource/ResourceManager.java | 6 +- .../common/resource/ResourceReader.java | 2 +- .../state/AbstractStatefulObjectLayout.java | 19 +- .../common/state/HashMapStateStorage.java | 2 +- .../progressia/common/state/IOContext.java | 6 +- .../state/InspectingStatefulObjectLayout.java | 24 +- .../common/state/IntStateField.java | 22 +- .../common/state/OptimizedStateStorage.java | 2 +- .../state/OptimizedStatefulObjectLayout.java | 11 +- .../common/state/PrimitiveCounters.java | 2 +- .../progressia/common/state/StateChanger.java | 2 +- .../progressia/common/state/StateField.java | 22 +- .../common/state/StateFieldBuilder.java | 2 +- .../progressia/common/state/StateStorage.java | 2 +- .../common/state/StatefulObject.java | 74 +- .../common/state/StatefulObjectLayout.java | 20 +- .../common/state/StatefulObjectRegistry.java | 10 +- .../progressia/common/util/BinUtil.java | 2 +- .../common/util/ByteBufferInputStream.java | 2 +- .../common/util/ByteBufferOutputStream.java | 2 +- .../common/util/CoordinatePacker.java | 40 +- .../progressia/common/util/DataBuffer.java | 7 +- .../progressia/common/util/FloatMathUtil.java | 2 +- .../common/util/LowOverheadCache.java | 2 +- .../progressia/common/util/Matrices.java | 6 +- .../progressia/common/util/MultiLOC.java | 2 +- .../progressia/common/util/Named.java | 2 +- .../common/util/SizeLimitedList.java | 10 +- .../progressia/common/util/StashingStack.java | 52 +- .../progressia/common/util/TaskQueue.java | 8 +- .../progressia/common/util/VectorUtil.java | 80 +- .../progressia/common/util/Vectors.java | 6 +- .../common/util/crash/Analyzer.java | 30 +- .../common/util/crash/ContextProvider.java | 23 +- .../common/util/crash/CrashReports.java | 118 ++- .../common/util/crash/ReportingEventBus.java | 15 +- .../crash/analyzers/OutOfMemoryAnalyzer.java | 2 +- .../crash/providers/ArgsContextProvider.java | 2 +- .../providers/JavaVersionContextProvider.java | 2 +- .../providers/LanguageContextProvider.java | 2 +- .../crash/providers/OSContextProvider.java | 2 +- .../providers/OpenALContextProvider.java | 2 +- .../crash/providers/RAMContextProvider.java | 9 +- .../common/util/dynstr/DoubleFlusher.java | 2 +- .../common/util/dynstr/DynamicString.java | 6 +- .../common/util/dynstr/DynamicStrings.java | 2 +- .../common/util/dynstr/FloatFlusher.java | 2 +- .../common/util/dynstr/IntFlusher.java | 218 +---- .../util/namespaces/IllegalIdException.java | 10 +- .../common/util/namespaces/Namespaced.java | 2 +- .../namespaces/NamespacedFactoryRegistry.java | 7 +- .../NamespacedInstanceRegistry.java | 13 +- .../util/namespaces/NamespacedUtil.java | 38 +- .../progressia/common/world/BlockRay.java | 8 +- .../progressia/common/world/ChunkData.java | 70 +- .../common/world/ChunkDataListener.java | 69 +- .../common/world/ChunkDataListeners.java | 2 +- .../progressia/common/world/Coordinates.java | 80 +- .../common/world/DecodingException.java | 2 +- .../world/IllegalCoordinatesException.java | 10 +- .../common/world/PacketAffectChunk.java | 2 +- .../common/world/PacketAffectWorld.java | 2 +- .../common/world/PacketRevokeChunk.java | 2 +- .../common/world/PacketSendChunk.java | 2 +- .../common/world/PacketSetLocalPlayer.java | 2 +- .../progressia/common/world/PlayerData.java | 2 +- .../progressia/common/world/WorldData.java | 28 +- .../common/world/WorldDataListener.java | 51 +- .../common/world/block/BlockData.java | 2 +- .../common/world/block/BlockDataRegistry.java | 2 +- .../common/world/block/BlockFace.java | 33 +- .../common/world/block/BlockRelation.java | 10 +- .../common/world/block/PacketAffectBlock.java | 2 +- .../common/world/block/PacketSetBlock.java | 2 +- .../common/world/entity/EntityData.java | 37 +- .../world/entity/EntityDataRegistry.java | 2 +- .../world/entity/PacketAffectEntity.java | 2 +- .../world/entity/PacketChangeEntity.java | 2 +- .../world/entity/PacketRevokeEntity.java | 2 +- .../common/world/entity/PacketSendEntity.java | 2 +- .../common/world/generic/ChunkMap.java | 14 +- .../common/world/generic/ChunkSet.java | 8 +- .../common/world/generic/ChunkSets.java | 8 +- .../common/world/generic/GenericBlock.java | 2 +- .../common/world/generic/GenericChunk.java | 79 +- .../common/world/generic/GenericEntity.java | 2 +- .../common/world/generic/GenericTile.java | 2 +- .../world/generic/GenericTileStack.java | 5 +- .../common/world/generic/GenericWorld.java | 2 +- .../world/generic/LongBasedChunkMap.java | 2 +- .../world/generic/LongBasedChunkSet.java | 2 +- .../common/world/io/ChunkCodec.java | 5 +- .../progressia/common/world/io/ChunkIO.java | 31 +- .../common/world/tile/PacketAddTile.java | 2 +- .../common/world/tile/PacketAffectTile.java | 2 +- .../common/world/tile/PacketRemoveTile.java | 13 +- .../common/world/tile/TileData.java | 2 +- .../common/world/tile/TileDataRegistry.java | 2 +- .../common/world/tile/TileDataStack.java | 60 +- .../common/world/tile/TileReference.java | 2 +- .../world/tile/TileStackIsFullException.java | 10 +- .../progressia/server/ChunkLoader.java | 2 +- .../progressia/server/ChunkManager.java | 18 +- .../progressia/server/EntityManager.java | 7 +- .../ru/windcorp/progressia/server/Player.java | 2 +- .../progressia/server/PlayerManager.java | 9 +- .../ru/windcorp/progressia/server/Server.java | 49 +- .../progressia/server/ServerState.java | 2 +- .../progressia/server/ServerThread.java | 7 +- .../progressia/server/TickingSettings.java | 2 +- .../progressia/server/comms/Client.java | 2 +- .../progressia/server/comms/ClientChat.java | 2 +- .../server/comms/ClientManager.java | 17 +- .../progressia/server/comms/ClientPlayer.java | 2 +- .../comms/DefaultServerCommsListener.java | 7 +- .../server/comms/controls/ControlLogic.java | 14 +- .../comms/controls/ControlLogicRegistry.java | 2 +- .../progressia/server/world/ChunkLogic.java | 18 +- .../server/world/ChunkTickContext.java | 2 +- .../server/world/TickAndUpdateUtil.java | 37 +- .../progressia/server/world/TickContext.java | 2 +- .../server/world/TickContextMutable.java | 29 +- .../server/world/UpdateTriggerer.java | 18 +- .../progressia/server/world/WorldLogic.java | 17 +- .../server/world/block/BlockLogic.java | 2 +- .../world/block/BlockLogicRegistry.java | 2 +- .../server/world/block/BlockTickContext.java | 2 +- .../server/world/block/TickableBlock.java | 2 +- .../server/world/block/UpdateableBlock.java | 11 +- .../server/world/entity/EntityLogic.java | 2 +- .../world/entity/EntityLogicRegistry.java | 2 +- .../generation/AbstractWorldGenerator.java | 2 +- .../world/generation/WorldGenerator.java | 2 +- .../server/world/tasks/AddTile.java | 2 +- .../world/tasks/BlockTriggeredUpdate.java | 2 +- .../server/world/tasks/CachedBlockChange.java | 2 +- .../server/world/tasks/CachedChange.java | 2 +- .../server/world/tasks/CachedChunkChange.java | 2 +- .../server/world/tasks/CachedEvaluation.java | 2 +- .../server/world/tasks/CachedTileChange.java | 9 +- .../server/world/tasks/CachedWorldChange.java | 2 +- .../server/world/tasks/ChangeEntity.java | 2 +- .../server/world/tasks/RemoveTile.java | 2 +- .../server/world/tasks/SetBlock.java | 2 +- .../server/world/tasks/StateChange.java | 2 +- .../server/world/tasks/TickChunk.java | 36 +- .../server/world/tasks/TickEntitiesTask.java | 2 +- .../world/tasks/TileTriggeredUpdate.java | 2 +- .../server/world/tasks/WorldAccessor.java | 20 +- .../server/world/ticking/Change.java | 15 +- .../world/ticking/DevilInvasionException.java | 2 +- .../server/world/ticking/Evaluation.java | 17 +- .../server/world/ticking/Ticker.java | 2 +- .../world/ticking/TickerCoordinator.java | 43 +- .../server/world/ticking/TickerTask.java | 32 +- .../server/world/ticking/TickingPolicy.java | 19 +- .../server/world/tile/HangingTileLogic.java | 2 +- .../server/world/tile/TSTickContext.java | 10 +- .../server/world/tile/TickableTile.java | 2 +- .../server/world/tile/TileLogic.java | 2 +- .../server/world/tile/TileLogicRegistry.java | 2 +- .../server/world/tile/TileLogicStack.java | 5 +- .../server/world/tile/TileTickContext.java | 2 +- .../server/world/tile/UpdateableTile.java | 2 +- .../test/TestEntityLogicFallingBlock.java | 22 +- .../test/gen/TestTerrainGenerator.java | 42 +- .../test/gen/TestWorldGenerator.java | 14 +- 413 files changed, 2581 insertions(+), 5099 deletions(-) diff --git a/src/main/java/kdotjpg/opensimplex2/areagen/OpenSimplex2S.java b/src/main/java/kdotjpg/opensimplex2/areagen/OpenSimplex2S.java index 3a17d8a..1f3c355 100644 --- a/src/main/java/kdotjpg/opensimplex2/areagen/OpenSimplex2S.java +++ b/src/main/java/kdotjpg/opensimplex2/areagen/OpenSimplex2S.java @@ -28,7 +28,7 @@ import java.util.Set; import java.util.HashSet; public class OpenSimplex2S { - + private static final int PSIZE = 2048; private static final int PMASK = 2047; @@ -40,12 +40,12 @@ public class OpenSimplex2S { perm = new short[PSIZE]; permGrad2 = new Grad2[PSIZE]; permGrad3 = new Grad3[PSIZE]; - short[] source = new short[PSIZE]; + short[] source = new short[PSIZE]; for (short i = 0; i < PSIZE; i++) source[i] = i; for (int i = PSIZE - 1; i >= 0; i--) { seed = seed * 6364136223846793005L + 1442695040888963407L; - int r = (int)((seed + 31) % (i + 1)); + int r = (int) ((seed + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; @@ -54,55 +54,52 @@ public class OpenSimplex2S { source[r] = source[i]; } } - + /* * Traditional evaluators */ - + /** * 2D SuperSimplex noise, standard lattice orientation. */ public double noise2(double x, double y) { - + // Get points for A2* lattice double s = 0.366025403784439 * (x + y); double xs = x + s, ys = y + s; - + return noise2_Base(xs, ys); } - + /** - * 2D SuperSimplex noise, with Y pointing down the main diagonal. - * Might be better for a 2D sandbox style game, where Y is vertical. - * Probably slightly less optimal for heightmaps or continent maps. + * 2D SuperSimplex noise, with Y pointing down the main diagonal. Might be + * better for a 2D sandbox style game, where Y is vertical. Probably + * slightly less optimal for heightmaps or continent maps. */ public double noise2_XBeforeY(double x, double y) { - + // Skew transform and rotation baked into one. double xx = x * 0.7071067811865476; double yy = y * 1.224744871380249; - + return noise2_Base(yy + xx, yy - xx); } - + /** - * 2D SuperSimplex noise base. - * Lookup table implementation inspired by DigitalShadow. + * 2D SuperSimplex noise base. Lookup table implementation inspired by + * DigitalShadow. */ private double noise2_Base(double xs, double ys) { double value = 0; - + // Get base points and offsets int xsb = fastFloor(xs), ysb = fastFloor(ys); double xsi = xs - xsb, ysi = ys - ysb; - + // Index to point list - int a = (int)(xsi + ysi); - int index = - (a << 2) | - (int)(xsi - ysi / 2 + 1 - a / 2.0) << 3 | - (int)(ysi - xsi / 2 + 1 - a / 2.0) << 4; - + int a = (int) (xsi + ysi); + int index = (a << 2) | (int) (xsi - ysi / 2 + 1 - a / 2.0) << 3 | (int) (ysi - xsi / 2 + 1 - a / 2.0) << 4; + double ssi = (xsi + ysi) * -0.211324865405187; double xi = xsi + ssi, yi = ysi + ssi; @@ -112,98 +109,107 @@ public class OpenSimplex2S { double dx = xi + c.dx, dy = yi + c.dy; double attn = 2.0 / 3.0 - dx * dx - dy * dy; - if (attn <= 0) continue; + if (attn <= 0) + continue; int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK; Grad2 grad = permGrad2[perm[pxm] ^ pym]; double extrapolation = grad.dx * dx + grad.dy * dy; - + attn *= attn; value += attn * attn * extrapolation; } - + return value; } - + /** - * 3D Re-oriented 8-point BCC noise, classic orientation - * Proper substitute for what 3D SuperSimplex would be, - * in light of Forbidden Formulae. - * Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. + * 3D Re-oriented 8-point BCC noise, classic orientation Proper substitute + * for what 3D SuperSimplex would be, in light of Forbidden Formulae. Use + * noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate. */ public double noise3_Classic(double x, double y, double z) { - - // Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices. - // If texturing objects that don't tend to have cardinal plane faces, you could even remove this. + + // Re-orient the cubic lattices via rotation, to produce the expected + // look on cardinal planar slices. + // If texturing objects that don't tend to have cardinal plane faces, + // you could even remove this. // Orthonormal rotation. Not a skew transform. double r = (2.0 / 3.0) * (x + y + z); double xr = r - x, yr = r - y, zr = r - z; - + // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } - + /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y). - * Recommended for 3D terrain and time-varied animations. - * The Z coordinate should always be the "different" coordinate in your use case. - * If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. - * If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). - * For a time varied animation, call noise3_XYBeforeZ(x, y, T). + * Recommended for 3D terrain and time-varied animations. The Z coordinate + * should always be the "different" coordinate in your use case. If Y is + * vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use + * noise3_XZBeforeY. If Z is vertical in world coordinates, call + * noise3_XYBeforeZ(x, y, Z). For a time varied animation, call + * noise3_XYBeforeZ(x, y, T). */ public double noise3_XYBeforeZ(double x, double y, double z) { - - // Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D. + + // Re-orient the cubic lattices without skewing, to make X and Y + // triangular like 2D. // Orthonormal rotation. Not a skew transform. double xy = x + y; double s2 = xy * -0.211324865405187; double zz = z * 0.577350269189626; double xr = x + s2 - zz, yr = y + s2 - zz; double zr = xy * 0.577350269189626 + zz; - + // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } - + /** * 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z). - * Recommended for 3D terrain and time-varied animations. - * The Y coordinate should always be the "different" coordinate in your use case. - * If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). - * If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. - * For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ. + * Recommended for 3D terrain and time-varied animations. The Y coordinate + * should always be the "different" coordinate in your use case. If Y is + * vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). If Z is + * vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use + * noise3_XYBeforeZ. For a time varied animation, call noise3_XZBeforeY(x, + * T, y) or use noise3_XYBeforeZ. */ public double noise3_XZBeforeY(double x, double y, double z) { - - // Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D. + + // Re-orient the cubic lattices without skewing, to make X and Z + // triangular like 2D. // Orthonormal rotation. Not a skew transform. double xz = x + z; double s2 = xz * -0.211324865405187; double yy = y * 0.577350269189626; - double xr = x + s2 - yy; double zr = z + s2 - yy; + double xr = x + s2 - yy; + double zr = z + s2 - yy; double yr = xz * 0.577350269189626 + yy; - + // Evaluate both lattices to form a BCC lattice. return noise3_BCC(xr, yr, zr); } - + /** - * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. - * Lookup table implementation inspired by DigitalShadow. - * It was actually faster to narrow down the points in the loop itself, - * than to build up the index with enough info to isolate 8 points. + * Generate overlapping cubic lattices for 3D Re-oriented BCC noise. Lookup + * table implementation inspired by DigitalShadow. It was actually faster to + * narrow down the points in the loop itself, than to build up the index + * with enough info to isolate 8 points. */ private double noise3_BCC(double xr, double yr, double zr) { - + // Get base and offsets inside cube of first lattice. int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb; - - // Identify which octant of the cube we're in. This determines which cell - // in the other cubic lattice we're in, and also narrows down one point on each. - int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5); + + // Identify which octant of the cube we're in. This determines which + // cell + // in the other cubic lattice we're in, and also narrows down one point + // on each. + int xht = (int) (xri + 0.5), yht = (int) (yri + 0.5), zht = (int) (zri + 0.5); int index = (xht << 0) | (yht << 1) | (zht << 2); - + // Point contributions double value = 0; LatticePoint3D c = LOOKUP_3D[index]; @@ -216,7 +222,7 @@ public class OpenSimplex2S { int pxm = (xrb + c.xrv) & PMASK, pym = (yrb + c.yrv) & PMASK, pzm = (zrb + c.zrv) & PMASK; Grad3 grad = permGrad3[perm[perm[pxm] ^ pym] ^ pzm]; double extrapolation = grad.dx * dxr + grad.dy * dyr + grad.dz * dzr; - + attn *= attn; value += attn * attn * extrapolation; c = c.nextOnSuccess; @@ -224,122 +230,138 @@ public class OpenSimplex2S { } return value; } - + /* * Area Generators */ - + /** - * Generate the 2D noise over a large area. - * Propagates by flood-fill instead of iterating over a range. - * Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel. + * Generate the 2D noise over a large area. Propagates by flood-fill instead + * of iterating over a range. Results may occasionally slightly exceed [-1, + * 1] due to the grid-snapped pre-generated kernel. */ public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0) { int height = buffer.length; int width = buffer[0].length; generate2(context, buffer, x0, y0, width, height, 0, 0); } - + /** - * Generate the 2D noise over a large area. - * Propagates by flood-fill instead of iterating over a range. - * Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel. + * Generate the 2D noise over a large area. Propagates by flood-fill instead + * of iterating over a range. Results may occasionally slightly exceed [-1, + * 1] due to the grid-snapped pre-generated kernel. */ - public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0, int width, int height, int skipX, int skipY) { + public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0, int width, int height, + int skipX, int skipY) { Queue queue = new LinkedList(); Set seen = new HashSet(); - + int scaledRadiusX = context.scaledRadiusX; int scaledRadiusY = context.scaledRadiusY; double[][] kernel = context.kernel; int x0Skipped = x0 + skipX, y0Skipped = y0 + skipY; - + // It seems that it's better for performance, to create a local copy. // - Slightly faster than generating the kernel here. // - Much faster than referencing it directly from the context object. // - Much faster than computing the kernel equation every time. // You can remove these lines if you find it's the opposite for you. // You'll have to double the bounds again in GenerateContext2D - kernel = new double[scaledRadiusY * 2][/*scaledRadiusX * 2*/]; + kernel = new double[scaledRadiusY * 2][/* scaledRadiusX * 2 */]; for (int yy = 0; yy < scaledRadiusY; yy++) { kernel[2 * scaledRadiusY - yy - 1] = kernel[yy] = (double[]) context.kernel[yy].clone(); } - + // Get started with one point/vertex. - // For some lattices, you might need to try a handful of points in the cell, - // or flip a couple of coordinates, to guarantee it or a neighbor contributes. + // For some lattices, you might need to try a handful of points in the + // cell, + // or flip a couple of coordinates, to guarantee it or a neighbor + // contributes. // For An* lattices, the base coordinate seems fine. - double x0f = x0Skipped * context.xFrequency; double y0f = y0Skipped * context.yFrequency; + double x0f = x0Skipped * context.xFrequency; + double y0f = y0Skipped * context.yFrequency; double x0s = context.orientation.s00 * x0f + context.orientation.s01 * y0f; double y0s = context.orientation.s10 * x0f + context.orientation.s11 * y0f; int x0sb = fastFloor(x0s), y0sb = fastFloor(y0s); AreaGenLatticePoint2D firstPoint = new AreaGenLatticePoint2D(context, x0sb, y0sb); queue.add(firstPoint); seen.add(firstPoint); - + while (!queue.isEmpty()) { AreaGenLatticePoint2D point = queue.remove(); int destPointX = point.destPointX; int destPointY = point.destPointY; - + // Prepare gradient vector int pxm = point.xsv & PMASK, pym = point.ysv & PMASK; Grad2 grad = context.orientation.gradients[perm[perm[pxm] ^ pym]]; double gx = grad.dx * context.xFrequency; double gy = grad.dy * context.yFrequency; - double gOff = 0.5 * (gx + gy); // to correct for (0.5, 0.5)-offset kernel - + double gOff = 0.5 * (gx + gy); // to correct for (0.5, 0.5)-offset + // kernel + // Contribution kernel bounds - int yy0 = destPointY - scaledRadiusY; if (yy0 < y0Skipped) yy0 = y0Skipped; - int yy1 = destPointY + scaledRadiusY; if (yy1 > y0 + height) yy1 = y0 + height; - + int yy0 = destPointY - scaledRadiusY; + if (yy0 < y0Skipped) + yy0 = y0Skipped; + int yy1 = destPointY + scaledRadiusY; + if (yy1 > y0 + height) + yy1 = y0 + height; + // For each row of the contribution circle, for (int yy = yy0; yy < yy1; yy++) { int dy = yy - destPointY; int ky = dy + scaledRadiusY; - + // Set up bounds so we only loop over what we need to int thisScaledRadiusX = context.kernelBounds[ky]; - int xx0 = destPointX - thisScaledRadiusX; if (xx0 < x0Skipped) xx0 = x0Skipped; - int xx1 = destPointX + thisScaledRadiusX; if (xx1 > x0 + width) xx1 = x0 + width; - + int xx0 = destPointX - thisScaledRadiusX; + if (xx0 < x0Skipped) + xx0 = x0Skipped; + int xx1 = destPointX + thisScaledRadiusX; + if (xx1 > x0 + width) + xx1 = x0 + width; + // For each point on that row for (int xx = xx0; xx < xx1; xx++) { int dx = xx - destPointX; int kx = dx + scaledRadiusX; - - // gOff accounts for our choice to offset the pre-generated kernel by (0.5, 0.5) to avoid the zero center. - // I found almost no difference in performance using gOff vs not (under 1ns diff per value on my system) + + // gOff accounts for our choice to offset the pre-generated + // kernel by (0.5, 0.5) to avoid the zero center. + // I found almost no difference in performance using gOff vs + // not (under 1ns diff per value on my system) double extrapolation = gx * dx + gy * dy + gOff; buffer[yy - y0][xx - x0] += kernel[ky][kx] * extrapolation; - + } } - + // For each neighbor of the point for (int i = 0; i < NEIGHBOR_MAP_2D.length; i++) { - AreaGenLatticePoint2D neighbor = new AreaGenLatticePoint2D(context, - point.xsv + NEIGHBOR_MAP_2D[i][0], point.ysv + NEIGHBOR_MAP_2D[i][1]); - + AreaGenLatticePoint2D neighbor = new AreaGenLatticePoint2D(context, point.xsv + NEIGHBOR_MAP_2D[i][0], + point.ysv + NEIGHBOR_MAP_2D[i][1]); + // If it's in range of the buffer region and not seen before - if (neighbor.destPointX + scaledRadiusX >= x0Skipped && neighbor.destPointX - scaledRadiusX <= x0 + width - 1 - && neighbor.destPointY + scaledRadiusY >= y0Skipped && neighbor.destPointY - scaledRadiusY <= y0 + height - 1 - && !seen.contains(neighbor)) { - + if (neighbor.destPointX + scaledRadiusX >= x0Skipped + && neighbor.destPointX - scaledRadiusX <= x0 + width - 1 + && neighbor.destPointY + scaledRadiusY >= y0Skipped + && neighbor.destPointY - scaledRadiusY <= y0 + height - 1 && !seen.contains(neighbor)) { + // Add it to the queue so we can process it at some point queue.add(neighbor); - + // Add it to the set so we don't add it to the queue again seen.add(neighbor); } } } } - + /** - * Generate the 3D noise over a large area/volume. - * Propagates by flood-fill instead of iterating over a range. - * Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel. + * Generate the 3D noise over a large area/volume. Propagates by flood-fill + * instead of iterating over a range. Results may occasionally slightly + * exceed [-1, 1] due to the grid-snapped pre-generated kernel. */ public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0) { int depth = buffer.length; @@ -347,121 +369,142 @@ public class OpenSimplex2S { int width = buffer[0][0].length; generate3(context, buffer, x0, y0, z0, width, height, depth, 0, 0, 0); } - + /** - * Generate the 3D noise over a large area/volume. - * Propagates by flood-fill instead of iterating over a range. - * Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel. + * Generate the 3D noise over a large area/volume. Propagates by flood-fill + * instead of iterating over a range. Results may occasionally slightly + * exceed [-1, 1] due to the grid-snapped pre-generated kernel. */ - public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0, int width, int height, int depth, int skipX, int skipY, int skipZ) { + public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0, int width, int height, + int depth, int skipX, int skipY, int skipZ) { Queue queue = new LinkedList(); Set seen = new HashSet(); - + int scaledRadiusX = context.scaledRadiusX; int scaledRadiusY = context.scaledRadiusY; int scaledRadiusZ = context.scaledRadiusZ; double[][][] kernel = context.kernel; int x0Skipped = x0 + skipX, y0Skipped = y0 + skipY, z0Skipped = z0 + skipZ; - + // Quaternion multiplication for rotation. // https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/ - double qx = context.orientation.qx, qy = context.orientation.qy, qz = context.orientation.qz, qw = context.orientation.qw; - double x0f = x0Skipped * context.xFrequency, y0f = y0Skipped * context.yFrequency, z0f = z0Skipped * context.zFrequency; + double qx = context.orientation.qx, qy = context.orientation.qy, qz = context.orientation.qz, + qw = context.orientation.qw; + double x0f = x0Skipped * context.xFrequency, y0f = y0Skipped * context.yFrequency, + z0f = z0Skipped * context.zFrequency; double tx = 2 * (qy * z0f - qz * y0f); double ty = 2 * (qz * x0f - qx * z0f); double tz = 2 * (qx * y0f - qy * x0f); double x0r = x0f + qw * tx + (qy * tz - qz * ty); double y0r = y0f + qw * ty + (qz * tx - qx * tz); double z0r = z0f + qw * tz + (qx * ty - qy * tx); - + int x0rb = fastFloor(x0r), y0rb = fastFloor(y0r), z0rb = fastFloor(z0r); - + AreaGenLatticePoint3D firstPoint = new AreaGenLatticePoint3D(context, x0rb, y0rb, z0rb, 0); queue.add(firstPoint); seen.add(firstPoint); - + while (!queue.isEmpty()) { AreaGenLatticePoint3D point = queue.remove(); int destPointX = point.destPointX; int destPointY = point.destPointY; int destPointZ = point.destPointZ; - + // Prepare gradient vector int pxm = point.xsv & PMASK, pym = point.ysv & PMASK, pzm = point.zsv & PMASK; Grad3 grad = context.orientation.gradients[perm[perm[perm[pxm] ^ pym] ^ pzm]]; double gx = grad.dx * context.xFrequency; double gy = grad.dy * context.yFrequency; double gz = grad.dz * context.zFrequency; - double gOff = 0.5 * (gx + gy + gz); // to correct for (0.5, 0.5, 0.5)-offset kernel - + double gOff = 0.5 * (gx + gy + gz); // to correct for (0.5, 0.5, + // 0.5)-offset kernel + // Contribution kernel bounds. - int zz0 = destPointZ - scaledRadiusZ; if (zz0 < z0Skipped) zz0 = z0Skipped; - int zz1 = destPointZ + scaledRadiusZ; if (zz1 > z0 + depth) zz1 = z0 + depth; - + int zz0 = destPointZ - scaledRadiusZ; + if (zz0 < z0Skipped) + zz0 = z0Skipped; + int zz1 = destPointZ + scaledRadiusZ; + if (zz1 > z0 + depth) + zz1 = z0 + depth; + // For each x/y slice of the contribution sphere, for (int zz = zz0; zz < zz1; zz++) { int dz = zz - destPointZ; int kz = dz + scaledRadiusZ; - + // Set up bounds so we only loop over what we need to int thisScaledRadiusY = context.kernelBoundsY[kz]; - int yy0 = destPointY - thisScaledRadiusY; if (yy0 < y0Skipped) yy0 = y0Skipped; - int yy1 = destPointY + thisScaledRadiusY; if (yy1 > y0 + height) yy1 = y0 + height; - + int yy0 = destPointY - thisScaledRadiusY; + if (yy0 < y0Skipped) + yy0 = y0Skipped; + int yy1 = destPointY + thisScaledRadiusY; + if (yy1 > y0 + height) + yy1 = y0 + height; + // For each row of the contribution circle, for (int yy = yy0; yy < yy1; yy++) { int dy = yy - destPointY; int ky = dy + scaledRadiusY; - + // Set up bounds so we only loop over what we need to int thisScaledRadiusX = context.kernelBoundsX[kz][ky]; - int xx0 = destPointX - thisScaledRadiusX; if (xx0 < x0Skipped) xx0 = x0Skipped; - int xx1 = destPointX + thisScaledRadiusX; if (xx1 > x0 + width) xx1 = x0 + width; - + int xx0 = destPointX - thisScaledRadiusX; + if (xx0 < x0Skipped) + xx0 = x0Skipped; + int xx1 = destPointX + thisScaledRadiusX; + if (xx1 > x0 + width) + xx1 = x0 + width; + // For each point on that row for (int xx = xx0; xx < xx1; xx++) { int dx = xx - destPointX; int kx = dx + scaledRadiusX; - - // gOff accounts for our choice to offset the pre-generated kernel by (0.5, 0.5, 0.5) to avoid the zero center. + + // gOff accounts for our choice to offset the + // pre-generated kernel by (0.5, 0.5, 0.5) to avoid the + // zero center. double extrapolation = gx * dx + gy * dy + gz * dz + gOff; buffer[zz - z0][yy - y0][xx - x0] += kernel[kz][ky][kx] * extrapolation; - + } } } - + // For each neighbor of the point for (int i = 0; i < NEIGHBOR_MAP_3D[0].length; i++) { int l = point.lattice; AreaGenLatticePoint3D neighbor = new AreaGenLatticePoint3D(context, - point.xsv + NEIGHBOR_MAP_3D[l][i][0], point.ysv + NEIGHBOR_MAP_3D[l][i][1], point.zsv + NEIGHBOR_MAP_3D[l][i][2], 1 ^ l); - + point.xsv + NEIGHBOR_MAP_3D[l][i][0], point.ysv + NEIGHBOR_MAP_3D[l][i][1], + point.zsv + NEIGHBOR_MAP_3D[l][i][2], 1 ^ l); + // If it's in range of the buffer region and not seen before - if (neighbor.destPointX + scaledRadiusX >= x0Skipped && neighbor.destPointX - scaledRadiusX <= x0 + width - 1 - && neighbor.destPointY + scaledRadiusY >= y0Skipped && neighbor.destPointY - scaledRadiusY <= y0 + height - 1 - && neighbor.destPointZ + scaledRadiusZ >= z0Skipped && neighbor.destPointZ - scaledRadiusZ <= z0 + depth - 1 - && !seen.contains(neighbor)) { - + if (neighbor.destPointX + scaledRadiusX >= x0Skipped + && neighbor.destPointX - scaledRadiusX <= x0 + width - 1 + && neighbor.destPointY + scaledRadiusY >= y0Skipped + && neighbor.destPointY - scaledRadiusY <= y0 + height - 1 + && neighbor.destPointZ + scaledRadiusZ >= z0Skipped + && neighbor.destPointZ - scaledRadiusZ <= z0 + depth - 1 && !seen.contains(neighbor)) { + // Add it to the queue so we can process it at some point queue.add(neighbor); - + // Add it to the set so we don't add it to the queue again seen.add(neighbor); } } } } - + /* * Utility */ - + private static int fastFloor(double x) { - int xi = (int)x; + int xi = (int) x; return x < xi ? xi - 1 : xi; } - + /* * Definitions */ @@ -471,186 +514,242 @@ public class OpenSimplex2S { static { LOOKUP_2D = new LatticePoint2D[8 * 4]; LOOKUP_3D = new LatticePoint3D[8]; - + for (int i = 0; i < 8; i++) { int i1, j1, i2, j2; if ((i & 1) == 0) { - if ((i & 2) == 0) { i1 = -1; j1 = 0; } else { i1 = 1; j1 = 0; } - if ((i & 4) == 0) { i2 = 0; j2 = -1; } else { i2 = 0; j2 = 1; } + if ((i & 2) == 0) { + i1 = -1; + j1 = 0; + } else { + i1 = 1; + j1 = 0; + } + if ((i & 4) == 0) { + i2 = 0; + j2 = -1; + } else { + i2 = 0; + j2 = 1; + } } else { - if ((i & 2) != 0) { i1 = 2; j1 = 1; } else { i1 = 0; j1 = 1; } - if ((i & 4) != 0) { i2 = 1; j2 = 2; } else { i2 = 1; j2 = 0; } + if ((i & 2) != 0) { + i1 = 2; + j1 = 1; + } else { + i1 = 0; + j1 = 1; + } + if ((i & 4) != 0) { + i2 = 1; + j2 = 2; + } else { + i2 = 1; + j2 = 0; + } } LOOKUP_2D[i * 4 + 0] = new LatticePoint2D(0, 0); LOOKUP_2D[i * 4 + 1] = new LatticePoint2D(1, 1); LOOKUP_2D[i * 4 + 2] = new LatticePoint2D(i1, j1); LOOKUP_2D[i * 4 + 3] = new LatticePoint2D(i2, j2); } - + for (int i = 0; i < 8; i++) { int i1, j1, k1, i2, j2, k2; - i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1; - i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1; - - // The two points within this octant, one from each of the two cubic half-lattices. + i1 = (i >> 0) & 1; + j1 = (i >> 1) & 1; + k1 = (i >> 2) & 1; + i2 = i1 ^ 1; + j2 = j1 ^ 1; + k2 = k1 ^ 1; + + // The two points within this octant, one from each of the two cubic + // half-lattices. LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0); LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1); - + // (1, 0, 0) vs (0, 1, 1) away from octant. LatticePoint3D c2 = new LatticePoint3D(i1 ^ 1, j1, k1, 0); LatticePoint3D c3 = new LatticePoint3D(i1, j1 ^ 1, k1 ^ 1, 0); - + // (1, 0, 0) vs (0, 1, 1) away from octant, on second half-lattice. LatticePoint3D c4 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + k2, 1); LatticePoint3D c5 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + (k2 ^ 1), 1); - + // (0, 1, 0) vs (1, 0, 1) away from octant. LatticePoint3D c6 = new LatticePoint3D(i1, j1 ^ 1, k1, 0); LatticePoint3D c7 = new LatticePoint3D(i1 ^ 1, j1, k1 ^ 1, 0); - + // (0, 1, 0) vs (1, 0, 1) away from octant, on second half-lattice. LatticePoint3D c8 = new LatticePoint3D(i1 + i2, j1 + (j2 ^ 1), k1 + k2, 1); LatticePoint3D c9 = new LatticePoint3D(i1 + (i2 ^ 1), j1 + j2, k1 + (k2 ^ 1), 1); - + // (0, 0, 1) vs (1, 1, 0) away from octant. LatticePoint3D cA = new LatticePoint3D(i1, j1, k1 ^ 1, 0); LatticePoint3D cB = new LatticePoint3D(i1 ^ 1, j1 ^ 1, k1, 0); - + // (0, 0, 1) vs (1, 1, 0) away from octant, on second half-lattice. LatticePoint3D cC = new LatticePoint3D(i1 + i2, j1 + j2, k1 + (k2 ^ 1), 1); LatticePoint3D cD = new LatticePoint3D(i1 + (i2 ^ 1), j1 + (j2 ^ 1), k1 + k2, 1); - + // First two points are guaranteed. c0.nextOnFailure = c0.nextOnSuccess = c1; c1.nextOnFailure = c1.nextOnSuccess = c2; - + // If c2 is in range, then we know c3 and c4 are not. - c2.nextOnFailure = c3; c2.nextOnSuccess = c5; - c3.nextOnFailure = c4; c3.nextOnSuccess = c4; - + c2.nextOnFailure = c3; + c2.nextOnSuccess = c5; + c3.nextOnFailure = c4; + c3.nextOnSuccess = c4; + // If c4 is in range, then we know c5 is not. - c4.nextOnFailure = c5; c4.nextOnSuccess = c6; + c4.nextOnFailure = c5; + c4.nextOnSuccess = c6; c5.nextOnFailure = c5.nextOnSuccess = c6; - + // If c6 is in range, then we know c7 and c8 are not. - c6.nextOnFailure = c7; c6.nextOnSuccess = c9; - c7.nextOnFailure = c8; c7.nextOnSuccess = c8; - + c6.nextOnFailure = c7; + c6.nextOnSuccess = c9; + c7.nextOnFailure = c8; + c7.nextOnSuccess = c8; + // If c8 is in range, then we know c9 is not. - c8.nextOnFailure = c9; c8.nextOnSuccess = cA; + c8.nextOnFailure = c9; + c8.nextOnSuccess = cA; c9.nextOnFailure = c9.nextOnSuccess = cA; - + // If cA is in range, then we know cB and cC are not. - cA.nextOnFailure = cB; cA.nextOnSuccess = cD; - cB.nextOnFailure = cC; cB.nextOnSuccess = cC; - + cA.nextOnFailure = cB; + cA.nextOnSuccess = cD; + cB.nextOnFailure = cC; + cB.nextOnSuccess = cC; + // If cC is in range, then we know cD is not. - cC.nextOnFailure = cD; cC.nextOnSuccess = null; + cC.nextOnFailure = cD; + cC.nextOnSuccess = null; cD.nextOnFailure = cD.nextOnSuccess = null; - + LOOKUP_3D[i] = c0; - + } } - + // Hexagon surrounding each vertex. - private static final int[][] NEIGHBOR_MAP_2D = { - { 1, 0 }, { 1, 1 }, { 0, 1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } - }; - + private static final int[][] NEIGHBOR_MAP_2D = { { 1, 0 }, { 1, 1 }, { 0, 1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } }; + // Cube surrounding each vertex. // Alternates between half-lattices. private static final int[][][] NEIGHBOR_MAP_3D = { - { - { 1024, 1024, 1024 }, { 1025, 1024, 1024 }, { 1024, 1025, 1024 }, { 1025, 1025, 1024 }, - { 1024, 1024, 1025 }, { 1025, 1024, 1025 }, { 1024, 1025, 1025 }, { 1025, 1025, 1025 } - }, - { - { -1024, -1024, -1024 }, { -1025, -1024, 1024 }, { -1024, -1025, -1024 }, { -1025, -1025, -1024 }, - { -1024, -1024, -1025 }, { -1025, -1024, -1025 }, { -1024, -1025, -1025 }, { -1025, -1025, 1025 } - }, - }; - + { { 1024, 1024, 1024 }, { 1025, 1024, 1024 }, { 1024, 1025, 1024 }, { 1025, 1025, 1024 }, + { 1024, 1024, 1025 }, { 1025, 1024, 1025 }, { 1024, 1025, 1025 }, { 1025, 1025, 1025 } }, + { { -1024, -1024, -1024 }, { -1025, -1024, 1024 }, { -1024, -1025, -1024 }, { -1025, -1025, -1024 }, + { -1024, -1024, -1025 }, { -1025, -1024, -1025 }, { -1024, -1025, -1025 }, + { -1025, -1025, 1025 } }, }; + private static class LatticePoint2D { int xsv, ysv; double dx, dy; + public LatticePoint2D(int xsv, int ysv) { - this.xsv = xsv; this.ysv = ysv; + this.xsv = xsv; + this.ysv = ysv; double ssv = (xsv + ysv) * -0.211324865405187; this.dx = -xsv - ssv; this.dy = -ysv - ssv; } } - + private static class LatticePoint3D { public double dxr, dyr, dzr; public int xrv, yrv, zrv; LatticePoint3D nextOnFailure, nextOnSuccess; + public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) { - this.dxr = -xrv + lattice * 0.5; this.dyr = -yrv + lattice * 0.5; this.dzr = -zrv + lattice * 0.5; - this.xrv = xrv + lattice * 1024; this.yrv = yrv + lattice * 1024; this.zrv = zrv + lattice * 1024; + this.dxr = -xrv + lattice * 0.5; + this.dyr = -yrv + lattice * 0.5; + this.dzr = -zrv + lattice * 0.5; + this.xrv = xrv + lattice * 1024; + this.yrv = yrv + lattice * 1024; + this.zrv = zrv + lattice * 1024; } } - + private static class AreaGenLatticePoint2D { int xsv, ysv; int destPointX, destPointY; + public AreaGenLatticePoint2D(GenerateContext2D context, int xsv, int ysv) { - this.xsv = xsv; this.ysv = ysv; - - //Matrix multiplication for inverse rotation. Simplex skew transforms have always been shorthand for matrices. - this.destPointX = (int)Math.ceil((context.orientation.t00 * xsv + context.orientation.t01 * ysv) * context.xFrequencyInverse); - this.destPointY = (int)Math.ceil((context.orientation.t10 * xsv + context.orientation.t11 * ysv) * context.yFrequencyInverse); + this.xsv = xsv; + this.ysv = ysv; + + // Matrix multiplication for inverse rotation. Simplex skew + // transforms have always been shorthand for matrices. + this.destPointX = (int) Math + .ceil((context.orientation.t00 * xsv + context.orientation.t01 * ysv) * context.xFrequencyInverse); + this.destPointY = (int) Math + .ceil((context.orientation.t10 * xsv + context.orientation.t11 * ysv) * context.yFrequencyInverse); } + @Override public int hashCode() { return xsv * 7841 + ysv; } + @Override public boolean equals(Object obj) { - if (!(obj instanceof AreaGenLatticePoint2D)) return false; + if (!(obj instanceof AreaGenLatticePoint2D)) + return false; AreaGenLatticePoint2D other = (AreaGenLatticePoint2D) obj; return (other.xsv == this.xsv && other.ysv == this.ysv); } } - + private static class AreaGenLatticePoint3D { int xsv, ysv, zsv, lattice; int destPointX, destPointY, destPointZ; + public AreaGenLatticePoint3D(GenerateContext3D context, int xsv, int ysv, int zsv, int lattice) { - this.xsv = xsv; this.ysv = ysv; this.zsv = zsv; this.lattice = lattice; + this.xsv = xsv; + this.ysv = ysv; + this.zsv = zsv; + this.lattice = lattice; double xr = (xsv - lattice * 1024.5); double yr = (ysv - lattice * 1024.5); double zr = (zsv - lattice * 1024.5); - + // Quaternion multiplication for inverse rotation. // https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/ - double qx = -context.orientation.qx, qy = -context.orientation.qy, qz = -context.orientation.qz, qw = context.orientation.qw; + double qx = -context.orientation.qx, qy = -context.orientation.qy, qz = -context.orientation.qz, + qw = context.orientation.qw; double tx = 2 * (qy * zr - qz * yr); double ty = 2 * (qz * xr - qx * zr); double tz = 2 * (qx * yr - qy * xr); double xrr = xr + qw * tx + (qy * tz - qz * ty); double yrr = yr + qw * ty + (qz * tx - qx * tz); double zrr = zr + qw * tz + (qx * ty - qy * tx); - - this.destPointX = (int)Math.ceil(xrr * context.xFrequencyInverse); - this.destPointY = (int)Math.ceil(yrr * context.yFrequencyInverse); - this.destPointZ = (int)Math.ceil(zrr * context.zFrequencyInverse); + + this.destPointX = (int) Math.ceil(xrr * context.xFrequencyInverse); + this.destPointY = (int) Math.ceil(yrr * context.yFrequencyInverse); + this.destPointZ = (int) Math.ceil(zrr * context.zFrequencyInverse); } + @Override public int hashCode() { return xsv * 2122193 + ysv * 2053 + zsv * 2 + lattice; } + @Override public boolean equals(Object obj) { - if (!(obj instanceof AreaGenLatticePoint3D)) return false; + if (!(obj instanceof AreaGenLatticePoint3D)) + return false; AreaGenLatticePoint3D other = (AreaGenLatticePoint3D) obj; - return (other.xsv == this.xsv && other.ysv == this.ysv && other.zsv == this.zsv && other.lattice == this.lattice); + return (other.xsv == this.xsv && other.ysv == this.ysv && other.zsv == this.zsv + && other.lattice == this.lattice); } } - + public static class GenerateContext2D { - + double xFrequency; double yFrequency; double xFrequencyInverse; @@ -660,37 +759,37 @@ public class OpenSimplex2S { double[][] kernel; int[] kernelBounds; LatticeOrientation2D orientation; - - public GenerateContext2D(LatticeOrientation2D orientation, double xFrequency, double yFrequency, double amplitude) { - + + public GenerateContext2D(LatticeOrientation2D orientation, double xFrequency, double yFrequency, + double amplitude) { + // These will be used by every call to generate this.orientation = orientation; this.xFrequency = xFrequency; this.yFrequency = yFrequency; this.xFrequencyInverse = 1.0 / xFrequency; this.yFrequencyInverse = 1.0 / yFrequency; - + double preciseScaledRadiusX = Math.sqrt(2.0 / 3.0) * xFrequencyInverse; double preciseScaledRadiusY = Math.sqrt(2.0 / 3.0) * yFrequencyInverse; - + // 0.25 because we offset center by 0.5 - this.scaledRadiusX = (int)Math.ceil(preciseScaledRadiusX + 0.25); - this.scaledRadiusY = (int)Math.ceil(preciseScaledRadiusY + 0.25); - + this.scaledRadiusX = (int) Math.ceil(preciseScaledRadiusX + 0.25); + this.scaledRadiusY = (int) Math.ceil(preciseScaledRadiusY + 0.25); + // So will these - kernel = new double[scaledRadiusY/* * 2*/][]; + kernel = new double[scaledRadiusY/* * 2 */][]; kernelBounds = new int[scaledRadiusY * 2]; for (int yy = 0; yy < scaledRadiusY * 2; yy++) { - + // Pre-generate boundary of circle - kernelBounds[yy] = (int)Math.ceil( - Math.sqrt(1.0 - - (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) / (scaledRadiusY * scaledRadiusY) - ) * scaledRadiusX); - + kernelBounds[yy] = (int) Math.ceil(Math.sqrt( + 1.0 - (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) / (scaledRadiusY * scaledRadiusY)) + * scaledRadiusX); + if (yy < scaledRadiusY) { kernel[yy] = new double[scaledRadiusX * 2]; - + // Pre-generate kernel for (int xx = 0; xx < scaledRadiusX * 2; xx++) { double dx = (xx + 0.5 - scaledRadiusX) * xFrequency; @@ -703,13 +802,13 @@ public class OpenSimplex2S { kernel[yy][xx] = 0.0; } } - } /* else kernel[yy] = kernel[2 * scaledRadiusY - yy - 1];*/ + } /* else kernel[yy] = kernel[2 * scaledRadiusY - yy - 1]; */ } } } - + public static class GenerateContext3D { - + double xFrequency; double yFrequency; double zFrequency; @@ -723,9 +822,10 @@ public class OpenSimplex2S { int[] kernelBoundsY; int[][] kernelBoundsX; LatticeOrientation3D orientation; - - public GenerateContext3D(LatticeOrientation3D orientation, double xFrequency, double yFrequency, double zFrequency, double amplitude) { - + + public GenerateContext3D(LatticeOrientation3D orientation, double xFrequency, double yFrequency, + double zFrequency, double amplitude) { + // These will be used by every call to generate this.orientation = orientation; this.xFrequency = xFrequency; @@ -734,27 +834,27 @@ public class OpenSimplex2S { this.xFrequencyInverse = 1.0 / xFrequency; this.yFrequencyInverse = 1.0 / yFrequency; this.zFrequencyInverse = 1.0 / zFrequency; - + double preciseScaledRadiusX = Math.sqrt(0.75) * xFrequencyInverse; double preciseScaledRadiusY = Math.sqrt(0.75) * yFrequencyInverse; double preciseScaledRadiusZ = Math.sqrt(0.75) * zFrequencyInverse; - + // 0.25 because we offset center by 0.5 - this.scaledRadiusX = (int)Math.ceil(preciseScaledRadiusX + 0.25); - this.scaledRadiusY = (int)Math.ceil(preciseScaledRadiusY + 0.25); - this.scaledRadiusZ = (int)Math.ceil(preciseScaledRadiusZ + 0.25); - + this.scaledRadiusX = (int) Math.ceil(preciseScaledRadiusX + 0.25); + this.scaledRadiusY = (int) Math.ceil(preciseScaledRadiusY + 0.25); + this.scaledRadiusZ = (int) Math.ceil(preciseScaledRadiusZ + 0.25); + // So will these kernel = new double[scaledRadiusZ * 2][][]; kernelBoundsY = new int[scaledRadiusZ * 2]; kernelBoundsX = new int[scaledRadiusZ * 2][]; for (int zz = 0; zz < scaledRadiusZ * 2; zz++) { - + // Pre-generate boundary of sphere - kernelBoundsY[zz] = (int)Math.ceil( - Math.sqrt(1.0 - (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ) - / (scaledRadiusZ * scaledRadiusZ)) * scaledRadiusY); - + kernelBoundsY[zz] = (int) Math.ceil(Math.sqrt( + 1.0 - (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ) / (scaledRadiusZ * scaledRadiusZ)) + * scaledRadiusY); + if (zz < scaledRadiusZ) { kernel[zz] = new double[scaledRadiusY * 2][]; kernelBoundsX[zz] = new int[scaledRadiusY * 2]; @@ -762,20 +862,21 @@ public class OpenSimplex2S { kernel[zz] = kernel[2 * scaledRadiusZ - zz - 1]; kernelBoundsX[zz] = kernelBoundsX[2 * scaledRadiusZ - zz - 1]; } - + if (zz < scaledRadiusZ) { for (int yy = 0; yy < scaledRadiusY * 2; yy++) { - + // Pre-generate boundary of sphere - kernelBoundsX[zz][yy] = (int)Math.ceil( - Math.sqrt(1.0 - - (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) / (scaledRadiusY * scaledRadiusY) - - (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ) / (scaledRadiusZ * scaledRadiusZ) - ) * scaledRadiusX); - + kernelBoundsX[zz][yy] = (int) Math.ceil(Math.sqrt(1.0 + - (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) + / (scaledRadiusY * scaledRadiusY) + - (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ) + / (scaledRadiusZ * scaledRadiusZ)) + * scaledRadiusX); + if (yy < scaledRadiusY) { kernel[zz][yy] = new double[scaledRadiusX * 2]; - + // Pre-generate kernel for (int xx = 0; xx < scaledRadiusX * 2; xx++) { double dx = (xx + 0.5 - scaledRadiusX) * xFrequency; @@ -789,108 +890,112 @@ public class OpenSimplex2S { kernel[zz][yy][xx] = 0.0; } } - - } else kernel[zz][yy] = kernel[zz][2 * scaledRadiusY - yy - 1]; + + } else + kernel[zz][yy] = kernel[zz][2 * scaledRadiusY - yy - 1]; } } } } } - + public enum LatticeOrientation2D { - // Simplex skew transforms have always been shorthand for the matrices they represent. - // But when we bake the rotation into the skew transform, we need to use the general form. - Standard(GRADIENTS_2D, - 1.366025403784439, 0.366025403784439, 0.366025403784439, 1.366025403784439, - 0.788675134594813, -0.211324865405187, -0.211324865405187, 0.788675134594813), - XBeforeY(GRADIENTS_2D_X_BEFORE_Y, - 0.7071067811865476, 1.224744871380249, -0.7071067811865476, 1.224744871380249, - 0.7071067811865476, -0.7071067811865476, 0.40824829046764305, 0.40824829046764305); - + // Simplex skew transforms have always been shorthand for the matrices + // they represent. + // But when we bake the rotation into the skew transform, we need to use + // the general form. + Standard(GRADIENTS_2D, 1.366025403784439, 0.366025403784439, 0.366025403784439, 1.366025403784439, + 0.788675134594813, -0.211324865405187, -0.211324865405187, + 0.788675134594813), XBeforeY(GRADIENTS_2D_X_BEFORE_Y, 0.7071067811865476, 1.224744871380249, + -0.7071067811865476, 1.224744871380249, 0.7071067811865476, -0.7071067811865476, + 0.40824829046764305, 0.40824829046764305); + Grad2[] gradients; double s00, s01, s10, s11; double t00, t01, t10, t11; - - private LatticeOrientation2D(Grad2[] gradients, - double s00, double s01, double s10, double s11, - double t00, double t01, double t10, double t11) { + + private LatticeOrientation2D(Grad2[] gradients, double s00, double s01, double s10, double s11, double t00, + double t01, double t10, double t11) { this.gradients = gradients; - this.s00 = s00; this.s01 = s01; this.s10 = s10; this.s11 = s11; - this.t00 = t00; this.t01 = t01; this.t10 = t10; this.t11 = t11; + this.s00 = s00; + this.s01 = s01; + this.s10 = s10; + this.s11 = s11; + this.t00 = t00; + this.t01 = t01; + this.t10 = t10; + this.t11 = t11; } } - + public enum LatticeOrientation3D { - // Quaternions for 3D. Could use matrices, but I already wrote this code before I moved them into here. - Classic(GRADIENTS_3D_CLASSIC, 0.577350269189626, 0.577350269189626, 0.577350269189626, 0), - XYBeforeZ(GRADIENTS_3D_XY_BEFORE_Z, 0.3250575836718682, -0.3250575836718682, 0, 0.8880738339771154), - XZBeforeY(GRADIENTS_3D_XZ_BEFORE_Y, -0.3250575836718682, 0, 0.3250575836718682, 0.8880738339771154); - + // Quaternions for 3D. Could use matrices, but I already wrote this code + // before I moved them into here. + Classic(GRADIENTS_3D_CLASSIC, 0.577350269189626, 0.577350269189626, 0.577350269189626, 0), XYBeforeZ( + GRADIENTS_3D_XY_BEFORE_Z, 0.3250575836718682, -0.3250575836718682, 0, 0.8880738339771154), XZBeforeY( + GRADIENTS_3D_XZ_BEFORE_Y, -0.3250575836718682, 0, 0.3250575836718682, 0.8880738339771154); + Grad3[] gradients; double qx, qy, qz, qw; - + private LatticeOrientation3D(Grad3[] gradients, double qx, double qy, double qz, double qw) { this.gradients = gradients; - this.qx = qx; this.qy = qy; this.qz = qz; this.qw = qw; + this.qx = qx; + this.qy = qy; + this.qz = qz; + this.qw = qw; } } - + /* * Gradients */ - + public static class Grad2 { double dx, dy; + public Grad2(double dx, double dy) { - this.dx = dx; this.dy = dy; + this.dx = dx; + this.dy = dy; } } - + public static class Grad3 { double dx, dy, dz; + public Grad3(double dx, double dy, double dz) { - this.dx = dx; this.dy = dy; this.dz = dz; + this.dx = dx; + this.dy = dy; + this.dz = dz; } } - + public static final double N2 = 0.05481866495625118; public static final double N3 = 0.2781926117527186; private static final Grad2[] GRADIENTS_2D, GRADIENTS_2D_X_BEFORE_Y; private static final Grad3[] GRADIENTS_3D, GRADIENTS_3D_CLASSIC, GRADIENTS_3D_XY_BEFORE_Z, GRADIENTS_3D_XZ_BEFORE_Y; static { - + GRADIENTS_2D = new Grad2[PSIZE]; GRADIENTS_2D_X_BEFORE_Y = new Grad2[PSIZE]; - Grad2[] grad2 = { - new Grad2( 0.130526192220052, 0.99144486137381), - new Grad2( 0.38268343236509, 0.923879532511287), - new Grad2( 0.608761429008721, 0.793353340291235), - new Grad2( 0.793353340291235, 0.608761429008721), - new Grad2( 0.923879532511287, 0.38268343236509), - new Grad2( 0.99144486137381, 0.130526192220051), - new Grad2( 0.99144486137381, -0.130526192220051), - new Grad2( 0.923879532511287, -0.38268343236509), - new Grad2( 0.793353340291235, -0.60876142900872), - new Grad2( 0.608761429008721, -0.793353340291235), - new Grad2( 0.38268343236509, -0.923879532511287), - new Grad2( 0.130526192220052, -0.99144486137381), - new Grad2(-0.130526192220052, -0.99144486137381), - new Grad2(-0.38268343236509, -0.923879532511287), - new Grad2(-0.608761429008721, -0.793353340291235), - new Grad2(-0.793353340291235, -0.608761429008721), - new Grad2(-0.923879532511287, -0.38268343236509), - new Grad2(-0.99144486137381, -0.130526192220052), - new Grad2(-0.99144486137381, 0.130526192220051), - new Grad2(-0.923879532511287, 0.38268343236509), - new Grad2(-0.793353340291235, 0.608761429008721), - new Grad2(-0.608761429008721, 0.793353340291235), - new Grad2(-0.38268343236509, 0.923879532511287), - new Grad2(-0.130526192220052, 0.99144486137381) - }; + Grad2[] grad2 = { new Grad2(0.130526192220052, 0.99144486137381), + new Grad2(0.38268343236509, 0.923879532511287), new Grad2(0.608761429008721, 0.793353340291235), + new Grad2(0.793353340291235, 0.608761429008721), new Grad2(0.923879532511287, 0.38268343236509), + new Grad2(0.99144486137381, 0.130526192220051), new Grad2(0.99144486137381, -0.130526192220051), + new Grad2(0.923879532511287, -0.38268343236509), new Grad2(0.793353340291235, -0.60876142900872), + new Grad2(0.608761429008721, -0.793353340291235), new Grad2(0.38268343236509, -0.923879532511287), + new Grad2(0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381), + new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235), + new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509), + new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051), + new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721), + new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287), + new Grad2(-0.130526192220052, 0.99144486137381) }; Grad2[] grad2XBeforeY = new Grad2[grad2.length]; for (int i = 0; i < grad2.length; i++) { - grad2[i].dx /= N2; grad2[i].dy /= N2; - + grad2[i].dx /= N2; + grad2[i].dy /= N2; + // Unrotated gradients for XBeforeY 2D double xx = grad2[i].dx * 0.7071067811865476; double yy = grad2[i].dy * 0.7071067811865476; @@ -900,82 +1005,64 @@ public class OpenSimplex2S { GRADIENTS_2D[i] = grad2[i % grad2.length]; GRADIENTS_2D_X_BEFORE_Y[i] = grad2XBeforeY[i % grad2XBeforeY.length]; } - + GRADIENTS_3D = new Grad3[PSIZE]; GRADIENTS_3D_CLASSIC = new Grad3[PSIZE]; GRADIENTS_3D_XY_BEFORE_Z = new Grad3[PSIZE]; GRADIENTS_3D_XZ_BEFORE_Y = new Grad3[PSIZE]; - Grad3[] grad3 = { - new Grad3(-2.22474487139, -2.22474487139, -1.0), - new Grad3(-2.22474487139, -2.22474487139, 1.0), - new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0), - new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0), - new Grad3(-2.22474487139, -1.0, -2.22474487139), - new Grad3(-2.22474487139, 1.0, -2.22474487139), - new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017), - new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978), - new Grad3(-2.22474487139, -1.0, 2.22474487139), - new Grad3(-2.22474487139, 1.0, 2.22474487139), - new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978), - new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), - new Grad3(-2.22474487139, 2.22474487139, -1.0), - new Grad3(-2.22474487139, 2.22474487139, 1.0), - new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0), - new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0), - new Grad3(-1.0, -2.22474487139, -2.22474487139), - new Grad3( 1.0, -2.22474487139, -2.22474487139), - new Grad3( 0.0, -3.0862664687972017, -1.1721513422464978), - new Grad3( 0.0, -1.1721513422464978, -3.0862664687972017), - new Grad3(-1.0, -2.22474487139, 2.22474487139), - new Grad3( 1.0, -2.22474487139, 2.22474487139), - new Grad3( 0.0, -1.1721513422464978, 3.0862664687972017), - new Grad3( 0.0, -3.0862664687972017, 1.1721513422464978), - new Grad3(-1.0, 2.22474487139, -2.22474487139), - new Grad3( 1.0, 2.22474487139, -2.22474487139), - new Grad3( 0.0, 1.1721513422464978, -3.0862664687972017), - new Grad3( 0.0, 3.0862664687972017, -1.1721513422464978), - new Grad3(-1.0, 2.22474487139, 2.22474487139), - new Grad3( 1.0, 2.22474487139, 2.22474487139), - new Grad3( 0.0, 3.0862664687972017, 1.1721513422464978), - new Grad3( 0.0, 1.1721513422464978, 3.0862664687972017), - new Grad3( 2.22474487139, -2.22474487139, -1.0), - new Grad3( 2.22474487139, -2.22474487139, 1.0), - new Grad3( 1.1721513422464978, -3.0862664687972017, 0.0), - new Grad3( 3.0862664687972017, -1.1721513422464978, 0.0), - new Grad3( 2.22474487139, -1.0, -2.22474487139), - new Grad3( 2.22474487139, 1.0, -2.22474487139), - new Grad3( 3.0862664687972017, 0.0, -1.1721513422464978), - new Grad3( 1.1721513422464978, 0.0, -3.0862664687972017), - new Grad3( 2.22474487139, -1.0, 2.22474487139), - new Grad3( 2.22474487139, 1.0, 2.22474487139), - new Grad3( 1.1721513422464978, 0.0, 3.0862664687972017), - new Grad3( 3.0862664687972017, 0.0, 1.1721513422464978), - new Grad3( 2.22474487139, 2.22474487139, -1.0), - new Grad3( 2.22474487139, 2.22474487139, 1.0), - new Grad3( 3.0862664687972017, 1.1721513422464978, 0.0), - new Grad3( 1.1721513422464978, 3.0862664687972017, 0.0) - }; + Grad3[] grad3 = { new Grad3(-2.22474487139, -2.22474487139, -1.0), + new Grad3(-2.22474487139, -2.22474487139, 1.0), + new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0), + new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0), + new Grad3(-2.22474487139, -1.0, -2.22474487139), new Grad3(-2.22474487139, 1.0, -2.22474487139), + new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017), + new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978), + new Grad3(-2.22474487139, -1.0, 2.22474487139), new Grad3(-2.22474487139, 1.0, 2.22474487139), + new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978), + new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), new Grad3(-2.22474487139, 2.22474487139, -1.0), + new Grad3(-2.22474487139, 2.22474487139, 1.0), new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0), + new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0), + new Grad3(-1.0, -2.22474487139, -2.22474487139), new Grad3(1.0, -2.22474487139, -2.22474487139), + new Grad3(0.0, -3.0862664687972017, -1.1721513422464978), + new Grad3(0.0, -1.1721513422464978, -3.0862664687972017), + new Grad3(-1.0, -2.22474487139, 2.22474487139), new Grad3(1.0, -2.22474487139, 2.22474487139), + new Grad3(0.0, -1.1721513422464978, 3.0862664687972017), + new Grad3(0.0, -3.0862664687972017, 1.1721513422464978), new Grad3(-1.0, 2.22474487139, -2.22474487139), + new Grad3(1.0, 2.22474487139, -2.22474487139), new Grad3(0.0, 1.1721513422464978, -3.0862664687972017), + new Grad3(0.0, 3.0862664687972017, -1.1721513422464978), new Grad3(-1.0, 2.22474487139, 2.22474487139), + new Grad3(1.0, 2.22474487139, 2.22474487139), new Grad3(0.0, 3.0862664687972017, 1.1721513422464978), + new Grad3(0.0, 1.1721513422464978, 3.0862664687972017), new Grad3(2.22474487139, -2.22474487139, -1.0), + new Grad3(2.22474487139, -2.22474487139, 1.0), new Grad3(1.1721513422464978, -3.0862664687972017, 0.0), + new Grad3(3.0862664687972017, -1.1721513422464978, 0.0), new Grad3(2.22474487139, -1.0, -2.22474487139), + new Grad3(2.22474487139, 1.0, -2.22474487139), new Grad3(3.0862664687972017, 0.0, -1.1721513422464978), + new Grad3(1.1721513422464978, 0.0, -3.0862664687972017), new Grad3(2.22474487139, -1.0, 2.22474487139), + new Grad3(2.22474487139, 1.0, 2.22474487139), new Grad3(1.1721513422464978, 0.0, 3.0862664687972017), + new Grad3(3.0862664687972017, 0.0, 1.1721513422464978), new Grad3(2.22474487139, 2.22474487139, -1.0), + new Grad3(2.22474487139, 2.22474487139, 1.0), new Grad3(3.0862664687972017, 1.1721513422464978, 0.0), + new Grad3(1.1721513422464978, 3.0862664687972017, 0.0) }; Grad3[] grad3Classic = new Grad3[grad3.length]; Grad3[] grad3XYBeforeZ = new Grad3[grad3.length]; Grad3[] grad3XZBeforeY = new Grad3[grad3.length]; for (int i = 0; i < grad3.length; i++) { - grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3; - double gxr = grad3[i].dx, gyr = grad3[i].dy, gzr = grad3[i].dz; + grad3[i].dx /= N3; + grad3[i].dy /= N3; + grad3[i].dz /= N3; + double gxr = grad3[i].dx, gyr = grad3[i].dy, gzr = grad3[i].dz; // Unrotated gradients for classic 3D double grr = (2.0 / 3.0) * (gxr + gyr + gzr); -// double dx = grr - gxr, dy = grr - gyr, dz = grr - gzr; - grad3Classic[i] = new Grad3( grr - gxr, grr - gyr, grr - gzr ); - + // double dx = grr - gxr, dy = grr - gyr, dz = grr - gzr; + grad3Classic[i] = new Grad3(grr - gxr, grr - gyr, grr - gzr); + // Unrotated gradients for XYBeforeZ 3D double s2 = (gxr + gyr) * -0.211324865405187; double zz = gzr * 0.577350269189626; - grad3XYBeforeZ[i] = new Grad3( gxr + s2 + zz, gyr + s2 + zz, (gzr - gxr - gyr) * 0.577350269189626 ); - + grad3XYBeforeZ[i] = new Grad3(gxr + s2 + zz, gyr + s2 + zz, (gzr - gxr - gyr) * 0.577350269189626); + // Unrotated gradients for plane-first 3D s2 = (gxr + gzr) * -0.211324865405187; double yy = gyr * 0.577350269189626; - grad3XZBeforeY[i] = new Grad3( gxr + s2 + yy, (gyr - gxr - gzr) * 0.577350269189626, gzr + s2 + yy ); + grad3XZBeforeY[i] = new Grad3(gxr + s2 + yy, (gyr - gxr - gzr) * 0.577350269189626, gzr + s2 + yy); } for (int i = 0; i < PSIZE; i++) { GRADIENTS_3D[i] = grad3[i % grad3.length]; diff --git a/src/main/java/ru/windcorp/jputil/ArrayUtil.java b/src/main/java/ru/windcorp/jputil/ArrayUtil.java index 4c57314..7ae5dcc 100644 --- a/src/main/java/ru/windcorp/jputil/ArrayUtil.java +++ b/src/main/java/ru/windcorp/jputil/ArrayUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil; import java.lang.reflect.Array; @@ -611,8 +611,7 @@ public class ArrayUtil { int end = offset + length; if (end > arrayLength || offset < 0) throw new IllegalArgumentException( - "Array contains [0; " + arrayLength + "), requested [" + offset + "; " + end + ")" - ); + "Array contains [0; " + arrayLength + "), requested [" + offset + "; " + end + ")"); return length; } @@ -628,8 +627,7 @@ public class ArrayUtil { if (end > arrayLength || start < 0) throw new IllegalArgumentException( - "Array contains [0; " + arrayLength + "), requested [" + start + "; " + end + ")" - ); + "Array contains [0; " + arrayLength + "), requested [" + start + "; " + end + ")"); return end; } diff --git a/src/main/java/ru/windcorp/jputil/CSVWriter.java b/src/main/java/ru/windcorp/jputil/CSVWriter.java index 57ddec0..b74d88c 100644 --- a/src/main/java/ru/windcorp/jputil/CSVWriter.java +++ b/src/main/java/ru/windcorp/jputil/CSVWriter.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil; import java.io.OutputStream; diff --git a/src/main/java/ru/windcorp/jputil/PrimitiveUtil.java b/src/main/java/ru/windcorp/jputil/PrimitiveUtil.java index 7579413..28c6435 100644 --- a/src/main/java/ru/windcorp/jputil/PrimitiveUtil.java +++ b/src/main/java/ru/windcorp/jputil/PrimitiveUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil; import java.util.HashMap; @@ -30,18 +30,8 @@ public class PrimitiveUtil { private static final Map, Object> PRIMITIVE_TO_NULL = new HashMap<>(); static { - for ( - Class boxed : new Class[] { - Boolean.class, - Byte.class, - Short.class, - Character.class, - Integer.class, - Long.class, - Float.class, - Double.class - } - ) { + for (Class boxed : new Class[] { Boolean.class, Byte.class, Short.class, Character.class, Integer.class, + Long.class, Float.class, Double.class }) { try { PRIMITIVE_TO_BOXED.put((Class) boxed.getField("TYPE").get(null), boxed); } catch (Exception e) { diff --git a/src/main/java/ru/windcorp/jputil/SyncStreams.java b/src/main/java/ru/windcorp/jputil/SyncStreams.java index 9b2bc3a..80ed01b 100644 --- a/src/main/java/ru/windcorp/jputil/SyncStreams.java +++ b/src/main/java/ru/windcorp/jputil/SyncStreams.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil; import java.util.function.*; @@ -40,8 +40,7 @@ import java.util.stream.Stream; /** * Contains static methods to create {@link Stream Streams} that synchronize - * their - * * terminal operations on a given monitor. * @@ -50,7 +49,7 @@ import java.util.stream.Stream; */ // SonarLint: "Stream.peek" should be used with caution (java:S3864) -// We are implementing Stream, so peek() is required. +// We are implementing Stream, so peek() is required. @SuppressWarnings("squid:S3864") public class SyncStreams { @@ -1070,21 +1069,18 @@ public class SyncStreams { } /** - * Wraps the given {@link Stream} to make all - * * terminal operations acquire the provided monitor's lock before - * execution. Intermediate operations - * return streams that are also synchronized on the same object. The created - * stream will behave identically - * to the provided stream in all other aspects. Use this to synchronize - * access to stream's source. + * execution. Intermediate operations return streams that are also + * synchronized on the same object. The created stream will behave + * identically to the provided stream in all other aspects. Use this to + * synchronize access to stream's source. *

    * The returned {@code Stream}'s {@link Stream#iterator() iterator()} and - * {@link Stream#spliterator() - * spliterator()} methods return regular non-synchronized iterators and - * spliterators respectively. It - * is the user's responsibility to avoid concurrency issues: + * {@link Stream#spliterator() spliterator()} methods return regular + * non-synchronized iterators and spliterators respectively. It is the + * user's responsibility to avoid concurrency issues: * *

     	 * synchronized (stream.getMonitor()) {
    @@ -1103,14 +1099,17 @@ public class SyncStreams {
     	 * stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
     	 * 
    * - * @param the class of objects in the Stream - * @param stream the stream to wrap. - * @param monitor the object that the stream will use for synchronization. - * When {@code null}, the stream - * will synchronize on itself. + * @param + * the class of objects in the Stream + * @param stream + * the stream to wrap. + * @param monitor + * the object that the stream will use for synchronization. When + * {@code null}, the stream will synchronize on itself. * @return a {@link SyncStream SyncStream<T>} synchronized on * {@code monitor} and backed by {@code stream}. - * @throws NullPointerException if {@code stream == null}. + * @throws NullPointerException + * if {@code stream == null}. */ public static SyncStream synchronizedStream(Stream stream, Object monitor) { Objects.requireNonNull(stream, "stream cannot be null"); @@ -1118,22 +1117,19 @@ public class SyncStreams { } /** - * Wraps the given {@link IntStream} to make all - * * terminal operations acquire the provided monitor's lock before - * execution. Intermediate operations - * return streams that are also synchronized on the same object. The created - * stream will behave identically - * to the provided stream in all other aspects. Use this to synchronize - * access to stream's source. + * execution. Intermediate operations return streams that are also + * synchronized on the same object. The created stream will behave + * identically to the provided stream in all other aspects. Use this to + * synchronize access to stream's source. *

    * The returned {@code IntStream}'s {@link IntStream#iterator() - * iterator()} and - * {@link IntStream#spliterator() spliterator()} methods return regular - * non-synchronized iterators and - * spliterators respectively. It is the user's responsibility to avoid - * concurrency issues: + * iterator()} and {@link IntStream#spliterator() spliterator()} methods + * return regular non-synchronized iterators and spliterators + * respectively. It is the user's responsibility to avoid concurrency + * issues: * *

     	 * synchronized (stream.getMonitor()) {
    @@ -1152,13 +1148,15 @@ public class SyncStreams {
     	 * stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
     	 * 
    * - * @param stream the stream to wrap. - * @param monitor the object that the stream will use for synchronization. - * When {@code null}, the stream - * will synchronize on itself. + * @param stream + * the stream to wrap. + * @param monitor + * the object that the stream will use for synchronization. When + * {@code null}, the stream will synchronize on itself. * @return a {@link SyncIntStream} synchronized on {@code monitor} and * backed by {@code stream}. - * @throws NullPointerException if {@code stream == null}. + * @throws NullPointerException + * if {@code stream == null}. */ public static SyncIntStream synchronizedStream(IntStream stream, Object monitor) { Objects.requireNonNull(stream, "stream cannot be null"); @@ -1166,22 +1164,19 @@ public class SyncStreams { } /** - * Wraps the given {@link LongStream} to make all - * * terminal operations acquire the provided monitor's lock before - * execution. Intermediate operations - * return streams that are also synchronized on the same object. The created - * stream will behave identically - * to the provided stream in all other aspects. Use this to synchronize - * access to stream's source. + * execution. Intermediate operations return streams that are also + * synchronized on the same object. The created stream will behave + * identically to the provided stream in all other aspects. Use this to + * synchronize access to stream's source. *

    * The returned {@code LongStream}'s {@link LongStream#iterator() - * iterator()} and - * {@link LongStream#spliterator() spliterator()} methods return regular - * non-synchronized iterators and - * spliterators respectively. It is the user's responsibility to avoid - * concurrency issues: + * iterator()} and {@link LongStream#spliterator() spliterator()} methods + * return regular non-synchronized iterators and spliterators + * respectively. It is the user's responsibility to avoid concurrency + * issues: * *

     	 * synchronized (stream.getMonitor()) {
    @@ -1200,13 +1195,15 @@ public class SyncStreams {
     	 * stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
     	 * 
    * - * @param stream the stream to wrap. - * @param monitor the object that the stream will use for synchronization. - * When {@code null}, the stream - * will synchronize on itself. + * @param stream + * the stream to wrap. + * @param monitor + * the object that the stream will use for synchronization. When + * {@code null}, the stream will synchronize on itself. * @return a {@link SyncLongStream} synchronized on {@code monitor} and * backed by {@code stream}. - * @throws NullPointerException if {@code stream == null}. + * @throws NullPointerException + * if {@code stream == null}. */ public static SyncLongStream synchronizedStream(LongStream stream, Object monitor) { Objects.requireNonNull(stream, "stream cannot be null"); @@ -1214,22 +1211,19 @@ public class SyncStreams { } /** - * Wraps the given {@link DoubleStream} to make all - * * terminal operations acquire the provided monitor's lock before - * execution. Intermediate operations - * return streams that are also synchronized on the same object. The created - * stream will behave identically - * to the provided stream in all other aspects. Use this to synchronize - * access to stream's source. + * execution. Intermediate operations return streams that are also + * synchronized on the same object. The created stream will behave + * identically to the provided stream in all other aspects. Use this to + * synchronize access to stream's source. *

    * The returned {@code DoubleStream}'s {@link DoubleStream#iterator() - * iterator()} and - * {@link DoubleStream#spliterator() spliterator()} methods return regular - * non-synchronized iterators and - * spliterators respectively. It is the user's responsibility to avoid - * concurrency issues: + * iterator()} and {@link DoubleStream#spliterator() spliterator()} methods + * return regular non-synchronized iterators and spliterators + * respectively. It is the user's responsibility to avoid concurrency + * issues: * *

     	 * synchronized (stream.getMonitor()) {
    @@ -1248,13 +1242,15 @@ public class SyncStreams {
     	 * stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
     	 * 
    * - * @param stream the stream to wrap. - * @param monitor the object that the stream will use for synchronization. - * When {@code null}, the stream - * will synchronize on itself. + * @param stream + * the stream to wrap. + * @param monitor + * the object that the stream will use for synchronization. When + * {@code null}, the stream will synchronize on itself. * @return a {@link SyncDoubleStream} synchronized on {@code monitor} and * backed by {@code stream}. - * @throws NullPointerException if {@code stream == null}. + * @throws NullPointerException + * if {@code stream == null}. */ public static SyncDoubleStream synchronizedStream(DoubleStream stream, Object monitor) { Objects.requireNonNull(stream, "stream cannot be null"); diff --git a/src/main/java/ru/windcorp/jputil/SyntaxException.java b/src/main/java/ru/windcorp/jputil/SyntaxException.java index 02cc3c4..8fdb710 100644 --- a/src/main/java/ru/windcorp/jputil/SyntaxException.java +++ b/src/main/java/ru/windcorp/jputil/SyntaxException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil; public class SyntaxException extends Exception { diff --git a/src/main/java/ru/windcorp/jputil/chars/CharArrayIterator.java b/src/main/java/ru/windcorp/jputil/chars/CharArrayIterator.java index be0940d..659b567 100644 --- a/src/main/java/ru/windcorp/jputil/chars/CharArrayIterator.java +++ b/src/main/java/ru/windcorp/jputil/chars/CharArrayIterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.text.CharacterIterator; @@ -108,7 +108,7 @@ public class CharArrayIterator implements CharacterIterator { return pos; } -// @SuppressWarnings("all") Just STFU, this _is_ terrific + // @SuppressWarnings("all") Just STFU, this _is_ terrific // SonarLint: "clone" should not be overridden (java:S2975) // And I wouldn't have done that if only CharacterIterator had not required diff --git a/src/main/java/ru/windcorp/jputil/chars/CharConsumer.java b/src/main/java/ru/windcorp/jputil/chars/CharConsumer.java index 7b68bb1..55448b0 100644 --- a/src/main/java/ru/windcorp/jputil/chars/CharConsumer.java +++ b/src/main/java/ru/windcorp/jputil/chars/CharConsumer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.util.function.IntConsumer; diff --git a/src/main/java/ru/windcorp/jputil/chars/CharConsumers.java b/src/main/java/ru/windcorp/jputil/chars/CharConsumers.java index 1ac7973..12a518d 100644 --- a/src/main/java/ru/windcorp/jputil/chars/CharConsumers.java +++ b/src/main/java/ru/windcorp/jputil/chars/CharConsumers.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.util.Objects; diff --git a/src/main/java/ru/windcorp/jputil/chars/CharPredicate.java b/src/main/java/ru/windcorp/jputil/chars/CharPredicate.java index 03ded02..c02beed 100644 --- a/src/main/java/ru/windcorp/jputil/chars/CharPredicate.java +++ b/src/main/java/ru/windcorp/jputil/chars/CharPredicate.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.util.Arrays; diff --git a/src/main/java/ru/windcorp/jputil/chars/CharSupplier.java b/src/main/java/ru/windcorp/jputil/chars/CharSupplier.java index 0743d79..2a9749b 100644 --- a/src/main/java/ru/windcorp/jputil/chars/CharSupplier.java +++ b/src/main/java/ru/windcorp/jputil/chars/CharSupplier.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.util.function.IntSupplier; diff --git a/src/main/java/ru/windcorp/jputil/chars/EscapeException.java b/src/main/java/ru/windcorp/jputil/chars/EscapeException.java index 935f72f..544c50f 100644 --- a/src/main/java/ru/windcorp/jputil/chars/EscapeException.java +++ b/src/main/java/ru/windcorp/jputil/chars/EscapeException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; public class EscapeException extends Exception { diff --git a/src/main/java/ru/windcorp/jputil/chars/Escaper.java b/src/main/java/ru/windcorp/jputil/chars/Escaper.java index f19f6c7..a07dc08 100644 --- a/src/main/java/ru/windcorp/jputil/chars/Escaper.java +++ b/src/main/java/ru/windcorp/jputil/chars/Escaper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.text.CharacterIterator; @@ -103,14 +103,8 @@ public class Escaper { } - public static final Escaper JAVA = new Escaper( - '\\', - 'u', - "tbnrf'\"".toCharArray(), - "\t\b\n\r\f\'\"".toCharArray(), - true, - true - ); + public static final Escaper JAVA = new Escaper('\\', 'u', "tbnrf'\"".toCharArray(), "\t\b\n\r\f\'\"".toCharArray(), + true, true); private final char escapeChar; private final char unicodeEscapeChar; @@ -120,14 +114,8 @@ public class Escaper { private final boolean preferUnicode; private final boolean strict; - protected Escaper( - char escapeChar, - char unicodeEscapeChar, - char[] safes, - char[] unsafes, - boolean preferUnicode, - boolean strict - ) { + protected Escaper(char escapeChar, char unicodeEscapeChar, char[] safes, char[] unsafes, boolean preferUnicode, + boolean strict) { this.escapeChar = escapeChar; this.unicodeEscapeChar = unicodeEscapeChar; this.safes = safes; @@ -152,8 +140,7 @@ public class Escaper { for (char c : unsafes) { if (c == escapeChar) throw new IllegalArgumentException( - "Unsafe characters contain escape chatacter (escape character is escaped automatically)" - ); + "Unsafe characters contain escape chatacter (escape character is escaped automatically)"); if (c == unicodeEscapeChar) throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter"); } @@ -173,11 +160,7 @@ public class Escaper { end = Integer.MAX_VALUE; else end = src.getPosition() + length; - while ( - src.has() && - src.getPosition() < end && - (until == null || !until.test(src.current())) - ) + while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) escape(src.consume(), output); } @@ -225,11 +208,7 @@ public class Escaper { int result = 0; - while ( - src.has() && - src.getPosition() < end && - (until == null || !until.test(src.current())) - ) { + while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) { result += getEscapedLength(src.consume()); } @@ -257,11 +236,7 @@ public class Escaper { end = Integer.MAX_VALUE; else end = src.getPosition() + length; - while ( - src.has() && - src.getPosition() < end && - (until == null || !until.test(src.current())) - ) { + while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) { output.accept(unescapeOneSequence(src)); } } @@ -282,10 +257,8 @@ public class Escaper { if (src.current() == unicodeEscapeChar) { src.next(); - return (char) (hexValue(src.consume()) << (4 * 3) | - hexValue(src.consume()) << (4 * 2) | - hexValue(src.consume()) << (4 * 1) | - hexValue(src.consume()) << (4 * 0)); + return (char) (hexValue(src.consume()) << (4 * 3) | hexValue(src.consume()) << (4 * 2) + | hexValue(src.consume()) << (4 * 1) | hexValue(src.consume()) << (4 * 0)); } int index = ArrayUtil.firstIndexOf(safes, src.current()); @@ -315,11 +288,7 @@ public class Escaper { int result = 0; - while ( - src.has() && - src.getPosition() < end && - (until == null || !until.test(src.current())) - ) { + while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) { skipOneSequence(src); result++; } @@ -328,11 +297,7 @@ public class Escaper { } public void skipOneSequence(CharReader src) { - if ( - src.current() == escapeChar - && - src.next() == unicodeEscapeChar - ) { + if (src.current() == escapeChar && src.next() == unicodeEscapeChar) { src.advance(4); } src.next(); diff --git a/src/main/java/ru/windcorp/jputil/chars/FancyCharacterIterator.java b/src/main/java/ru/windcorp/jputil/chars/FancyCharacterIterator.java index 183b672..da4e81e 100644 --- a/src/main/java/ru/windcorp/jputil/chars/FancyCharacterIterator.java +++ b/src/main/java/ru/windcorp/jputil/chars/FancyCharacterIterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.text.CharacterIterator; @@ -86,7 +86,7 @@ public class FancyCharacterIterator implements CharacterIterator { return sb.toString(); } -// @SuppressWarnings("all") Just STFU, this _is_ terrific + // @SuppressWarnings("all") Just STFU, this _is_ terrific // SonarLint: "clone" should not be overridden (java:S2975) // And I wouldn't have done that if only CharacterIterator had not required diff --git a/src/main/java/ru/windcorp/jputil/chars/IndentedStringBuilder.java b/src/main/java/ru/windcorp/jputil/chars/IndentedStringBuilder.java index 92ba836..21afc6f 100644 --- a/src/main/java/ru/windcorp/jputil/chars/IndentedStringBuilder.java +++ b/src/main/java/ru/windcorp/jputil/chars/IndentedStringBuilder.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; public class IndentedStringBuilder { diff --git a/src/main/java/ru/windcorp/jputil/chars/StringUtil.java b/src/main/java/ru/windcorp/jputil/chars/StringUtil.java index f08018a..eb66975 100644 --- a/src/main/java/ru/windcorp/jputil/chars/StringUtil.java +++ b/src/main/java/ru/windcorp/jputil/chars/StringUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.io.IOException; @@ -41,13 +41,8 @@ public class StringUtil { private static final String EMPTY_PLACEHOLDER = "[empty]"; private static final String DEFAULT_SEPARATOR = "; "; - public static String arrayToString( - T[] array, - String separator, - String empty, - String nullPlaceholder, - String nullArray - ) { + public static String arrayToString(T[] array, String separator, String empty, String nullPlaceholder, + String nullArray) { if (separator == null) { throw new IllegalArgumentException(new NullPointerException()); @@ -79,13 +74,8 @@ public class StringUtil { return arrayToString(array, DEFAULT_SEPARATOR); } - public static String iteratorToString( - Iterator iterator, - String separator, - String empty, - String nullPlaceholder, - String nullIterator - ) { + public static String iteratorToString(Iterator iterator, String separator, String empty, String nullPlaceholder, + String nullIterator) { if (separator == null) { throw new IllegalArgumentException(new NullPointerException()); @@ -119,13 +109,8 @@ public class StringUtil { return iteratorToString(iterator, DEFAULT_SEPARATOR); } - public static String iterableToString( - Iterable iterable, - String separator, - String empty, - String nullPlaceholder, - String nullIterable - ) { + public static String iterableToString(Iterable iterable, String separator, String empty, String nullPlaceholder, + String nullIterable) { if (separator == null) { throw new IllegalArgumentException(new NullPointerException()); @@ -146,14 +131,8 @@ public class StringUtil { return iterableToString(iterable, DEFAULT_SEPARATOR); } - public static String supplierToString( - IntFunction supplier, - int length, - String separator, - String empty, - String nullPlaceholder, - String nullSupplier - ) { + public static String supplierToString(IntFunction supplier, int length, String separator, String empty, + String nullPlaceholder, String nullSupplier) { if (separator == null) throw new IllegalArgumentException(new NullPointerException()); @@ -163,28 +142,15 @@ public class StringUtil { return empty; if (length > 0) { - return supplierToStringExactly( - supplier, - length, - separator, - nullPlaceholder - ); + return supplierToStringExactly(supplier, length, separator, nullPlaceholder); } else { - return supplierToStringUntilNull( - supplier, - separator, - empty - ); + return supplierToStringUntilNull(supplier, separator, empty); } } - private static String supplierToStringExactly( - IntFunction supplier, - int length, - String separator, - String nullPlaceholder - ) { + private static String supplierToStringExactly(IntFunction supplier, int length, String separator, + String nullPlaceholder) { T element = supplier.apply(0); StringBuilder sb = new StringBuilder(element == null ? nullPlaceholder : element.toString()); @@ -198,11 +164,7 @@ public class StringUtil { return sb.toString(); } - private static String supplierToStringUntilNull( - IntFunction supplier, - String separator, - String empty - ) { + private static String supplierToStringUntilNull(IntFunction supplier, String separator, String empty) { T element = supplier.apply(0); if (element == null) { @@ -366,11 +328,7 @@ public class StringUtil { StringBuilder sb = new StringBuilder(); charLoop: for (char c : src.toCharArray()) { - if ( - (resultIndex + 1) < arrayLength - && - test.test(c) - ) { + if ((resultIndex + 1) < arrayLength && test.test(c)) { result[resultIndex] = resetStringBuilder(sb); ++resultIndex; continue charLoop; @@ -389,17 +347,17 @@ public class StringUtil { * index. *

    * Indices {@code 0} and {@code src.length() - 1} produce {@code str} - * excluding - * the specified character and {@code ""}. + * excluding the specified character and {@code ""}. *

    * - * @param src the String to split - * @param at index to split at - * @throws IllegalArgumentException if the index is out of bounds for - * {@code src} + * @param src + * the String to split + * @param at + * index to split at + * @throws IllegalArgumentException + * if the index is out of bounds for {@code src} * @return an array containing the substrings, in order of encounter in - * {@code src}. - * Its length is always 2. + * {@code src}. Its length is always 2. */ public static String[] splitAt(String src, int at) { Objects.requireNonNull(src, "src"); @@ -416,10 +374,7 @@ public class StringUtil { return new String[] { src.substring(0, src.length() - 1), "" }; } - return new String[] { - src.substring(0, at), - src.substring(at + 1) - }; + return new String[] { src.substring(0, at), src.substring(at + 1) }; } /** @@ -427,8 +382,7 @@ public class StringUtil { * indices. *

    * Indices {@code 0} and {@code src.length() - 1} produce extra zero-length - * outputs. - * Duplicate indices produce extra zero-length outputs. + * outputs. Duplicate indices produce extra zero-length outputs. *

    * Examples: * @@ -439,13 +393,14 @@ public class StringUtil { * splitAt("a.b", 1, 1, 1) -> {"a", "", "", "b"} * * - * @param src the String to split - * @param at indices to split at, in any order - * @throws IllegalArgumentException if some index is out of bounds for - * {@code src} + * @param src + * the String to split + * @param at + * indices to split at, in any order + * @throws IllegalArgumentException + * if some index is out of bounds for {@code src} * @return an array containing the substrings, in order of encounter in - * {@code src}. - * Its length is always {@code at.length + 1}. + * {@code src}. Its length is always {@code at.length + 1}. */ public static String[] splitAt(String src, int... at) { Objects.requireNonNull(src, "src"); @@ -553,10 +508,8 @@ public class StringUtil { } if (endPos < beginPos) { - throw new IllegalArgumentException( - "endPos must be greater than or equal to beginPos (endPos=" - + endPos + ", beginPos=" + beginPos + ")" - ); + throw new IllegalArgumentException("endPos must be greater than or equal to beginPos (endPos=" + endPos + + ", beginPos=" + beginPos + ")"); } if (endPos >= Math.min(a.length, b.length)) { @@ -592,8 +545,7 @@ public class StringUtil { /** * Finds and returns the index of the specified appearance of the specified - * character - * in the given array. The search starts at index 0. + * character in the given array. The search starts at index 0. *

    * Examples: *

    @@ -630,10 +582,12 @@ public class StringUtil { * * * - * @param src - the array to search in. - * @param target - the character to search for. - * @param skip - the amount of target characters to be - * skipped. + * @param src + * - the array to search in. + * @param target + * - the character to search for. + * @param skip + * - the amount of target characters to be skipped. * @return The index of the skip+1th target * character or -1, if none found. * @see StringUtil#indexFromEnd(char[], char, int) @@ -653,8 +607,7 @@ public class StringUtil { /** * Finds and returns the index of the specified appearance of the specified - * character - * in the given array. The search starts at index + * character in the given array. The search starts at index * src.length - 1. *

    * Examples: @@ -692,13 +645,15 @@ public class StringUtil { * * * - * @param src - the array to search in. - * @param target - the character to search for. - * @param skip - the amount of target characters to be - * skipped. + * @param src + * - the array to search in. + * @param target + * - the character to search for. + * @param skip + * - the amount of target characters to be skipped. * @return The index of the skip+1th - * targetcharacter - * from the end of the array or -1, if none found. + * targetcharacter from the end of the array or -1, if + * none found. * @see StringUtil#indexFromBeginning(char[], char, int) */ public static int indexFromEnd(char[] src, char target, int skip) { @@ -873,12 +828,8 @@ public class StringUtil { return result; } - private static void buildCombinations( - StringBuilder sb, - Collection result, - Iterable[] parts, - int index - ) { + private static void buildCombinations(StringBuilder sb, Collection result, Iterable[] parts, + int index) { if (index >= parts.length) { result.add(sb.toString()); } else { @@ -904,13 +855,8 @@ public class StringUtil { return result; } - private static void buildCombinations( - StringBuilder sb, - String[] result, - int[] resultIndex, - String[][] parts, - int index - ) { + private static void buildCombinations(StringBuilder sb, String[] result, int[] resultIndex, String[][] parts, + int index) { if (index >= parts.length) { result[resultIndex[0]++] = sb.toString(); } else { @@ -985,10 +931,7 @@ public class StringUtil { } private static char hexDigit(long value, int digit) { - return hexDigit( - (int) (value >>> (4 * digit)) - & 0xF - ); + return hexDigit((int) (value >>> (4 * digit)) & 0xF); } public static char hexDigit(int value) { diff --git a/src/main/java/ru/windcorp/jputil/chars/UncheckedEscapeException.java b/src/main/java/ru/windcorp/jputil/chars/UncheckedEscapeException.java index 33717ee..66b7002 100644 --- a/src/main/java/ru/windcorp/jputil/chars/UncheckedEscapeException.java +++ b/src/main/java/ru/windcorp/jputil/chars/UncheckedEscapeException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; public class UncheckedEscapeException extends RuntimeException { diff --git a/src/main/java/ru/windcorp/jputil/chars/WordReader.java b/src/main/java/ru/windcorp/jputil/chars/WordReader.java index 22d6969..04dc5b6 100644 --- a/src/main/java/ru/windcorp/jputil/chars/WordReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/WordReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars; import java.io.IOException; diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/AbstractCharReader.java b/src/main/java/ru/windcorp/jputil/chars/reader/AbstractCharReader.java index d31e092..aacf905 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/AbstractCharReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/AbstractCharReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; /** @@ -27,10 +27,9 @@ public abstract class AbstractCharReader implements CharReader { /** * Current position of this CharReader. The reader maps its input to - * positions starting from 0. - * Positions that are negative or lower than 0 are invalid. - * {@link #current()} - * will throw an exception if position is invalid. + * positions starting from 0. Positions that are negative or lower than 0 + * are invalid. {@link #current()} will throw an exception if position is + * invalid. */ protected int position = 0; diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/ArrayCharReader.java b/src/main/java/ru/windcorp/jputil/chars/reader/ArrayCharReader.java index f12f590..09f5e6c 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/ArrayCharReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/ArrayCharReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; import java.util.Objects; diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/BufferedCharReader.java b/src/main/java/ru/windcorp/jputil/chars/reader/BufferedCharReader.java index 83ae6b2..36e6eef 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/BufferedCharReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/BufferedCharReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; /** @@ -51,9 +51,12 @@ public abstract class BufferedCharReader extends AbstractCharReader { /** * Acquires next characters and stores them in the array. * - * @param buffer the output array - * @param offset index of the first character - * @param length maximum amount of characters to be pulled + * @param buffer + * the output array + * @param offset + * index of the first character + * @param length + * maximum amount of characters to be pulled * @return the amount of characters actually pulled */ protected int pullChars(char[] buffer, int offset, int length) { diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/CharReader.java b/src/main/java/ru/windcorp/jputil/chars/reader/CharReader.java index 147daf3..01f21b9 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/CharReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/CharReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; import java.io.IOException; @@ -30,7 +30,7 @@ import ru.windcorp.jputil.chars.Escaper; */ // SonarLint: Constants should not be defined in interfaces (java:S1214) -// DONE is an essential part of the interface +// DONE is an essential part of the interface @SuppressWarnings("squid:S1214") public interface CharReader { @@ -179,8 +179,7 @@ public interface CharReader { /** * Skips to the end of the current line. Both "\n", - * "\r" - * and "\r\n" are considered line separators. + * "\r" and "\r\n" are considered line separators. * * @return the amount of characters in the skipped line */ diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/CharReaders.java b/src/main/java/ru/windcorp/jputil/chars/reader/CharReaders.java index a181dbf..d6978a0 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/CharReaders.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/CharReaders.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; import java.io.InputStream; diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/ReaderCharReader.java b/src/main/java/ru/windcorp/jputil/chars/reader/ReaderCharReader.java index 51a88db..fec35b2 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/ReaderCharReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/ReaderCharReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; import java.io.IOException; diff --git a/src/main/java/ru/windcorp/jputil/chars/reader/StringCharReader.java b/src/main/java/ru/windcorp/jputil/chars/reader/StringCharReader.java index 5836d15..b8be2f8 100644 --- a/src/main/java/ru/windcorp/jputil/chars/reader/StringCharReader.java +++ b/src/main/java/ru/windcorp/jputil/chars/reader/StringCharReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.chars.reader; import java.util.Objects; @@ -38,8 +38,7 @@ public class StringCharReader extends AbstractCharReader { int end = offset + length; if (end > str.length() || offset < 0) throw new IllegalArgumentException( - "String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")" - ); + "String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")"); this.offset = offset; this.length = length; diff --git a/src/main/java/ru/windcorp/jputil/functions/FloatSupplier.java b/src/main/java/ru/windcorp/jputil/functions/FloatSupplier.java index a157032..774e36b 100644 --- a/src/main/java/ru/windcorp/jputil/functions/FloatSupplier.java +++ b/src/main/java/ru/windcorp/jputil/functions/FloatSupplier.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.functions; @FunctionalInterface diff --git a/src/main/java/ru/windcorp/jputil/functions/ThrowingBiConsumer.java b/src/main/java/ru/windcorp/jputil/functions/ThrowingBiConsumer.java index be7cb8f..2ed41a3 100644 --- a/src/main/java/ru/windcorp/jputil/functions/ThrowingBiConsumer.java +++ b/src/main/java/ru/windcorp/jputil/functions/ThrowingBiConsumer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.functions; import java.util.function.BiConsumer; @@ -44,9 +44,16 @@ public interface ThrowingBiConsumer { } public static ThrowingBiConsumer concat( - ThrowingBiConsumer first, - ThrowingBiConsumer second - ) { + ThrowingBiConsumer first, + ThrowingBiConsumer second) { + return (t, u) -> { + first.accept(t, u); + second.accept(t, u); + }; + } + + public static ThrowingBiConsumer concat(BiConsumer first, + ThrowingBiConsumer second) { return (t, u) -> { first.accept(t, u); second.accept(t, u); @@ -54,19 +61,7 @@ public interface ThrowingBiConsumer { } public static ThrowingBiConsumer concat( - BiConsumer first, - ThrowingBiConsumer second - ) { - return (t, u) -> { - first.accept(t, u); - second.accept(t, u); - }; - } - - public static ThrowingBiConsumer concat( - ThrowingBiConsumer first, - BiConsumer second - ) { + ThrowingBiConsumer first, BiConsumer second) { return (t, u) -> { first.accept(t, u); second.accept(t, u); diff --git a/src/main/java/ru/windcorp/jputil/functions/ThrowingConsumer.java b/src/main/java/ru/windcorp/jputil/functions/ThrowingConsumer.java index 14449ca..e89bde5 100644 --- a/src/main/java/ru/windcorp/jputil/functions/ThrowingConsumer.java +++ b/src/main/java/ru/windcorp/jputil/functions/ThrowingConsumer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.functions; import java.util.function.BiConsumer; @@ -39,30 +39,24 @@ public interface ThrowingConsumer { }; } - public static ThrowingConsumer concat( - ThrowingConsumer first, - ThrowingConsumer second - ) { + public static ThrowingConsumer concat(ThrowingConsumer first, + ThrowingConsumer second) { return t -> { first.accept(t); second.accept(t); }; } - public static ThrowingConsumer concat( - Consumer first, - ThrowingConsumer second - ) { + public static ThrowingConsumer concat(Consumer first, + ThrowingConsumer second) { return t -> { first.accept(t); second.accept(t); }; } - public static ThrowingConsumer concat( - ThrowingConsumer first, - Consumer second - ) { + public static ThrowingConsumer concat(ThrowingConsumer first, + Consumer second) { return t -> { first.accept(t); second.accept(t); diff --git a/src/main/java/ru/windcorp/jputil/functions/ThrowingFunction.java b/src/main/java/ru/windcorp/jputil/functions/ThrowingFunction.java index afdd078..7c32b16 100644 --- a/src/main/java/ru/windcorp/jputil/functions/ThrowingFunction.java +++ b/src/main/java/ru/windcorp/jputil/functions/ThrowingFunction.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.functions; import java.util.function.BiConsumer; @@ -28,10 +28,8 @@ public interface ThrowingFunction { R apply(T t) throws E; @SuppressWarnings("unchecked") - default Function withHandler( - BiConsumer handler, - Function value - ) { + default Function withHandler(BiConsumer handler, + Function value) { return t -> { try { return apply(t); @@ -58,23 +56,18 @@ public interface ThrowingFunction { } public static ThrowingFunction compose( - ThrowingFunction first, - ThrowingFunction second - ) { + ThrowingFunction first, + ThrowingFunction second) { + return t -> second.apply(first.apply(t)); + } + + public static ThrowingFunction compose(Function first, + ThrowingFunction second) { return t -> second.apply(first.apply(t)); } public static ThrowingFunction compose( - Function first, - ThrowingFunction second - ) { - return t -> second.apply(first.apply(t)); - } - - public static ThrowingFunction compose( - ThrowingFunction first, - Function second - ) { + ThrowingFunction first, Function second) { return t -> second.apply(first.apply(t)); } diff --git a/src/main/java/ru/windcorp/jputil/functions/ThrowingRunnable.java b/src/main/java/ru/windcorp/jputil/functions/ThrowingRunnable.java index f27429b..f93ea61 100644 --- a/src/main/java/ru/windcorp/jputil/functions/ThrowingRunnable.java +++ b/src/main/java/ru/windcorp/jputil/functions/ThrowingRunnable.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.functions; import java.util.function.Consumer; @@ -38,10 +38,8 @@ public interface ThrowingRunnable { }; } - public static ThrowingRunnable concat( - ThrowingRunnable first, - ThrowingRunnable second - ) { + public static ThrowingRunnable concat(ThrowingRunnable first, + ThrowingRunnable second) { return () -> { first.run(); second.run(); diff --git a/src/main/java/ru/windcorp/jputil/functions/ThrowingSupplier.java b/src/main/java/ru/windcorp/jputil/functions/ThrowingSupplier.java index 84ad690..6583789 100644 --- a/src/main/java/ru/windcorp/jputil/functions/ThrowingSupplier.java +++ b/src/main/java/ru/windcorp/jputil/functions/ThrowingSupplier.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.functions; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/jputil/iterators/ArrayIterator.java b/src/main/java/ru/windcorp/jputil/iterators/ArrayIterator.java index 0b8fab2..aec4324 100644 --- a/src/main/java/ru/windcorp/jputil/iterators/ArrayIterator.java +++ b/src/main/java/ru/windcorp/jputil/iterators/ArrayIterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.iterators; import java.util.Iterator; diff --git a/src/main/java/ru/windcorp/jputil/iterators/FunctionIterator.java b/src/main/java/ru/windcorp/jputil/iterators/FunctionIterator.java index abc5b44..e32d250 100644 --- a/src/main/java/ru/windcorp/jputil/iterators/FunctionIterator.java +++ b/src/main/java/ru/windcorp/jputil/iterators/FunctionIterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.iterators; import java.util.Iterator; diff --git a/src/main/java/ru/windcorp/jputil/iterators/PeekingIterator.java b/src/main/java/ru/windcorp/jputil/iterators/PeekingIterator.java index 67f3da9..754e1ae 100644 --- a/src/main/java/ru/windcorp/jputil/iterators/PeekingIterator.java +++ b/src/main/java/ru/windcorp/jputil/iterators/PeekingIterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.iterators; import java.util.Iterator; diff --git a/src/main/java/ru/windcorp/jputil/iterators/RangeIterator.java b/src/main/java/ru/windcorp/jputil/iterators/RangeIterator.java index 7da8ada..0047fa9 100644 --- a/src/main/java/ru/windcorp/jputil/iterators/RangeIterator.java +++ b/src/main/java/ru/windcorp/jputil/iterators/RangeIterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.iterators; import java.util.Iterator; @@ -49,10 +49,8 @@ public class RangeIterator implements Iterator { public E next() { update(); if (nextIndex >= from + amount) { - throw new NoSuchElementException( - "RangeIterator about to retrieve element " + nextIndex - + " which exceeds upper boundary " + (from + amount) - ); + throw new NoSuchElementException("RangeIterator about to retrieve element " + nextIndex + + " which exceeds upper boundary " + (from + amount)); } E result = parent.next(); diff --git a/src/main/java/ru/windcorp/jputil/iterators/Reiterator.java b/src/main/java/ru/windcorp/jputil/iterators/Reiterator.java index 7969bc1..85d9122 100644 --- a/src/main/java/ru/windcorp/jputil/iterators/Reiterator.java +++ b/src/main/java/ru/windcorp/jputil/iterators/Reiterator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.iterators; import java.util.ArrayList; diff --git a/src/main/java/ru/windcorp/jputil/selectors/AbstractSelectorOperator.java b/src/main/java/ru/windcorp/jputil/selectors/AbstractSelectorOperator.java index 481e558..3448929 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/AbstractSelectorOperator.java +++ b/src/main/java/ru/windcorp/jputil/selectors/AbstractSelectorOperator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; public abstract class AbstractSelectorOperator implements SelectorOperator { diff --git a/src/main/java/ru/windcorp/jputil/selectors/NamedParameterizedSelector.java b/src/main/java/ru/windcorp/jputil/selectors/NamedParameterizedSelector.java index e0676fd..d0a7692 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/NamedParameterizedSelector.java +++ b/src/main/java/ru/windcorp/jputil/selectors/NamedParameterizedSelector.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import ru.windcorp.jputil.SyntaxException; diff --git a/src/main/java/ru/windcorp/jputil/selectors/NamedSelector.java b/src/main/java/ru/windcorp/jputil/selectors/NamedSelector.java index 196be14..7765505 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/NamedSelector.java +++ b/src/main/java/ru/windcorp/jputil/selectors/NamedSelector.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import ru.windcorp.jputil.SyntaxException; diff --git a/src/main/java/ru/windcorp/jputil/selectors/OperatorAnd.java b/src/main/java/ru/windcorp/jputil/selectors/OperatorAnd.java index 603c6d4..4b68bb6 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/OperatorAnd.java +++ b/src/main/java/ru/windcorp/jputil/selectors/OperatorAnd.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.Deque; diff --git a/src/main/java/ru/windcorp/jputil/selectors/OperatorExclude.java b/src/main/java/ru/windcorp/jputil/selectors/OperatorExclude.java index a805a2f..810f15f 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/OperatorExclude.java +++ b/src/main/java/ru/windcorp/jputil/selectors/OperatorExclude.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.Deque; diff --git a/src/main/java/ru/windcorp/jputil/selectors/OperatorNot.java b/src/main/java/ru/windcorp/jputil/selectors/OperatorNot.java index 2bf0300..b12f5dc 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/OperatorNot.java +++ b/src/main/java/ru/windcorp/jputil/selectors/OperatorNot.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.Deque; diff --git a/src/main/java/ru/windcorp/jputil/selectors/OperatorOr.java b/src/main/java/ru/windcorp/jputil/selectors/OperatorOr.java index 367e6c3..2388105 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/OperatorOr.java +++ b/src/main/java/ru/windcorp/jputil/selectors/OperatorOr.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.Deque; diff --git a/src/main/java/ru/windcorp/jputil/selectors/OperatorXor.java b/src/main/java/ru/windcorp/jputil/selectors/OperatorXor.java index 467e6a0..9b8a719 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/OperatorXor.java +++ b/src/main/java/ru/windcorp/jputil/selectors/OperatorXor.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.Deque; diff --git a/src/main/java/ru/windcorp/jputil/selectors/PredicateWrapper.java b/src/main/java/ru/windcorp/jputil/selectors/PredicateWrapper.java index 278df45..f43760a 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/PredicateWrapper.java +++ b/src/main/java/ru/windcorp/jputil/selectors/PredicateWrapper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.function.Predicate; diff --git a/src/main/java/ru/windcorp/jputil/selectors/Selector.java b/src/main/java/ru/windcorp/jputil/selectors/Selector.java index eec8b06..450e717 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/Selector.java +++ b/src/main/java/ru/windcorp/jputil/selectors/Selector.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.function.Predicate; diff --git a/src/main/java/ru/windcorp/jputil/selectors/SelectorOperator.java b/src/main/java/ru/windcorp/jputil/selectors/SelectorOperator.java index 665d231..20b46b3 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/SelectorOperator.java +++ b/src/main/java/ru/windcorp/jputil/selectors/SelectorOperator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.Deque; diff --git a/src/main/java/ru/windcorp/jputil/selectors/SelectorSystem.java b/src/main/java/ru/windcorp/jputil/selectors/SelectorSystem.java index 0361795..a5543fe 100644 --- a/src/main/java/ru/windcorp/jputil/selectors/SelectorSystem.java +++ b/src/main/java/ru/windcorp/jputil/selectors/SelectorSystem.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.jputil.selectors; import java.util.ArrayList; @@ -37,7 +37,7 @@ public class SelectorSystem { private final Collection> selectors = Collections.synchronizedCollection(new ArrayList>()); private final Collection operators = Collections - .synchronizedCollection(new ArrayList()); + .synchronizedCollection(new ArrayList()); private String stackPrefix = null; diff --git a/src/main/java/ru/windcorp/progressia/Progressia.java b/src/main/java/ru/windcorp/progressia/Progressia.java index db899ea..fd3529f 100644 --- a/src/main/java/ru/windcorp/progressia/Progressia.java +++ b/src/main/java/ru/windcorp/progressia/Progressia.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia; public class Progressia { diff --git a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java index c8935fc..08ce1e9 100644 --- a/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java +++ b/src/main/java/ru/windcorp/progressia/ProgressiaLauncher.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia; import ru.windcorp.progressia.common.util.crash.CrashReports; diff --git a/src/main/java/ru/windcorp/progressia/Proxy.java b/src/main/java/ru/windcorp/progressia/Proxy.java index a1af080..8b5542e 100644 --- a/src/main/java/ru/windcorp/progressia/Proxy.java +++ b/src/main/java/ru/windcorp/progressia/Proxy.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia; public interface Proxy { diff --git a/src/main/java/ru/windcorp/progressia/client/Client.java b/src/main/java/ru/windcorp/progressia/client/Client.java index d8800c7..5602048 100644 --- a/src/main/java/ru/windcorp/progressia/client/Client.java +++ b/src/main/java/ru/windcorp/progressia/client/Client.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client; import ru.windcorp.progressia.client.comms.DefaultClientCommsListener; @@ -69,11 +69,7 @@ public class Client { return; } - getCamera().setAnchor( - new EntityAnchor( - getWorld().getEntityRenderable(entity) - ) - ); + getCamera().setAnchor(new EntityAnchor(getWorld().getEntityRenderable(entity))); } } diff --git a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java index 1d154e7..c7a221e 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientProxy.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientProxy.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client; import ru.windcorp.progressia.Proxy; @@ -42,10 +42,8 @@ public class ClientProxy implements Proxy { try { RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init); RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init); - RenderTaskQueue.waitAndInvoke( - () -> Typefaces - .setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz"))) - ); + RenderTaskQueue.waitAndInvoke(() -> Typefaces + .setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))); } catch (InterruptedException e) { throw CrashReports.report(e, "ClientProxy failed"); } @@ -60,7 +58,7 @@ public class ClientProxy implements Proxy { ServerState.startServer(); ClientState.connectToLocalServer(); - + TestMusicPlayer.start(); } diff --git a/src/main/java/ru/windcorp/progressia/client/ClientState.java b/src/main/java/ru/windcorp/progressia/client/ClientState.java index 75f0f07..6060623 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientState.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientState.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client; import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel; @@ -43,9 +43,7 @@ public class ClientState { WorldData world = new WorldData(); - LocalServerCommsChannel channel = new LocalServerCommsChannel( - ServerState.getInstance() - ); + LocalServerCommsChannel channel = new LocalServerCommsChannel(ServerState.getInstance()); Client client = new Client(world, channel); diff --git a/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java b/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java index bb0482d..d578c85 100644 --- a/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java +++ b/src/main/java/ru/windcorp/progressia/client/ProgressiaClientMain.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client; import ru.windcorp.progressia.ProgressiaLauncher; diff --git a/src/main/java/ru/windcorp/progressia/client/audio/AudioFormat.java b/src/main/java/ru/windcorp/progressia/client/audio/AudioFormat.java index 848e66c..cade47d 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/AudioFormat.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/AudioFormat.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio; public enum AudioFormat { diff --git a/src/main/java/ru/windcorp/progressia/client/audio/AudioManager.java b/src/main/java/ru/windcorp/progressia/client/audio/AudioManager.java index 49f2312..a7ddd32 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/AudioManager.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/AudioManager.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio; import org.lwjgl.openal.*; @@ -43,10 +43,7 @@ public class AudioManager { private static Speaker musicSpeaker; public static void initAL() { - String defaultDeviceName = alcGetString( - 0, - ALC_DEFAULT_DEVICE_SPECIFIER - ); + String defaultDeviceName = alcGetString(0, ALC_DEFAULT_DEVICE_SPECIFIER); device = alcOpenDevice(defaultDeviceName); @@ -75,10 +72,7 @@ public class AudioManager { lastSoundIndex = 0; } speaker = soundSpeakers.get(lastSoundIndex); - } while ( - speaker.getState() - .equals(Speaker.State.PLAYING_LOOP) - ); + } while (speaker.getState().equals(Speaker.State.PLAYING_LOOP)); return speaker; } diff --git a/src/main/java/ru/windcorp/progressia/client/audio/AudioRegistry.java b/src/main/java/ru/windcorp/progressia/client/audio/AudioRegistry.java index 3199622..2f1da30 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/AudioRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/AudioRegistry.java @@ -21,9 +21,9 @@ import ru.windcorp.progressia.client.audio.backend.SoundType; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; public class AudioRegistry extends NamespacedInstanceRegistry { - + private static final AudioRegistry INSTANCE = new AudioRegistry(); - + /** * @return the instance */ diff --git a/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java b/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java index 24cc2de..a4cab80 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/AudioSystem.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio; import ru.windcorp.progressia.common.resource.ResourceManager; @@ -29,10 +29,7 @@ public class AudioSystem { } static void loadAudioData() { - AudioManager.loadSound( - ResourceManager.getResource("assets/sounds/block_destroy_clap.ogg"), - "Progressia:BlockDestroy", - AudioFormat.MONO - ); + AudioManager.loadSound(ResourceManager.getResource("assets/sounds/block_destroy_clap.ogg"), + "Progressia:BlockDestroy", AudioFormat.MONO); } } diff --git a/src/main/java/ru/windcorp/progressia/client/audio/Music.java b/src/main/java/ru/windcorp/progressia/client/audio/Music.java index 031b58e..d60860a 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/Music.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/Music.java @@ -15,18 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio; import glm.vec._3.Vec3; import ru.windcorp.progressia.client.audio.backend.SoundType; import ru.windcorp.progressia.client.audio.backend.Speaker; -public class Music - extends Sound { - - - +public class Music extends Sound { + public Music(SoundType soundType, int timeLength, float pitch, float gain) { super(soundType, timeLength, new Vec3(), new Vec3(), pitch, gain); } @@ -47,7 +44,7 @@ public class Music protected Speaker initSpeaker() { return AudioManager.initMusicSpeaker(soundType); } - + @Override public void setPosition(Vec3 position) { throw new UnsupportedOperationException(); diff --git a/src/main/java/ru/windcorp/progressia/client/audio/Sound.java b/src/main/java/ru/windcorp/progressia/client/audio/Sound.java index 77f0c9e..a45b535 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/Sound.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/Sound.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio; import glm.vec._3.Vec3; @@ -29,9 +29,9 @@ public class Sound { protected float pitch = 1.0f; protected float gain = 1.0f; protected int timeLength = 0; - + protected SoundType soundType; - + public Sound(SoundType soundType) { this.soundType = soundType; } @@ -39,37 +39,23 @@ public class Sound { public Sound(String id) { this(AudioRegistry.getInstance().get(id)); } - - public Sound( - String id, - int timeLength, - Vec3 position, - Vec3 velocity, - float pitch, - float gain - ) { + + public Sound(String id, int timeLength, Vec3 position, Vec3 velocity, float pitch, float gain) { this(id); this.position = position; this.velocity = velocity; this.pitch = pitch; this.gain = gain; } - - public Sound( - SoundType soundType, - int timeLength, - Vec3 position, - Vec3 velocity, - float pitch, - float gain - ) { + + public Sound(SoundType soundType, int timeLength, Vec3 position, Vec3 velocity, float pitch, float gain) { this(soundType); this.position = position; this.velocity = velocity; this.pitch = pitch; this.gain = gain; } - + protected Speaker initSpeaker() { return AudioManager.initSpeaker(soundType); } @@ -119,7 +105,7 @@ public class Sound { public float getPitch() { return pitch; } - + public double getDuration() { return soundType.getDuration(); } diff --git a/src/main/java/ru/windcorp/progressia/client/audio/backend/AudioReader.java b/src/main/java/ru/windcorp/progressia/client/audio/backend/AudioReader.java index 9fa48e0..27e77b8 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/backend/AudioReader.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/backend/AudioReader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio.backend; import org.lwjgl.BufferUtils; @@ -39,12 +39,7 @@ public class AudioReader { ShortBuffer rawAudio = decodeVorbis(resource, channelBuffer, rateBuffer); - return new SoundType( - id, - rawAudio, - format, - rateBuffer.get(0) - ); + return new SoundType(id, rawAudio, format, rateBuffer.get(0)); } public static SoundType readAsMono(Resource resource, String id) { @@ -55,15 +50,7 @@ public class AudioReader { return readAsSpecified(resource, id, AL_FORMAT_STEREO16); } - private static ShortBuffer decodeVorbis( - Resource dataToDecode, - IntBuffer channelsBuffer, - IntBuffer rateBuffer - ) { - return stb_vorbis_decode_memory( - dataToDecode.readAsBytes(), - channelsBuffer, - rateBuffer - ); + private static ShortBuffer decodeVorbis(Resource dataToDecode, IntBuffer channelsBuffer, IntBuffer rateBuffer) { + return stb_vorbis_decode_memory(dataToDecode.readAsBytes(), channelsBuffer, rateBuffer); } } diff --git a/src/main/java/ru/windcorp/progressia/client/audio/backend/Listener.java b/src/main/java/ru/windcorp/progressia/client/audio/backend/Listener.java index 8f6fe35..78a9c9a 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/backend/Listener.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/backend/Listener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio.backend; import glm.vec._3.Vec3; @@ -55,9 +55,8 @@ public class Listener { if (isInWorld) { if (wasInWorld) { - velocity.set(camera.getLastAnchorPosition()).sub(position).div( - (float) GraphicsInterface.getFrameLength() - ); + velocity.set(camera.getLastAnchorPosition()).sub(position) + .div((float) GraphicsInterface.getFrameLength()); } else { // If !wasInWorld, previous position is nonsence. Assume 0. velocity.set(0); @@ -72,9 +71,9 @@ public class Listener { } /* - * Only apply if there is a chance that params changed. - * This can only happen if we are in world now (isInWorld) or we just - * left world (wasInWorld, then we need to reset). + * Only apply if there is a chance that params changed. This can only + * happen if we are in world now (isInWorld) or we just left world + * (wasInWorld, then we need to reset). */ if (isInWorld || wasInWorld) { applyParams(); @@ -91,17 +90,7 @@ public class Listener { private void applyParams() { alListener3f(AL_POSITION, position.x, position.y, position.z); alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); - alListenerfv( - AL_ORIENTATION, - new float[] { - oriAt.x, - oriAt.y, - oriAt.z, - oriUp.x, - oriUp.y, - oriUp.z - } - ); + alListenerfv(AL_ORIENTATION, new float[] { oriAt.x, oriAt.y, oriAt.z, oriUp.x, oriUp.y, oriUp.z }); } } diff --git a/src/main/java/ru/windcorp/progressia/client/audio/backend/SoundType.java b/src/main/java/ru/windcorp/progressia/client/audio/backend/SoundType.java index cdb1954..fa7d5a0 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/backend/SoundType.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/backend/SoundType.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio.backend; import ru.windcorp.progressia.common.util.namespaces.Namespaced; @@ -34,12 +34,7 @@ public class SoundType extends Namespaced { private int audioBuffer; private double duration; - public SoundType( - String id, - ShortBuffer rawAudio, - int format, - int sampleRate - ) { + public SoundType(String id, ShortBuffer rawAudio, int format, int sampleRate) { super(id); this.rawAudio = rawAudio; this.sampleRate = sampleRate; @@ -56,7 +51,7 @@ public class SoundType extends Namespaced { public void initSpeaker(Speaker speaker) { speaker.setAudioData(audioBuffer); } - + public double getDuration() { return duration; } diff --git a/src/main/java/ru/windcorp/progressia/client/audio/backend/Speaker.java b/src/main/java/ru/windcorp/progressia/client/audio/backend/Speaker.java index c649a6a..6e7af4b 100644 --- a/src/main/java/ru/windcorp/progressia/client/audio/backend/Speaker.java +++ b/src/main/java/ru/windcorp/progressia/client/audio/backend/Speaker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.audio.backend; import glm.vec._3.Vec3; @@ -24,9 +24,7 @@ import static org.lwjgl.openal.AL11.*; public class Speaker { public enum State { - NOT_PLAYING, - PLAYING, - PLAYING_LOOP + NOT_PLAYING, PLAYING, PLAYING_LOOP } // Buffers @@ -49,13 +47,7 @@ public class Speaker { setAudioData(audioData); } - public Speaker( - int audioData, - Vec3 position, - Vec3 velocity, - float pitch, - float gain - ) { + public Speaker(int audioData, Vec3 position, Vec3 velocity, float pitch, float gain) { setAudioData(audioData); setPosition(position); setVelocity(velocity); @@ -63,12 +55,7 @@ public class Speaker { setGain(gain); } - public Speaker( - Vec3 position, - Vec3 velocity, - float pitch, - float gain - ) { + public Speaker(Vec3 position, Vec3 velocity, float pitch, float gain) { setPosition(position); setVelocity(velocity); setPitch(pitch); diff --git a/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java b/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java index dad05fd..e983e51 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms; import java.io.IOException; @@ -39,9 +39,7 @@ public class DefaultClientCommsListener implements CommsListener { @Override public void onPacketReceived(Packet packet) { if (packet instanceof PacketAffectWorld) { - ((PacketAffectWorld) packet).apply( - getClient().getWorld().getData() - ); + ((PacketAffectWorld) packet).apply(getClient().getWorld().getData()); } else if (packet instanceof PacketSetLocalPlayer) { setLocalPlayer((PacketSetLocalPlayer) packet); } diff --git a/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java b/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java index 3a0a1b1..6bf9a8e 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms; import ru.windcorp.progressia.common.comms.CommsChannel; diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTrigger.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTrigger.java index 88e9fa3..0f0e091 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTrigger.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTrigger.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerInputBased.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerInputBased.java index b2f8de4..f1985b3 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerInputBased.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerInputBased.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import ru.windcorp.progressia.client.graphics.input.InputEvent; diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLambda.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLambda.java index 22004b8..476c482 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLambda.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLambda.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import java.util.function.BiConsumer; @@ -33,17 +33,12 @@ public class ControlTriggerLambda extends ControlTriggerInputBased { private final Predicate predicate; private final BiConsumer dataWriter; - public ControlTriggerLambda( - String id, - Predicate predicate, - BiConsumer dataWriter - ) { + public ControlTriggerLambda(String id, Predicate predicate, + BiConsumer dataWriter) { super(id); - this.packetId = NamespacedUtil.getId( - NamespacedUtil.getNamespace(id), - "ControlKeyPress" + NamespacedUtil.getName(id) - ); + this.packetId = NamespacedUtil.getId(NamespacedUtil.getNamespace(id), + "ControlKeyPress" + NamespacedUtil.getName(id)); this.predicate = predicate; this.dataWriter = dataWriter; @@ -54,10 +49,7 @@ public class ControlTriggerLambda extends ControlTriggerInputBased { if (!predicate.test(event)) return null; - PacketControl packet = new PacketControl( - packetId, - ControlDataRegistry.getInstance().create(getId()) - ); + PacketControl packet = new PacketControl(packetId, ControlDataRegistry.getInstance().create(getId())); dataWriter.accept(event, packet.getControl()); diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLocalLambda.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLocalLambda.java index b2ae739..7708328 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLocalLambda.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerLocalLambda.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import java.util.function.Consumer; @@ -29,11 +29,7 @@ public class ControlTriggerLocalLambda extends ControlTriggerInputBased { private final Predicate predicate; private final Consumer action; - public ControlTriggerLocalLambda( - String id, - Predicate predicate, - Consumer action - ) { + public ControlTriggerLocalLambda(String id, Predicate predicate, Consumer action) { super(id); this.predicate = predicate; diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerRegistry.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerRegistry.java index a2ec71e..5a3f4a9 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggerRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggers.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggers.java index 2c0d61d..260e220 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggers.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/ControlTriggers.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import java.util.function.BiConsumer; @@ -27,122 +27,59 @@ import ru.windcorp.progressia.common.comms.controls.ControlData; public class ControlTriggers { - public static ControlTriggerInputBased of( - String id, - BiConsumer dataWriter, - Predicate predicate - ) { + public static ControlTriggerInputBased of(String id, BiConsumer dataWriter, + Predicate predicate) { return new ControlTriggerLambda(id, predicate, dataWriter); } - public static ControlTriggerInputBased of( - String id, - Consumer dataWriter, - Predicate predicate - ) { - return of( - id, - (input, control) -> dataWriter.accept(control), - predicate - ); + public static ControlTriggerInputBased of(String id, Consumer dataWriter, + Predicate predicate) { + return of(id, (input, control) -> dataWriter.accept(control), predicate); } - public static ControlTriggerInputBased of( - String id, - Predicate predicate - ) { - return of( - id, - (input, control) -> { - }, - predicate - ); + public static ControlTriggerInputBased of(String id, Predicate predicate) { + return of(id, (input, control) -> { + }, predicate); } @SafeVarargs - public static ControlTriggerInputBased of( - String id, - Class inputType, - BiConsumer dataWriter, - Predicate... predicates - ) { - return of( - id, - createCheckedDataWriter(inputType, dataWriter), - createCheckedCompoundPredicate(inputType, predicates) - ); + public static ControlTriggerInputBased of(String id, Class inputType, + BiConsumer dataWriter, Predicate... predicates) { + return of(id, createCheckedDataWriter(inputType, dataWriter), + createCheckedCompoundPredicate(inputType, predicates)); } @SafeVarargs - public static ControlTriggerInputBased of( - String id, - Class inputType, - Consumer dataWriter, - Predicate... predicates - ) { - return of( - id, - inputType, - (input, control) -> dataWriter.accept(control), - predicates - ); + public static ControlTriggerInputBased of(String id, Class inputType, + Consumer dataWriter, Predicate... predicates) { + return of(id, inputType, (input, control) -> dataWriter.accept(control), predicates); } @SafeVarargs - public static ControlTriggerInputBased of( - String id, - Class inputType, - Predicate... predicates - ) { - return of( - id, - (input, control) -> { - }, - createCheckedCompoundPredicate(inputType, predicates) - ); + public static ControlTriggerInputBased of(String id, Class inputType, + Predicate... predicates) { + return of(id, (input, control) -> { + }, createCheckedCompoundPredicate(inputType, predicates)); } @SafeVarargs - public static ControlTriggerInputBased of( - String id, - BiConsumer dataWriter, - Predicate... predicates - ) { - return of( - id, - InputEvent.class, - dataWriter, - predicates - ); + public static ControlTriggerInputBased of(String id, BiConsumer dataWriter, + Predicate... predicates) { + return of(id, InputEvent.class, dataWriter, predicates); } @SafeVarargs - public static ControlTriggerInputBased of( - String id, - Consumer dataWriter, - Predicate... predicates - ) { - return of( - id, - (input, control) -> dataWriter.accept(control), - predicates - ); + public static ControlTriggerInputBased of(String id, Consumer dataWriter, + Predicate... predicates) { + return of(id, (input, control) -> dataWriter.accept(control), predicates); } @SafeVarargs - public static ControlTriggerInputBased of( - String id, - Predicate... predicates - ) { - return of( - id, - InputEvent.class, - (input, control) -> { - }, - predicates - ); + public static ControlTriggerInputBased of(String id, Predicate... predicates) { + return of(id, InputEvent.class, (input, control) -> { + }, predicates); } - + // // /// @@ -156,101 +93,53 @@ public class ControlTriggers { // // // - - public static ControlTriggerInputBased localOf( - String id, - Consumer action, - Predicate predicate - ) { + + public static ControlTriggerInputBased localOf(String id, Consumer action, + Predicate predicate) { return new ControlTriggerLocalLambda(id, predicate, action); } - public static ControlTriggerInputBased localOf( - String id, - Runnable action, - Predicate predicate - ) { - return localOf( - id, - input -> action.run(), - predicate - ); + public static ControlTriggerInputBased localOf(String id, Runnable action, Predicate predicate) { + return localOf(id, input -> action.run(), predicate); } @SafeVarargs - public static ControlTriggerInputBased localOf( - String id, - Class inputType, - Consumer action, - Predicate... predicates - ) { - return localOf( - id, - createCheckedAction(inputType, action), - createCheckedCompoundPredicate(inputType, predicates) - ); + public static ControlTriggerInputBased localOf(String id, Class inputType, + Consumer action, Predicate... predicates) { + return localOf(id, createCheckedAction(inputType, action), + createCheckedCompoundPredicate(inputType, predicates)); } @SafeVarargs - public static ControlTriggerInputBased localOf( - String id, - Class inputType, - Runnable action, - Predicate... predicates - ) { - return localOf( - id, - inputType, - input -> action.run(), - predicates - ); + public static ControlTriggerInputBased localOf(String id, Class inputType, + Runnable action, Predicate... predicates) { + return localOf(id, inputType, input -> action.run(), predicates); } @SafeVarargs - public static ControlTriggerInputBased localOf( - String id, - Consumer action, - Predicate... predicates - ) { - return localOf( - id, - InputEvent.class, - action, - predicates - ); + public static ControlTriggerInputBased localOf(String id, Consumer action, + Predicate... predicates) { + return localOf(id, InputEvent.class, action, predicates); } @SafeVarargs - public static ControlTriggerInputBased localOf( - String id, - Runnable action, - Predicate... predicates - ) { - return of( - id, - input -> action.run(), - predicates - ); + public static ControlTriggerInputBased localOf(String id, Runnable action, + Predicate... predicates) { + return of(id, input -> action.run(), predicates); } private static BiConsumer createCheckedDataWriter( - Class inputType, - BiConsumer dataWriter - ) { + Class inputType, BiConsumer dataWriter) { return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control); } - - private static Consumer createCheckedAction( - Class inputType, - Consumer action - ) { + + private static Consumer createCheckedAction(Class inputType, + Consumer action) { return inputEvent -> action.accept(inputType.cast(inputEvent)); } - private static Predicate createCheckedCompoundPredicate( - Class inputType, - Predicate[] predicates - ) { + private static Predicate createCheckedCompoundPredicate(Class inputType, + Predicate[] predicates) { return new CompoundCastPredicate<>(inputType, predicates); } diff --git a/src/main/java/ru/windcorp/progressia/client/comms/controls/InputBasedControls.java b/src/main/java/ru/windcorp/progressia/client/comms/controls/InputBasedControls.java index 28b9e1b..2fbd086 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/controls/InputBasedControls.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/controls/InputBasedControls.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.controls; import ru.windcorp.progressia.client.Client; @@ -32,8 +32,7 @@ public class InputBasedControls { this.client = client; this.controls = ControlTriggerRegistry.getInstance().values().stream() - .filter(ControlTriggerInputBased.class::isInstance) - .toArray(ControlTriggerInputBased[]::new); + .filter(ControlTriggerInputBased.class::isInstance).toArray(ControlTriggerInputBased[]::new); } public void handleInput(Input input) { diff --git a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java index 816fba8..9fc0e47 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.localhost; import java.io.IOException; diff --git a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java index 194a2a1..14ec90a 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.comms.localhost; import ru.windcorp.progressia.client.comms.ServerCommsChannel; @@ -34,11 +34,7 @@ public class LocalServerCommsChannel extends ServerCommsChannel { public void connect(String login) { setState(State.CONNECTED); - this.localClient = new LocalClient( - server.getClientManager().grabClientId(), - login, - this - ); + this.localClient = new LocalClient(server.getClientManager().grabClientId(), login, this); server.getClientManager().addClient(localClient); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/Colors.java b/src/main/java/ru/windcorp/progressia/client/graphics/Colors.java index 78aa79b..0aeee7d 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/Colors.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/Colors.java @@ -15,26 +15,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics; import glm.vec._4.Vec4; public class Colors { - public static final Vec4 WHITE = toVector(0xFFFFFFFF), - BLACK = toVector(0xFF000000), + public static final Vec4 WHITE = toVector(0xFFFFFFFF), BLACK = toVector(0xFF000000), - GRAY_4 = toVector(0xFF444444), - GRAY = toVector(0xFF888888), - GRAY_A = toVector(0xFFAAAAAA), + GRAY_4 = toVector(0xFF444444), GRAY = toVector(0xFF888888), GRAY_A = toVector(0xFFAAAAAA), - DEBUG_RED = toVector(0xFFFF0000), - DEBUG_GREEN = toVector(0xFF00FF00), - DEBUG_BLUE = toVector(0xFF0000FF), - DEBUG_CYAN = toVector(0xFF00FFFF), - DEBUG_MAGENTA = toVector(0xFFFF00FF), - DEBUG_YELLOW = toVector(0xFFFFFF00); + DEBUG_RED = toVector(0xFFFF0000), DEBUG_GREEN = toVector(0xFF00FF00), DEBUG_BLUE = toVector(0xFF0000FF), + DEBUG_CYAN = toVector(0xFF00FFFF), DEBUG_MAGENTA = toVector(0xFFFF00FF), + DEBUG_YELLOW = toVector(0xFFFFFF00); public static Vec4 toVector(int argb) { return toVector(argb, new Vec4()); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java b/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java index fc099d2..97e499c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/GUI.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics; import java.util.ArrayList; @@ -42,7 +42,7 @@ public class GUI { } private static final List MODIFICATION_QUEUE = Collections - .synchronizedList(new ArrayList<>()); + .synchronizedList(new ArrayList<>()); private static class ModifiableInput extends Input { @Override diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/Layer.java b/src/main/java/ru/windcorp/progressia/client/graphics/Layer.java index 2dbef4a..ef6424c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/Layer.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/Layer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/FaceCulling.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/FaceCulling.java index 61645f4..bdab268 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/FaceCulling.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/FaceCulling.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import java.util.ArrayDeque; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsBackend.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsBackend.java index 04c4a3d..233f3c9 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsBackend.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsBackend.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import glm.vec._2.i.Vec2i; @@ -61,7 +61,7 @@ public class GraphicsBackend { static void setOpenGLInitialized(boolean isOpenGLInitialized) { GraphicsBackend.isOpenGLInitialized = isOpenGLInitialized; } - + public static void initialize() { startRenderThread(); } @@ -159,27 +159,14 @@ public class GraphicsBackend { public static void setFullscreen() { GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - glfwSetWindowMonitor( - getWindowHandle(), - glfwGetPrimaryMonitor(), - 0, - 0, - vidmode.width(), - vidmode.height(), - 0); + glfwSetWindowMonitor(getWindowHandle(), glfwGetPrimaryMonitor(), 0, 0, vidmode.width(), vidmode.height(), 0); isFullscreen = true; } public static void setWindowed() { GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); - glfwSetWindowMonitor( - getWindowHandle(), - 0, - (vidmode.width() - getFrameWidth()) / 2, - (vidmode.height() - getFrameHeight()) / 2, - getFrameWidth(), - getFrameHeight(), - 0); + glfwSetWindowMonitor(getWindowHandle(), 0, (vidmode.width() - getFrameWidth()) / 2, + (vidmode.height() - getFrameHeight()) / 2, getFrameWidth(), getFrameHeight(), 0); isFullscreen = false; } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsInterface.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsInterface.java index 799edfd..1fb18e3 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsInterface.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/GraphicsInterface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import glm.vec._2.i.Vec2i; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java index 34d936c..2dcbd44 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import org.lwjgl.glfw.GLFW; @@ -49,13 +49,7 @@ public class InputHandler { private static final ModifiableKeyEvent THE_KEY_EVENT = new ModifiableKeyEvent(); - static void handleKeyInput( - long window, - int key, - int scancode, - int action, - int mods - ) { + static void handleKeyInput(long window, int key, int scancode, int action, int mods) { if (GraphicsBackend.getWindowHandle() != window) return; THE_KEY_EVENT.initialize(key, scancode, action, mods); @@ -71,12 +65,7 @@ public class InputHandler { } } - static void handleMouseButtonInput( - long window, - int key, - int action, - int mods - ) { + static void handleMouseButtonInput(long window, int key, int action, int mods) { handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods); } @@ -97,11 +86,7 @@ public class InputHandler { private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT = new ModifiableCursorMoveEvent(); - static void handleMouseMoveInput( - long window, - double x, - double y - ) { + static void handleMouseMoveInput(long window, double x, double y) { if (GraphicsBackend.getWindowHandle() != window) return; y = GraphicsInterface.getFrameHeight() - y; // Flip y axis @@ -131,11 +116,7 @@ public class InputHandler { private static final ModifiableWheelScrollEvent THE_WHEEL_SCROLL_EVENT = new ModifiableWheelScrollEvent(); - static void handleWheelScroll( - long window, - double xoffset, - double yoffset - ) { + static void handleWheelScroll(long window, double xoffset, double yoffset) { if (GraphicsBackend.getWindowHandle() != window) return; THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset); @@ -162,10 +143,7 @@ public class InputHandler { /* * NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend */ - static void handleFrameResize( - int width, - int height - ) { + static void handleFrameResize(int width, int height) { THE_FRAME_RESIZE_EVENT.initialize(width, height); dispatch(THE_FRAME_RESIZE_EVENT); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputTracker.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputTracker.java index 29dec99..8e7e86c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputTracker.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputTracker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import glm.vec._2.d.Vec2d; @@ -24,10 +24,7 @@ import gnu.trove.set.hash.TIntHashSet; public class InputTracker { - private static final Vec2d CURSOR_POSITION = new Vec2d( - Double.NaN, - Double.NaN - ); + private static final Vec2d CURSOR_POSITION = new Vec2d(Double.NaN, Double.NaN); private static final TIntSet PRESSED_KEYS = new TIntHashSet(256); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java index 83c06c8..e311316 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/LWJGLInitializer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import static org.lwjgl.opengl.GL11.*; @@ -68,7 +68,7 @@ class LWJGLInitializer { glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwMakeContextCurrent(handle); - glfwSwapInterval(0); // TODO: remove after config system is added + glfwSwapInterval(0); // TODO: remove after config system is added } private static void positionWindow() { @@ -94,16 +94,10 @@ class LWJGLInitializer { private static void setupWindowCallbacks() { long handle = GraphicsBackend.getWindowHandle(); - glfwSetFramebufferSizeCallback( - handle, - GraphicsBackend::onFrameResized - ); + glfwSetFramebufferSizeCallback(handle, GraphicsBackend::onFrameResized); glfwSetKeyCallback(handle, InputHandler::handleKeyInput); - glfwSetMouseButtonCallback( - handle, - InputHandler::handleMouseButtonInput - ); + glfwSetMouseButtonCallback(handle, InputHandler::handleMouseButtonInput); glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java index c467d45..a62a32f 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/OpenGLObjectTracker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import java.lang.ref.PhantomReference; @@ -34,19 +34,13 @@ public class OpenGLObjectTracker { private static final ReferenceQueue DELETE_QUEUE = new ReferenceQueue<>(); public synchronized static void register(OpenGLDeletable object, IntConsumer glDeleter) { - GLPhantomReference glRef = new GLPhantomReference<>( - object, - DELETE_QUEUE, - object.getHandle(), - glDeleter - ); + GLPhantomReference glRef = new GLPhantomReference<>(object, DELETE_QUEUE, object.getHandle(), + glDeleter); TO_DELETE.add(glRef); } public static void deleteAllObjects() { - for ( - GLPhantomReference glRef : TO_DELETE - ) { + for (GLPhantomReference glRef : TO_DELETE) { glRef.clear(); } } @@ -75,20 +69,16 @@ public class OpenGLObjectTracker { * It is possible to create a phantom reference with a {@code null} * queue, but such a reference is completely useless: Its {@code get} * method will always return {@code null} and, since it does not have a - * queue, - * it will never be enqueued. + * queue, it will never be enqueued. * - * @param referent the object the new phantom reference will refer to - * @param q the queue with which the reference is to be - * registered, - * or {@code null} if registration is not required + * @param referent + * the object the new phantom reference will refer to + * @param q + * the queue with which the reference is to be registered, or + * {@code null} if registration is not required */ - public GLPhantomReference( - T referent, - ReferenceQueue q, - int referentGLhandle, - IntConsumer GLDeleter - ) { + public GLPhantomReference(T referent, ReferenceQueue q, int referentGLhandle, + IntConsumer GLDeleter) { super(referent, q); this.referentGLhandle = referentGLhandle; this.GLDeleter = GLDeleter; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderTaskQueue.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderTaskQueue.java index 0a1d722..5c8d260 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderTaskQueue.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderTaskQueue.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import ru.windcorp.jputil.functions.ThrowingRunnable; @@ -41,11 +41,7 @@ public class RenderTaskQueue { HANDLER.invokeNow(task); } - public static void waitAndInvoke( - ThrowingRunnable task - ) - throws InterruptedException, - E { + public static void waitAndInvoke(ThrowingRunnable task) throws InterruptedException, E { HANDLER.waitAndInvoke(task); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderThread.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderThread.java index 47d4306..d92385e 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderThread.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/RenderThread.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import static org.lwjgl.glfw.GLFW.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/Usage.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/Usage.java index 8a526c1..dc3199d 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/Usage.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/Usage.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import static org.lwjgl.opengl.GL15.GL_DYNAMIC_DRAW; @@ -23,9 +23,7 @@ import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; import static org.lwjgl.opengl.GL15.GL_STREAM_DRAW; public enum Usage { // TODO add _COPY and _READ, pref. as another enum - STATIC(GL_STATIC_DRAW), - DYNAMIC(GL_DYNAMIC_DRAW), - STREAM(GL_STREAM_DRAW); + STATIC(GL_STATIC_DRAW), DYNAMIC(GL_DYNAMIC_DRAW), STREAM(GL_STREAM_DRAW); private final int glCode; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/VertexBufferObject.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/VertexBufferObject.java index 7fe23f7..ad81138 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/VertexBufferObject.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/VertexBufferObject.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend; import static org.lwjgl.opengl.GL20.*; @@ -28,8 +28,7 @@ import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGL public class VertexBufferObject implements OpenGLDeletable { public static enum BindTarget { - ARRAY(GL_ARRAY_BUFFER), - ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER); + ARRAY(GL_ARRAY_BUFFER), ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER); private final int glCode; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/CombinedShader.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/CombinedShader.java index 63fb4c9..754efba 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/CombinedShader.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/CombinedShader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders; import ru.windcorp.progressia.common.resource.Resource; @@ -32,12 +32,7 @@ public class CombinedShader extends Shader { for (int i = 1; i < resources.length; ++i) { if (ShaderType.guessByResourceName(resources[i]) != first) { throw new IllegalArgumentException( - "Deduced shader types of " - + resources[0] - + " and " - + resources[i] - + " differ" - ); + "Deduced shader types of " + resources[0] + " and " + resources[i] + " differ"); } } @@ -71,19 +66,8 @@ public class CombinedShader extends Shader { if (contents.codePointAt(versionIndex) == '#') { final String versionAnnotation = "#version "; - if ( - contents.regionMatches( - versionIndex, - versionAnnotation, - 0, - versionAnnotation.length() - ) - ) { - contents = contents.substring( - versionIndex - + versionAnnotation.length() - + "120".length() - ); + if (contents.regionMatches(versionIndex, versionAnnotation, 0, versionAnnotation.length())) { + contents = contents.substring(versionIndex + versionAnnotation.length() + "120".length()); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java index 98d512e..b980c21 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Program.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders; import static org.lwjgl.opengl.GL11.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java index 714fd1a..8851f66 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/Shader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders; import static org.lwjgl.opengl.GL11.*; @@ -57,10 +57,7 @@ public class Shader implements OpenGLDeletable { if (resource.contains("fsh")) return FRAGMENT; - throw new IllegalArgumentException( - "Cannot deduce shader type from resource name \"" + - resource + "\"" - ); + throw new IllegalArgumentException("Cannot deduce shader type from resource name \"" + resource + "\""); } } @@ -90,10 +87,7 @@ public class Shader implements OpenGLDeletable { } public Shader(String resource) { - this( - ShaderType.guessByResourceName(resource), - getShaderResource(resource).readAsString() - ); + this(ShaderType.guessByResourceName(resource), getShaderResource(resource).readAsString()); } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java index d56210a..028a0b3 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/Attribute.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.attributes; import ru.windcorp.progressia.client.graphics.backend.shaders.Program; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/AttributeVertexArray.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/AttributeVertexArray.java index 2ca192d..b380540 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/AttributeVertexArray.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/attributes/AttributeVertexArray.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.attributes; import static org.lwjgl.opengl.GL11.*; @@ -51,104 +51,29 @@ public class AttributeVertexArray extends Attribute { } } - public void set( - int size, - boolean normalized, - int stride, - ByteBuffer pointer - ) { - glVertexAttribPointer( - handle, - size, - GL_BYTE, - normalized, - stride, - pointer - ); + public void set(int size, boolean normalized, int stride, ByteBuffer pointer) { + glVertexAttribPointer(handle, size, GL_BYTE, normalized, stride, pointer); } - public void set( - int size, - boolean normalized, - int stride, - FloatBuffer pointer - ) { - glVertexAttribPointer( - handle, - size, - GL_FLOAT, - normalized, - stride, - pointer - ); + public void set(int size, boolean normalized, int stride, FloatBuffer pointer) { + glVertexAttribPointer(handle, size, GL_FLOAT, normalized, stride, pointer); } - public void set( - int size, - boolean normalized, - int stride, - IntBuffer pointer - ) { - glVertexAttribPointer( - handle, - size, - GL_INT, - normalized, - stride, - pointer - ); + public void set(int size, boolean normalized, int stride, IntBuffer pointer) { + glVertexAttribPointer(handle, size, GL_INT, normalized, stride, pointer); } - public void set( - int size, - boolean normalized, - int stride, - ShortBuffer pointer - ) { - glVertexAttribPointer( - handle, - size, - GL_SHORT, - normalized, - stride, - pointer - ); + public void set(int size, boolean normalized, int stride, ShortBuffer pointer) { + glVertexAttribPointer(handle, size, GL_SHORT, normalized, stride, pointer); } - public void set( - int size, - int type, - boolean normalized, - int stride, - long pointer - ) { - glVertexAttribPointer( - handle, - size, - type, - normalized, - stride, - pointer - ); + public void set(int size, int type, boolean normalized, int stride, long pointer) { + glVertexAttribPointer(handle, size, type, normalized, stride, pointer); } - public void set( - int size, - int type, - boolean normalized, - int stride, - VertexBufferObject vbo, - long offset - ) { + public void set(int size, int type, boolean normalized, int stride, VertexBufferObject vbo, long offset) { glBindBuffer(GL_ARRAY_BUFFER, vbo.getHandle()); - glVertexAttribPointer( - handle, - size, - type, - normalized, - stride, - offset - ); + glVertexAttribPointer(handle, size, type, normalized, stride, offset); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java index 8de5f1c..aa09d49 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import ru.windcorp.progressia.client.graphics.backend.shaders.Program; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Float.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Float.java index 6e2a62b..b41e313 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Float.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Float.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Int.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Int.java index 79d14a0..6389583 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Int.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform1Int.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Float.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Float.java index 166f47b..1c609c2 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Float.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Float.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Int.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Int.java index d8dde9b..679de9d 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Int.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Int.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Matrix.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Matrix.java index 6bbc3a9..b45c598 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Matrix.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform2Matrix.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Float.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Float.java index 21ea95b..d381a14 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Float.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Float.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Int.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Int.java index 1eb4690..283c459 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Int.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Int.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Matrix.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Matrix.java index 255fe2a..f2a0c12 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Matrix.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform3Matrix.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Float.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Float.java index daaab36..5aea97f 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Float.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Float.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Int.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Int.java index 6c2e760..31db411 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Int.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Int.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Matrix.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Matrix.java index e8281bd..e83cea5 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Matrix.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/shaders/uniforms/Uniform4Matrix.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms; import static org.lwjgl.opengl.GL20.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatLayer.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatLayer.java index 83f9d6f..7bf8161 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatLayer.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatLayer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import ru.windcorp.progressia.client.graphics.Layer; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatRenderHelper.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatRenderHelper.java index 5696ac2..789a378 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatRenderHelper.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/AssembledFlatRenderHelper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.nio.FloatBuffer; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/DefaultFlatRenderHelper.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/DefaultFlatRenderHelper.java index 4ec676a..5550c24 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/DefaultFlatRenderHelper.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/DefaultFlatRenderHelper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.nio.FloatBuffer; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatGraphics.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatGraphics.java index 2b615ec..e7723e6 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatGraphics.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatGraphics.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; public class FlatGraphics { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderHelper.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderHelper.java index 704c579..1cdaf14 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderHelper.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderHelper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.nio.FloatBuffer; @@ -37,9 +37,8 @@ public abstract class FlatRenderHelper extends ShapeRenderHelper { float width = GraphicsInterface.getFrameWidth(); float height = GraphicsInterface.getFrameHeight(); - return finalTransform.identity().translate(-1, -1, 0) - .scale(2 / width, 2 / height, 1 / MAX_DEPTH) - .mul(getTransform()); + return finalTransform.identity().translate(-1, -1, 0).scale(2 / width, 2 / height, 1 / MAX_DEPTH) + .mul(getTransform()); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderProgram.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderProgram.java index 774e6f3..aecc404 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderProgram.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/FlatRenderProgram.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.nio.FloatBuffer; @@ -33,10 +33,8 @@ public class FlatRenderProgram extends ShapeRenderProgram { private static FlatRenderProgram def = null; public static void init() { - def = new FlatRenderProgram( - new String[] { "FlatDefault.vertex.glsl" }, - new String[] { "FlatDefault.fragment.glsl" } - ); + def = new FlatRenderProgram(new String[] { "FlatDefault.vertex.glsl" }, + new String[] { "FlatDefault.fragment.glsl" }); } public static FlatRenderProgram getDefault() { @@ -48,20 +46,13 @@ public class FlatRenderProgram extends ShapeRenderProgram { private static final String FLAT_VERTEX_SHADER_RESOURCE = "Flat.vertex.glsl"; private static final String FLAT_FRAGMENT_SHADER_RESOURCE = "Flat.fragment.glsl"; - private static final String MASK_COUNT_UNIFORM_NAME = "maskCount", - MASKS_UNIFORM_NAME = "masks"; + private static final String MASK_COUNT_UNIFORM_NAME = "maskCount", MASKS_UNIFORM_NAME = "masks"; private final Uniform1Int maskCountUniform; private final Uniform2Float masksUniform; - public FlatRenderProgram( - String[] vertexShaderResources, - String[] fragmentShaderResources - ) { - super( - attachVertexShader(vertexShaderResources), - attachFragmentShader(fragmentShaderResources) - ); + public FlatRenderProgram(String[] vertexShaderResources, String[] fragmentShaderResources) { + super(attachVertexShader(vertexShaderResources), attachFragmentShader(fragmentShaderResources)); this.maskCountUniform = getUniform(MASK_COUNT_UNIFORM_NAME).as1Int(); this.masksUniform = getUniform(MASKS_UNIFORM_NAME).as2Float(); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/Mask.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/Mask.java index e13400a..2114c24 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/Mask.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/Mask.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; public class Mask { @@ -88,8 +88,7 @@ public class Mask { @Override public String toString() { - return "(" + getStartX() + "; " + getStartY() + - ") -> (" + getEndX() + "; " + getEndY() + ")"; + return "(" + getStartX() + "; " + getStartY() + ") -> (" + getEndX() + "; " + getEndY() + ")"; } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/MaskStack.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/MaskStack.java index f114058..5f0e23c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/MaskStack.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/MaskStack.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.nio.FloatBuffer; @@ -24,9 +24,8 @@ import org.lwjgl.BufferUtils; public class MaskStack { - private final FloatBuffer buffer = BufferUtils.createFloatBuffer( - FlatRenderProgram.MASK_STACK_SIZE * TransformedMask.SIZE_IN_FLOATS - ); + private final FloatBuffer buffer = BufferUtils + .createFloatBuffer(FlatRenderProgram.MASK_STACK_SIZE * TransformedMask.SIZE_IN_FLOATS); public void pushMask(TransformedMask mask) { mask.writeToBuffer(buffer); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java index 1fea54e..080b876 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/RenderTarget.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.util.ArrayList; @@ -45,11 +45,7 @@ public class RenderTarget { private final Mat4 transform; private final Renderable renderable; - public Clip( - Iterable masks, - Mat4 transform, - Renderable renderable - ) { + public Clip(Iterable masks, Mat4 transform, Renderable renderable) { for (TransformedMask mask : masks) { this.masks.pushMask(mask); } @@ -94,33 +90,19 @@ public class RenderTarget { protected void assembleCurrentClipFromFaces() { if (!currentClipFaces.isEmpty()) { - Face[] faces = currentClipFaces.toArray( - new Face[currentClipFaces.size()] - ); + Face[] faces = currentClipFaces.toArray(new Face[currentClipFaces.size()]); currentClipFaces.clear(); - Shape shape = new Shape( - Usage.STATIC, - FlatRenderProgram.getDefault(), - faces - ); + Shape shape = new Shape(Usage.STATIC, FlatRenderProgram.getDefault(), faces); - assembled.add( - new Clip( - maskStack, - getTransform(), - shape - ) - ); + assembled.add(new Clip(maskStack, getTransform(), shape)); } } public Clip[] assemble() { assembleCurrentClipFromFaces(); - Clip[] result = assembled.toArray( - new Clip[assembled.size()] - ); + Clip[] result = assembled.toArray(new Clip[assembled.size()]); reset(); @@ -142,21 +124,11 @@ public class RenderTarget { pushTransform(new Mat4().identity().translate(startX, startY, 0)); - maskStack.push( - new TransformedMask( - new Mask(startX, startY, endX, endY), - getTransform() - ) - ); + maskStack.push(new TransformedMask(new Mask(startX, startY, endX, endY), getTransform())); } public void pushMask(Mask mask) { - pushMaskStartEnd( - mask.getStartX(), - mask.getStartY(), - mask.getEndX(), - mask.getEndY() - ); + pushMaskStartEnd(mask.getStartX(), mask.getStartY(), mask.getEndX(), mask.getEndY()); } public void pushMaskStartSize(int x, int y, int width, int height) { @@ -189,142 +161,58 @@ public class RenderTarget { public void addCustomRenderer(Renderable renderable) { assembleCurrentClipFromFaces(); - assembled.add( - new Clip( - maskStack, - getTransform(), - renderable - ) - ); + assembled.add(new Clip(maskStack, getTransform(), renderable)); } protected void addFaceToCurrentClip(Face face) { currentClipFaces.add(face); } - public void drawTexture( - int x, - int y, - int width, - int height, - Vec4 color, - Texture texture - ) { - addFaceToCurrentClip( - createRectagleFace(x, y, width, height, color, texture) - ); + public void drawTexture(int x, int y, int width, int height, Vec4 color, Texture texture) { + addFaceToCurrentClip(createRectagleFace(x, y, width, height, color, texture)); } - public void drawTexture( - int x, - int y, - int width, - int height, - int color, - Texture texture - ) { + public void drawTexture(int x, int y, int width, int height, int color, Texture texture) { drawTexture(x, y, width, height, Colors.toVector(color), texture); } - public void drawTexture( - int x, - int y, - int width, - int height, - Texture texture - ) { + public void drawTexture(int x, int y, int width, int height, Texture texture) { drawTexture(x, y, width, height, Colors.WHITE, texture); } - public void fill( - int x, - int y, - int width, - int height, - Vec4 color - ) { + public void fill(int x, int y, int width, int height, Vec4 color) { drawTexture(x, y, width, height, color, null); } - public void fill( - int x, - int y, - int width, - int height, - int color - ) { + public void fill(int x, int y, int width, int height, int color) { fill(x, y, width, height, Colors.toVector(color)); } public void fill(Vec4 color) { - fill( - Integer.MIN_VALUE / 2, - Integer.MIN_VALUE / 2, - Integer.MAX_VALUE, - Integer.MAX_VALUE, - color - ); + fill(Integer.MIN_VALUE / 2, Integer.MIN_VALUE / 2, Integer.MAX_VALUE, Integer.MAX_VALUE, color); } public void fill(int color) { fill(Colors.toVector(color)); } - public Face createRectagleFace( - int x, - int y, - int width, - int height, - Vec4 color, - Texture texture - ) { + public Face createRectagleFace(int x, int y, int width, int height, Vec4 color, Texture texture) { float depth = this.depth--; - return Faces.createRectangle( - FlatRenderProgram.getDefault(), - texture, - color, - new Vec3(x, y, depth), - new Vec3(width, 0, 0), - new Vec3(0, height, 0), - false - ); + return Faces.createRectangle(FlatRenderProgram.getDefault(), texture, color, new Vec3(x, y, depth), + new Vec3(width, 0, 0), new Vec3(0, height, 0), false); } - public Face createRectagleFace( - int x, - int y, - int width, - int height, - int color, - Texture texture - ) { + public Face createRectagleFace(int x, int y, int width, int height, int color, Texture texture) { return createRectagleFace(x, y, width, height, Colors.toVector(color), texture); } - public Shape createRectagle( - int x, - int y, - int width, - int height, - Vec4 color, - Texture texture - ) { - return new Shape( - Usage.STATIC, - FlatRenderProgram.getDefault(), - createRectagleFace(x, y, width, height, color, texture) - ); + public Shape createRectagle(int x, int y, int width, int height, Vec4 color, Texture texture) { + return new Shape(Usage.STATIC, FlatRenderProgram.getDefault(), + createRectagleFace(x, y, width, height, color, texture)); } - public Shape createRectagle( - int x, - int y, - int width, - int height, - int color, - Texture texture - ) { + public Shape createRectagle(int x, int y, int width, int height, int color, Texture texture) { return createRectagle(x, y, width, height, Colors.toVector(color), texture); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/flat/TransformedMask.java b/src/main/java/ru/windcorp/progressia/client/graphics/flat/TransformedMask.java index 5328cc8..0f17a52 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/flat/TransformedMask.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/flat/TransformedMask.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.flat; import java.nio.FloatBuffer; @@ -42,14 +42,8 @@ public class TransformedMask { private Vec4 endXstartY = null; private Vec4 endXendY = null; - public TransformedMask( - Vec2 origin, - Vec2 width, - Vec2 height, - Vec2 counterOrigin, - Vec2 counterWidth, - Vec2 counterHeight - ) { + public TransformedMask(Vec2 origin, Vec2 width, Vec2 height, Vec2 counterOrigin, Vec2 counterWidth, + Vec2 counterHeight) { set(origin, width, height, counterOrigin, counterWidth, counterHeight); } @@ -61,14 +55,8 @@ public class TransformedMask { // Do nothing } - public TransformedMask set( - Vec2 origin, - Vec2 width, - Vec2 height, - Vec2 counterOrigin, - Vec2 counterWidth, - Vec2 counterHeight - ) { + public TransformedMask set(Vec2 origin, Vec2 width, Vec2 height, Vec2 counterOrigin, Vec2 counterWidth, + Vec2 counterHeight) { this.origin.set(origin.x, origin.y); this.width.set(width.x, width.y); this.height.set(height.x, height.y); @@ -112,35 +100,17 @@ public class TransformedMask { } private void setFields() { - origin.set( - startXstartY.x, - startXstartY.y - ); + origin.set(startXstartY.x, startXstartY.y); - width.set( - endXstartY.x - startXstartY.x, - endXstartY.y - startXstartY.y - ); + width.set(endXstartY.x - startXstartY.x, endXstartY.y - startXstartY.y); - height.set( - startXendY.x - startXstartY.x, - startXendY.y - startXstartY.y - ); + height.set(startXendY.x - startXstartY.x, startXendY.y - startXstartY.y); - counterOrigin.set( - endXendY.x, - endXendY.y - ); + counterOrigin.set(endXendY.x, endXendY.y); - counterWidth.set( - startXendY.x - endXendY.x, - startXendY.y - endXendY.y - ); + counterWidth.set(startXendY.x - endXendY.x, startXendY.y - endXendY.y); - counterHeight.set( - endXstartY.x - endXendY.x, - endXstartY.y - endXendY.y - ); + counterHeight.set(endXstartY.x - endXendY.x, endXstartY.y - endXendY.y); } public void writeToBuffer(FloatBuffer output) { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java index 591ff83..c7524a4 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/Font.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.font; import java.util.function.Supplier; @@ -68,17 +68,11 @@ public class Font { return color; } - public Renderable assemble( - CharSequence chars, - float maxWidth - ) { + public Renderable assemble(CharSequence chars, float maxWidth) { return typeface.assembleStatic(chars, style, align, maxWidth, color); } - public Renderable assembleDynamic( - Supplier supplier, - float maxWidth - ) { + public Renderable assembleDynamic(Supplier supplier, float maxWidth) { return typeface.assembleDynamic(supplier, style, align, maxWidth, color); } @@ -102,7 +96,8 @@ public class Font { * Creates a new {@link Font} with the specified {@code style} exactly. This * object's style is ignored. * - * @param style the new style + * @param style + * the new style * @return the new font */ public Font withStyle(int style) { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifont.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifont.java index f28975d..6b687b2 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifont.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifont.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.font; import gnu.trove.map.TCharObjectMap; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java index 9ead1db..3725b91 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/GNUUnifontLoader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.font; import java.io.BufferedReader; @@ -73,7 +73,7 @@ public class GNUUnifontLoader { public static GNUUnifont load(Resource resource) { try (BufferedReader reader = createReader(resource)) { return createStream(reader).map(GNUUnifontLoader::parse).map(GNUUnifontLoader::addToAtlas) - .collect(Collectors.collectingAndThen(createMapper(), GNUUnifont::new)); + .collect(Collectors.collectingAndThen(createMapper(), GNUUnifont::new)); } catch (IOException | UncheckedIOException e) { throw CrashReports.report(e, "Could not load GNUUnifont"); } @@ -81,8 +81,7 @@ public class GNUUnifontLoader { private static BufferedReader createReader(Resource resource) throws IOException { return new BufferedReader( - new InputStreamReader(new GZIPInputStream(resource.getInputStream()), StandardCharsets.UTF_8) - ); + new InputStreamReader(new GZIPInputStream(resource.getInputStream()), StandardCharsets.UTF_8)); } private static Stream createStream(BufferedReader reader) { @@ -97,13 +96,8 @@ public class GNUUnifontLoader { char c = getChar(declar); - TextureDataEditor editor = new TextureDataEditor( - width, - GNUUnifont.HEIGHT, - width, - GNUUnifont.HEIGHT, - TEXTURE_SETTINGS - ); + TextureDataEditor editor = new TextureDataEditor(width, GNUUnifont.HEIGHT, width, GNUUnifont.HEIGHT, + TEXTURE_SETTINGS); for (int y = 0; y < GNUUnifont.HEIGHT; ++y) { for (int x = 0; x < width; ++x) { @@ -165,8 +159,7 @@ public class GNUUnifontLoader { if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) { throw new IOException( - "Illegal char in declar \"" + declar + "\" at index " + i + "; expected 0-9A-F" - ); + "Illegal char in declar \"" + declar + "\" at index " + i + "; expected 0-9A-F"); } } } @@ -190,18 +183,16 @@ public class GNUUnifontLoader { } private static Collector> createMapper() { - return Collector.of( - TCharObjectHashMap::new, + return Collector.of(TCharObjectHashMap::new, - (map, glyph) -> map.put(glyph.c, glyph.texture), + (map, glyph) -> map.put(glyph.c, glyph.texture), - (a, b) -> { - a.putAll(b); - return a; - }, + (a, b) -> { + a.putAll(b); + return a; + }, - Characteristics.UNORDERED - ); + Characteristics.UNORDERED); } private GNUUnifontLoader() { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java index 7920799..4b13a79 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/SpriteTypeface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.font; import java.util.ArrayList; @@ -105,13 +105,7 @@ public abstract class SpriteTypeface extends Typeface { public abstract ShapeRenderProgram getProgram(); @Override - public Vec2i getSize( - CharSequence chars, - int style, - float align, - float maxWidth, - Vec2i output - ) { + public Vec2i getSize(CharSequence chars, int style, float align, float maxWidth, Vec2i output) { if (output == null) output = new Vec2i(); @@ -141,19 +135,8 @@ public abstract class SpriteTypeface extends Typeface { } private Shape createCharShape(char c) { - return new Shape( - Usage.STATIC, - getProgram(), - Faces.createRectangle( - getProgram(), - getTexture(c), - Colors.WHITE, - Vectors.ZERO_3, - new Vec3(getWidth(c), 0, 0), - new Vec3(0, getHeight(), 0), - false - ) - ); + return new Shape(Usage.STATIC, getProgram(), Faces.createRectangle(getProgram(), getTexture(c), Colors.WHITE, + Vectors.ZERO_3, new Vec3(getWidth(c), 0, 0), new Vec3(0, getHeight(), 0), false)); } private class DynamicText implements Renderable, Drawer { @@ -164,19 +147,8 @@ public abstract class SpriteTypeface extends Typeface { private final float maxWidth; private final Vec4 color; - private final Renderable unitLine = new Shape( - Usage.STATIC, - getProgram(), - Faces.createRectangle( - getProgram(), - null, - Vectors.UNIT_4, - Vectors.ZERO_3, - new Vec3(1, 0, 0), - new Vec3(0, 1, 0), - false - ) - ); + private final Renderable unitLine = new Shape(Usage.STATIC, getProgram(), Faces.createRectangle(getProgram(), + null, Vectors.UNIT_4, Vectors.ZERO_3, new Vec3(1, 0, 0), new Vec3(0, 1, 0), false)); private class DynamicWorkspace extends Workspace { private ShapeRenderHelper renderer; @@ -190,13 +162,7 @@ public abstract class SpriteTypeface extends Typeface { private final DynamicWorkspace workspace = new DynamicWorkspace(); - public DynamicText( - Supplier supplier, - int style, - float align, - float maxWidth, - Vec4 color - ) { + public DynamicText(Supplier supplier, int style, float align, float maxWidth, Vec4 color) { this.supplier = supplier; this.style = style; this.align = align; @@ -297,25 +263,12 @@ public abstract class SpriteTypeface extends Typeface { workspace.width.sub(workspace.origin); workspace.height.sub(workspace.origin); - workspace.faces.add( - Faces.createRectangle( - getProgram(), - texture, - color, - workspace.origin, - workspace.width, - workspace.height, - false - ) - ); + workspace.faces.add(Faces.createRectangle(getProgram(), texture, color, workspace.origin, workspace.width, + workspace.height, false)); } public Renderable assemble() { - return new Shape( - Usage.STATIC, - getProgram(), - workspace.faces.toArray(new Face[workspace.faces.size()]) - ); + return new Shape(Usage.STATIC, getProgram(), workspace.faces.toArray(new Face[workspace.faces.size()])); } } @@ -328,13 +281,8 @@ public abstract class SpriteTypeface extends Typeface { } @Override - public Renderable assembleDynamic( - Supplier supplier, - int style, - float align, - float maxWidth, - Vec4 color - ) { + public Renderable assembleDynamic(Supplier supplier, int style, float align, float maxWidth, + Vec4 color) { return new DynamicText(supplier, style, align, maxWidth, color); } @@ -424,15 +372,8 @@ public abstract class SpriteTypeface extends Typeface { void drawRectangle(Vec2 size, Vec4 color, Mat4 transform); } - protected void draw( - CharSequence text, - Drawer drawer, - Workspace workspace, - int style, - float align, - float maxWidth, - Vec4 color - ) { + protected void draw(CharSequence text, Drawer drawer, Workspace workspace, int style, float align, float maxWidth, + Vec4 color) { workspace.text = text; workspace.toIndex = text.length(); workspace.align = align; @@ -489,12 +430,7 @@ public abstract class SpriteTypeface extends Typeface { return w.align * (w.totalSize.x - w.currentWidth); } - private static final float[][] OUTLINE_DIRECTIONS = new float[][] { - { 0, 1 }, - { 1, 0 }, - { -1, 0 }, - { 0, -1 } - }; + private static final float[][] OUTLINE_DIRECTIONS = new float[][] { { 0, 1 }, { 1, 0 }, { -1, 0 }, { 0, -1 } }; private void drawLine(Drawer drawer, Workspace workspace) { int style = workspace.styles.peek(); @@ -591,11 +527,8 @@ public abstract class SpriteTypeface extends Typeface { workspace.styles.pop(); } else { - throw new IllegalArgumentException( - "Style contains unknown flags " + Integer.toBinaryString( - (style & ~(Style.BOLD | Style.ITALIC | Style.SHADOW | Style.STRIKETHRU | Style.UNDERLINED)) - ) - ); + throw new IllegalArgumentException("Style contains unknown flags " + Integer.toBinaryString( + (style & ~(Style.BOLD | Style.ITALIC | Style.SHADOW | Style.STRIKETHRU | Style.UNDERLINED)))); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java index 3be5ebb..5cf83db 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/Typeface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.font; import java.util.function.Supplier; @@ -29,12 +29,8 @@ import ru.windcorp.progressia.common.util.Vectors; public abstract class Typeface extends Named { public static class Style { - public static final int BOLD = 1 << 0, - ITALIC = 1 << 1, - UNDERLINED = 1 << 2, - STRIKETHRU = 1 << 3, - SHADOW = 1 << 4, - OUTLINED = 1 << 5; + public static final int BOLD = 1 << 0, ITALIC = 1 << 1, UNDERLINED = 1 << 2, STRIKETHRU = 1 << 3, + SHADOW = 1 << 4, OUTLINED = 1 << 5; public static final int PLAIN = 0; @@ -71,40 +67,19 @@ public abstract class Typeface extends Named { super(name); } - public abstract Renderable assembleStatic( - CharSequence chars, - int style, - float align, - float maxWidth, - Vec4 color - ); + public abstract Renderable assembleStatic(CharSequence chars, int style, float align, float maxWidth, Vec4 color); - public abstract Renderable assembleDynamic( - Supplier supplier, - int style, - float align, - float maxWidth, - Vec4 color - ); + public abstract Renderable assembleDynamic(Supplier supplier, int style, float align, float maxWidth, + Vec4 color); - public int getWidth( - CharSequence chars, - int style, - float align, - float maxWidth - ) { + public int getWidth(CharSequence chars, int style, float align, float maxWidth) { Vec2i v = Vectors.grab2i(); v = getSize(chars, style, align, maxWidth, v); Vectors.release(v); return v.x; } - public int getHeight( - CharSequence chars, - int style, - float align, - float maxWidth - ) { + public int getHeight(CharSequence chars, int style, float align, float maxWidth) { Vec2i v = Vectors.grab2i(); v = getSize(chars, style, align, maxWidth, v); Vectors.release(v); @@ -113,13 +88,7 @@ public abstract class Typeface extends Named { public abstract int getLineHeight(); - public abstract Vec2i getSize( - CharSequence chars, - int style, - float align, - float maxWidth, - Vec2i result - ); + public abstract Vec2i getSize(CharSequence chars, int style, float align, float maxWidth, Vec2i result); public abstract boolean supports(char c); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/font/Typefaces.java b/src/main/java/ru/windcorp/progressia/client/graphics/font/Typefaces.java index ed9c7c4..813087d 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/font/Typefaces.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/font/Typefaces.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.font; public class Typefaces { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java index 4a131d8..05416e8 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui; import java.util.Collections; @@ -475,11 +475,8 @@ public class Component extends Named { eventBus.post(event); } - public void addListener( - Class type, - boolean handlesConsumed, - InputListener listener - ) { + public void addListener(Class type, boolean handlesConsumed, + InputListener listener) { if (inputBus == null) { inputBus = new InputBus(); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java index bddad7b..ff62027 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/DynamicLabel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui; import glm.mat._4.Mat4; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/GUILayer.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/GUILayer.java index 2e0981c..9a4c648 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/GUILayer.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/GUILayer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui; import ru.windcorp.progressia.client.graphics.flat.AssembledFlatLayer; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java index f7dbe33..cb074da 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Label.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui; import glm.mat._4.Mat4; @@ -95,13 +95,13 @@ public class Label extends Component { protected void assembleSelf(RenderTarget target) { float startX = getX() + font.getAlign() * (getWidth() - currentSize.x); - target.pushTransform( - new Mat4().identity().translate(startX, getY(), -1000) // TODO wtf - // is this - // magic - // <--- - .scale(2) - ); + target.pushTransform(new Mat4().identity().translate(startX, getY(), -1000) // TODO + // wtf + // is + // this + // magic + // <--- + .scale(2)); target.addCustomRenderer(font.assemble(currentText, maxWidth)); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Layout.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Layout.java index 8d5d84f..4d08ed4 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Layout.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Layout.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui; import glm.vec._2.i.Vec2i; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Panel.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Panel.java index 88e10f1..7f0cba9 100755 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Panel.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Panel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui; public class Panel extends Component { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildAddedEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildAddedEvent.java index f1611fe..9bbf93a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildAddedEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildAddedEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildEvent.java index a27cf79..0d63e38 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildRemovedEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildRemovedEvent.java index 897d787..ec2e46c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildRemovedEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ChildRemovedEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ComponentEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ComponentEvent.java index b1d1175..dbf6e1c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ComponentEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ComponentEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/FocusEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/FocusEvent.java index ff859f3..fe476c2 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/FocusEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/FocusEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HierarchyEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HierarchyEvent.java index d3a4984..5195c7e 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HierarchyEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HierarchyEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HoverEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HoverEvent.java index b1d63ad..1e788f9 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HoverEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/HoverEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ParentChangedEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ParentChangedEvent.java index a7d9d40..ca5556a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ParentChangedEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/event/ParentChangedEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.event; import ru.windcorp.progressia.client.graphics.gui.Component; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutAlign.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutAlign.java index d521914..422e108 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutAlign.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutAlign.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.layout; import static java.lang.Math.max; @@ -56,13 +56,8 @@ public class LayoutAlign implements Layout { size.x = min(size.x, cWidth); size.y = min(size.y, cHeight); - child.setBounds( - c.getX() + - (int) ((cWidth - size.x) * alignX) + margin, - c.getY() + - (int) ((cHeight - size.y) * alignY) + margin, - size - ); + child.setBounds(c.getX() + (int) ((cWidth - size.x) * alignX) + margin, + c.getY() + (int) ((cHeight - size.y) * alignY) + margin, size); }); } @@ -71,12 +66,10 @@ public class LayoutAlign implements Layout { public Vec2i calculatePreferredSize(Component c) { Vec2i result = new Vec2i(0, 0); - c.getChildren().stream() - .map(child -> child.getPreferredSize()) - .forEach(size -> { - result.x = max(size.x, result.x); - result.y = max(size.y, result.y); - }); + c.getChildren().stream().map(child -> child.getPreferredSize()).forEach(size -> { + result.x = max(size.x, result.x); + result.y = max(size.y, result.y); + }); result.x += 2 * margin; result.y += 2 * margin; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderHorizontal.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderHorizontal.java index 3e271de..05b9723 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderHorizontal.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderHorizontal.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.layout; import static java.lang.Math.max; @@ -26,9 +26,7 @@ import ru.windcorp.progressia.client.graphics.gui.Layout; public class LayoutBorderHorizontal implements Layout { - public static final String CENTER = "Center", - LEFT = "Left", - RIGHT = "Right"; + public static final String CENTER = "Center", LEFT = "Left", RIGHT = "Right"; private final int margin; @@ -51,32 +49,17 @@ public class LayoutBorderHorizontal implements Layout { if (child.getLayoutHint() == LEFT) { childSize = child.getPreferredSize(); left = childSize.x + margin; - child.setBounds( - c.getX(), - c.getY(), - childSize.x, - c.getHeight() - ); + child.setBounds(c.getX(), c.getY(), childSize.x, c.getHeight()); } else if (child.getLayoutHint() == RIGHT) { childSize = child.getPreferredSize(); right = childSize.x + margin; - child.setBounds( - c.getX() + c.getWidth() - childSize.x, - c.getY(), - childSize.x, - c.getHeight() - ); + child.setBounds(c.getX() + c.getWidth() - childSize.x, c.getY(), childSize.x, c.getHeight()); } } for (Component child : c.getChildren()) { if (child.getLayoutHint() == CENTER) { - child.setBounds( - c.getX() + left, - c.getY(), - c.getWidth() - left - right, - c.getHeight() - ); + child.setBounds(c.getX() + left, c.getY(), c.getWidth() - left - right, c.getHeight()); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderVertical.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderVertical.java index 0efcaa4..1d94db4 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderVertical.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutBorderVertical.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.layout; import static java.lang.Math.max; @@ -26,9 +26,7 @@ import ru.windcorp.progressia.client.graphics.gui.Layout; public class LayoutBorderVertical implements Layout { - public static final String CENTER = "Center", - UP = "Up", - DOWN = "Down"; + public static final String CENTER = "Center", UP = "Up", DOWN = "Down"; private final int margin; @@ -51,32 +49,17 @@ public class LayoutBorderVertical implements Layout { if (child.getLayoutHint() == UP) { childSize = child.getPreferredSize(); top = childSize.y + margin; - child.setBounds( - c.getX(), - c.getY(), - c.getWidth(), - childSize.y - ); + child.setBounds(c.getX(), c.getY(), c.getWidth(), childSize.y); } else if (child.getLayoutHint() == DOWN) { childSize = child.getPreferredSize(); bottom = childSize.y + margin; - child.setBounds( - c.getX(), - c.getY() + c.getHeight() - childSize.y, - c.getWidth(), - childSize.y - ); + child.setBounds(c.getX(), c.getY() + c.getHeight() - childSize.y, c.getWidth(), childSize.y); } } for (Component child : c.getChildren()) { if (child.getLayoutHint() == CENTER) { - child.setBounds( - c.getX(), - c.getY() + top, - c.getWidth(), - c.getHeight() - top - bottom - ); + child.setBounds(c.getX(), c.getY() + top, c.getWidth(), c.getHeight() - top - bottom); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutGrid.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutGrid.java index fa2cdfe..20aebc1 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutGrid.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutGrid.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.layout; import java.util.Arrays; @@ -98,16 +98,13 @@ public class LayoutGrid implements Layout { if (!isSummed) throw new IllegalStateException("Not summed yet"); - child.setBounds( - parent.getX() + columns[column], - parent.getY() + rows[row], + child.setBounds(parent.getX() + columns[column], parent.getY() + rows[row], - (column != (columns.length - 1) ? (columns[column + 1] - columns[column] - gap) - : (parent.getWidth() - margin - columns[column])), + (column != (columns.length - 1) ? (columns[column + 1] - columns[column] - gap) + : (parent.getWidth() - margin - columns[column])), - (row != (rows.length - 1) ? (rows[row + 1] - rows[row] - gap) - : (parent.getHeight() - margin - rows[row])) - ); + (row != (rows.length - 1) ? (rows[row + 1] - rows[row] - gap) + : (parent.getHeight() - margin - rows[row]))); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutHorizontal.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutHorizontal.java index 85c37fa..5ce33b4 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutHorizontal.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutHorizontal.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.layout; import static java.lang.Math.max; @@ -43,8 +43,7 @@ public class LayoutHorizontal implements Layout { @Override public void layout(Component c) { - int x = c.getX() + margin, - y = c.getY() + margin; + int x = c.getX() + margin, y = c.getY() + margin; int width; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutVertical.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutVertical.java index 6e48d69..d03e124 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutVertical.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/layout/LayoutVertical.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.gui.layout; import static java.lang.Math.max; @@ -43,8 +43,7 @@ public class LayoutVertical implements Layout { @Override public void layout(Component c) { - int x = c.getX() + margin, - y = c.getY() + c.getHeight(); + int x = c.getX() + margin, y = c.getY() + c.getHeight(); synchronized (c.getChildren()) { for (Component child : c.getChildren()) { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorEvent.java index 43dd965..8bc480b 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import glm.vec._2.d.Vec2d; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java index c87fc62..ccb107f 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/CursorMoveEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import glm.vec._2.Vec2; @@ -87,22 +87,14 @@ public class CursorMoveEvent extends CursorEvent { @Override public CursorMoveEvent snapshot() { - return new StaticMouseMoveEvent( - getPreviousPosition(), - getNewPosition(), - getTime() - ); + return new StaticMouseMoveEvent(getPreviousPosition(), getNewPosition(), getTime()); } private class StaticMouseMoveEvent extends CursorMoveEvent { private final Vec2d previousPosition = new Vec2d(); - public StaticMouseMoveEvent( - Vec2d previousPosition, - Vec2d newPosition, - double time - ) { + public StaticMouseMoveEvent(Vec2d previousPosition, Vec2d newPosition, double time) { super(newPosition, time); this.previousPosition.set(previousPosition.x, previousPosition.y); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/FrameResizeEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/FrameResizeEvent.java index 5589158..cf1a296 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/FrameResizeEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/FrameResizeEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import glm.vec._2.i.Vec2i; @@ -67,11 +67,7 @@ public class FrameResizeEvent extends InputEvent { private final Vec2i previousSize; - public StaticFrameResizeEvent( - Vec2i newSize, - Vec2i previousSize, - double time - ) { + public StaticFrameResizeEvent(Vec2i newSize, Vec2i previousSize, double time) { super(newSize, time); this.previousSize = previousSize; } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/InputEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/InputEvent.java index b0c2483..dc8a187 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/InputEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/InputEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; public abstract class InputEvent { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyEvent.java index 291b89e..c36e059 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import org.lwjgl.glfw.GLFW; @@ -27,13 +27,7 @@ public class KeyEvent extends InputEvent { protected int action; protected int mods; - protected KeyEvent( - int key, - int scancode, - int action, - int mods, - double time - ) { + protected KeyEvent(int key, int scancode, int action, int mods, double time) { super(time); this.key = key; this.scancode = scancode; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyMatcher.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyMatcher.java index 6fedcd6..6073a7b 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyMatcher.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/KeyMatcher.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import java.util.function.Predicate; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java index 3904f59..e0d6980 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/Keys.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import java.lang.reflect.Field; @@ -46,17 +46,12 @@ public class Keys { private static final String MOUSE_BUTTON_PREFIX = "GLFW_MOUSE_BUTTON_"; private static final Set IGNORE_FIELDS = new HashSet<>( - Arrays.asList( - "GLFW_KEY_UNKNOWN", - "GLFW_KEY_LAST", - "GLFW_MOUSE_BUTTON_LAST", - "GLFW_MOUSE_BUTTON_1", // Alias - // for - // LEFT - "GLFW_MOUSE_BUTTON_2", // Alias for RIGHT - "GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE - ) - ); + Arrays.asList("GLFW_KEY_UNKNOWN", "GLFW_KEY_LAST", "GLFW_MOUSE_BUTTON_LAST", "GLFW_MOUSE_BUTTON_1", // Alias + // for + // LEFT + "GLFW_MOUSE_BUTTON_2", // Alias for RIGHT + "GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE + )); static { initializeDictionary(); @@ -100,14 +95,8 @@ public class Keys { } if (CODES_TO_NAMES.containsKey(value)) { - throw CrashReports.report( - null, - "Duplicate keys: %s and %s both map to %d(0x%s)", - CODES_TO_NAMES.get(value), - name, - value, - Integer.toHexString(value) - ); + throw CrashReports.report(null, "Duplicate keys: %s and %s both map to %d(0x%s)", CODES_TO_NAMES.get(value), + name, value, Integer.toHexString(value)); } CODES_TO_NAMES.put(value, name); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelEvent.java index 24938c3..80c5282 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; public abstract class WheelEvent extends InputEvent { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelScrollEvent.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelScrollEvent.java index 968ff64..0ba2d2b 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelScrollEvent.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/WheelScrollEvent.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input; import glm.vec._2.d.Vec2d; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/Input.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/Input.java index 1aad6bb..46da738 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/Input.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/Input.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input.bus; import ru.windcorp.progressia.client.graphics.input.InputEvent; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputBus.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputBus.java index a22a243..665831f 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputBus.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputBus.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input.bus; import java.util.ArrayList; @@ -31,28 +31,21 @@ public class InputBus { private final boolean handleConsumed; private final InputListener listener; - public WrappedListener( - Class type, - boolean handleConsumed, - InputListener listener - ) { + public WrappedListener(Class type, boolean handleConsumed, InputListener listener) { this.type = type; this.handleConsumed = handleConsumed; this.listener = listener; } private boolean handles(Input input) { - return (!input.isConsumed() || handleConsumed) && - type.isInstance(input.getEvent()); + return (!input.isConsumed() || handleConsumed) && type.isInstance(input.getEvent()); } @SuppressWarnings("unchecked") public void handle(Input input) { if (handles(input)) { boolean consumed = ((InputListener) listener) - .handle( - (InputEvent) type.cast(input.getEvent()) - ); + .handle((InputEvent) type.cast(input.getEvent())); input.setConsumed(consumed); } @@ -66,18 +59,12 @@ public class InputBus { listeners.forEach(l -> l.handle(input)); } - public void register( - Class type, - boolean handlesConsumed, - InputListener listener - ) { + public void register(Class type, boolean handlesConsumed, + InputListener listener) { listeners.add(new WrappedListener(type, handlesConsumed, listener)); } - public void register( - Class type, - InputListener listener - ) { + public void register(Class type, InputListener listener) { register(type, false, listener); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputListener.java b/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputListener.java index 0d68b5e..f6e3811 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputListener.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/input/bus/InputListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.input.bus; import ru.windcorp.progressia.client.graphics.input.InputEvent; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java index 3b929c0..e850d1a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/BlockFaceVectors.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import static ru.windcorp.progressia.common.world.block.BlockFace.*; @@ -38,60 +38,40 @@ class BlockFaceVectors { Vec3 width = outer.getWidth(face); Vec3 height = outer.getHeight(face); - originBuilder.put( - face, - new Vec3(outer.getOrigin(face)) - ); + originBuilder.put(face, new Vec3(outer.getOrigin(face))); widthBuilder.put(face, new Vec3(width)); heightBuilder.put(face, new Vec3(height)); } - return new BlockFaceVectors( - originBuilder.build(), - widthBuilder.build(), - heightBuilder.build() - ); + return new BlockFaceVectors(originBuilder.build(), widthBuilder.build(), heightBuilder.build()); } private static final BlockFaceVectors OUTER; private static final BlockFaceVectors INNER; static { - OUTER = new BlockFaceVectors( - ImmutableMap.builder() + OUTER = new BlockFaceVectors(ImmutableMap.builder() - .put(TOP, new Vec3(-0.5f, +0.5f, +0.5f)) - .put(BOTTOM, new Vec3(-0.5f, -0.5f, -0.5f)) - .put(NORTH, new Vec3(+0.5f, -0.5f, -0.5f)) - .put(SOUTH, new Vec3(-0.5f, +0.5f, -0.5f)) - .put(WEST, new Vec3(+0.5f, +0.5f, -0.5f)) - .put(EAST, new Vec3(-0.5f, -0.5f, -0.5f)) + .put(TOP, new Vec3(-0.5f, +0.5f, +0.5f)).put(BOTTOM, new Vec3(-0.5f, -0.5f, -0.5f)) + .put(NORTH, new Vec3(+0.5f, -0.5f, -0.5f)).put(SOUTH, new Vec3(-0.5f, +0.5f, -0.5f)) + .put(WEST, new Vec3(+0.5f, +0.5f, -0.5f)).put(EAST, new Vec3(-0.5f, -0.5f, -0.5f)) .build(), - ImmutableMap.builder() + ImmutableMap.builder() - .put(TOP, new Vec3(0, -1, 0)) - .put(BOTTOM, new Vec3(0, +1, 0)) - .put(NORTH, new Vec3(0, +1, 0)) - .put(SOUTH, new Vec3(0, -1, 0)) - .put(WEST, new Vec3(-1, 0, 0)) - .put(EAST, new Vec3(+1, 0, 0)) + .put(TOP, new Vec3(0, -1, 0)).put(BOTTOM, new Vec3(0, +1, 0)).put(NORTH, new Vec3(0, +1, 0)) + .put(SOUTH, new Vec3(0, -1, 0)).put(WEST, new Vec3(-1, 0, 0)).put(EAST, new Vec3(+1, 0, 0)) - .build(), + .build(), - ImmutableMap.builder() + ImmutableMap.builder() - .put(TOP, new Vec3(+1, 0, 0)) - .put(BOTTOM, new Vec3(+1, 0, 0)) - .put(NORTH, new Vec3(0, 0, +1)) - .put(SOUTH, new Vec3(0, 0, +1)) - .put(WEST, new Vec3(0, 0, +1)) - .put(EAST, new Vec3(0, 0, +1)) + .put(TOP, new Vec3(+1, 0, 0)).put(BOTTOM, new Vec3(+1, 0, 0)).put(NORTH, new Vec3(0, 0, +1)) + .put(SOUTH, new Vec3(0, 0, +1)).put(WEST, new Vec3(0, 0, +1)).put(EAST, new Vec3(0, 0, +1)) - .build() - ); + .build()); INNER = createInner(OUTER); } @@ -104,11 +84,8 @@ class BlockFaceVectors { private final ImmutableMap widths; private final ImmutableMap heights; - public BlockFaceVectors( - ImmutableMap origins, - ImmutableMap widths, - ImmutableMap heights - ) { + public BlockFaceVectors(ImmutableMap origins, ImmutableMap widths, + ImmutableMap heights) { this.origins = origins; this.widths = widths; this.heights = heights; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/DynamicModel.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/DynamicModel.java index 9460bd7..80f880a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/DynamicModel.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/DynamicModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.util.ArrayList; @@ -33,22 +33,14 @@ public abstract class DynamicModel extends Model { private final Mat4[] transforms; private final boolean[] dynamics; - public DynamicModel( - Renderable[] parts, - Mat4[] transforms, - boolean[] dynamic - ) { + public DynamicModel(Renderable[] parts, Mat4[] transforms, boolean[] dynamic) { super(parts); this.transforms = transforms; this.dynamics = dynamic; } public DynamicModel(Builder builder) { - this( - builder.getParts(), - builder.getTransforms(), - builder.getDynamics() - ); + this(builder.getParts(), builder.getTransforms(), builder.getDynamics()); } @Override @@ -78,11 +70,7 @@ public abstract class DynamicModel extends Model { protected Builder() { } - private Builder addPart( - Renderable part, - Mat4 transform, - boolean isDynamic - ) { + private Builder addPart(Renderable part, Mat4 transform, boolean isDynamic) { parts.add(Objects.requireNonNull(part, "part")); transforms.add(Objects.requireNonNull(transform, "transform")); dynamics.add(isDynamic); @@ -90,22 +78,15 @@ public abstract class DynamicModel extends Model { return this; } - public Builder addStaticPart( - Renderable part, - Mat4 transform - ) { + public Builder addStaticPart(Renderable part, Mat4 transform) { return addPart(part, new Mat4(transform), false); } - public Builder addDynamicPart( - Renderable part - ) { + public Builder addDynamicPart(Renderable part) { return addPart(part, new Mat4(), true); } - public Builder addStaticPart( - Renderable part - ) { + public Builder addStaticPart(Renderable part) { return addStaticPart(part, IDENTITY); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/EmptyModel.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/EmptyModel.java index f9cff67..f3e40a0 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/EmptyModel.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/EmptyModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import glm.mat._4.Mat4; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java index 79da464..752c23a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Face.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.nio.ByteBuffer; @@ -40,20 +40,13 @@ public class Face implements Comparable { private ShortBuffer userIndices; private boolean userIndicesUpdated = true; - public Face( - Texture texture, - ByteBuffer vertices, - ShortBuffer indices - ) { + public Face(Texture texture, ByteBuffer vertices, ShortBuffer indices) { setTexture(texture); setVertices(vertices); setIndices(indices); } - public Face( - Texture texture, - ByteBuffer vertices - ) { + public Face(Texture texture, ByteBuffer vertices) { this(texture, vertices, null); } @@ -66,22 +59,16 @@ public class Face implements Comparable { private void checkVertices() { if (vertices.remaining() % getBytesPerVertex() != 0) { - throw new IllegalArgumentException( - "Invalid vertex buffer: " + - (vertices.remaining() % getBytesPerVertex()) + - " extra bytes after last vertex" - ); + throw new IllegalArgumentException("Invalid vertex buffer: " + (vertices.remaining() % getBytesPerVertex()) + + " extra bytes after last vertex"); } } private void checkIndices() { if (userIndices != GENERATE_SUCCESSIVE_LATER) { if (userIndices.remaining() % 3 != 0) { - throw new IllegalArgumentException( - "Invalid vertex indices: " + - (userIndices.remaining() % 3) + - " extra indices after last triangle" - ); + throw new IllegalArgumentException("Invalid vertex indices: " + (userIndices.remaining() % 3) + + " extra indices after last triangle"); } userIndices.mark(); @@ -91,21 +78,15 @@ public class Face implements Comparable { short index = userIndices.get(); if (index < 0 || index >= vertexCount) { throw new IllegalArgumentException( - "Invalid vertex index " + index + - " (" + vertexCount + " vertices available)" - ); + "Invalid vertex index " + index + " (" + vertexCount + " vertices available)"); } } userIndices.reset(); } else { if (getVertexCount() % 3 != 0) { - throw new IllegalArgumentException( - "Invalid vertices: " + - (getVertexCount() % 3) + - " extra indices after last triangle " + - "(indices are automatic)" - ); + throw new IllegalArgumentException("Invalid vertices: " + (getVertexCount() % 3) + + " extra indices after last triangle " + "(indices are automatic)"); } } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java index ee91544..7dc0356 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/FaceGroup.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -38,9 +38,8 @@ public class FaceGroup { for (int i = start; i < end; ++i) { Face face = faces[i]; - assert this.texture == null - ? (face.getTexture() == null) - : (face.getTexture().getSprite().getPrimitive() == this.texture); + assert this.texture == null ? (face.getTexture() == null) + : (face.getTexture().getSprite().getPrimitive() == this.texture); indexCount += face.getIndexCount(); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java index d1e9c07..42eb2c0 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Faces.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.nio.ShortBuffer; @@ -32,86 +32,30 @@ public class Faces { private Faces() { } - public static Face createRectangle( - ShapeRenderProgram program, - Texture texture, - Vec4 colorMultiplier, - Vec3 origin, - Vec3 width, - Vec3 height, - boolean flip - ) { + public static Face createRectangle(ShapeRenderProgram program, Texture texture, Vec4 colorMultiplier, Vec3 origin, + Vec3 width, Vec3 height, boolean flip) { VertexBuilder builder = program.getVertexBuilder(); - builder.addVertex( - origin, - colorMultiplier, - new Vec2(0, 0) - ).addVertex( - origin.add_(height), - colorMultiplier, - new Vec2(0, 1) - ).addVertex( - origin.add_(width), - colorMultiplier, - new Vec2(1, 0) - ).addVertex( - origin.add_(width).add(height), - colorMultiplier, - new Vec2(1, 1) - ); + builder.addVertex(origin, colorMultiplier, new Vec2(0, 0)) + .addVertex(origin.add_(height), colorMultiplier, new Vec2(0, 1)) + .addVertex(origin.add_(width), colorMultiplier, new Vec2(1, 0)) + .addVertex(origin.add_(width).add(height), colorMultiplier, new Vec2(1, 1)); - ShortBuffer buffer = flip ? ShortBuffer.wrap( - new short[] { - 0, - 1, - 3, - 0, - 3, - 2 - } - ) - : ShortBuffer.wrap( - new short[] { - 3, - 1, - 0, - 2, - 3, - 0 - } - ); + ShortBuffer buffer = flip ? ShortBuffer.wrap(new short[] { 0, 1, 3, 0, 3, 2 }) + : ShortBuffer.wrap(new short[] { 3, 1, 0, 2, 3, 0 }); - return new Face( - texture, - builder.assemble(), - buffer - ); + return new Face(texture, builder.assemble(), buffer); } - public static Face createBlockFace( - ShapeRenderProgram program, - Texture texture, - Vec4 colorMultiplier, - Vec3 blockCenter, - BlockFace face, - boolean inner - ) { + public static Face createBlockFace(ShapeRenderProgram program, Texture texture, Vec4 colorMultiplier, + Vec3 blockCenter, BlockFace face, boolean inner) { BlockFaceVectors vectors = BlockFaceVectors.get(inner); Vec3 origin = blockCenter.add_(vectors.getOrigin(face)); Vec3 width = vectors.getWidth(face); Vec3 height = vectors.getHeight(face); - return createRectangle( - program, - texture, - colorMultiplier, - origin, - width, - height, - inner - ); + return createRectangle(program, texture, colorMultiplier, origin, width, height, inner); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/LambdaModel.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/LambdaModel.java index 0ae31bf..b38df91 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/LambdaModel.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/LambdaModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.util.ArrayList; @@ -37,23 +37,13 @@ public class LambdaModel extends DynamicModel { private final TransformGetter[] getters; - public LambdaModel( - Renderable[] parts, - Mat4[] transforms, - boolean[] dynamic, - TransformGetter[] getters - ) { + public LambdaModel(Renderable[] parts, Mat4[] transforms, boolean[] dynamic, TransformGetter[] getters) { super(parts, transforms, dynamic); this.getters = getters; } public LambdaModel(Builder builder) { - this( - builder.getParts(), - builder.getTransforms(), - builder.getDynamics(), - builder.getGetters() - ); + this(builder.getParts(), builder.getTransforms(), builder.getDynamics(), builder.getGetters()); } @Override @@ -75,11 +65,7 @@ public class LambdaModel extends DynamicModel { protected Builder() { } - private Builder addPart( - Renderable part, - Mat4 transform, - TransformGetter getter - ) { + private Builder addPart(Renderable part, Mat4 transform, TransformGetter getter) { parts.add(Objects.requireNonNull(part, "part")); transforms.add(Objects.requireNonNull(transform, "transform")); dynamics.add(getter != null); @@ -88,23 +74,15 @@ public class LambdaModel extends DynamicModel { return this; } - public Builder addStaticPart( - Renderable part, - Mat4 transform - ) { + public Builder addStaticPart(Renderable part, Mat4 transform) { return addPart(part, new Mat4(transform), null); } - public Builder addDynamicPart( - Renderable part, - TransformGetter getter - ) { + public Builder addDynamicPart(Renderable part, TransformGetter getter) { return addPart(part, new Mat4(), getter); } - public Builder addStaticPart( - Renderable part - ) { + public Builder addStaticPart(Renderable part) { return addStaticPart(part, IDENTITY); } @@ -127,12 +105,8 @@ public class LambdaModel extends DynamicModel { } public static LambdaModel animate(Renderable model, TransformGetter transform) { - return new LambdaModel( - new Renderable[] { model }, - new Mat4[] { new Mat4() }, - new boolean[] { true }, - new TransformGetter[] { transform } - ); + return new LambdaModel(new Renderable[] { model }, new Mat4[] { new Mat4() }, new boolean[] { true }, + new TransformGetter[] { transform }); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Model.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Model.java index 47cd88b..5e59007 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Model.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Model.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import glm.mat._4.Mat4; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Renderable.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Renderable.java index 6063685..b379b75 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Renderable.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Renderable.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; public interface Renderable { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java index 145b149..3a29c74 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shape.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.nio.ByteBuffer; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderHelper.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderHelper.java index 67578f6..517c711 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderHelper.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderHelper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import glm.mat._4.Mat4; @@ -28,15 +28,10 @@ public class ShapeRenderHelper { protected static final int TRANSFORM_STACK_SIZE = 64; protected static final int COLOR_MULTIPLIER_STACK_SIZE = TRANSFORM_STACK_SIZE; - protected final StashingStack transformStack = new StashingStack<>( - TRANSFORM_STACK_SIZE, - Mat4::new - ); + protected final StashingStack transformStack = new StashingStack<>(TRANSFORM_STACK_SIZE, Mat4::new); - protected final StashingStack colorMultiplierStack = new StashingStack<>( - COLOR_MULTIPLIER_STACK_SIZE, - Vec4::new - ); + protected final StashingStack colorMultiplierStack = new StashingStack<>(COLOR_MULTIPLIER_STACK_SIZE, + Vec4::new); { transformStack.push().identity(); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java index e27bc77..13a33e8 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeRenderProgram.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.nio.ByteBuffer; @@ -43,19 +43,18 @@ import ru.windcorp.progressia.common.util.Vectors; public class ShapeRenderProgram extends Program { private static final int DEFAULT_BYTES_PER_VERTEX = 3 * Float.BYTES + // Position - 4 * Float.BYTES + // Color multiplier - 2 * Float.BYTES; // Texture coordinates + 4 * Float.BYTES + // Color multiplier + 2 * Float.BYTES; // Texture coordinates private static final String SHAPE_VERTEX_SHADER_RESOURCE = "Shape.vertex.glsl"; private static final String SHAPE_FRAGMENT_SHADER_RESOURCE = "Shape.fragment.glsl"; private static final String FINAL_TRANSFORM_UNIFORM_NAME = "finalTransform", - POSITIONS_ATTRIBUTE_NAME = "inputPositions", - UNIFORM_COLOR_MULTIPLER_ATTRIBUTE_NAME = "uniformColorMultiplier", - ATTRIBUTE_COLOR_MULTIPLER_ATTRIBUTE_NAME = "inputColorMultiplier", - TEXTURE_COORDS_ATTRIBUTE_NAME = "inputTextureCoords", - USE_TEXTURE_UNIFORM_NAME = "useTexture", - TEXTURE_SLOT_UNIFORM_NAME = "textureSlot"; + POSITIONS_ATTRIBUTE_NAME = "inputPositions", + UNIFORM_COLOR_MULTIPLER_ATTRIBUTE_NAME = "uniformColorMultiplier", + ATTRIBUTE_COLOR_MULTIPLER_ATTRIBUTE_NAME = "inputColorMultiplier", + TEXTURE_COORDS_ATTRIBUTE_NAME = "inputTextureCoords", USE_TEXTURE_UNIFORM_NAME = "useTexture", + TEXTURE_SLOT_UNIFORM_NAME = "textureSlot"; private final Uniform4Matrix finalTransformUniform; private final AttributeVertexArray positionsAttribute; @@ -65,21 +64,11 @@ public class ShapeRenderProgram extends Program { private final Uniform1Int useTextureUniform; private final Uniform1Int textureSlotUniform; - public ShapeRenderProgram( - String[] vertexShaderResources, - String[] fragmentShaderResources - ) { - super( - new CombinedShader( - attachVertexShader(vertexShaderResources) - ), - new CombinedShader( - attachFragmentShader(fragmentShaderResources) - ) - ); + public ShapeRenderProgram(String[] vertexShaderResources, String[] fragmentShaderResources) { + super(new CombinedShader(attachVertexShader(vertexShaderResources)), + new CombinedShader(attachFragmentShader(fragmentShaderResources))); - this.finalTransformUniform = getUniform(FINAL_TRANSFORM_UNIFORM_NAME) - .as4Matrix(); + this.finalTransformUniform = getUniform(FINAL_TRANSFORM_UNIFORM_NAME).as4Matrix(); this.positionsAttribute = getAttribute(POSITIONS_ATTRIBUTE_NAME).asVertexArray(); @@ -89,11 +78,9 @@ public class ShapeRenderProgram extends Program { this.textureCoordsAttribute = getAttribute(TEXTURE_COORDS_ATTRIBUTE_NAME).asVertexArray(); - this.useTextureUniform = getUniform(USE_TEXTURE_UNIFORM_NAME) - .as1Int(); + this.useTextureUniform = getUniform(USE_TEXTURE_UNIFORM_NAME).as1Int(); - this.textureSlotUniform = getUniform(TEXTURE_SLOT_UNIFORM_NAME) - .as1Int(); + this.textureSlotUniform = getUniform(TEXTURE_SLOT_UNIFORM_NAME).as1Int(); } private static String[] attachVertexShader(String[] others) { @@ -104,10 +91,7 @@ public class ShapeRenderProgram extends Program { return ObjectArrays.concat(SHAPE_FRAGMENT_SHADER_RESOURCE, others); } - public void render( - ShapeRenderHelper helper, - Shape shape - ) { + public void render(ShapeRenderHelper helper, Shape shape) { use(); configure(helper); @@ -145,34 +129,13 @@ public class ShapeRenderProgram extends Program { int vertexStride = getBytesPerVertex(); int offset = 0; - positionsAttribute.set( - 3, - GL11.GL_FLOAT, - false, - vertexStride, - vertices, - offset - ); + positionsAttribute.set(3, GL11.GL_FLOAT, false, vertexStride, vertices, offset); offset += 3 * Float.BYTES; - colorsAttribute.set( - 4, - GL11.GL_FLOAT, - false, - vertexStride, - vertices, - offset - ); + colorsAttribute.set(4, GL11.GL_FLOAT, false, vertexStride, vertices, offset); offset += 4 * Float.BYTES; - textureCoordsAttribute.set( - 2, - GL11.GL_FLOAT, - false, - vertexStride, - vertices, - offset - ); + textureCoordsAttribute.set(2, GL11.GL_FLOAT, false, vertexStride, vertices, offset); offset += 2 * Float.BYTES; return offset; @@ -193,12 +156,8 @@ public class ShapeRenderProgram extends Program { useTextureUniform.set(0); } - GL11.glDrawElements( - GL11.GL_TRIANGLES, - group.getIndexCount(), - GL11.GL_UNSIGNED_SHORT, - group.getByteOffsetOfIndices() - ); + GL11.glDrawElements(GL11.GL_TRIANGLES, group.getIndexCount(), GL11.GL_UNSIGNED_SHORT, + group.getByteOffsetOfIndices()); } public int getBytesPerVertex() { @@ -220,13 +179,9 @@ public class ShapeRenderProgram extends Program { Sprite sprite = face.getTexture().getSprite(); for (int i = 0; i < face.getVertexCount(); i++) { - int offset = vertices.position() + i * getBytesPerVertex() + (3 * Float.BYTES + - 4 * Float.BYTES); + int offset = vertices.position() + i * getBytesPerVertex() + (3 * Float.BYTES + 4 * Float.BYTES); - v.set( - vertices.getFloat(offset + 0 * Float.BYTES), - vertices.getFloat(offset + 1 * Float.BYTES) - ); + v.set(vertices.getFloat(offset + 0 * Float.BYTES), vertices.getFloat(offset + 1 * Float.BYTES)); v.mul(sprite.getSize()).add(sprite.getStart()); @@ -244,34 +199,11 @@ public class ShapeRenderProgram extends Program { } public static interface VertexBuilder { - VertexBuilder addVertex( - float x, - float y, - float z, - float r, - float g, - float b, - float tx, - float ty - ); + VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float tx, float ty); - VertexBuilder addVertex( - float x, - float y, - float z, - float r, - float g, - float b, - float a, - float tx, - float ty - ); + VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float a, float tx, float ty); - VertexBuilder addVertex( - Vec3 position, - Vec4 colorMultiplier, - Vec2 textureCoords - ); + VertexBuilder addVertex(Vec3 position, Vec4 colorMultiplier, Vec2 textureCoords); ByteBuffer assemble(); } @@ -293,84 +225,35 @@ public class ShapeRenderProgram extends Program { private final List vertices = new ArrayList<>(); @Override - public VertexBuilder addVertex( - float x, - float y, - float z, - float r, - float g, - float b, - float a, - float tx, - float ty - ) { - vertices.add( - new Vertex( - new Vec3(x, y, z), - new Vec4(r, g, b, a), - new Vec2(tx, ty) - ) - ); + public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float a, float tx, + float ty) { + vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, a), new Vec2(tx, ty))); return this; } @Override - public VertexBuilder addVertex( - float x, - float y, - float z, - float r, - float g, - float b, - float tx, - float ty - ) { - vertices.add( - new Vertex( - new Vec3(x, y, z), - new Vec4(r, g, b, 1f), - new Vec2(tx, ty) - ) - ); + public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float tx, float ty) { + vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, 1f), new Vec2(tx, ty))); return this; } @Override - public VertexBuilder addVertex( - Vec3 position, - Vec4 colorMultiplier, - Vec2 textureCoords - ) { - vertices.add( - new Vertex( - new Vec3(position), - new Vec4(colorMultiplier), - new Vec2(textureCoords) - ) - ); + public VertexBuilder addVertex(Vec3 position, Vec4 colorMultiplier, Vec2 textureCoords) { + vertices.add(new Vertex(new Vec3(position), new Vec4(colorMultiplier), new Vec2(textureCoords))); return this; } @Override public ByteBuffer assemble() { - ByteBuffer result = BufferUtils.createByteBuffer( - DEFAULT_BYTES_PER_VERTEX * vertices.size() - ); + ByteBuffer result = BufferUtils.createByteBuffer(DEFAULT_BYTES_PER_VERTEX * vertices.size()); for (Vertex v : vertices) { - result - .putFloat(v.position.x) - .putFloat(v.position.y) - .putFloat(v.position.z) - .putFloat(v.colorMultiplier.x) - .putFloat(v.colorMultiplier.y) - .putFloat(v.colorMultiplier.z) - .putFloat(v.colorMultiplier.w) - .putFloat(v.textureCoords.x) - .putFloat(v.textureCoords.y); + result.putFloat(v.position.x).putFloat(v.position.y).putFloat(v.position.z) + .putFloat(v.colorMultiplier.x).putFloat(v.colorMultiplier.y).putFloat(v.colorMultiplier.z) + .putFloat(v.colorMultiplier.w).putFloat(v.textureCoords.x).putFloat(v.textureCoords.y); } result.flip(); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java index 7ddd5d6..e361392 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/Shapes.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.util.Map; @@ -29,97 +29,37 @@ import ru.windcorp.progressia.common.world.block.BlockFace; public class Shapes { public static Shape createParallelepiped( - // Try saying that 10 times fast - ShapeRenderProgram program, + // Try saying that 10 times fast + ShapeRenderProgram program, - Vec3 origin, + Vec3 origin, - Vec3 width, - Vec3 height, - Vec3 depth, + Vec3 width, Vec3 height, Vec3 depth, - Vec4 colorMultiplier, + Vec4 colorMultiplier, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture, + Texture topTexture, Texture bottomTexture, Texture northTexture, Texture southTexture, Texture eastTexture, + Texture westTexture, - boolean flip - ) { + boolean flip) { - Face top = Faces.createRectangle( - program, - topTexture, - colorMultiplier, - origin.add_(height).add(width), - width.negate_(), - depth, - flip - ); + Face top = Faces.createRectangle(program, topTexture, colorMultiplier, origin.add_(height).add(width), + width.negate_(), depth, flip); - Face bottom = Faces.createRectangle( - program, - bottomTexture, - colorMultiplier, - origin, - width, - depth, - flip - ); + Face bottom = Faces.createRectangle(program, bottomTexture, colorMultiplier, origin, width, depth, flip); - Face north = Faces.createRectangle( - program, - northTexture, - colorMultiplier, - origin.add_(depth), - width, - height, - flip - ); + Face north = Faces.createRectangle(program, northTexture, colorMultiplier, origin.add_(depth), width, height, + flip); - Face south = Faces.createRectangle( - program, - southTexture, - colorMultiplier, - origin.add_(width), - width.negate_(), - height, - flip - ); + Face south = Faces.createRectangle(program, southTexture, colorMultiplier, origin.add_(width), width.negate_(), + height, flip); - Face east = Faces.createRectangle( - program, - eastTexture, - colorMultiplier, - origin, - depth, - height, - flip - ); + Face east = Faces.createRectangle(program, eastTexture, colorMultiplier, origin, depth, height, flip); - Face west = Faces.createRectangle( - program, - westTexture, - colorMultiplier, - origin.add_(width).add(depth), - depth.negate_(), - height, - flip - ); + Face west = Faces.createRectangle(program, westTexture, colorMultiplier, origin.add_(width).add(depth), + depth.negate_(), height, flip); - Shape result = new Shape( - Usage.STATIC, - program, - top, - bottom, - north, - south, - east, - west - ); + Shape result = new Shape(Usage.STATIC, program, top, bottom, north, south, east, west); return result; } @@ -145,15 +85,8 @@ public class Shapes { private boolean flip = false; - public PppBuilder( - ShapeRenderProgram program, - Texture top, - Texture bottom, - Texture north, - Texture south, - Texture east, - Texture west - ) { + public PppBuilder(ShapeRenderProgram program, Texture top, Texture bottom, Texture north, Texture south, + Texture east, Texture west) { this.program = program; this.topTexture = top; this.bottomTexture = bottom; @@ -163,19 +96,10 @@ public class Shapes { this.westTexture = west; } - public PppBuilder( - ShapeRenderProgram program, - Map textureMap - ) { - this( - program, - textureMap.get(BlockFace.TOP), - textureMap.get(BlockFace.BOTTOM), - textureMap.get(BlockFace.NORTH), - textureMap.get(BlockFace.SOUTH), - textureMap.get(BlockFace.EAST), - textureMap.get(BlockFace.WEST) - ); + public PppBuilder(ShapeRenderProgram program, Map textureMap) { + this(program, textureMap.get(BlockFace.TOP), textureMap.get(BlockFace.BOTTOM), + textureMap.get(BlockFace.NORTH), textureMap.get(BlockFace.SOUTH), textureMap.get(BlockFace.EAST), + textureMap.get(BlockFace.WEST)); } public PppBuilder(ShapeRenderProgram program, Texture texture) { @@ -266,21 +190,8 @@ public class Shapes { } public Shape create() { - return createParallelepiped( - program, - origin, - width, - height, - depth, - colorMultiplier, - topTexture, - bottomTexture, - northTexture, - southTexture, - eastTexture, - westTexture, - flip - ); + return createParallelepiped(program, origin, width, height, depth, colorMultiplier, topTexture, + bottomTexture, northTexture, southTexture, eastTexture, westTexture, flip); } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/StaticModel.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/StaticModel.java index 4c489d3..8c5ae87 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/StaticModel.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/StaticModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.model; import java.util.ArrayList; @@ -30,10 +30,7 @@ public class StaticModel extends Model { private final Mat4[] transforms; - public StaticModel( - Renderable[] parts, - Mat4[] transforms - ) { + public StaticModel(Renderable[] parts, Mat4[] transforms) { super(parts); this.transforms = transforms; } @@ -55,19 +52,14 @@ public class StaticModel extends Model { protected Builder() { } - public Builder addPart( - Renderable part, - Mat4 transform - ) { + public Builder addPart(Renderable part, Mat4 transform) { parts.add(Objects.requireNonNull(part, "part")); transforms.add(Objects.requireNonNull(transform, "transform")); return this; } - public Builder addPart( - Renderable part - ) { + public Builder addPart(Renderable part) { return addPart(part, IDENTITY); } @@ -78,7 +70,7 @@ public class StaticModel extends Model { private Mat4[] getTransforms() { return transforms.toArray(new Mat4[transforms.size()]); } - + public StaticModel build() { return new StaticModel(getParts(), getTransforms()); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java index 94ed270..7ebe8fb 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Atlases.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import java.io.IOException; @@ -87,11 +87,8 @@ public class Atlases { editor.draw(data, nextX, nextY); - Sprite result = new Sprite( - getPrimitive(), - toPrimitiveCoords(nextX, nextY), - toPrimitiveCoords(width, height) - ); + Sprite result = new Sprite(getPrimitive(), toPrimitiveCoords(nextX, nextY), + toPrimitiveCoords(width, height)); nextX += width; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java index a4f2881..31ecd52 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/ComplexTexture.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import java.util.Map; @@ -30,67 +30,27 @@ public class ComplexTexture { private final float assumedWidth; private final float assumedHeight; - public ComplexTexture( - TexturePrimitive primitive, - int abstractWidth, - int abstractHeight - ) { + public ComplexTexture(TexturePrimitive primitive, int abstractWidth, int abstractHeight) { this.primitive = primitive; - this.assumedWidth = abstractWidth - / (float) primitive.getWidth() * primitive.getBufferWidth(); + this.assumedWidth = abstractWidth / (float) primitive.getWidth() * primitive.getBufferWidth(); - this.assumedHeight = abstractHeight - / (float) primitive.getHeight() * primitive.getBufferHeight(); + this.assumedHeight = abstractHeight / (float) primitive.getHeight() * primitive.getBufferHeight(); } public Texture get(int x, int y, int width, int height) { - return new SimpleTexture( - new Sprite( - primitive, - new Vec2(x / assumedWidth, y / assumedHeight), - new Vec2(width / assumedWidth, height / assumedHeight) - ) - ); + return new SimpleTexture(new Sprite(primitive, new Vec2(x / assumedWidth, y / assumedHeight), + new Vec2(width / assumedWidth, height / assumedHeight))); } - public Map getCuboidTextures( - int x, - int y, - int width, - int height, - int depth - ) { - return BlockFace.mapToFaces( - get( - x + depth + width, - y + height + depth, - -width, - -depth - ), - get( - x + depth + width + width, - y + height + depth, - -width, - -depth - ), - get(x + depth, y, width, height), - get( - x + depth + width + depth, - y, - width, - height - ), - get(x, y, depth, height), - get(x + depth + width, y, depth, height) - ); + public Map getCuboidTextures(int x, int y, int width, int height, int depth) { + return BlockFace.mapToFaces(get(x + depth + width, y + height + depth, -width, -depth), + get(x + depth + width + width, y + height + depth, -width, -depth), get(x + depth, y, width, height), + get(x + depth + width + depth, y, width, height), get(x, y, depth, height), + get(x + depth + width, y, depth, height)); } - public Map getCuboidTextures( - int x, - int y, - int size - ) { + public Map getCuboidTextures(int x, int y, int size) { return getCuboidTextures(x, y, size, size, size); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTexture.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTexture.java index d772faa..f631f54 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTexture.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTexture.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; public class SimpleTexture extends Texture { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java index 12db086..b547a8a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/SimpleTextures.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import java.io.IOException; @@ -44,9 +44,7 @@ public class SimpleTextures { try { TextureDataEditor data = TextureLoader.loadPixels(resource, SETTINGS); - return new SimpleTexture( - new Sprite(new TexturePrimitive(data.getData())) - ); + return new SimpleTexture(new Sprite(new TexturePrimitive(data.getData()))); } catch (IOException e) { throw CrashReports.report(e, "Could not load texture %s", resource); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Sprite.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Sprite.java index fc13896..388c2dc 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Sprite.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Sprite.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import java.util.Objects; @@ -38,14 +38,8 @@ public class Sprite { } public Sprite(TexturePrimitive primitive) { - this( - primitive, - ORIGIN, - new Vec2( - primitive.getWidth() / (float) primitive.getBufferWidth(), - primitive.getHeight() / (float) primitive.getBufferHeight() - ) - ); + this(primitive, ORIGIN, new Vec2(primitive.getWidth() / (float) primitive.getBufferWidth(), + primitive.getHeight() / (float) primitive.getBufferHeight())); } public TexturePrimitive getPrimitive() { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Texture.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Texture.java index a4d89bf..3041679 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/Texture.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/Texture.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; public abstract class Texture { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureData.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureData.java index 0453984..891111b 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureData.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import static org.lwjgl.opengl.GL11.*; @@ -35,14 +35,8 @@ class TextureData { private final int width; private final int height; - public TextureData( - ByteBuffer data, - int bufferWidth, - int bufferHeight, - int width, - int height, - TextureSettings settings - ) { + public TextureData(ByteBuffer data, int bufferWidth, int bufferHeight, int width, int height, + TextureSettings settings) { this.data = data; this.width = width; this.height = height; @@ -66,16 +60,15 @@ class TextureData { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D( - GL_TEXTURE_2D, // Load 2D image - 0, // Not mipmapped - GL_RGBA, // Use RGBA - bufferWidth, // Width - bufferHeight, // Height - 0, // No border - GL_RGBA, // Use RGBA (required) - GL_UNSIGNED_BYTE, // Use unsigned bytes - data // Data buffer + glTexImage2D(GL_TEXTURE_2D, // Load 2D image + 0, // Not mipmapped + GL_RGBA, // Use RGBA + bufferWidth, // Width + bufferHeight, // Height + 0, // No border + GL_RGBA, // Use RGBA (required) + GL_UNSIGNED_BYTE, // Use unsigned bytes + data // Data buffer ); return handle; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureDataEditor.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureDataEditor.java index 7079f59..e52365c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureDataEditor.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureDataEditor.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import static ru.windcorp.progressia.client.graphics.texture.TextureUtil.BYTES_PER_PIXEL; @@ -28,21 +28,10 @@ public class TextureDataEditor { protected final TextureData data; - public TextureDataEditor( - int bufferWidth, - int bufferHeight, - int contentWidth, - int contentHeight, - TextureSettings settings - ) { - this.data = new TextureData( - BufferUtils.createByteBuffer(bufferWidth * bufferHeight * 4), - bufferWidth, - bufferHeight, - contentWidth, - contentHeight, - settings - ); + public TextureDataEditor(int bufferWidth, int bufferHeight, int contentWidth, int contentHeight, + TextureSettings settings) { + this.data = new TextureData(BufferUtils.createByteBuffer(bufferWidth * bufferHeight * 4), bufferWidth, + bufferHeight, contentWidth, contentHeight, settings); } public TextureDataEditor(TextureData data) { @@ -61,21 +50,13 @@ public class TextureDataEditor { TextureData t = getData(); ByteBuffer fromBuffer = getBuffer(); - ByteBuffer toBuffer = BufferUtils.createByteBuffer( - fromBuffer.capacity() - ); + ByteBuffer toBuffer = BufferUtils.createByteBuffer(fromBuffer.capacity()); copy(fromBuffer, 0, fromBuffer.capacity(), toBuffer); toBuffer.clear(); - return new TextureData( - toBuffer, - t.getBufferWidth(), - t.getBufferHeight(), - t.getContentWidth(), - t.getContentHeight(), - t.getSettings() - ); + return new TextureData(toBuffer, t.getBufferWidth(), t.getBufferHeight(), t.getContentWidth(), + t.getContentHeight(), t.getSettings()); } public TextureData createSnapshot(TextureData output) { @@ -114,16 +95,7 @@ public class TextureDataEditor { return getData().getSettings(); } - public void draw( - ByteBuffer src, - int srcWidth, - int srcX, - int srcY, - int dstX, - int dstY, - int width, - int height - ) { + public void draw(ByteBuffer src, int srcWidth, int srcX, int srcY, int dstX, int dstY, int width, int height) { ByteBuffer dst = getBuffer(); int position = src.position(); @@ -148,77 +120,20 @@ public class TextureDataEditor { } } - public void draw( - TextureData source, - int srcX, - int srcY, - int dstX, - int dstY, - int width, - int height - ) { - draw( - source.getData(), - source.getBufferWidth(), - srcX, - srcY, - dstX, - dstY, - width, - height - ); + public void draw(TextureData source, int srcX, int srcY, int dstX, int dstY, int width, int height) { + draw(source.getData(), source.getBufferWidth(), srcX, srcY, dstX, dstY, width, height); } - public void draw( - TextureData source, - int dstX, - int dstY - ) { - draw( - source, - 0, - 0, - dstX, - dstY, - source.getContentWidth(), - source.getContentHeight() - ); + public void draw(TextureData source, int dstX, int dstY) { + draw(source, 0, 0, dstX, dstY, source.getContentWidth(), source.getContentHeight()); } - public void draw( - TextureDataEditor source, - int srcX, - int srcY, - int dstX, - int dstY, - int width, - int height - ) { - draw( - source.getData(), - srcX, - srcY, - dstX, - dstY, - width, - height - ); + public void draw(TextureDataEditor source, int srcX, int srcY, int dstX, int dstY, int width, int height) { + draw(source.getData(), srcX, srcY, dstX, dstY, width, height); } - public void draw( - TextureDataEditor source, - int dstX, - int dstY - ) { - draw( - source, - 0, - 0, - dstX, - dstY, - source.getContentWidth(), - source.getContentHeight() - ); + public void draw(TextureDataEditor source, int dstX, int dstY) { + draw(source, 0, 0, dstX, dstY, source.getContentWidth(), source.getContentHeight()); } public void setPixel(int x, int y, int color) { @@ -237,12 +152,7 @@ public class TextureDataEditor { buffer.limit(buffer.position() + length * BYTES_PER_PIXEL); } - private static void copy( - ByteBuffer src, - int srcStart, - int srcEnd, - ByteBuffer dst - ) { + private static void copy(ByteBuffer src, int srcStart, int srcEnd, ByteBuffer dst) { int position = src.position(); int limit = src.limit(); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureLoader.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureLoader.java index 18f2326..d406c65 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureLoader.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureLoader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import java.awt.Graphics2D; @@ -31,11 +31,7 @@ import ru.windcorp.progressia.common.util.BinUtil; public class TextureLoader { - public static TextureDataEditor loadPixels( - InputStream compressed, - TextureSettings settings - ) - throws IOException { + public static TextureDataEditor loadPixels(InputStream compressed, TextureSettings settings) throws IOException { BufferedImage readResult = ImageIO.read(compressed); int width = readResult.getWidth(); @@ -44,10 +40,7 @@ public class TextureLoader { int bufferWidth = BinUtil.roundToGreaterPowerOf2(width); int bufferHeight = BinUtil.roundToGreaterPowerOf2(height); - WritableRaster raster = TextureUtil.createRaster( - bufferWidth, - bufferHeight - ); + WritableRaster raster = TextureUtil.createRaster(bufferWidth, bufferHeight); BufferedImage canvas = TextureUtil.createCanvas(raster); @@ -56,49 +49,22 @@ public class TextureLoader { try { g.setColor(TextureUtil.CANVAS_BACKGROUND); g.fillRect(0, 0, bufferWidth, bufferHeight); - g.drawImage( - readResult, - 0, - 0, - width, - height, - 0, - height, - width, - 0, // Flip the image - null - ); + g.drawImage(readResult, 0, 0, width, height, 0, height, width, 0, // Flip + // the + // image + null); } finally { g.dispose(); } - TextureDataEditor result = new TextureDataEditor( - bufferWidth, - bufferHeight, - width, - height, - settings - ); + TextureDataEditor result = new TextureDataEditor(bufferWidth, bufferHeight, width, height, settings); - result.draw( - TextureUtil.extractBytes(raster), - bufferWidth, - 0, - 0, - 0, - 0, - width, - height - ); + result.draw(TextureUtil.extractBytes(raster), bufferWidth, 0, 0, 0, 0, width, height); return result; } - public static TextureDataEditor loadPixels( - Resource resource, - TextureSettings settings - ) - throws IOException { + public static TextureDataEditor loadPixels(Resource resource, TextureSettings settings) throws IOException { return loadPixels(resource.getInputStream(), settings); } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java index a1895bb..62c981b 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TexturePrimitive.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import static org.lwjgl.opengl.GL11.*; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureSettings.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureSettings.java index 3dd43a4..0b75742 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureSettings.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureSettings.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; public class TextureSettings { diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureUtil.java b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureUtil.java index ea0fdee..72eab34 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureUtil.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/texture/TextureUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.texture; import java.awt.Color; @@ -39,35 +39,28 @@ public class TextureUtil { public static final Color CANVAS_BACKGROUND = new Color(0, true); - public static final ColorModel COLOR_MODEL = new ComponentColorModel( - ColorSpace.getInstance(ColorSpace.CS_sRGB), // Use RGB - null, // Use every bit - true, // Has alpha - false, // Not premultiplied - Transparency.TRANSLUCENT, // Can have any alpha - DataBuffer.TYPE_BYTE // Store bytewise + public static final ColorModel COLOR_MODEL = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), // Use + // RGB + null, // Use every bit + true, // Has alpha + false, // Not premultiplied + Transparency.TRANSLUCENT, // Can have any alpha + DataBuffer.TYPE_BYTE // Store bytewise ); private static final Hashtable BUFFERED_IMAGE_PROPERTIES = new Hashtable<>(); - public static WritableRaster createRaster( - int bufferWidth, - int bufferHeight - ) { - return Raster.createInterleavedRaster( - DataBuffer.TYPE_BYTE, // Storage model - bufferWidth, // Buffer width - bufferHeight, // Buffer height - BYTES_PER_PIXEL, // ARGB - null // Location (here (0; 0)) + public static WritableRaster createRaster(int bufferWidth, int bufferHeight) { + return Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, // Storage + // model + bufferWidth, // Buffer width + bufferHeight, // Buffer height + BYTES_PER_PIXEL, // ARGB + null // Location (here (0; 0)) ); } - public static WritableRaster createRaster( - ByteBuffer buffer, - int bufferWidth, - int bufferHeight - ) { + public static WritableRaster createRaster(ByteBuffer buffer, int bufferWidth, int bufferHeight) { final int bands = BYTES_PER_PIXEL; byte[] bytes = new byte[bufferWidth * bufferHeight * bands]; @@ -77,23 +70,21 @@ public class TextureUtil { DataBufferByte dataBuffer = new DataBufferByte(bytes, bytes.length); - return Raster.createInterleavedRaster( - dataBuffer, // The buffer - bufferWidth, // Buffer width - bufferHeight, // Buffer height - bands * bufferWidth, // Scanline stride - bands, // Pixel stride - new int[] { 0, 1, 2, 3 }, // Band offsets - null // Location (here (0; 0)) + return Raster.createInterleavedRaster(dataBuffer, // The buffer + bufferWidth, // Buffer width + bufferHeight, // Buffer height + bands * bufferWidth, // Scanline stride + bands, // Pixel stride + new int[] { 0, 1, 2, 3 }, // Band offsets + null // Location (here (0; 0)) ); } public static BufferedImage createCanvas(WritableRaster raster) { - return new BufferedImage( - COLOR_MODEL, // Color model - raster, // Backing raster - false, // Raster is not premultipied - BUFFERED_IMAGE_PROPERTIES // Properties + return new BufferedImage(COLOR_MODEL, // Color model + raster, // Backing raster + false, // Raster is not premultipied + BUFFERED_IMAGE_PROPERTIES // Properties ); } @@ -107,10 +98,7 @@ public class TextureUtil { return buffer; } - public static ByteBuffer extractBytes( - WritableRaster raster, - ByteBuffer output - ) { + public static ByteBuffer extractBytes(WritableRaster raster, ByteBuffer output) { byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData(); output.put(data); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java index 46b551c..c8faf61 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Camera.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import static java.lang.Math.*; @@ -42,10 +42,7 @@ public class Camera { void applyCameraRotation(Mat4 output); - public static Mode of( - Consumer offsetGetter, - Consumer rotator - ) { + public static Mode of(Consumer offsetGetter, Consumer rotator) { return new Mode() { @Override public void getCameraOffset(Vec3 output) { @@ -121,13 +118,8 @@ public class Camera { private void applyPerspective(WorldRenderHelper helper) { Mat4 previous = helper.getViewTransform(); - Glm.perspective( - computeFovY(), - GraphicsInterface.getAspectRatio(), - 0.01f, - 150.0f, - helper.pushViewTransform() - ).mul(previous); + Glm.perspective(computeFovY(), GraphicsInterface.getAspectRatio(), 0.01f, 150.0f, helper.pushViewTransform()) + .mul(previous); } private void rotateCoordinateSystem(WorldRenderHelper helper) { @@ -152,23 +144,14 @@ public class Camera { float pitch = anchor.getCameraPitch(); float yaw = anchor.getCameraYaw(); - helper.pushViewTransform() - .rotateY(-pitch) - .rotateZ(-yaw); + helper.pushViewTransform().rotateY(-pitch).rotateZ(-yaw); this.lastAnchorYaw = yaw; this.lastAnchorPitch = pitch; - this.lastAnchorLookingAt.set( - cos(pitch) * cos(yaw), - cos(pitch) * sin(yaw), - sin(pitch) - ); - this.lastAnchorUp.set( - cos(pitch + PI_F / 2) * cos(yaw), - cos(pitch + PI_F / 2) * sin(yaw), - sin(pitch + PI_F / 2) - ); + this.lastAnchorLookingAt.set(cos(pitch) * cos(yaw), cos(pitch) * sin(yaw), sin(pitch)); + this.lastAnchorUp.set(cos(pitch + PI_F / 2) * cos(yaw), cos(pitch + PI_F / 2) * sin(yaw), + sin(pitch + PI_F / 2)); } private void applyPosition(WorldRenderHelper helper) { @@ -194,11 +177,7 @@ public class Camera { if (widthOverHeight >= 1) { return fieldOfView; } else { - return (float) (2 * atan( - 1 / widthOverHeight - * - tan(fieldOfView / 2) - )); + return (float) (2 * atan(1 / widthOverHeight * tan(fieldOfView / 2))); } } @@ -234,9 +213,7 @@ public class Camera { if (modesCollection.isEmpty()) { throw new IllegalArgumentException( - "Anchor " + anchor + " returned no camera modes," - + " at least one required" - ); + "Anchor " + anchor + " returned no camera modes," + " at least one required"); } this.anchor = anchor; @@ -250,24 +227,8 @@ public class Camera { this.lastAnchorYaw = Float.NaN; this.lastAnchorPitch = Float.NaN; - this.lastCameraMatrix.set( - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN, - Float.NaN - ); + this.lastCameraMatrix.set(Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, + Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN, Float.NaN); this.lastAnchorLookingAt.set(Float.NaN); this.lastAnchorUp.set(Float.NaN); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java index d11ea92..6b34029 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/EntityAnchor.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import java.util.Collection; @@ -39,23 +39,16 @@ public class EntityAnchor implements Anchor { this.model = model; this.modes = ImmutableList.of( - // From viewpoint / first person - Mode.of(v -> v.set(0), m -> { - }), + // From viewpoint / first person + Mode.of(v -> v.set(0), m -> { + }), - // Third person, looking forward - Mode.of( - v -> v.set(-3.5f, +0.5f, 0), - m -> { - } - ), + // Third person, looking forward + Mode.of(v -> v.set(-3.5f, +0.5f, 0), m -> { + }), - // Third person, looking back - Mode.of( - v -> v.set(-3.5f, 0, 0), - m -> m.rotateZ((float) Math.PI) - ) - ); + // Third person, looking back + Mode.of(v -> v.set(-3.5f, 0, 0), m -> m.rotateZ((float) Math.PI))); } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index 317dfa2..ccc052a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import java.util.ArrayList; @@ -132,12 +132,8 @@ public class LayerWorld extends Layer { tmp_collideableList.clear(); tmp_collideableList.addAll(this.client.getWorld().getData().getEntities()); - Collider.performCollisions( - tmp_collideableList, - this.client.getWorld().getData(), - tickLength, - tmp_colliderWorkspace - ); + Collider.performCollisions(tmp_collideableList, this.client.getWorld().getData(), tickLength, + tmp_colliderWorkspace); } private static final Renderable SELECTION_BOX = tmp_createSelectionBox(); @@ -166,26 +162,14 @@ public class LayerWorld extends Layer { for (float phi = 0; phi < 2 * FloatMathUtil.PI_F; phi += FloatMathUtil.PI_F / 2) { Mat4 rot = new Mat4().identity().rotateZ(phi).scale(scale); - b.addPart( - new PppBuilder(p, (Texture) null).setOrigin( - new Vec3(-f - 0.5f, -f - 0.5f, -f - 0.5f) - ).setSize(f, f, 2 * f + 1).setColorMultiplier(color).create(), - rot - ); + b.addPart(new PppBuilder(p, (Texture) null).setOrigin(new Vec3(-f - 0.5f, -f - 0.5f, -f - 0.5f)) + .setSize(f, f, 2 * f + 1).setColorMultiplier(color).create(), rot); - b.addPart( - new PppBuilder(p, (Texture) null).setOrigin( - new Vec3(-f - 0.5f, -0.5f, -f - 0.5f) - ).setSize(f, 1, f).setColorMultiplier(color).create(), - rot - ); + b.addPart(new PppBuilder(p, (Texture) null).setOrigin(new Vec3(-f - 0.5f, -0.5f, -f - 0.5f)) + .setSize(f, 1, f).setColorMultiplier(color).create(), rot); - b.addPart( - new PppBuilder(p, (Texture) null).setOrigin( - new Vec3(-f - 0.5f, -0.5f, +0.5f) - ).setSize(f, 1, f).setColorMultiplier(color).create(), - rot - ); + b.addPart(new PppBuilder(p, (Texture) null).setOrigin(new Vec3(-f - 0.5f, -0.5f, +0.5f)).setSize(f, 1, f) + .setColorMultiplier(color).create(), rot); } return b.build(); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java index 620185b..7a4443a 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import ru.windcorp.progressia.client.Client; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java index cd4ba29..3d997ee 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/Selection.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import glm.vec._2.Vec2; diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderHelper.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderHelper.java index de17238..e677eaf 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderHelper.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderHelper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import glm.mat._4.Mat4; @@ -24,10 +24,7 @@ import ru.windcorp.progressia.common.util.StashingStack; public class WorldRenderHelper extends ShapeRenderHelper { - private final StashingStack viewTransformStack = new StashingStack<>( - TRANSFORM_STACK_SIZE, - Mat4::new - ); + private final StashingStack viewTransformStack = new StashingStack<>(TRANSFORM_STACK_SIZE, Mat4::new); { viewTransformStack.push().identity(); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java index 5e55297..3e7223c 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/WorldRenderProgram.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.graphics.world; import java.nio.ByteBuffer; @@ -44,10 +44,8 @@ public class WorldRenderProgram extends ShapeRenderProgram { private static WorldRenderProgram def = null; public static void init() { - def = new WorldRenderProgram( - new String[] { "WorldDefault.vertex.glsl" }, - new String[] { "WorldDefault.fragment.glsl" } - ); + def = new WorldRenderProgram(new String[] { "WorldDefault.vertex.glsl" }, + new String[] { "WorldDefault.fragment.glsl" }); } public static WorldRenderProgram getDefault() { @@ -55,33 +53,25 @@ public class WorldRenderProgram extends ShapeRenderProgram { } private static final int DEFAULT_BYTES_PER_VERTEX = 3 * Float.BYTES + // Position - 4 * Float.BYTES + // Color multiplier - 2 * Float.BYTES + // Texture coordinates - 3 * Float.BYTES; // Normals + 4 * Float.BYTES + // Color multiplier + 2 * Float.BYTES + // Texture coordinates + 3 * Float.BYTES; // Normals private static final String WORLD_VERTEX_SHADER_RESOURCE = "World.vertex.glsl"; private static final String WORLD_FRAGMENT_SHADER_RESOURCE = "World.fragment.glsl"; private static final String WORLD_TRANSFORM_UNIFORM_NAME = "worldTransform", - NORMALS_ATTRIBUTE_NAME = "inputNormals"; + NORMALS_ATTRIBUTE_NAME = "inputNormals"; private final Uniform4Matrix worldTransformUniform; private final AttributeVertexArray normalsAttribute; - public WorldRenderProgram( - String[] vertexShaderResources, - String[] fragmentShaderResources - ) { - super( - attachVertexShader(vertexShaderResources), - attachFragmentShader(fragmentShaderResources) - ); + public WorldRenderProgram(String[] vertexShaderResources, String[] fragmentShaderResources) { + super(attachVertexShader(vertexShaderResources), attachFragmentShader(fragmentShaderResources)); - this.worldTransformUniform = getUniform(WORLD_TRANSFORM_UNIFORM_NAME) - .as4Matrix(); + this.worldTransformUniform = getUniform(WORLD_TRANSFORM_UNIFORM_NAME).as4Matrix(); - this.normalsAttribute = getAttribute(NORMALS_ATTRIBUTE_NAME) - .asVertexArray(); + this.normalsAttribute = getAttribute(NORMALS_ATTRIBUTE_NAME).asVertexArray(); } private static String[] attachVertexShader(String[] others) { @@ -103,14 +93,7 @@ public class WorldRenderProgram extends ShapeRenderProgram { int vertexStride = getBytesPerVertex(); int offset = super.bindVertices(vertices); - normalsAttribute.set( - 3, - GL11.GL_FLOAT, - false, - vertexStride, - vertices, - offset - ); + normalsAttribute.set(3, GL11.GL_FLOAT, false, vertexStride, vertices, offset); offset += 3 * Float.BYTES; return offset; @@ -130,8 +113,7 @@ public class WorldRenderProgram extends ShapeRenderProgram { @Override public int getBytesPerVertex() { - return super.getBytesPerVertex() + - 3 * Float.BYTES; // Normals + return super.getBytesPerVertex() + 3 * Float.BYTES; // Normals } @Override @@ -171,12 +153,7 @@ public class WorldRenderProgram extends ShapeRenderProgram { Vectors.release(normal); } - private void computeOneNormal( - Vec3 a, - Vec3 b, - Vec3 c, - Vec3 normal - ) { + private void computeOneNormal(Vec3 a, Vec3 b, Vec3 c, Vec3 normal) { b.sub(a); c.sub(a); b.cross(c, normal); @@ -187,18 +164,14 @@ public class WorldRenderProgram extends ShapeRenderProgram { ByteBuffer vertices = face.getVertices(); int offset = vertices.position() + index * getBytesPerVertex(); - result.set( - vertices.getFloat(offset + 0 * Float.BYTES), - vertices.getFloat(offset + 1 * Float.BYTES), - vertices.getFloat(offset + 2 * Float.BYTES) - ); + result.set(vertices.getFloat(offset + 0 * Float.BYTES), vertices.getFloat(offset + 1 * Float.BYTES), + vertices.getFloat(offset + 2 * Float.BYTES)); } private void saveVertexNormal(Face face, int index, Vec3 normal) { ByteBuffer vertices = face.getVertices(); - int offset = vertices.position() + index * getBytesPerVertex() + (3 * Float.BYTES + - 4 * Float.BYTES + - 2 * Float.BYTES); + int offset = vertices.position() + index * getBytesPerVertex() + + (3 * Float.BYTES + 4 * Float.BYTES + 2 * Float.BYTES); vertices.putFloat(offset + 0 * Float.BYTES, normal.x); vertices.putFloat(offset + 1 * Float.BYTES, normal.y); @@ -231,87 +204,36 @@ public class WorldRenderProgram extends ShapeRenderProgram { private final List vertices = new ArrayList<>(); @Override - public VertexBuilder addVertex( - float x, - float y, - float z, - float r, - float g, - float b, - float tx, - float ty - ) { - vertices.add( - new Vertex( - new Vec3(x, y, z), - new Vec4(r, g, b, 1), - new Vec2(tx, ty) - ) - ); + public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float tx, float ty) { + vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, 1), new Vec2(tx, ty))); return this; } @Override - public VertexBuilder addVertex( - float x, - float y, - float z, - float r, - float g, - float b, - float a, - float tx, - float ty - ) { - vertices.add( - new Vertex( - new Vec3(x, y, z), - new Vec4(r, g, b, a), - new Vec2(tx, ty) - ) - ); + public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float a, float tx, + float ty) { + vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, a), new Vec2(tx, ty))); return this; } @Override - public VertexBuilder addVertex( - Vec3 position, - Vec4 colorMultiplier, - Vec2 textureCoords - ) { - vertices.add( - new Vertex( - new Vec3(position), - new Vec4(colorMultiplier), - new Vec2(textureCoords) - ) - ); + public VertexBuilder addVertex(Vec3 position, Vec4 colorMultiplier, Vec2 textureCoords) { + vertices.add(new Vertex(new Vec3(position), new Vec4(colorMultiplier), new Vec2(textureCoords))); return this; } @Override public ByteBuffer assemble() { - ByteBuffer result = BufferUtils.createByteBuffer( - DEFAULT_BYTES_PER_VERTEX * vertices.size() - ); + ByteBuffer result = BufferUtils.createByteBuffer(DEFAULT_BYTES_PER_VERTEX * vertices.size()); for (Vertex v : vertices) { - result - .putFloat(v.position.x) - .putFloat(v.position.y) - .putFloat(v.position.z) - .putFloat(v.colorMultiplier.x) - .putFloat(v.colorMultiplier.y) - .putFloat(v.colorMultiplier.z) - .putFloat(v.colorMultiplier.w) - .putFloat(v.textureCoords.x) - .putFloat(v.textureCoords.y) - .putFloat(Float.NaN) - .putFloat(Float.NaN) - .putFloat(Float.NaN); + result.putFloat(v.position.x).putFloat(v.position.y).putFloat(v.position.z) + .putFloat(v.colorMultiplier.x).putFloat(v.colorMultiplier.y).putFloat(v.colorMultiplier.z) + .putFloat(v.colorMultiplier.w).putFloat(v.textureCoords.x).putFloat(v.textureCoords.y) + .putFloat(Float.NaN).putFloat(Float.NaN).putFloat(Float.NaN); } result.flip(); diff --git a/src/main/java/ru/windcorp/progressia/client/localization/LocaleListener.java b/src/main/java/ru/windcorp/progressia/client/localization/LocaleListener.java index b7c1f54..8e06d9f 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/LocaleListener.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/LocaleListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; @FunctionalInterface diff --git a/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java b/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java index b61d000..e90ecd8 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/Localizer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; import java.lang.ref.WeakReference; @@ -35,7 +35,7 @@ public class Localizer { private final Map langList; private final Collection> listeners = Collections - .synchronizedCollection(new LinkedList<>()); + .synchronizedCollection(new LinkedList<>()); // lang list must be in the same folder as .lang files public Localizer(String langFolder) { diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java index a96d804..a1dfc92 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableString.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; import java.lang.ref.WeakReference; @@ -34,7 +34,7 @@ public abstract class MutableString { protected String data; protected final Collection> listeners = Collections - .synchronizedCollection(new LinkedList<>()); + .synchronizedCollection(new LinkedList<>()); private Collection myListeners = null; diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java index f31fbca..e16533e 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringConcat.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; public class MutableStringConcat extends MutableString { diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java index fddba06..07fad9d 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFormatter.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; import java.util.IllegalFormatException; diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java index d945618..82ae330 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringFunc.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; import java.util.function.Function; diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java index 583d9e5..32a6d68 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringLocalized.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; public class MutableStringLocalized extends MutableString { diff --git a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java index d7b0fae..fd6c8fd 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/MutableStringParented.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; public abstract class MutableStringParented extends MutableString { diff --git a/src/main/java/ru/windcorp/progressia/client/localization/Parser.java b/src/main/java/ru/windcorp/progressia/client/localization/Parser.java index 7d587dc..cdb220a 100644 --- a/src/main/java/ru/windcorp/progressia/client/localization/Parser.java +++ b/src/main/java/ru/windcorp/progressia/client/localization/Parser.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.localization; import ru.windcorp.jputil.chars.EscapeException; @@ -30,8 +30,7 @@ import java.util.Map; public class Parser { private String filePath; - static private final Escaper ESCAPER = new Escaper.EscaperBuilder() - .withChars("n", "\n").build(); + static private final Escaper ESCAPER = new Escaper.EscaperBuilder().withChars("n", "\n").build(); public Parser(String filePath) { this.filePath = filePath; @@ -43,11 +42,7 @@ public class Parser { public Map parse() { Map parsedData = new HashMap<>(); - try ( - Reader rawData = ResourceManager - .getResource(filePath) - .getReader() - ) { + try (Reader rawData = ResourceManager.getResource(filePath).getReader()) { int code; char c; StringBuilder stringBuilder = new StringBuilder(); @@ -88,10 +83,7 @@ public class Parser { stringBuilder.append(c); } } - parsedData.put( - ESCAPER.unescape(key), - ESCAPER.unescape(stringBuilder.toString()) - ); + parsedData.put(ESCAPER.unescape(key), ESCAPER.unescape(stringBuilder.toString())); stringBuilder.setLength(0); } } else if (c == '\n') { diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index 21f6098..43f883c 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world; import java.util.Collections; @@ -34,8 +34,7 @@ import ru.windcorp.progressia.common.world.block.BlockFace; import ru.windcorp.progressia.common.world.generic.GenericChunk; import ru.windcorp.progressia.common.world.tile.TileDataStack; -public class ChunkRender - implements GenericChunk { +public class ChunkRender implements GenericChunk { private final WorldRender world; private final ChunkData data; @@ -43,7 +42,7 @@ public class ChunkRender private final ChunkRenderModel model; private final Map tileRenderLists = Collections - .synchronizedMap(new WeakHashMap<>()); + .synchronizedMap(new WeakHashMap<>()); public ChunkRender(WorldRender world, ChunkData data) { this.world = world; @@ -58,9 +57,7 @@ public class ChunkRender @Override public BlockRender getBlock(Vec3i posInChunk) { - return BlockRenderRegistry.getInstance().get( - getData().getBlock(posInChunk).getId() - ); + return BlockRenderRegistry.getInstance().get(getData().getBlock(posInChunk).getId()); } @Override @@ -74,10 +71,7 @@ public class ChunkRender } private TileRenderStack getTileStackWrapper(TileDataStack tileDataList) { - return tileRenderLists.computeIfAbsent( - tileDataList, - TileRenderStackImpl::new - ); + return tileRenderLists.computeIfAbsent(tileDataList, TileRenderStackImpl::new); } public WorldRender getWorld() { diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 9653abe..d15ba68 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -39,9 +39,9 @@ import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.block.BlockFace; public class ChunkRenderModel implements Renderable { - + private final ChunkRender chunk; - + private final Collection optimizers = new ArrayList<>(); private Model model = null; @@ -51,44 +51,42 @@ public class ChunkRenderModel implements Renderable { @Override public void render(ShapeRenderHelper renderer) { - if (model == null) return; - - renderer.pushTransform().translate( - chunk.getX() * ChunkData.BLOCKS_PER_CHUNK, - chunk.getY() * ChunkData.BLOCKS_PER_CHUNK, - chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK - ); + if (model == null) + return; + + renderer.pushTransform().translate(chunk.getX() * ChunkData.BLOCKS_PER_CHUNK, + chunk.getY() * ChunkData.BLOCKS_PER_CHUNK, chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK); model.render(renderer); renderer.popTransform(); } - + public void update() { setupCROs(); - + StaticModel.Builder sink = StaticModel.builder(); - + optimizers.forEach(ChunkRenderOptimizer::startRender); - + chunk.forEachBiC(blockInChunk -> { processBlockAndTiles(blockInChunk, sink); }); - + for (ChunkRenderOptimizer optimizer : optimizers) { Renderable renderable = optimizer.endRender(); if (renderable != null) { sink.addPart(renderable); } } - + this.model = sink.build(); this.optimizers.clear(); } private void setupCROs() { Set ids = ChunkRenderOptimizerRegistry.getInstance().keySet(); - + for (String id : ids) { ChunkRenderOptimizer optimizer = ChunkRenderOptimizerRegistry.getInstance().create(id); optimizer.setup(chunk); @@ -98,7 +96,7 @@ public class ChunkRenderModel implements Renderable { private void processBlockAndTiles(Vec3i blockInChunk, Builder sink) { processBlock(blockInChunk, sink); - + for (BlockFace face : BlockFace.getFaces()) { processTileStack(blockInChunk, face, sink); } @@ -106,18 +104,16 @@ public class ChunkRenderModel implements Renderable { private void processBlock(Vec3i blockInChunk, Builder sink) { BlockRender block = chunk.getBlock(blockInChunk); - + if (block instanceof BlockRenderNone) { return; } - + if (block.needsOwnRenderable()) { - sink.addPart( - block.createRenderable(chunk.getData(), blockInChunk), - new Mat4().identity().translate(blockInChunk.x, blockInChunk.y, blockInChunk.z) - ); + sink.addPart(block.createRenderable(chunk.getData(), blockInChunk), + new Mat4().identity().translate(blockInChunk.x, blockInChunk.y, blockInChunk.z)); } - + processBlockWithCROs(block, blockInChunk); } @@ -129,26 +125,24 @@ public class ChunkRenderModel implements Renderable { private void processTileStack(Vec3i blockInChunk, BlockFace face, Builder sink) { TileRenderStack trs = chunk.getTilesOrNull(blockInChunk, face); - + if (trs == null || trs.isEmpty()) { return; } - + trs.forEach(tile -> processTile(tile, blockInChunk, face, sink)); } - private void processTile(TileRender tile, Vec3i blockInChunk, BlockFace face, Builder sink) { + private void processTile(TileRender tile, Vec3i blockInChunk, BlockFace face, Builder sink) { if (tile instanceof TileRenderNone) { return; } - + if (tile.needsOwnRenderable()) { - sink.addPart( - tile.createRenderable(chunk.getData(), blockInChunk, face), - new Mat4().identity().translate(blockInChunk.x, blockInChunk.y, blockInChunk.z) - ); + sink.addPart(tile.createRenderable(chunk.getData(), blockInChunk, face), + new Mat4().identity().translate(blockInChunk.x, blockInChunk.y, blockInChunk.z)); } - + processTileWithCROs(tile, blockInChunk, face); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java index c348498..8e0eb1d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world; import glm.vec._3.i.Vec3i; @@ -39,7 +39,7 @@ class ChunkUpdateListener implements ChunkDataListener { public void onChunkChanged(ChunkData chunk) { world.getChunk(chunk).markForUpdate(); } - + @Override public void onChunkLoaded(ChunkData chunk) { Vec3i cursor = new Vec3i(); @@ -49,37 +49,32 @@ class ChunkUpdateListener implements ChunkDataListener { world.markChunkForUpdate(cursor); } } - + @Override public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { onLocationChanged(chunk, blockInChunk); } - + @Override - public void onChunkTilesChanged( - ChunkData chunk, - Vec3i blockInChunk, - BlockFace face, - TileData tile, - boolean wasAdded - ) { + public void onChunkTilesChanged(ChunkData chunk, Vec3i blockInChunk, BlockFace face, TileData tile, + boolean wasAdded) { onLocationChanged(chunk, blockInChunk); } private void onLocationChanged(ChunkData chunk, Vec3i blockInChunk) { Vec3i chunkPos = Vectors.grab3i().set(chunk.getX(), chunk.getY(), chunk.getZ()); - + checkCoordinate(blockInChunk, chunkPos, VectorUtil.Axis.X); checkCoordinate(blockInChunk, chunkPos, VectorUtil.Axis.Y); checkCoordinate(blockInChunk, chunkPos, VectorUtil.Axis.Z); - + Vectors.release(chunkPos); } private void checkCoordinate(Vec3i blockInChunk, Vec3i chunkPos, VectorUtil.Axis axis) { int block = VectorUtil.get(blockInChunk, axis); int diff = 0; - + if (block == 0) { diff = -1; } else if (block == ChunkData.BLOCKS_PER_CHUNK - 1) { @@ -87,12 +82,12 @@ class ChunkUpdateListener implements ChunkDataListener { } else { return; } - + int previousChunkPos = VectorUtil.get(chunkPos, axis); VectorUtil.set(chunkPos, axis, previousChunkPos + diff); world.markChunkForUpdate(chunkPos); - + VectorUtil.set(chunkPos, axis, previousChunkPos); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java index 8be08c2..c8e63a9 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world; import java.util.Collection; @@ -47,7 +47,7 @@ import ru.windcorp.progressia.common.world.generic.ChunkSets; import ru.windcorp.progressia.common.world.generic.GenericWorld; public class WorldRender - implements GenericWorld { + implements GenericWorld { private final WorldData data; private final Client client; @@ -207,15 +207,11 @@ public class WorldRender } public EntityRenderable getEntityRenderable(EntityData entity) { - return entityModels.computeIfAbsent( - entity, - WorldRender::createEntityRenderable - ); + return entityModels.computeIfAbsent(entity, WorldRender::createEntityRenderable); } private static EntityRenderable createEntityRenderable(EntityData entity) { - return EntityRenderRegistry.getInstance().get(entity.getId()) - .createRenderable(entity); + return EntityRenderRegistry.getInstance().get(entity.getId()).createRenderable(entity); } public void markChunkForUpdate(Vec3i chunkPos) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java index d350fa8..9b6c7ca 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; @@ -32,9 +32,7 @@ public abstract class BlockRender extends Namespaced implements GenericBlock { } public void render(ShapeRenderHelper renderer) { - throw new UnsupportedOperationException( - "BlockRender.render() not implemented in " + this - ); + throw new UnsupportedOperationException("BlockRender.render() not implemented in " + this); } public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java index 84a2c4b..3f422f2 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.block; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java index e4d8723..5b2dc27 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderOpaqueCube.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -23,36 +23,13 @@ import ru.windcorp.progressia.common.world.block.BlockFace; public class BlockRenderOpaqueCube extends BlockRenderTexturedCube { - public BlockRenderOpaqueCube( - String id, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture - ) { - super( - id, - topTexture, - bottomTexture, - northTexture, - southTexture, - eastTexture, - westTexture - ); + public BlockRenderOpaqueCube(String id, Texture topTexture, Texture bottomTexture, Texture northTexture, + Texture southTexture, Texture eastTexture, Texture westTexture) { + super(id, topTexture, bottomTexture, northTexture, southTexture, eastTexture, westTexture); } public BlockRenderOpaqueCube(String id, Texture texture) { - this( - id, - texture, - texture, - texture, - texture, - texture, - texture - ); + this(id, texture, texture, texture, texture, texture, texture); } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderRegistry.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderRegistry.java index 29bac40..2caacba 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Atlases; @@ -37,11 +37,7 @@ public class BlockRenderRegistry extends NamespacedInstanceRegistry public static Texture getBlockTexture(String name) { return new SimpleTexture( - Atlases.getSprite( - ResourceManager.getTextureResource("blocks/" + name), - BLOCKS_ATLAS_GROUP - ) - ); + Atlases.getSprite(ResourceManager.getTextureResource("blocks/" + name), BLOCKS_ATLAS_GROUP)); } public static AtlasGroup getBlocksAtlasGroup() { diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java index 1042a46..d254798 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.block; import static ru.windcorp.progressia.common.world.block.BlockFace.*; @@ -40,21 +40,12 @@ import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.block.BlockFace; -public abstract class BlockRenderTexturedCube - extends BlockRender - implements BlockOptimizedSurface { +public abstract class BlockRenderTexturedCube extends BlockRender implements BlockOptimizedSurface { private final Map textures = new HashMap<>(); - public BlockRenderTexturedCube( - String id, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture - ) { + public BlockRenderTexturedCube(String id, Texture topTexture, Texture bottomTexture, Texture northTexture, + Texture southTexture, Texture eastTexture, Texture westTexture) { super(id); textures.put(TOP, topTexture); @@ -68,52 +59,39 @@ public abstract class BlockRenderTexturedCube public Texture getTexture(BlockFace blockFace) { return textures.get(blockFace); } - + public Vec4 getColorMultiplier(BlockFace blockFace) { return Colors.WHITE; } @Override - public final void getFaces( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, - boolean inner, - Consumer output, - Vec3 offset - ) { + public final void getFaces(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, boolean inner, + Consumer output, Vec3 offset) { output.accept(createFace(chunk, blockInChunk, blockFace, inner, offset)); } - - private Face createFace( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, - boolean inner, - Vec3 offset - ) { - return Faces.createBlockFace( - WorldRenderProgram.getDefault(), - getTexture(blockFace), - getColorMultiplier(blockFace), - offset, - blockFace, - inner - ); + + private Face createFace(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, boolean inner, Vec3 offset) { + return Faces.createBlockFace(WorldRenderProgram.getDefault(), getTexture(blockFace), + getColorMultiplier(blockFace), offset, blockFace, inner); } @Override public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { boolean opaque = isBlockOpaque(); - + Face[] faces = new Face[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; - + for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { faces[i] = createFace(chunk, blockInChunk, BlockFace.getFaces().get(i), false, Vectors.ZERO_3); } - + if (!opaque) { for (int i = 0; i < BLOCK_FACE_COUNT; ++i) { - faces[i + BLOCK_FACE_COUNT] = createFace(chunk, blockInChunk, BlockFace.getFaces().get(i), true, Vectors.ZERO_3); + faces[i + BLOCK_FACE_COUNT] = createFace(chunk, blockInChunk, BlockFace.getFaces().get(i), true, + Vectors.ZERO_3); } } - + return new Shape(Usage.STATIC, WorldRenderProgram.getDefault(), faces); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java index 7f3df03..944d451 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTransparentCube.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -23,36 +23,13 @@ import ru.windcorp.progressia.common.world.block.BlockFace; public class BlockRenderTransparentCube extends BlockRenderTexturedCube { - public BlockRenderTransparentCube( - String id, - Texture topTexture, - Texture bottomTexture, - Texture northTexture, - Texture southTexture, - Texture eastTexture, - Texture westTexture - ) { - super( - id, - topTexture, - bottomTexture, - northTexture, - southTexture, - eastTexture, - westTexture - ); + public BlockRenderTransparentCube(String id, Texture topTexture, Texture bottomTexture, Texture northTexture, + Texture southTexture, Texture eastTexture, Texture westTexture) { + super(id, topTexture, bottomTexture, northTexture, southTexture, eastTexture, westTexture); } public BlockRenderTransparentCube(String id, Texture texture) { - this( - id, - texture, - texture, - texture, - texture, - texture, - texture - ); + this(id, texture, texture, texture, texture, texture, texture); } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java index b684c6a..ddf923a 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizer.java @@ -35,10 +35,9 @@ import ru.windcorp.progressia.common.world.block.BlockFace; * tiles. An example of a CRO is {@link ChunkRenderOptimizerSurface}: it removes * block surfaces and tiles that it knows cannot be seen, thus significantly * reducing total polygon count. - *

    CRO lifecycle

    - * A CRO instance is created by {@link ChunkRenderOptimizerRegistry}. It may - * then be used to work on multiple chunks sequentially. Each chunk is processed - * in the following way: + *

    CRO lifecycle

    A CRO instance is created by + * {@link ChunkRenderOptimizerRegistry}. It may then be used to work on multiple + * chunks sequentially. Each chunk is processed in the following way: *
      *
    1. {@link #setup(ChunkRender)} is invoked to provide the {@link ChunkRender} * instance.
    2. @@ -63,7 +62,8 @@ public abstract class ChunkRenderOptimizer extends Namespaced { /** * Creates a new CRO instance with the specified ID. * - * @param id the ID of this CRO + * @param id + * the ID of this CRO */ public ChunkRenderOptimizer(String id) { super(id); @@ -74,7 +74,8 @@ public abstract class ChunkRenderOptimizer extends Namespaced { * specify the chunk. When overriding, {@code super.setup(chunk)} must be * invoked. * - * @param chunk the chunk that will be processed next + * @param chunk + * the chunk that will be processed next */ public void setup(ChunkRender chunk) { this.chunk = chunk; @@ -98,10 +99,11 @@ public abstract class ChunkRenderOptimizer extends Namespaced { * method is only invoked once per block. This method is not necessarily * invoked for each block. * - * @param block a {@link BlockRender} instance describing the block. - * It corresponds to - * {@code getChunk().getBlock(blockInChunk)}. - * @param blockInChunk the position of the block + * @param block + * a {@link BlockRender} instance describing the block. It + * corresponds to {@code getChunk().getBlock(blockInChunk)}. + * @param blockInChunk + * the position of the block */ public abstract void addBlock(BlockRender block, Vec3i blockInChunk); @@ -112,9 +114,12 @@ public abstract class ChunkRenderOptimizer extends Namespaced { * invoked for each tile. When multiple tiles in a tile stack are requested, * this method is invoked for lower tiles first. * - * @param tile a {@link BlockRender} instance describing the tile - * @param blockInChunk the position of the block that the tile belongs to - * @param blockFace the face that the tile belongs to + * @param tile + * a {@link BlockRender} instance describing the tile + * @param blockInChunk + * the position of the block that the tile belongs to + * @param blockFace + * the face that the tile belongs to */ public abstract void addTile(TileRender tile, Vec3i blockInChunk, BlockFace blockFace); diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerRegistry.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerRegistry.java index 7e4dc87..7676b4f 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerRegistry.java @@ -15,15 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.cro; import ru.windcorp.progressia.common.util.namespaces.NamespacedFactoryRegistry; public class ChunkRenderOptimizerRegistry extends NamespacedFactoryRegistry { - + private static final ChunkRenderOptimizerRegistry INSTANCE = new ChunkRenderOptimizerRegistry(); - + /** * @return the instance */ diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index 488938e..12b4275 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -56,32 +56,31 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { * The coordinates of the face vertices must be in chunk coordinate * system. * - * @param chunk the chunk that contains the requested face - * @param blockInChunk the block in chunk - * @param blockFace the requested face - * @param inner whether this face should be visible from inside - * ({@code true}) or outside ({@code false}) - * @param output a consumer that the created faces must be given - * to - * @param offset an additional offset that must be applied to all - * vertices + * @param chunk + * the chunk that contains the requested face + * @param blockInChunk + * the block in chunk + * @param blockFace + * the requested face + * @param inner + * whether this face should be visible from inside + * ({@code true}) or outside ({@code false}) + * @param output + * a consumer that the created faces must be given to + * @param offset + * an additional offset that must be applied to all vertices */ - void getFaces( - ChunkData chunk, - Vec3i blockInChunk, - BlockFace blockFace, - boolean inner, - Consumer output, - Vec3 offset /* kostyl 156% */ + void getFaces(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, boolean inner, Consumer output, + Vec3 offset /* kostyl 156% */ ); /** * Returns the opacity of the surface identified by the provided - * {@link BlockFace}. - * Opaque surfaces prevent surfaces behind them from being included in - * chunk models. + * {@link BlockFace}. Opaque surfaces prevent surfaces behind them from + * being included in chunk models. * - * @param blockFace the face to query + * @param blockFace + * the face to query * @return {@code true} iff the surface is opaque. */ boolean isOpaque(BlockFace blockFace); @@ -95,8 +94,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { /** * Returns the opacity of the block. Opaque blocks do not expect that * the camera can be inside them. Opaque blocks prevent surfaces that - * face them - * from being included in chunk models. + * face them from being included in chunk models. * * @return {@code true} iff the block is opaque. */ @@ -207,9 +205,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { @Override public Renderable endRender() { - Collection shapeFaces = new ArrayList<>( - BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * 3 - ); + Collection shapeFaces = new ArrayList<>(BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * 3); Vec3i cursor = new Vec3i(); Consumer consumer = shapeFaces::add; @@ -227,17 +223,11 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { return null; } - return new Shape( - Usage.STATIC, - WorldRenderProgram.getDefault(), - shapeFaces.toArray(new Face[shapeFaces.size()]) - ); + return new Shape(Usage.STATIC, WorldRenderProgram.getDefault(), + shapeFaces.toArray(new Face[shapeFaces.size()])); } - private void processOuterFaces( - Vec3i blockInChunk, - Consumer output - ) { + private void processOuterFaces(Vec3i blockInChunk, Consumer output) { for (BlockFace blockFace : BlockFace.getFaces()) { processOuterFace(blockInChunk, blockFace, output); } @@ -255,11 +245,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { Vec3 faceOrigin = new Vec3(blockInChunk.x, blockInChunk.y, blockInChunk.z); Vec3 offset = new Vec3(blockFace.getFloatVector()).mul(OVERLAY_OFFSET); - for ( - int layer = info.topOpaqueSurface; - layer < info.tileCount; - ++layer - ) { + for (int layer = info.topOpaqueSurface; layer < info.tileCount; ++layer) { OptimizedSurface surface = info.getSurface(layer); if (surface == null) continue; // layer may be BLOCK_LAYER, then block may be null @@ -270,10 +256,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { } } - private void processInnerFaces( - Vec3i blockInChunk, - Consumer output - ) { + private void processInnerFaces(Vec3i blockInChunk, Consumer output) { for (BlockFace blockFace : BlockFace.getFaces()) { processInnerFace(blockInChunk, blockFace, output); } @@ -291,11 +274,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { Vec3 faceOrigin = new Vec3(blockInChunk.x, blockInChunk.y, blockInChunk.z); Vec3 offset = new Vec3(blockFace.getFloatVector()).mul(OVERLAY_OFFSET); - for ( - int layer = FaceInfo.BLOCK_LAYER; - layer <= info.bottomOpaqueSurface && layer < info.tileCount; - ++layer - ) { + for (int layer = FaceInfo.BLOCK_LAYER; layer <= info.bottomOpaqueSurface && layer < info.tileCount; ++layer) { OptimizedSurface surface = info.getSurface(layer); if (surface == null) continue; // layer may be BLOCK_LAYER, then block may be null @@ -365,12 +344,8 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { blockInChunk.z = 0; chunkPos.z += 1; } else { - throw new AssertionError( - "Requested incorrent neighbor (" - + blockInLocalChunk.x + "; " - + blockInLocalChunk.y + "; " - + blockInLocalChunk.z + ")" - ); + throw new AssertionError("Requested incorrent neighbor (" + blockInLocalChunk.x + "; " + + blockInLocalChunk.y + "; " + blockInLocalChunk.z + ")"); } ChunkRender chunk = this.chunk.getWorld().getChunk(chunkPos); diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRender.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRender.java index 13a2b24..8243c9d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRender.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.entity; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java index 60b7bf6..e6ff550 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.entity; import java.io.IOException; @@ -37,14 +37,9 @@ public class EntityRenderRegistry extends NamespacedInstanceRegistry. */ - + package ru.windcorp.progressia.client.world.entity; import glm.vec._3.Vec3; diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java index 1609bfc..2f13407 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/HumanoidModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.entity; import static java.lang.Math.*; @@ -32,11 +32,7 @@ public class HumanoidModel extends NPedModel { protected static abstract class Limb extends BodyPart { private final float animationOffset; - public Limb( - Renderable renderable, - Vec3 joint, - float animationOffset - ) { + public Limb(Renderable renderable, Vec3 joint, float animationOffset) { super(renderable, joint); this.animationOffset = animationOffset; } @@ -54,11 +50,7 @@ public class HumanoidModel extends NPedModel { } public static class Leg extends Limb { - public Leg( - Renderable renderable, - Vec3 joint, - float animationOffset - ) { + public Leg(Renderable renderable, Vec3 joint, float animationOffset) { super(renderable, joint, animationOffset); } @@ -69,11 +61,7 @@ public class HumanoidModel extends NPedModel { } public static class Arm extends Limb { - public Arm( - Renderable renderable, - Vec3 joint, - float animationOffset - ) { + public Arm(Renderable renderable, Vec3 joint, float animationOffset) { super(renderable, joint, animationOffset); } @@ -91,18 +79,11 @@ public class HumanoidModel extends NPedModel { private float walkingLegSwing; private float walkingArmSwing; - public HumanoidModel( - EntityData entity, + public HumanoidModel(EntityData entity, - Body body, - Head head, - Arm leftArm, - Arm rightArm, - Leg leftLeg, - Leg rightLeg, + Body body, Head head, Arm leftArm, Arm rightArm, Leg leftLeg, Leg rightLeg, - float scale - ) { + float scale) { super(entity, body, head, scale); this.leftArm = leftArm; this.rightArm = rightArm; diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java index ead6565..33bef76 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/NPedModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.entity; import static java.lang.Math.atan2; @@ -47,10 +47,7 @@ public abstract class NPedModel extends EntityRenderable { } } - protected void render( - ShapeRenderHelper renderer, - NPedModel model - ) { + protected void render(ShapeRenderHelper renderer, NPedModel model) { renderer.pushTransform().translate(translation); applyTransform(renderer.pushTransform(), model); renderable.render(renderer); @@ -82,13 +79,7 @@ public abstract class NPedModel extends EntityRenderable { private final Vec3 viewPoint; - public Head( - Renderable renderable, - Vec3 joint, - double maxYawDegrees, - double maxPitchDegrees, - Vec3 viewPoint - ) { + public Head(Renderable renderable, Vec3 joint, double maxYawDegrees, double maxPitchDegrees, Vec3 viewPoint) { super(renderable, joint); this.maxYaw = (float) toRadians(maxYawDegrees); this.maxPitch = (float) toRadians(maxPitchDegrees); @@ -176,11 +167,7 @@ public abstract class NPedModel extends EntityRenderable { bodyYaw = normalizeAngle(bodyYaw); - headPitch = Glm.clamp( - getData().getPitch(), - -head.maxPitch, - head.maxPitch - ); + headPitch = Glm.clamp(getData().getPitch(), -head.maxPitch, head.maxPitch); } private void accountForVelocity() { @@ -194,9 +181,8 @@ public abstract class NPedModel extends EntityRenderable { // TODO switch to world time walkingParameter += velocity * GraphicsInterface.getFrameLength() * 1000; - bodyYaw += velocityParameter * normalizeAngle( - (float) (atan2(horizontal.y, horizontal.x) - bodyYaw) - ) * min(1, GraphicsInterface.getFrameLength() * 10); + bodyYaw += velocityParameter * normalizeAngle((float) (atan2(horizontal.y, horizontal.x) - bodyYaw)) + * min(1, GraphicsInterface.getFrameLength() * 10); } private void evaluateVelocityCoeff() { @@ -212,12 +198,7 @@ public abstract class NPedModel extends EntityRenderable { Mat4 m = new Mat4(); Vec4 v = new Vec4(); - m.identity() - .scale(scale) - .rotateZ(bodyYaw) - .translate(head.getTranslation()) - .rotateZ(headYaw) - .rotateY(headPitch); + m.identity().scale(scale).rotateZ(bodyYaw).translate(head.getTranslation()).rotateZ(headYaw).rotateY(headPitch); v.set(head.getViewPoint(), 1); m.mul(v); @@ -247,9 +228,8 @@ public abstract class NPedModel extends EntityRenderable { /** * Returns a number in the range [0; 1] that can be used to scale animation - * effects that depend on speed. - * This parameter is 0 when the entity is not moving and 1 when it's moving - * "fast". + * effects that depend on speed. This parameter is 0 when the entity is not + * moving and 1 when it's moving "fast". * * @return velocity parameter */ @@ -259,9 +239,8 @@ public abstract class NPedModel extends EntityRenderable { /** * Returns a number that can be used to parameterize animation effects that - * depend on walking. - * This parameter increases when the entity moves (e.g. this can be total - * traveled distance). + * depend on walking. This parameter increases when the entity moves (e.g. + * this can be total traveled distance). * * @return walking parameter */ diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java b/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java index 8755b08..d31579f 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/QuadripedModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.entity; import static java.lang.Math.*; @@ -33,11 +33,7 @@ public class QuadripedModel extends NPedModel { public static class Leg extends BodyPart { private final float animationOffset; - public Leg( - Renderable renderable, - Vec3 joint, - float animationOffset - ) { + public Leg(Renderable renderable, Vec3 joint, float animationOffset) { super(renderable, joint); this.animationOffset = animationOffset; } @@ -57,18 +53,11 @@ public class QuadripedModel extends NPedModel { private float walkingSwing = (float) toRadians(30); - public QuadripedModel( - EntityData entity, + public QuadripedModel(EntityData entity, - Body body, - Head head, - Leg leftForeLeg, - Leg rightForeLeg, - Leg leftHindLeg, - Leg rightHindLeg, + Body body, Head head, Leg leftForeLeg, Leg rightForeLeg, Leg leftHindLeg, Leg rightHindLeg, - float scale - ) { + float scale) { super(entity, body, head, scale); this.leftForeLeg = leftForeLeg; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java index 4f82d86..7cc3615 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; @@ -34,9 +34,7 @@ public class TileRender extends Namespaced implements GenericTile { } public void render(ShapeRenderHelper renderer, BlockFace face) { - throw new UnsupportedOperationException( - "TileRender.render() not implemented in " + this - ); + throw new UnsupportedOperationException("TileRender.render() not implemented in " + this); } public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, BlockFace face) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java index c73647b..e50d8d4 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderGrass.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; @@ -26,11 +26,7 @@ public class TileRenderGrass extends TileRenderSurface { private final Texture topTexture; private final Texture sideTexture; - public TileRenderGrass( - String id, - Texture top, - Texture side - ) { + public TileRenderGrass(String id, Texture top, Texture side) { super(id); this.topTexture = top; this.sideTexture = side; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java index 8e2a6e4..56ea3cb 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java @@ -28,12 +28,12 @@ public class TileRenderNone extends TileRender { public TileRenderNone(String id) { super(id); } - + @Override public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, BlockFace face) { return EmptyModel.getInstance(); } - + @Override public boolean needsOwnRenderable() { return false; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java index e4990e8..bcc9df5 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderOpaqueSurface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderRegistry.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderRegistry.java index b240933..7b9d5ec 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderRegistry.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Atlases; @@ -41,11 +41,7 @@ public class TileRenderRegistry extends NamespacedInstanceRegistry { public static Texture getTileTexture(String name) { return new SimpleTexture( - Atlases.getSprite( - ResourceManager.getTextureResource("tiles/" + name), - TILES_ATLAS_GROUP - ) - ); + Atlases.getSprite(ResourceManager.getTextureResource("tiles/" + name), TILES_ATLAS_GROUP)); } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java index 6bb8fb0..8c3d00b 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java @@ -15,15 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.common.world.generic.GenericTileStack; import ru.windcorp.progressia.common.world.tile.TileDataStack; -public abstract class TileRenderStack - extends GenericTileStack { +public abstract class TileRenderStack extends GenericTileStack { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java index eebcb07..c41d811 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import java.util.function.Consumer; @@ -44,7 +44,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi super(id); this.texture = texture; } - + public TileRenderSurface(String id) { this(id, null); } @@ -52,45 +52,28 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi public Texture getTexture(BlockFace blockFace) { return texture; } - + public Vec4 getColorMultiplier(BlockFace blockFace) { return Colors.WHITE; } - + @Override - public final void getFaces( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, - boolean inner, - Consumer output, - Vec3 offset - ) { + public final void getFaces(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, boolean inner, + Consumer output, Vec3 offset) { output.accept(createFace(chunk, blockInChunk, blockFace, inner, offset)); } - - private Face createFace( - ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, - boolean inner, - Vec3 offset - ) { - return Faces.createBlockFace( - WorldRenderProgram.getDefault(), - getTexture(blockFace), - getColorMultiplier(blockFace), - offset, - blockFace, - inner - ); + + private Face createFace(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace, boolean inner, Vec3 offset) { + return Faces.createBlockFace(WorldRenderProgram.getDefault(), getTexture(blockFace), + getColorMultiplier(blockFace), offset, blockFace, inner); } @Override public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, BlockFace blockFace) { - return new Shape( - Usage.STATIC, - WorldRenderProgram.getDefault(), - - createFace(chunk, blockInChunk, blockFace, false, Vectors.ZERO_3), - createFace(chunk, blockInChunk, blockFace, true, Vectors.ZERO_3) - ); + return new Shape(Usage.STATIC, WorldRenderProgram.getDefault(), + + createFace(chunk, blockInChunk, blockFace, false, Vectors.ZERO_3), + createFace(chunk, blockInChunk, blockFace, true, Vectors.ZERO_3)); } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java index b35986e..af512a9 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderTransparentSurface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.graphics.texture.Texture; diff --git a/src/main/java/ru/windcorp/progressia/common/Units.java b/src/main/java/ru/windcorp/progressia/common/Units.java index 842e378..0f868aa 100644 --- a/src/main/java/ru/windcorp/progressia/common/Units.java +++ b/src/main/java/ru/windcorp/progressia/common/Units.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common; import java.lang.annotation.ElementType; @@ -112,12 +112,9 @@ public class Units { private static final TCharFloatMap PREFIXES_BY_CHAR; static { - TCharFloatMap prefixes = new TCharFloatHashMap( - gnu.trove.impl.Constants.DEFAULT_CAPACITY, - gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR, - gnu.trove.impl.Constants.DEFAULT_CHAR_NO_ENTRY_VALUE, - Float.NaN - ); + TCharFloatMap prefixes = new TCharFloatHashMap(gnu.trove.impl.Constants.DEFAULT_CAPACITY, + gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR, gnu.trove.impl.Constants.DEFAULT_CHAR_NO_ENTRY_VALUE, + Float.NaN); prefixes.put('G', 1e+9f); prefixes.put('M', 1e+6f); @@ -133,13 +130,8 @@ public class Units { private static final TObjectFloatMap KNOWN_UNITS = createMap(); private static TObjectFloatMap createMap() { - return TCollections.synchronizedMap( - new TObjectFloatHashMap<>( - gnu.trove.impl.Constants.DEFAULT_CAPACITY, - gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR, - Float.NaN - ) - ); + return TCollections.synchronizedMap(new TObjectFloatHashMap<>(gnu.trove.impl.Constants.DEFAULT_CAPACITY, + gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR, Float.NaN)); } public static void registerUnits(Class source) throws IllegalAccessException { @@ -210,9 +202,9 @@ public class Units { * parenthesis are allowed at all. As such, *
        *
      • Multiple units under the division bar should be located after the - * single {@code '/'} and separated by {@code '*'}: - * gas constant ought - * to have {@code "J/K*mol"} units.
      • + * single {@code '/'} and separated by {@code '*'}: gas constant ought to + * have {@code "J/K*mol"} units. *
      • Exponentiation of parenthesis should be expanded: (m/s)² = * {@code "m^2/s^2"}.
      • *
      • Exponents should also be used for expressing roots: √s = @@ -221,8 +213,10 @@ public class Units { * discouraged.
      • *
      * - * @param unit unit declaration - * @throws IllegalArgumentException if the declaration is invalid + * @param unit + * unit declaration + * @throws IllegalArgumentException + * if the declaration is invalid * @return the value of the unit * @see #get(String) get(String) * @see #registerUnit(float, String...) diff --git a/src/main/java/ru/windcorp/progressia/common/collision/AABB.java b/src/main/java/ru/windcorp/progressia/common/collision/AABB.java index fd8ffe9..ce27f68 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/AABB.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/AABB.java @@ -15,14 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; /** - * An implementation of an - * Axis-Aligned * Bounding Box. * @@ -36,17 +35,7 @@ public class AABB implements AABBoid { private final Vec3 widthSelector = new Vec3(); private final Vec3 heightSelector = new Vec3(); - public AABBWallImpl( - float ox, - float oy, - float oz, - float wx, - float wy, - float wz, - float hx, - float hy, - float hz - ) { + public AABBWallImpl(float ox, float oy, float oz, float wx, float wy, float wz, float hx, float hy, float hz) { this.originOffset.set(ox, oy, oz); this.widthSelector.set(wx, wy, wz); this.heightSelector.set(hx, hy, hz); @@ -71,13 +60,12 @@ public class AABB implements AABBoid { public static final AABB UNIT_CUBE = new AABB(0, 0, 0, 1, 1, 1); - private final Wall[] walls = new Wall[] { - new AABBWallImpl(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0), // Top - new AABBWallImpl(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0), // Bottom - new AABBWallImpl(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1), // North - new AABBWallImpl(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1), // South - new AABBWallImpl(+0.5f, +0.5f, -0.5f, -1, 0, 0, 0, 0, +1), // West - new AABBWallImpl(-0.5f, -0.5f, -0.5f, +1, 0, 0, 0, 0, +1) // East + private final Wall[] walls = new Wall[] { new AABBWallImpl(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0), // Top + new AABBWallImpl(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0), // Bottom + new AABBWallImpl(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1), // North + new AABBWallImpl(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1), // South + new AABBWallImpl(+0.5f, +0.5f, -0.5f, -1, 0, 0, 0, 0, +1), // West + new AABBWallImpl(-0.5f, -0.5f, -0.5f, +1, 0, 0, 0, 0, +1) // East }; private final Vec3 origin = new Vec3(); @@ -87,14 +75,7 @@ public class AABB implements AABBoid { this(origin.x, origin.y, origin.z, size.x, size.y, size.z); } - public AABB( - float ox, - float oy, - float oz, - float xSize, - float ySize, - float zSize - ) { + public AABB(float ox, float oy, float oz, float xSize, float ySize, float zSize) { this.origin.set(ox, oy, oz); this.size.set(xSize, ySize, zSize); } diff --git a/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java b/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java index ab2cd80..04312f1 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/AABBoid.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; diff --git a/src/main/java/ru/windcorp/progressia/common/collision/Collideable.java b/src/main/java/ru/windcorp/progressia/common/collision/Collideable.java index 8db7805..14ca2c3 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/Collideable.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/Collideable.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; @@ -26,10 +26,11 @@ public interface Collideable { CollisionModel getCollisionModel(); /** - * Invoked by {@link Collider} when two entities are about to collide. - * The world is at the moment of collision. + * Invoked by {@link Collider} when two entities are about to collide. The + * world is at the moment of collision. * - * @param other the colliding object + * @param other + * the colliding object * @return {@code true} iff the collision should not be handled normally * (e.g. this object has disappeared) */ @@ -37,8 +38,8 @@ public interface Collideable { /** * Returns the mass of this {@link Collideable} that should be used to - * calculate collisions. - * Collision mass must be a positive number. Positive infinity is allowed. + * calculate collisions. Collision mass must be a positive number. Positive + * infinity is allowed. * * @return this object's collision mass */ diff --git a/src/main/java/ru/windcorp/progressia/common/collision/CollisionModel.java b/src/main/java/ru/windcorp/progressia/common/collision/CollisionModel.java index 9ade6af..209063a 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/CollisionModel.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/CollisionModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; diff --git a/src/main/java/ru/windcorp/progressia/common/collision/CollisionPathComputer.java b/src/main/java/ru/windcorp/progressia/common/collision/CollisionPathComputer.java index 4826bce..88a57e1 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/CollisionPathComputer.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/CollisionPathComputer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import java.util.function.Consumer; @@ -30,11 +30,7 @@ public class CollisionPathComputer { private static final float PADDING = 0.5f; - public static void forEveryBlockInCollisionPath( - Collideable coll, - float maxTime, - Consumer action - ) { + public static void forEveryBlockInCollisionPath(Collideable coll, float maxTime, Consumer action) { Vec3 displacement = Vectors.grab3(); coll.getCollideableVelocity(displacement); displacement.mul(maxTime); @@ -44,11 +40,7 @@ public class CollisionPathComputer { Vectors.release(displacement); } - private static void handleModel( - CollisionModel model, - Vec3 displacement, - Consumer action - ) { + private static void handleModel(CollisionModel model, Vec3 displacement, Consumer action) { if (model instanceof CompoundCollisionModel) { for (CollisionModel subModel : ((CompoundCollisionModel) model).getModels()) { handleModel(subModel, displacement, action); @@ -71,21 +63,13 @@ public class CollisionPathComputer { Vec3i pos = Vectors.grab3i(); - for ( - pos.x = (int) floor(origin.x + min(0, size.x) + min(0, displacement.x) - PADDING); - pos.x <= (int) ceil(origin.x + max(0, size.x) + max(0, displacement.x) + PADDING); - pos.x += 1 - ) { - for ( - pos.y = (int) floor(origin.y + min(0, size.y) + min(0, displacement.y) - PADDING); - pos.y <= (int) ceil(origin.y + max(0, size.y) + max(0, displacement.y) + PADDING); - pos.y += 1 - ) { - for ( - pos.z = (int) floor(origin.z + min(0, size.z) + min(0, displacement.z) - PADDING); - pos.z <= (int) ceil(origin.z + max(0, size.z) + max(0, displacement.z) + PADDING); - pos.z += 1 - ) { + for (pos.x = (int) floor(origin.x + min(0, size.x) + min(0, displacement.x) - PADDING); pos.x <= (int) ceil( + origin.x + max(0, size.x) + max(0, displacement.x) + PADDING); pos.x += 1) { + for (pos.y = (int) floor(origin.y + min(0, size.y) + min(0, displacement.y) - PADDING); pos.y <= (int) ceil( + origin.y + max(0, size.y) + max(0, displacement.y) + PADDING); pos.y += 1) { + for (pos.z = (int) floor( + origin.z + min(0, size.z) + min(0, displacement.z) - PADDING); pos.z <= (int) ceil( + origin.z + max(0, size.z) + max(0, displacement.z) + PADDING); pos.z += 1) { action.accept(pos); } } diff --git a/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java b/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java index 6f5ec24..a91dfdf 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/CompoundCollisionModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import java.util.Collection; diff --git a/src/main/java/ru/windcorp/progressia/common/collision/TransformedCollisionModel.java b/src/main/java/ru/windcorp/progressia/common/collision/TransformedCollisionModel.java index 96bfbee..9622423 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/TransformedCollisionModel.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/TransformedCollisionModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java b/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java index 4c33ad2..fd94cfc 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/TranslatedAABB.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; diff --git a/src/main/java/ru/windcorp/progressia/common/collision/Wall.java b/src/main/java/ru/windcorp/progressia/common/collision/Wall.java index 91ca006..91e9f72 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/Wall.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/Wall.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import glm.vec._3.Vec3; diff --git a/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java b/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java index 69d2d4a..c843edc 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision; import java.util.ArrayList; @@ -68,25 +68,22 @@ public class WorldCollisionHelper { /** * Changes the state of this helper's {@link #getCollideable()} so it is - * ready to adequately handle - * collisions with the {@code collideable} that might happen in the next - * {@code maxTime} seconds. - * This helper is only valid for checking collisions with the given - * Collideable and only within + * ready to adequately handle collisions with the {@code collideable} that + * might happen in the next {@code maxTime} seconds. This helper is only + * valid for checking collisions with the given Collideable and only within * the given time limit. * - * @param collideable the {@link Collideable} that collisions will be - * checked against - * @param maxTime maximum collision time + * @param collideable + * the {@link Collideable} that collisions will be checked + * against + * @param maxTime + * maximum collision time */ public void tuneToCollideable(WorldData world, Collideable collideable, float maxTime) { activeBlockModels.forEach(blockModelCache::release); activeBlockModels.clear(); - CollisionPathComputer.forEveryBlockInCollisionPath( - collideable, - maxTime, - v -> addModel(world.getCollisionModelOfBlock(v), v) - ); + CollisionPathComputer.forEveryBlockInCollisionPath(collideable, maxTime, + v -> addModel(world.getCollisionModelOfBlock(v), v)); } private void addModel(CollisionModel model, Vec3i pos) { diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java index 5fab3d8..7ff3ca1 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AABBoidCollider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision.colliders; import glm.mat._3.Mat3; @@ -29,14 +29,8 @@ import ru.windcorp.progressia.common.world.block.BlockFace; class AABBoidCollider { - static Collider.Collision computeModelCollision( - Collideable aBody, - Collideable bBody, - AABBoid aModel, - AABBoid bModel, - float tickLength, - ColliderWorkspace workspace - ) { + static Collider.Collision computeModelCollision(Collideable aBody, Collideable bBody, AABBoid aModel, + AABBoid bModel, float tickLength, ColliderWorkspace workspace) { Collideable obstacleBody = bBody; Collideable colliderBody = aBody; AABBoid obstacleModel = bModel; @@ -53,15 +47,8 @@ class AABBoidCollider { for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) { Wall wall = originCollisionSpace.getWall(i); - Collision collision = computeWallCollision( - wall, - colliderModel, - collisionVelocity, - tickLength, - workspace, - aBody, - bBody - ); + Collision collision = computeWallCollision(wall, colliderModel, collisionVelocity, tickLength, workspace, + aBody, bBody); // Update result if (collision != null) { @@ -86,11 +73,7 @@ class AABBoidCollider { return result; } - private static void computeCollisionVelocity( - Vec3 output, - Collideable obstacleBody, - Collideable colliderBody - ) { + private static void computeCollisionVelocity(Vec3 output, Collideable obstacleBody, Collideable colliderBody) { Vec3 obstacleVelocity = Vectors.grab3(); Vec3 colliderVelocity = Vectors.grab3(); @@ -124,53 +107,29 @@ class AABBoidCollider { /* * Here we determine whether a collision has actually happened, and if it - * did, at what moment. - * The basic idea is to compute the moment of collision and impact - * coordinates in wall coordinate space. - * Then, we can check impact coordinates to determine if we actually hit the - * wall or flew by and then - * check time to make sure the collision is not too far in the future and - * not in the past. - * DETAILED EXPLANATION: - * Consider a surface defined by an origin r_wall and two noncollinear - * nonzero vectors w and h. - * Consider a line defined by an origin r_line and a nonzero vector v. - * Then, a collision occurs if there exist x, y and t such that - * ______ _ - * r_line + v * t - * and - * ______ _ _ - * r_wall + w * x + h * y - * describe the same location (indeed, this corresponds to a collision at - * moment t0 + t - * with a point on the wall with coordinates (x; y) in (w; h) coordinate - * system). - * Therefore, - * ______ _ ______ _ _ - * r_line + v*t = r_wall + w*x + h*y; - * _ ⎡w_x h_x -v_x⎤ ⎡x⎤ _ ______ ______ - * r = ⎢w_y h_y -v_y⎥ * ⎢y⎥, where r = r_line - r_wall; - * ⎣w_z h_z -v_z⎦ ⎣t⎦ - * ⎡x⎤ ⎡w_x h_x -v_x⎤ -1 _ - * ⎢y⎥ = ⎢w_y h_y -v_y⎥ * r, if the matrix is invertible. - * ⎣t⎦ ⎣w_z h_z -v_z⎦ - * Then, one only needs to ensure that: - * 0 < x < 1, - * 0 < y < 1, and - * 0 < t < T, where T is remaining tick time. - * If the matrix is not invertible or any of the conditions are not met, no - * collision happened. - * If all conditions are satisfied, then the moment of impact is t0 + t. + * did, at what moment. The basic idea is to compute the moment of collision + * and impact coordinates in wall coordinate space. Then, we can check + * impact coordinates to determine if we actually hit the wall or flew by + * and then check time to make sure the collision is not too far in the + * future and not in the past. DETAILED EXPLANATION: Consider a surface + * defined by an origin r_wall and two noncollinear nonzero vectors w and h. + * Consider a line defined by an origin r_line and a nonzero vector v. Then, + * a collision occurs if there exist x, y and t such that ______ _ r_line + + * v * t and ______ _ _ r_wall + w * x + h * y describe the same location + * (indeed, this corresponds to a collision at moment t0 + t with a point on + * the wall with coordinates (x; y) in (w; h) coordinate system). Therefore, + * ______ _ ______ _ _ r_line + v*t = r_wall + w*x + h*y; _ ⎡w_x h_x + * -v_x⎤ ⎡x⎤ _ ______ ______ r = ⎢w_y h_y -v_y⎥ * ⎢y⎥, where r + * = r_line - r_wall; ⎣w_z h_z -v_z⎦ ⎣t⎦ ⎡x⎤ ⎡w_x h_x -v_x⎤ + * -1 _ ⎢y⎥ = ⎢w_y h_y -v_y⎥ * r, if the matrix is invertible. + * ⎣t⎦ ⎣w_z h_z -v_z⎦ Then, one only needs to ensure that: 0 < x < + * 1, 0 < y < 1, and 0 < t < T, where T is remaining tick time. If the + * matrix is not invertible or any of the conditions are not met, no + * collision happened. If all conditions are satisfied, then the moment of + * impact is t0 + t. */ - private static Collision computeWallCollision( - Wall obstacleWall, - AABBoid colliderModel, - Vec3 collisionVelocity, - float tickLength, - ColliderWorkspace workspace, - Collideable aBody, - Collideable bBody - ) { + private static Collision computeWallCollision(Wall obstacleWall, AABBoid colliderModel, Vec3 collisionVelocity, + float tickLength, ColliderWorkspace workspace, Collideable aBody, Collideable bBody) { Vec3 w = Vectors.grab3(); Vec3 h = Vectors.grab3(); Vec3 v = Vectors.grab3(); diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java index 559de13..a1f3383 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/AnythingWithCompoundCollider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision.colliders; import ru.windcorp.progressia.common.collision.Collideable; @@ -26,26 +26,13 @@ import ru.windcorp.progressia.common.collision.colliders.Collider.Collision; class AnythingWithCompoundCollider { - static Collider.Collision computeModelCollision( - Collideable aBody, - Collideable bBody, - CompoundCollisionModel aModel, - CollisionModel bModel, - float tickLength, - ColliderWorkspace workspace - ) { + static Collider.Collision computeModelCollision(Collideable aBody, Collideable bBody, CompoundCollisionModel aModel, + CollisionModel bModel, float tickLength, ColliderWorkspace workspace) { Collision result = null; for (CollisionModel aModelPart : aModel.getModels()) { - Collision collision = Collider.getCollision( - aBody, - bBody, - aModelPart, - bModel, - tickLength, - workspace - ); + Collision collision = Collider.getCollision(aBody, bBody, aModelPart, bModel, tickLength, workspace); // Update result if (collision != null) { diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java index 56bc8ad..48e1640 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.collision.colliders; import java.util.Collection; @@ -37,18 +37,14 @@ public class Collider { * Dear Princess Celestia, *

      * When {@linkplain #advanceTime(Collection, Collision, WorldData, float) - * advancing time}, - * time step for all entities except currently colliding bodies is - * the current - * collisions's timestamp relative to now. However, currently colliding - * bodies - * (Collision.a and Collision.b) have a smaller time step. This is done to - * make sure - * they don't intersect due to rounding errors. + * advancing time}, time step for all entities except currently + * colliding bodies is the current collisions's timestamp relative to now. + * However, currently colliding bodies (Collision.a and Collision.b) have a + * smaller time step. This is done to make sure they don't intersect due to + * rounding errors. *

      * Today I learned that bad code has nothing to do with friendship, although - * lemme tell ya: - * it's got some dank magic. + * lemme tell ya: it's got some dank magic. *

      * Your faithful student,
      * Kostyl. @@ -59,21 +55,14 @@ public class Collider { * 1f */; - public static void performCollisions( - List colls, - WorldData world, - float tickLength, - ColliderWorkspace workspace - ) { + public static void performCollisions(List colls, WorldData world, float tickLength, + ColliderWorkspace workspace) { int collisionCount = 0; int maxCollisions = colls.size() * MAX_COLLISIONS_PER_ENTITY; while (true) { if (collisionCount > maxCollisions) { - LogManager.getLogger().warn( - "Attempted to handle more than {} collisions", - maxCollisions - ); + LogManager.getLogger().warn("Attempted to handle more than {} collisions", maxCollisions); return; } @@ -93,12 +82,8 @@ public class Collider { advanceTime(colls, null, world, tickLength); } - private static Collision getFirstCollision( - List colls, - float tickLength, - WorldData world, - ColliderWorkspace workspace - ) { + private static Collision getFirstCollision(List colls, float tickLength, WorldData world, + ColliderWorkspace workspace) { Collision result = null; Collideable worldColl = workspace.worldCollisionHelper.getCollideable(); @@ -108,10 +93,7 @@ public class Collider { tuneWorldCollisionHelper(a, tickLength, world, workspace); - result = workspace.updateLatestCollision( - result, - getCollision(a, worldColl, tickLength, workspace) - ); + result = workspace.updateLatestCollision(result, getCollision(a, worldColl, tickLength, workspace)); for (int j = i + 1; j < colls.size(); ++j) { Collideable b = colls.get(j); @@ -123,81 +105,42 @@ public class Collider { return result; } - private static void tuneWorldCollisionHelper( - Collideable coll, - float tickLength, - WorldData world, - ColliderWorkspace workspace - ) { + private static void tuneWorldCollisionHelper(Collideable coll, float tickLength, WorldData world, + ColliderWorkspace workspace) { WorldCollisionHelper wch = workspace.worldCollisionHelper; wch.tuneToCollideable(world, coll, tickLength); } - static Collision getCollision( - Collideable a, - Collideable b, - float tickLength, - ColliderWorkspace workspace - ) { + static Collision getCollision(Collideable a, Collideable b, float tickLength, ColliderWorkspace workspace) { CollisionModel aModel = a.getCollisionModel(); CollisionModel bModel = b.getCollisionModel(); return getCollision(a, b, aModel, bModel, tickLength, workspace); } - static Collision getCollision( - Collideable aBody, - Collideable bBody, - CollisionModel aModel, - CollisionModel bModel, - float tickLength, - ColliderWorkspace workspace - ) { + static Collision getCollision(Collideable aBody, Collideable bBody, CollisionModel aModel, CollisionModel bModel, + float tickLength, ColliderWorkspace workspace) { if (aModel instanceof AABBoid && bModel instanceof AABBoid) { - return AABBoidCollider.computeModelCollision( - aBody, - bBody, - (AABBoid) aModel, - (AABBoid) bModel, - tickLength, - workspace - ); + return AABBoidCollider.computeModelCollision(aBody, bBody, (AABBoid) aModel, (AABBoid) bModel, tickLength, + workspace); } if (aModel instanceof CompoundCollisionModel) { - return AnythingWithCompoundCollider.computeModelCollision( - aBody, - bBody, - (CompoundCollisionModel) aModel, - bModel, - tickLength, - workspace - ); + return AnythingWithCompoundCollider.computeModelCollision(aBody, bBody, (CompoundCollisionModel) aModel, + bModel, tickLength, workspace); } if (bModel instanceof CompoundCollisionModel) { - return AnythingWithCompoundCollider.computeModelCollision( - bBody, - aBody, - (CompoundCollisionModel) bModel, - aModel, - tickLength, - workspace - ); + return AnythingWithCompoundCollider.computeModelCollision(bBody, aBody, (CompoundCollisionModel) bModel, + aModel, tickLength, workspace); } throw new UnsupportedOperationException( - "Collisions between " + aModel + " and " + bModel + " are not yet implemented" - ); + "Collisions between " + aModel + " and " + bModel + " are not yet implemented"); } - private static void collide( - Collision collision, + private static void collide(Collision collision, - Collection colls, - WorldData world, - float tickLength, - ColliderWorkspace workspace - ) { + Collection colls, WorldData world, float tickLength, ColliderWorkspace workspace) { advanceTime(colls, collision, world, collision.time); boolean doNotHandle = false; @@ -213,64 +156,38 @@ public class Collider { } /* - * Here we compute the change in body velocities due to a collision. - * We make the following simplifications: - * 1) The bodies are perfectly rigid; - * 2) The collision is perfectly inelastic - * (no bouncing); - * 3) The bodies are spherical; - * 4) No tangential friction exists - * (bodies do not experience friction when sliding against each other); - * 5) Velocities are not relativistic. - * Angular momentum is ignored per 3) and 4), - * e.g. when something pushes an end of a long stick, the stick does not - * rotate. - * DETAILED EXPLANATION: - * Two spherical (sic) bodies, a and b, experience a perfectly inelastic - * collision - * along a unit vector - * _ _ _ _ _ - * n = (w ⨯ h) / (|w ⨯ h|), - * _ _ - * where w and h are two noncollinear nonzero vectors on the dividing plane. - * ___ ___ - * Body masses and velocities are M_a, M_b and v_a, v_b, respectively. - * ___ ___ - * After the collision desired velocities are u_a and u_b, respectively. - * _ - * (Notation convention: suffix 'n' denotes a vector projection onto vector - * n, - * and suffix 't' denotes a vector projection onto the dividing plane.) - * Consider the law of conservation of momentum for axis n and the dividing - * plane: - * ____________ ____________ ________________ - * n: ⎧ p_a_before_n + p_b_before_n = p_common_after_n; - * ⎨ ___________ ____________ - * t: ⎩ p_i_after_t = p_i_before_t for any i in {a, b}. - * Expressing all p_* in given terms: - * ___ _ ___ _ ___ ___ ____ ____ - * n: ⎧ M_a * (v_a ⋅ n) + M_b * (v_b ⋅ n) = (M_a + M_b) * u_n, where u_n ≡ - * u_an = u_bn; - * ⎨ ____ ___ _ ___ _ - * t: ⎩ u_it = v_i - n * (v_i ⋅ n) for any i in {a, b}. - * Therefore: - * ___ _ ___ _ ___ _ - * u_n = n * ( M_a/(M_a + M_b) * v_a ⋅ n + M_b/(M_a + M_b) * v_b ⋅ n ); - * or, equivalently, - * ___ _ ___ _ ___ _ - * u_n = n * ( m_a * v_a ⋅ n + m_b * v_b ⋅ n ), - * where m_a and m_b are relative masses (see below). - * Finally, - * ___ ____ ___ - * u_i = u_it + u_n for any i in {a, b}. - * The usage of relative masses m_i permits a convenient generalization of - * the algorithm - * for infinite masses, signifying masses "significantly greater" than - * finite masses: - * 1) If both M_a and M_b are finite, let m_i = M_i / (M_a + M_b) for any i + * Here we compute the change in body velocities due to a collision. We make + * the following simplifications: 1) The bodies are perfectly rigid; 2) The + * collision is perfectly inelastic (no bouncing); 3) The bodies are + * spherical; 4) No tangential friction exists (bodies do not experience + * friction when sliding against each other); 5) Velocities are not + * relativistic. Angular momentum is ignored per 3) and 4), e.g. when + * something pushes an end of a long stick, the stick does not rotate. + * DETAILED EXPLANATION: Two spherical (sic) bodies, a and b, experience a + * perfectly inelastic collision along a unit vector _ _ _ _ _ n = (w ⨯ h) + * / (|w ⨯ h|), _ _ where w and h are two noncollinear nonzero vectors on + * the dividing plane. ___ ___ Body masses and velocities are M_a, M_b and + * v_a, v_b, respectively. ___ ___ After the collision desired velocities + * are u_a and u_b, respectively. _ (Notation convention: suffix 'n' denotes + * a vector projection onto vector n, and suffix 't' denotes a vector + * projection onto the dividing plane.) Consider the law of conservation of + * momentum for axis n and the dividing plane: ____________ ____________ + * ________________ n: ⎧ p_a_before_n + p_b_before_n = p_common_after_n; + * ⎨ ___________ ____________ t: ⎩ p_i_after_t = p_i_before_t for any i + * in {a, b}. Expressing all p_* in given terms: ___ _ ___ _ ___ ___ ____ + * ____ n: ⎧ M_a * (v_a ⋅ n) + M_b * (v_b ⋅ n) = (M_a + M_b) * u_n, + * where u_n ≡ u_an = u_bn; ⎨ ____ ___ _ ___ _ t: ⎩ u_it = v_i - n * + * (v_i ⋅ n) for any i in {a, b}. Therefore: ___ _ ___ _ ___ _ u_n = n * ( + * M_a/(M_a + M_b) * v_a ⋅ n + M_b/(M_a + M_b) * v_b ⋅ n ); or, + * equivalently, ___ _ ___ _ ___ _ u_n = n * ( m_a * v_a ⋅ n + m_b * v_b + * ⋅ n ), where m_a and m_b are relative masses (see below). Finally, ___ + * ____ ___ u_i = u_it + u_n for any i in {a, b}. The usage of relative + * masses m_i permits a convenient generalization of the algorithm for + * infinite masses, signifying masses "significantly greater" than finite + * masses: 1) If both M_a and M_b are finite, let m_i = M_i / (M_a + M_b) + * for any i in {a, b}. 2) If M_i is finite but M_j is infinite, let m_i = 0 + * and m_j = 1. 3) If both M_a and M_b are infinite, let m_i = 1/2 for any i * in {a, b}. - * 2) If M_i is finite but M_j is infinite, let m_i = 0 and m_j = 1. - * 3) If both M_a and M_b are infinite, let m_i = 1/2 for any i in {a, b}. */ private static void handlePhysics(Collision collision) { // Fuck JGLM @@ -333,12 +250,7 @@ public class Collider { Vectors.release(du_b); } - private static void separate( - Collision collision, - Vec3 normal, - float aRelativeMass, - float bRelativeMass - ) { + private static void separate(Collision collision, Vec3 normal, float aRelativeMass, float bRelativeMass) { final float margin = 1e-4f; Vec3 displacement = Vectors.grab3(); @@ -352,12 +264,8 @@ public class Collider { Vectors.release(displacement); } - private static void advanceTime( - Collection colls, - Collision exceptions, - WorldData world, - float step - ) { + private static void advanceTime(Collection colls, Collision exceptions, WorldData world, + float step) { world.advanceTime(step); Vec3 tmp = Vectors.grab3(); @@ -425,17 +333,12 @@ public class Collider { public final Vec3 wallHeight = new Vec3(); /** - * Time offset from the start of the tick. - * 0 means right now, tickLength means at the end of the tick. + * Time offset from the start of the tick. 0 means right now, tickLength + * means at the end of the tick. */ public float time; - public Collision set( - Collideable a, - Collideable b, - Wall wall, - float time - ) { + public Collision set(Collideable a, Collideable b, Wall wall, float time) { this.a = a; this.b = b; wall.getWidth(wallWidth); diff --git a/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java b/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java index 288b5dd..32e8829 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.comms; import java.io.IOException; @@ -56,15 +56,9 @@ public abstract class CommsChannel { protected abstract void doSendPacket(Packet packet) throws IOException; - private synchronized void sendPacket( - Packet packet, - State expectedState, - String errorMessage - ) { + private synchronized void sendPacket(Packet packet, State expectedState, String errorMessage) { if (getState() != expectedState) { - throw new IllegalStateException( - String.format(errorMessage, this, getState()) - ); + throw new IllegalStateException(String.format(errorMessage, this, getState())); } try { @@ -75,27 +69,15 @@ public abstract class CommsChannel { } public synchronized void sendPacket(Packet packet) { - sendPacket( - packet, - State.CONNECTED, - "Client %s is in state %s and cannot receive packets normally" - ); + sendPacket(packet, State.CONNECTED, "Client %s is in state %s and cannot receive packets normally"); } public synchronized void sendConnectingPacket(Packet packet) { - sendPacket( - packet, - State.CONNECTING, - "Client %s is in state %s and is no longer connecting" - ); + sendPacket(packet, State.CONNECTING, "Client %s is in state %s and is no longer connecting"); } public synchronized void sendDisconnectingPacket(Packet packet) { - sendPacket( - packet, - State.CONNECTING, - "Client %s is in state %s and is no longer disconnecting" - ); + sendPacket(packet, State.CONNECTING, "Client %s is in state %s and is no longer disconnecting"); } public abstract void disconnect(); diff --git a/src/main/java/ru/windcorp/progressia/common/comms/CommsListener.java b/src/main/java/ru/windcorp/progressia/common/comms/CommsListener.java index 7445e93..e133cf8 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/CommsListener.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/CommsListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.comms; import java.io.IOException; diff --git a/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlData.java b/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlData.java index 46e4e94..d90505b 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlData.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.comms.controls; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlDataRegistry.java b/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlDataRegistry.java index cd884e8..59a8529 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlDataRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/controls/ControlDataRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.comms.controls; import ru.windcorp.progressia.common.util.namespaces.NamespacedFactoryRegistry; diff --git a/src/main/java/ru/windcorp/progressia/common/comms/controls/PacketControl.java b/src/main/java/ru/windcorp/progressia/common/comms/controls/PacketControl.java index d5abd39..2d352bb 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/controls/PacketControl.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/controls/PacketControl.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.comms.controls; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/comms/packets/Packet.java b/src/main/java/ru/windcorp/progressia/common/comms/packets/Packet.java index 5421028..8669eb3 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/packets/Packet.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/packets/Packet.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.comms.packets; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java b/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java index 6bc7901..dada94e 100644 --- a/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java +++ b/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.hacks; import java.lang.reflect.Constructor; @@ -30,14 +30,10 @@ import ru.windcorp.progressia.common.util.crash.CrashReports; /** * This class had to be written because there is not legal way to instantiate a - * non-async - * {@link EventBus} with both a custom identifier and a custom exception - * handler. Which - * is a shame. Guava maintainers know about the issue but have rejected - * solutions multiple - * times without a clearly stated reason; looks like some dirty - * reflection will - * have to do. + * non-async {@link EventBus} with both a custom identifier and a custom + * exception handler. Which is a shame. Guava maintainers know about the issue + * but have rejected solutions multiple times without a clearly stated + * reason; looks like some dirty reflection will have to do. * * @author javapony */ @@ -50,30 +46,22 @@ public class GuavaEventBusHijacker { try { Class dispatcherClass = Class.forName("com.google.common.eventbus.Dispatcher"); - THE_CONSTRUCTOR = EventBus.class.getDeclaredConstructor( - String.class, - Executor.class, - dispatcherClass, - SubscriberExceptionHandler.class - ); + THE_CONSTRUCTOR = EventBus.class.getDeclaredConstructor(String.class, Executor.class, dispatcherClass, + SubscriberExceptionHandler.class); THE_CONSTRUCTOR.setAccessible(true); DISPATCHER__PER_THREAD_DISPATCH_QUEUE = dispatcherClass.getDeclaredMethod("perThreadDispatchQueue"); DISPATCHER__PER_THREAD_DISPATCH_QUEUE.setAccessible(true); } catch (Exception e) { - throw CrashReports - .report(e, "Something went horribly wrong when setting up EventBus hijacking. Has Guava updated?"); + throw CrashReports.report(e, + "Something went horribly wrong when setting up EventBus hijacking. Has Guava updated?"); } } public static EventBus newEventBus(String identifier, SubscriberExceptionHandler exceptionHandler) { try { - return THE_CONSTRUCTOR.newInstance( - identifier, - MoreExecutors.directExecutor(), - DISPATCHER__PER_THREAD_DISPATCH_QUEUE.invoke(null), - exceptionHandler - ); + return THE_CONSTRUCTOR.newInstance(identifier, MoreExecutors.directExecutor(), + DISPATCHER__PER_THREAD_DISPATCH_QUEUE.invoke(null), exceptionHandler); } catch (Exception e) { throw CrashReports.report(e, "Something went horribly wrong when hijacking EventBus. Has Guava updated?"); } diff --git a/src/main/java/ru/windcorp/progressia/common/resource/Resource.java b/src/main/java/ru/windcorp/progressia/common/resource/Resource.java index 6cd4d32..41cf621 100644 --- a/src/main/java/ru/windcorp/progressia/common/resource/Resource.java +++ b/src/main/java/ru/windcorp/progressia/common/resource/Resource.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.resource; import java.io.IOException; @@ -34,7 +34,7 @@ import ru.windcorp.progressia.common.util.Named; import ru.windcorp.progressia.common.util.crash.CrashReports; public class Resource extends Named { - + private final ResourceReader resourceReader; public Resource(String name, ResourceReader resourceReader) { @@ -45,7 +45,7 @@ public class Resource extends Named { public InputStream getInputStream() { return getResourceReader().read(getName()); } - + public ResourceReader getResourceReader() { return resourceReader; } diff --git a/src/main/java/ru/windcorp/progressia/common/resource/ResourceManager.java b/src/main/java/ru/windcorp/progressia/common/resource/ResourceManager.java index 33db64d..fcfc43f 100644 --- a/src/main/java/ru/windcorp/progressia/common/resource/ResourceManager.java +++ b/src/main/java/ru/windcorp/progressia/common/resource/ResourceManager.java @@ -15,18 +15,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.resource; public class ResourceManager { - + private static final ResourceReader CLASSPATH_READER = new ClasspathResourceReader(); private static final ResourceReader FILESYSTEM_READER = new FilesystemResourceReader(); public static Resource getResource(String name) { return new Resource(name, CLASSPATH_READER); } - + public static Resource getFileResource(String name) { return new Resource(name, FILESYSTEM_READER); } diff --git a/src/main/java/ru/windcorp/progressia/common/resource/ResourceReader.java b/src/main/java/ru/windcorp/progressia/common/resource/ResourceReader.java index 1f95f2c..49c221c 100644 --- a/src/main/java/ru/windcorp/progressia/common/resource/ResourceReader.java +++ b/src/main/java/ru/windcorp/progressia/common/resource/ResourceReader.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.common.resource; import java.io.InputStream; public interface ResourceReader { - + InputStream read(String name); } diff --git a/src/main/java/ru/windcorp/progressia/common/state/AbstractStatefulObjectLayout.java b/src/main/java/ru/windcorp/progressia/common/state/AbstractStatefulObjectLayout.java index b2feb80..6752fd7 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/AbstractStatefulObjectLayout.java +++ b/src/main/java/ru/windcorp/progressia/common/state/AbstractStatefulObjectLayout.java @@ -15,15 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public abstract class AbstractStatefulObjectLayout - extends StatefulObjectLayout { +public abstract class AbstractStatefulObjectLayout extends StatefulObjectLayout { public AbstractStatefulObjectLayout(String objectId) { super(objectId); @@ -34,12 +33,7 @@ public abstract class AbstractStatefulObjectLayout protected abstract StateField getField(int fieldIndex); @Override - public void read( - StatefulObject object, - DataInput input, - IOContext context - ) - throws IOException { + public void read(StatefulObject object, DataInput input, IOContext context) throws IOException { int fieldCount = getFieldCount(); for (int i = 0; i < fieldCount; ++i) { @@ -53,12 +47,7 @@ public abstract class AbstractStatefulObjectLayout } @Override - public void write( - StatefulObject object, - DataOutput output, - IOContext context - ) - throws IOException { + public void write(StatefulObject object, DataOutput output, IOContext context) throws IOException { int fieldCount = getFieldCount(); for (int i = 0; i < fieldCount; ++i) { diff --git a/src/main/java/ru/windcorp/progressia/common/state/HashMapStateStorage.java b/src/main/java/ru/windcorp/progressia/common/state/HashMapStateStorage.java index 52d446f..56ee25d 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/HashMapStateStorage.java +++ b/src/main/java/ru/windcorp/progressia/common/state/HashMapStateStorage.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import gnu.trove.map.TIntIntMap; diff --git a/src/main/java/ru/windcorp/progressia/common/state/IOContext.java b/src/main/java/ru/windcorp/progressia/common/state/IOContext.java index b18f875..c309596 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/IOContext.java +++ b/src/main/java/ru/windcorp/progressia/common/state/IOContext.java @@ -15,13 +15,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; public enum IOContext { - COMMS, - SAVE, - INTERNAL; + COMMS, SAVE, INTERNAL; } diff --git a/src/main/java/ru/windcorp/progressia/common/state/InspectingStatefulObjectLayout.java b/src/main/java/ru/windcorp/progressia/common/state/InspectingStatefulObjectLayout.java index 8b0a9fe..d32af14 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/InspectingStatefulObjectLayout.java +++ b/src/main/java/ru/windcorp/progressia/common/state/InspectingStatefulObjectLayout.java @@ -15,14 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.util.ArrayList; import java.util.List; -public class InspectingStatefulObjectLayout - extends AbstractStatefulObjectLayout { +public class InspectingStatefulObjectLayout extends AbstractStatefulObjectLayout { private final List fields = new ArrayList<>(); @@ -48,11 +47,7 @@ public class InspectingStatefulObjectLayout } public StatefulObjectLayout compile() { - return new OptimizedStatefulObjectLayout( - getObjectId(), - fields, - fieldIndexCounters - ); + return new OptimizedStatefulObjectLayout(getObjectId(), fields, fieldIndexCounters); } private T registerField(T field) { @@ -71,13 +66,7 @@ public class InspectingStatefulObjectLayout @Override public IntStateField build() { - return registerField( - new IntStateField( - id, - isLocal, - fieldIndexCounters.getIntsThenIncrement() - ) - ); + return registerField(new IntStateField(id, isLocal, fieldIndexCounters.getIntsThenIncrement())); } } @@ -105,10 +94,7 @@ public class InspectingStatefulObjectLayout public void setOrdinal(int ordinal) { if (ordinal != fields.size()) { throw new IllegalStateException( - "This field is going to receive ordinal " - + fields.size() + ", requested ordinal " - + ordinal - ); + "This field is going to receive ordinal " + fields.size() + ", requested ordinal " + ordinal); } } diff --git a/src/main/java/ru/windcorp/progressia/common/state/IntStateField.java b/src/main/java/ru/windcorp/progressia/common/state/IntStateField.java index abf8573..7390187 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/IntStateField.java +++ b/src/main/java/ru/windcorp/progressia/common/state/IntStateField.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.io.DataInput; @@ -24,11 +24,7 @@ import java.io.IOException; public class IntStateField extends StateField { - public IntStateField( - String id, - boolean isLocal, - int index - ) { + public IntStateField(String id, boolean isLocal, int index) { super(id, isLocal, index); } @@ -45,22 +41,12 @@ public class IntStateField extends StateField { } @Override - public void read( - StatefulObject object, - DataInput input, - IOContext context - ) - throws IOException { + public void read(StatefulObject object, DataInput input, IOContext context) throws IOException { object.getStorage().setInt(getIndex(), input.readInt()); } @Override - public void write( - StatefulObject object, - DataOutput output, - IOContext context - ) - throws IOException { + public void write(StatefulObject object, DataOutput output, IOContext context) throws IOException { output.writeInt(object.getStorage().getInt(getIndex())); } diff --git a/src/main/java/ru/windcorp/progressia/common/state/OptimizedStateStorage.java b/src/main/java/ru/windcorp/progressia/common/state/OptimizedStateStorage.java index 478fbac..fbedec7 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/OptimizedStateStorage.java +++ b/src/main/java/ru/windcorp/progressia/common/state/OptimizedStateStorage.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; public class OptimizedStateStorage extends StateStorage { diff --git a/src/main/java/ru/windcorp/progressia/common/state/OptimizedStatefulObjectLayout.java b/src/main/java/ru/windcorp/progressia/common/state/OptimizedStatefulObjectLayout.java index 1158ab0..c9269c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/OptimizedStatefulObjectLayout.java +++ b/src/main/java/ru/windcorp/progressia/common/state/OptimizedStatefulObjectLayout.java @@ -15,24 +15,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.util.List; import com.google.common.collect.ImmutableList; -public class OptimizedStatefulObjectLayout - extends AbstractStatefulObjectLayout { +public class OptimizedStatefulObjectLayout extends AbstractStatefulObjectLayout { private final List fields; private final PrimitiveCounters sizes; - public OptimizedStatefulObjectLayout( - String objectId, - List fields, - PrimitiveCounters counters - ) { + public OptimizedStatefulObjectLayout(String objectId, List fields, PrimitiveCounters counters) { super(objectId); this.fields = ImmutableList.copyOf(fields); this.sizes = new PrimitiveCounters(counters); diff --git a/src/main/java/ru/windcorp/progressia/common/state/PrimitiveCounters.java b/src/main/java/ru/windcorp/progressia/common/state/PrimitiveCounters.java index d3e2dbb..243d62a 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/PrimitiveCounters.java +++ b/src/main/java/ru/windcorp/progressia/common/state/PrimitiveCounters.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; class PrimitiveCounters { diff --git a/src/main/java/ru/windcorp/progressia/common/state/StateChanger.java b/src/main/java/ru/windcorp/progressia/common/state/StateChanger.java index cc8cd5a..a93e64e 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StateChanger.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StateChanger.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; public interface StateChanger { diff --git a/src/main/java/ru/windcorp/progressia/common/state/StateField.java b/src/main/java/ru/windcorp/progressia/common/state/StateField.java index ca88c4f..1e512ef 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StateField.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StateField.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.io.DataInput; @@ -29,11 +29,7 @@ public abstract class StateField extends Namespaced { private final boolean isLocal; private final int index; - public StateField( - String id, - boolean isLocal, - int index - ) { + public StateField(String id, boolean isLocal, int index) { super(id); this.isLocal = isLocal; this.index = index; @@ -47,19 +43,9 @@ public abstract class StateField extends Namespaced { return index; } - public abstract void read( - StatefulObject object, - DataInput input, - IOContext context - ) - throws IOException; + public abstract void read(StatefulObject object, DataInput input, IOContext context) throws IOException; - public abstract void write( - StatefulObject object, - DataOutput output, - IOContext context - ) - throws IOException; + public abstract void write(StatefulObject object, DataOutput output, IOContext context) throws IOException; public abstract void copy(StatefulObject from, StatefulObject to); diff --git a/src/main/java/ru/windcorp/progressia/common/state/StateFieldBuilder.java b/src/main/java/ru/windcorp/progressia/common/state/StateFieldBuilder.java index 97c7176..935129a 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StateFieldBuilder.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StateFieldBuilder.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; public interface StateFieldBuilder { diff --git a/src/main/java/ru/windcorp/progressia/common/state/StateStorage.java b/src/main/java/ru/windcorp/progressia/common/state/StateStorage.java index 2f999f0..647ae00 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StateStorage.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StateStorage.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; public abstract class StateStorage { diff --git a/src/main/java/ru/windcorp/progressia/common/state/StatefulObject.java b/src/main/java/ru/windcorp/progressia/common/state/StatefulObject.java index 39f5b58..39714b6 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StatefulObject.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StatefulObject.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.io.DataInput; @@ -26,24 +26,22 @@ import java.util.Objects; import ru.windcorp.progressia.common.util.namespaces.Namespaced; /** - * An abstract class describing objects that have trackable state, - * such as blocks, tiles or entities. This class contains the declaration of - * the state mechanics - * (implementation of which is mostly delegated to + * An abstract class describing objects that have trackable state, such as + * blocks, tiles or entities. This class contains the declaration of the state + * mechanics (implementation of which is mostly delegated to * {@link StatefulObjectLayout}). - *

      Structure

      - * Stateful objects are characterized by their likeness and state. + *

      Structure

      Stateful objects are characterized by their + * likeness and state. *

      * An object's likeness is the combination of the object's runtime class (as in * {@link #getClass()}) and its ID. Objects that are "alike" share the same - * internal structure, represented by a common - * {@linkplain StatefulObjectLayout layout}. Likeness can be tested with - * {@link #isLike(Object)}. + * internal structure, represented by a common {@linkplain StatefulObjectLayout + * layout}. Likeness can be tested with {@link #isLike(Object)}. *

      * An object's state is the combination of the values of an object's * {@linkplain StateField state fields}. State fields are different from object - * fields as described by the Java language: not every object field is a part - * of its state, although state fields are usually implemented as object fields. + * fields as described by the Java language: not every object field is a part of + * its state, although state fields are usually implemented as object fields. * Each state field is, in its turn, has the following characteristics: *

        *
      • ID, distinct from the ID of the stateful object to which it belongs. @@ -58,10 +56,7 @@ public abstract class StatefulObject extends Namespaced { private final StateStorage storage; - public StatefulObject( - StatefulObjectRegistry type, - String id - ) { + public StatefulObject(StatefulObjectRegistry type, String id) { super(id); this.layout = type.getLayout(getId()); this.storage = getLayout().createStorage(); @@ -69,8 +64,8 @@ public abstract class StatefulObject extends Namespaced { /** * Returns the {@link StatefulObjectLayout} describing objects that are - * {@linkplain #isLike(Object) "like"} this object. - * You probably don't need this. + * {@linkplain #isLike(Object) "like"} this object. You probably don't need + * this. * * @return this object's field layout */ @@ -106,8 +101,10 @@ public abstract class StatefulObject extends Namespaced { * sequence of invocations must occur during construction of each object * with the same ID. * - * @param namespace the namespace of the new field - * @param name the name of the new field + * @param namespace + * the namespace of the new field + * @param name + * the name of the new field * @return a configured builder */ protected StateFieldBuilder field(String id) { @@ -128,10 +125,13 @@ public abstract class StatefulObject extends Namespaced { * from {@code input}. If {@code context == COMMS}, the state of local * fields is unspecified after this operation. * - * @param input a {@link DataInput} that a state can be read from - * @param context the context - * @throws IOException if the state is encoded poorly or an error occurs - * in {@code input} + * @param input + * a {@link DataInput} that a state can be read from + * @param context + * the context + * @throws IOException + * if the state is encoded poorly or an error occurs in + * {@code input} */ public void read(DataInput input, IOContext context) throws IOException { getLayout().read(this, input, context); @@ -141,9 +141,12 @@ public abstract class StatefulObject extends Namespaced { * Writes the binary representation of the state of this object to the * {@code output}. * - * @param output a {@link DataOutput} that a state can be written to - * @param context the context - * @throws IOException if an error occurs in {@code output} + * @param output + * a {@link DataOutput} that a state can be written to + * @param context + * the context + * @throws IOException + * if an error occurs in {@code output} */ public void write(DataOutput output, IOContext context) throws IOException { getLayout().write(this, output, context); @@ -164,22 +167,19 @@ public abstract class StatefulObject extends Namespaced { * to {@code destination} can affect this object.
      • *
      * - * @param destination the object to copy this object into. + * @param destination + * the object to copy this object into. */ public StatefulObject copy(StatefulObject destination) { Objects.requireNonNull(destination, "destination"); if (destination == this) { - throw new IllegalArgumentException( - "Cannot copy an object into itself" - ); + throw new IllegalArgumentException("Cannot copy an object into itself"); } if (destination.getClass() != this.getClass()) { throw new IllegalArgumentException( - "Cannot copy from " + getClass() - + " (ID " + getId() + ") to " + destination.getClass() - ); + "Cannot copy from " + getClass() + " (ID " + getId() + ") to " + destination.getClass()); } getLayout().copy(this, destination); @@ -200,7 +200,8 @@ public abstract class StatefulObject extends Namespaced { * {@linkplain #isLike(Object) "like"} and their binary representations * match exactly. * - * @param obj the object to examine + * @param obj + * the object to examine * @return {@code true} if {@code obj != null} and this object is equal to * {@code obj} */ @@ -220,7 +221,8 @@ public abstract class StatefulObject extends Namespaced { * Returns {@code true} iff this object and {@code obj} have the same ID and * are instances of the same class. * - * @param obj the object to examine + * @param obj + * the object to examine * @return {@code true} if {@code obj} is "like" this object */ public boolean isLike(Object obj) { diff --git a/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectLayout.java b/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectLayout.java index 4490cdf..b841848 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectLayout.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectLayout.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.io.DataInput; @@ -38,25 +38,13 @@ public abstract class StatefulObjectLayout { protected void checkObject(StatefulObject object) { if (!object.getId().equals(getObjectId())) { - throw new IllegalArgumentException( - object.getId() + " is not " + getObjectId() - ); + throw new IllegalArgumentException(object.getId() + " is not " + getObjectId()); } } - public abstract void read( - StatefulObject object, - DataInput input, - IOContext context - ) - throws IOException; + public abstract void read(StatefulObject object, DataInput input, IOContext context) throws IOException; - public abstract void write( - StatefulObject object, - DataOutput output, - IOContext context - ) - throws IOException; + public abstract void write(StatefulObject object, DataOutput output, IOContext context) throws IOException; public abstract void copy(StatefulObject from, StatefulObject to); diff --git a/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectRegistry.java b/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectRegistry.java index aa082a6..8f01ac8 100644 --- a/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StatefulObjectRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.state; import java.util.Collections; @@ -78,9 +78,7 @@ public class StatefulObjectRegistry { StatefulObjectLayout layout = layouts.get(id); if (layout == null) { - throw new IllegalArgumentException( - "ID " + id + " has not been registered" - ); + throw new IllegalArgumentException("ID " + id + " has not been registered"); } return layout; @@ -88,9 +86,7 @@ public class StatefulObjectRegistry { protected void register(Type type) { if (!type.getRegistrationFlag().compareAndSet(false, true)) { - throw new IllegalStateException( - "ID " + type.getId() + " is already registered" - ); + throw new IllegalStateException("ID " + type.getId() + " is already registered"); } InspectingStatefulObjectLayout inspector = new InspectingStatefulObjectLayout(type.getId()); diff --git a/src/main/java/ru/windcorp/progressia/common/util/BinUtil.java b/src/main/java/ru/windcorp/progressia/common/util/BinUtil.java index ffc8a43..042d2a1 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/BinUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/BinUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; public class BinUtil { diff --git a/src/main/java/ru/windcorp/progressia/common/util/ByteBufferInputStream.java b/src/main/java/ru/windcorp/progressia/common/util/ByteBufferInputStream.java index 6b317a7..f3380a9 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/ByteBufferInputStream.java +++ b/src/main/java/ru/windcorp/progressia/common/util/ByteBufferInputStream.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.io.InputStream; diff --git a/src/main/java/ru/windcorp/progressia/common/util/ByteBufferOutputStream.java b/src/main/java/ru/windcorp/progressia/common/util/ByteBufferOutputStream.java index 8931c75..152a17f 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/ByteBufferOutputStream.java +++ b/src/main/java/ru/windcorp/progressia/common/util/ByteBufferOutputStream.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.io.IOException; diff --git a/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java b/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java index 0ef2413..f909b8a 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java +++ b/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import glm.vec._2.i.Vec2i; @@ -33,13 +33,10 @@ public class CoordinatePacker { BITS_3_INTS_INTO_LONG = 64 / 3; /* - * What happens below: - * 1. 1 << BITS_3_INTS_INTO_LONG: - * 0000 ... 00100 ... 0000 - * \_________/ - BITS_3_INTS_INTO_LONG zeros - * 2. (1 << BITS_3_INTS_INTO_LONG) - 1: - * 0000 ... 00011 ... 1111 - * \_________/ - BITS_3_INTS_INTO_LONG ones - WIN + * What happens below: 1. 1 << BITS_3_INTS_INTO_LONG: 0000 ... 00100 ... + * 0000 \_________/ - BITS_3_INTS_INTO_LONG zeros 2. (1 << + * BITS_3_INTS_INTO_LONG) - 1: 0000 ... 00011 ... 1111 \_________/ - + * BITS_3_INTS_INTO_LONG ones - WIN */ MASK_3_INTS_INTO_LONG = (1l << BITS_3_INTS_INTO_LONG) - 1; @@ -49,9 +46,9 @@ public class CoordinatePacker { } public static long pack3IntsIntoLong(int a, int b, int c) { - return ((a & MASK_3_INTS_INTO_LONG) << (2 * BITS_3_INTS_INTO_LONG)) | - ((b & MASK_3_INTS_INTO_LONG) << (1 * BITS_3_INTS_INTO_LONG)) | - ((c & MASK_3_INTS_INTO_LONG) << (0 * BITS_3_INTS_INTO_LONG)); + return ((a & MASK_3_INTS_INTO_LONG) << (2 * BITS_3_INTS_INTO_LONG)) + | ((b & MASK_3_INTS_INTO_LONG) << (1 * BITS_3_INTS_INTO_LONG)) + | ((c & MASK_3_INTS_INTO_LONG) << (0 * BITS_3_INTS_INTO_LONG)); } public static long pack3IntsIntoLong(Vec3i v) { @@ -63,8 +60,7 @@ public class CoordinatePacker { throw new IllegalArgumentException("Invalid index " + index); } - int result = (int) ((packed >>> ((2 - index) * BITS_3_INTS_INTO_LONG)) - & MASK_3_INTS_INTO_LONG); + int result = (int) ((packed >>> ((2 - index) * BITS_3_INTS_INTO_LONG)) & MASK_3_INTS_INTO_LONG); final long signMask = ((MASK_3_INTS_INTO_LONG + 1) >> 1); @@ -79,18 +75,14 @@ public class CoordinatePacker { if (output == null) output = new Vec3i(); - output.set( - unpack3IntsFromLong(packed, 0), - unpack3IntsFromLong(packed, 1), - unpack3IntsFromLong(packed, 2) - ); + output.set(unpack3IntsFromLong(packed, 0), unpack3IntsFromLong(packed, 1), unpack3IntsFromLong(packed, 2)); return output; } public static long pack2IntsIntoLong(int a, int b) { - return ((a & MASK_2_INTS_INTO_LONG) << (1 * BITS_2_INTS_INTO_LONG)) | - ((b & MASK_2_INTS_INTO_LONG) << (0 * BITS_2_INTS_INTO_LONG)); + return ((a & MASK_2_INTS_INTO_LONG) << (1 * BITS_2_INTS_INTO_LONG)) + | ((b & MASK_2_INTS_INTO_LONG) << (0 * BITS_2_INTS_INTO_LONG)); } public static long pack2IntsIntoLong(Vec2i v) { @@ -102,8 +94,7 @@ public class CoordinatePacker { throw new IllegalArgumentException("Invalid index " + index); } - int result = (int) ((packed >>> ((1 - index) * BITS_2_INTS_INTO_LONG)) - & MASK_2_INTS_INTO_LONG); + int result = (int) ((packed >>> ((1 - index) * BITS_2_INTS_INTO_LONG)) & MASK_2_INTS_INTO_LONG); return result; } @@ -112,10 +103,7 @@ public class CoordinatePacker { if (output == null) output = new Vec2i(); - output.set( - unpack2IntsFromLong(packed, 0), - unpack2IntsFromLong(packed, 1) - ); + output.set(unpack2IntsFromLong(packed, 0), unpack2IntsFromLong(packed, 1)); return output; } diff --git a/src/main/java/ru/windcorp/progressia/common/util/DataBuffer.java b/src/main/java/ru/windcorp/progressia/common/util/DataBuffer.java index 23522c1..b500ace 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/DataBuffer.java +++ b/src/main/java/ru/windcorp/progressia/common/util/DataBuffer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.io.DataInput; @@ -113,10 +113,7 @@ public class DataBuffer { int length = buffer.size(); while (position < length) { - int currentLength = Math.min( - transferBuffer.length, - length - position - ); + int currentLength = Math.min(transferBuffer.length, length - position); buffer.toArray(transferBuffer, position, 0, currentLength); sink.write(transferBuffer, 0, currentLength); diff --git a/src/main/java/ru/windcorp/progressia/common/util/FloatMathUtil.java b/src/main/java/ru/windcorp/progressia/common/util/FloatMathUtil.java index 43487c0..a1008de 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/FloatMathUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/FloatMathUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; public class FloatMathUtil { diff --git a/src/main/java/ru/windcorp/progressia/common/util/LowOverheadCache.java b/src/main/java/ru/windcorp/progressia/common/util/LowOverheadCache.java index c5b2952..9d668e9 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/LowOverheadCache.java +++ b/src/main/java/ru/windcorp/progressia/common/util/LowOverheadCache.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.ArrayList; diff --git a/src/main/java/ru/windcorp/progressia/common/util/Matrices.java b/src/main/java/ru/windcorp/progressia/common/util/Matrices.java index 8804272..b36669b 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/Matrices.java +++ b/src/main/java/ru/windcorp/progressia/common/util/Matrices.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import glm.mat._3.Mat3; @@ -37,8 +37,8 @@ import glm.mat._4.d.Mat4d; * } * * - * Provided objects may be reused after {@code release} has been invoked; - * do not store them. + * Provided objects may be reused after {@code release} has been invoked; do not + * store them. *

      * This class is thread- and recursion-safe. * diff --git a/src/main/java/ru/windcorp/progressia/common/util/MultiLOC.java b/src/main/java/ru/windcorp/progressia/common/util/MultiLOC.java index 295244d..3d417ac 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/MultiLOC.java +++ b/src/main/java/ru/windcorp/progressia/common/util/MultiLOC.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.HashMap; diff --git a/src/main/java/ru/windcorp/progressia/common/util/Named.java b/src/main/java/ru/windcorp/progressia/common/util/Named.java index d9fc97a..8722ad4 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/Named.java +++ b/src/main/java/ru/windcorp/progressia/common/util/Named.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.Objects; diff --git a/src/main/java/ru/windcorp/progressia/common/util/SizeLimitedList.java b/src/main/java/ru/windcorp/progressia/common/util/SizeLimitedList.java index 2010ccb..9e86954 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/SizeLimitedList.java +++ b/src/main/java/ru/windcorp/progressia/common/util/SizeLimitedList.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.Collection; @@ -27,9 +27,7 @@ import com.google.common.collect.ForwardingList; public class SizeLimitedList extends ForwardingList { - private static final class RandomAccessSizeLimitedList - extends SizeLimitedList - implements RandomAccess { + private static final class RandomAccessSizeLimitedList extends SizeLimitedList implements RandomAccess { protected RandomAccessSizeLimitedList(List parent, int maxSize) { super(parent, maxSize); } @@ -76,9 +74,7 @@ public class SizeLimitedList extends ForwardingList { private void checkMaxSize() { if (size() >= maxSize) { - throw new UnsupportedOperationException( - "Maximum size " + maxSize + " reached" - ); + throw new UnsupportedOperationException("Maximum size " + maxSize + " reached"); } } diff --git a/src/main/java/ru/windcorp/progressia/common/util/StashingStack.java b/src/main/java/ru/windcorp/progressia/common/util/StashingStack.java index 394c79d..fcd4059 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/StashingStack.java +++ b/src/main/java/ru/windcorp/progressia/common/util/StashingStack.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.Arrays; @@ -45,9 +45,8 @@ public class StashingStack implements Iterable { /** * Stores all elements. Elements with indices - * [0; {@link #head}] - * are present in the stack, elements with indices - * ({@link #head}; contents.length] are stashed. + * [0; {@link #head}] are present in the stack, elements with + * indices ({@link #head}; contents.length] are stashed. */ private final Object[] contents; @@ -66,7 +65,8 @@ public class StashingStack implements Iterable { /** * Creates a new stack. Its stash is filled with {@code null}s. * - * @param capacity stack's capacity + * @param capacity + * stack's capacity */ public StashingStack(int capacity) { this((T[]) new Object[capacity], 0); @@ -75,7 +75,8 @@ public class StashingStack implements Iterable { /** * Creates a new stack with the supplied stash. * - * @param contents elements that are put in the stash initially. + * @param contents + * elements that are put in the stash initially. */ public StashingStack(T[] contents) { this(contents.clone(), 0); @@ -84,7 +85,8 @@ public class StashingStack implements Iterable { /** * Creates a new stack with the supplied stash. * - * @param contents elements that are put in the stash initially. + * @param contents + * elements that are put in the stash initially. */ public StashingStack(Iterable contents) { this(Iterables.toArray(contents, Object.class), 0); @@ -95,8 +97,10 @@ public class StashingStack implements Iterable { * {@code generator}. The generator's {@link Supplier#get() get()} method * will only be invoked {@code capacity} times from within this constructor. * - * @param capacity stack's capacity - * @param generator a supplier of objects for the stash + * @param capacity + * stack's capacity + * @param generator + * a supplier of objects for the stash */ public StashingStack(int capacity, Supplier generator) { this(capacity); @@ -160,7 +164,8 @@ public class StashingStack implements Iterable { * empty throws a {@link NoSuchElementException}. * * @return head of this stack - * @throws NoSuchElementException is the stack is empty + * @throws NoSuchElementException + * is the stack is empty * @see #peek() */ public T getHead() { @@ -170,8 +175,8 @@ public class StashingStack implements Iterable { } /** - * Returns and removes the head of this stack. If the stack is - * empty returns {@code null}. + * Returns and removes the head of this stack. If the stack is empty returns + * {@code null}. * * @return head of this stack or {@code null} * @see #removeHead() @@ -183,11 +188,12 @@ public class StashingStack implements Iterable { } /** - * Returns and removes the head of this stack. If the stack is - * empty throws a {@link NoSuchElementException}. + * Returns and removes the head of this stack. If the stack is empty throws + * a {@link NoSuchElementException}. * * @return head of this stack - * @throws NoSuchElementException is the stack is empty + * @throws NoSuchElementException + * is the stack is empty * @see #pop() */ public T removeHead() { @@ -216,7 +222,8 @@ public class StashingStack implements Iterable { * removed. If the stack is already full throws an * {@link IllegalStateException}. * - * @param newElement the element to push + * @param newElement + * the element to push * @return the new head */ public T push(T newElement) { @@ -233,17 +240,16 @@ public class StashingStack implements Iterable { * bottom of the stack. If the index is out of bounds, an * {@link IndexOutOfBoundsException} is thrown. * - * @param index index of the element to retrieve, - * [0; {@link #getSize()}) + * @param index + * index of the element to retrieve, + * [0; {@link #getSize()}) * @return the requested element - * @throws IndexOutOfBoundsException if the index is negative or greater - * than head + * @throws IndexOutOfBoundsException + * if the index is negative or greater than head */ public T get(int index) { if (index > head) { - throw new IndexOutOfBoundsException( - "Requested index " + index + " > head " + head - ); + throw new IndexOutOfBoundsException("Requested index " + index + " > head " + head); } return (T) contents[index]; diff --git a/src/main/java/ru/windcorp/progressia/common/util/TaskQueue.java b/src/main/java/ru/windcorp/progressia/common/util/TaskQueue.java index a081356..7010896 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/TaskQueue.java +++ b/src/main/java/ru/windcorp/progressia/common/util/TaskQueue.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.Collection; @@ -62,11 +62,7 @@ public class TaskQueue { private final Object waitAndInvokeMonitor = new Object(); @SuppressWarnings("unchecked") - public void waitAndInvoke( - ThrowingRunnable task - ) - throws InterruptedException, - E { + public void waitAndInvoke(ThrowingRunnable task) throws InterruptedException, E { if (runNow.getAsBoolean()) { task.run(); diff --git a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java index 00ede3e..18cc6be 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/VectorUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import java.util.function.Consumer; @@ -37,15 +37,7 @@ public class VectorUtil { X, Y, Z, W; } - public static void iterateCuboid( - int x0, - int y0, - int z0, - int x1, - int y1, - int z1, - Consumer action - ) { + public static void iterateCuboid(int x0, int y0, int z0, int x1, int y1, int z1, Consumer action) { Vec3i cursor = Vectors.grab3i(); for (int x = x0; x < x1; ++x) { @@ -60,23 +52,12 @@ public class VectorUtil { Vectors.release(cursor); } - public static void iterateCuboid( - Vec3i vMin, - Vec3i vMax, - Consumer action - ) { + public static void iterateCuboid(Vec3i vMin, Vec3i vMax, Consumer action) { iterateCuboid(vMin.x, vMin.y, vMin.z, vMax.x, vMax.y, vMax.z, action); } - public static void iterateCuboidAround( - int cx, - int cy, - int cz, - int dx, - int dy, - int dz, - Consumer action - ) { + public static void iterateCuboidAround(int cx, int cy, int cz, int dx, int dy, int dz, + Consumer action) { if (dx < 0) throw new IllegalArgumentException("dx " + dx + " is negative"); if (dy < 0) @@ -98,29 +79,15 @@ public class VectorUtil { iterateCuboid(cx - dx, cy - dy, cz - dz, cx + dx + 1, cy + dy + 1, cz + dz + 1, action); } - public static void iterateCuboidAround( - Vec3i center, - Vec3i diameters, - Consumer action - ) { + public static void iterateCuboidAround(Vec3i center, Vec3i diameters, Consumer action) { iterateCuboidAround(center.x, center.y, center.z, diameters.x, diameters.y, diameters.z, action); } - public static void iterateCuboidAround( - int cx, - int cy, - int cz, - int diameter, - Consumer action - ) { + public static void iterateCuboidAround(int cx, int cy, int cz, int diameter, Consumer action) { iterateCuboidAround(cx, cy, cz, diameter, diameter, diameter, action); } - public static void iterateCuboidAround( - Vec3i center, - int diameter, - Consumer action - ) { + public static void iterateCuboidAround(Vec3i center, int diameter, Consumer action) { iterateCuboidAround(center.x, center.y, center.z, diameter, action); } @@ -143,35 +110,14 @@ public class VectorUtil { inOut.set(vec4.x, vec4.y, vec4.z); } - public static Vec3 linearCombination( - Vec3 va, - float ka, - Vec3 vb, - float kb, - Vec3 output - ) { - output.set( - va.x * ka + vb.x * kb, - va.y * ka + vb.y * kb, - va.z * ka + vb.z * kb - ); + public static Vec3 linearCombination(Vec3 va, float ka, Vec3 vb, float kb, Vec3 output) { + output.set(va.x * ka + vb.x * kb, va.y * ka + vb.y * kb, va.z * ka + vb.z * kb); return output; } - public static Vec3 linearCombination( - Vec3 va, - float ka, - Vec3 vb, - float kb, - Vec3 vc, - float kc, - Vec3 output - ) { - output.set( - va.x * ka + vb.x * kb + vc.x * kc, - va.y * ka + vb.y * kb + vc.y * kc, - va.z * ka + vb.z * kb + vc.z * kc - ); + public static Vec3 linearCombination(Vec3 va, float ka, Vec3 vb, float kb, Vec3 vc, float kc, Vec3 output) { + output.set(va.x * ka + vb.x * kb + vc.x * kc, va.y * ka + vb.y * kb + vc.y * kc, + va.z * ka + vb.z * kb + vc.z * kc); return output; } diff --git a/src/main/java/ru/windcorp/progressia/common/util/Vectors.java b/src/main/java/ru/windcorp/progressia/common/util/Vectors.java index 7d99ea5..2cb4336 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/Vectors.java +++ b/src/main/java/ru/windcorp/progressia/common/util/Vectors.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util; import glm.vec._2.Vec2; @@ -40,8 +40,8 @@ import glm.vec._4.i.Vec4i; * } * * - * Provided objects may be reused after {@code release} has been invoked; - * do not store them. + * Provided objects may be reused after {@code release} has been invoked; do not + * store them. *

      * This class is thread- and recursion-safe. * diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/Analyzer.java b/src/main/java/ru/windcorp/progressia/common/util/crash/Analyzer.java index 3289c3d..e17f964 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/Analyzer.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/Analyzer.java @@ -15,16 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash; /** * A crash report utility that performs analysis of a problem during crash * report generation and presents its conclusion to the user via the crash - * report. - * Unlike {@link ContextProvider}s, Analyzers are provided with the reported - * problem - * details. + * report. Unlike {@link ContextProvider}s, Analyzers are provided with the + * reported problem details. * * @see ContextProvider * @author serega404 @@ -32,22 +30,24 @@ package ru.windcorp.progressia.common.util.crash; public interface Analyzer { /** - * Provides a human-readable string describing this analyzer's conclusion - * on the presented problem, or returns {@code null} if no conclusion - * could be made. + * Provides a human-readable string describing this analyzer's conclusion on + * the presented problem, or returns {@code null} if no conclusion could be + * made. * - * @param throwable The reported throwable (may be {@code null}) - * @param messageFormat A {@linkplain java.util.Formatter#syntax format - * string} of a - * human-readable description of the problem - * @param args The arguments for the format string + * @param throwable + * The reported throwable (may be {@code null}) + * @param messageFormat + * A {@linkplain java.util.Formatter#syntax format string} of a + * human-readable description of the problem + * @param args + * The arguments for the format string * @return a conclusion or {@code null} */ String analyze(Throwable throwable, String messageFormat, Object... args); /** - * Returns this analyzer's human-readable name. - * It should be A String In Title Case With Spaces. + * Returns this analyzer's human-readable name. It should be A String In + * Title Case With Spaces. * * @return this analyzer's name */ diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/ContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/ContextProvider.java index 5b62663..8180e4a 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/ContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/ContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash; import java.util.Map; @@ -33,23 +33,20 @@ public interface ContextProvider { /** * Provides human-readable description of the state of the game and the - * system. - * This information is {@link Map#put(Object, Object) put} into the provided - * map - * as key-value pairs. Keys are the characteristic being described, such as - * "OS Name", - * and should be Strings In Title Case With Spaces. - * If this provider cannot provide any information at this moment, the map - * is not - * modified. + * system. This information is {@link Map#put(Object, Object) put} into the + * provided map as key-value pairs. Keys are the characteristic being + * described, such as "OS Name", and should be Strings In Title Case With + * Spaces. If this provider cannot provide any information at this moment, + * the map is not modified. * - * @param output the map to append output to + * @param output + * the map to append output to */ void provideContext(Map output); /** - * Returns this provider's human-readable name. - * It should be A String In Title Case With Spaces. + * Returns this provider's human-readable name. It should be A String In + * Title Case With Spaces. * * @return this provider's name */ diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java b/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java index ab0ec3e..3b634cf 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/CrashReports.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash; import org.apache.logging.log4j.LogManager; @@ -38,9 +38,8 @@ import java.util.*; /** * A utility for reporting critical problems, gathering system context and - * terminating the application consequently (crashing). - * Do not hesitate to use {@link #report(Throwable, String, Object...)} at every - * other line. + * terminating the application consequently (crashing). Do not hesitate to use + * {@link #report(Throwable, String, Object...)} at every other line. * * @author serega404 */ @@ -56,8 +55,8 @@ public class CrashReports { /** * Creates a {@link ReportedException} that describes the provided problem - * so the program can crash later. - * This method is intended to be used like so: + * so the program can crash later. This method is intended to be used like + * so: * *

       	 * try {
      @@ -68,26 +67,24 @@ public class CrashReports {
       	 * 
      *

      * Such usage ensures that the report will be dealt with at the top of the - * call stack - * (at least in methods that have a properly set up + * call stack (at least in methods that have a properly set up * {@linkplain #crash(Throwable, String, Object...) crash handler}). Not - * throwing the returned - * exception is pointless; using this in a thread without a crash handler - * will not produce a crash. + * throwing the returned exception is pointless; using this in a thread + * without a crash handler will not produce a crash. *

      * Avoid inserting variable information into {@code messageFormat} directly; - * use - * {@linkplain Formatter#summary format string} syntax and {@code args}. - * Different Strings - * in {@code messageFormat} may be interpreted as unrelated problems by - * {@linkplain Analyzer crash analyzers}. + * use {@linkplain Formatter#summary format string} syntax and {@code args}. + * Different Strings in {@code messageFormat} may be interpreted as + * unrelated problems by {@linkplain Analyzer crash analyzers}. * - * @param throwable a {@link Throwable} that caused the problem, if any; - * {@code null} otherwise - * @param messageFormat a human-readable description of the problem - * displayed in the crash report - * @param args an array of arguments for formatting - * {@code messageFormat} + * @param throwable + * a {@link Throwable} that caused the problem, if any; + * {@code null} otherwise + * @param messageFormat + * a human-readable description of the problem displayed in the + * crash report + * @param args + * an array of arguments for formatting {@code messageFormat} * @return an exception containing the provided information that must be * thrown */ @@ -102,32 +99,28 @@ public class CrashReports { * Crashes the program due to the supplied problem. *

      * Use {@link #report(Throwable, String, Object...)} unless you are - * creating a catch-all handler for a - * thread. + * creating a catch-all handler for a thread. *

      * This method recovers information about the problem by casting - * {@code throwable} to {@link ReportedException}, - * or, failing that, uses the provided arguments as the information instead. - * It then constructs a full crash - * report, exports it and terminates the program by invoking + * {@code throwable} to {@link ReportedException}, or, failing that, uses + * the provided arguments as the information instead. It then constructs a + * full crash report, exports it and terminates the program by invoking * {@link System#exit(int)}. *

      * Such behavior can be dangerous or lead to unwanted consequences in the - * middle of the call stack, so it is - * necessary to invoke this method as high on the call stack as possible, - * usually in a {@code catch} clause - * of a {@code try} statement enveloping the thread's main method(s). + * middle of the call stack, so it is necessary to invoke this method as + * high on the call stack as possible, usually in a {@code catch} clause of + * a {@code try} statement enveloping the thread's main method(s). * - * @param throwable a {@link ReportedException} or another - * {@link Throwable} that caused the problem, if any; - * {@code null} otherwise - * @param messageFormat a human-readable description of the problem used - * when {@code throwable} is not a - * {@link ReportedException}. See - * {@link #report(Throwable, String, Object...)} for - * details. - * @param args an array of arguments for formatting - * {@code messageFormat} + * @param throwable + * a {@link ReportedException} or another {@link Throwable} that + * caused the problem, if any; {@code null} otherwise + * @param messageFormat + * a human-readable description of the problem used when + * {@code throwable} is not a {@link ReportedException}. See + * {@link #report(Throwable, String, Object...)} for details. + * @param args + * an array of arguments for formatting {@code messageFormat} * @return {@code null}, although this method never returns normally. * Provided for convenience. */ @@ -229,12 +222,8 @@ public class CrashReports { } } - private static boolean appendAnalyzers( - StringBuilder output, - Throwable throwable, - String messageFormat, - Object[] args - ) { + private static boolean appendAnalyzers(StringBuilder output, Throwable throwable, String messageFormat, + Object[] args) { boolean analyzerResponsesExist = false; // Do a local copy to avoid deadlocks -OLEGSHA @@ -334,10 +323,8 @@ public class CrashReports { Files.createDirectory(CRASH_REPORTS_PATH); createFileForCrashReport(output, CRASH_REPORTS_PATH.toString() + "/latest.log"); - createFileForCrashReport( - output, - CRASH_REPORTS_PATH.toString() + "/crash-" + dateFormat.format(date) + ".log" - ); + createFileForCrashReport(output, + CRASH_REPORTS_PATH.toString() + "/crash-" + dateFormat.format(date) + ".log"); } catch (Throwable t) { // Crash Report not created } @@ -359,7 +346,8 @@ public class CrashReports { * Registers the provided {@link ContextProvider} so it is consulted in the * case of a crash. * - * @param provider the provider to register + * @param provider + * the provider to register */ public static void registerProvider(ContextProvider provider) { PROVIDERS.add(provider); @@ -369,7 +357,8 @@ public class CrashReports { * Registers the provided {@link Analyzer} so it is consulted in the case of * a crash. * - * @param analyzer the analyzer to register + * @param analyzer + * the analyzer to register */ public static void registerAnalyzer(Analyzer analyzer) { ANALYZERS.add(analyzer); @@ -377,11 +366,10 @@ public class CrashReports { /** * A wrapper used by {@link CrashReports} to transfer problem details from - * the place of - * occurrence to the handler at the top of the stack. Rethrow if caught - * (unless using {@link CrashReports#report(Throwable, String, Object...)}, - * which does - * so automatically). + * the place of occurrence to the handler at the top of the stack. Rethrow + * if caught (unless using + * {@link CrashReports#report(Throwable, String, Object...)}, which does so + * automatically). * * @author serega404 */ @@ -395,11 +383,13 @@ public class CrashReports { /** * Constructs a {@link ReportedException}. * - * @param throwable the reported {@link Throwable} or {@code null} - * @param messageFormat the reported message format. - * This is not the message of the constructed - * Exception. - * @param args the reported message format arguments + * @param throwable + * the reported {@link Throwable} or {@code null} + * @param messageFormat + * the reported message format. This is not the message + * of the constructed Exception. + * @param args + * the reported message format arguments */ public ReportedException(Throwable throwable, String messageFormat, Object... args) { super(throwable); diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java b/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java index 141efa9..87bb0f1 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash; import com.google.common.eventbus.EventBus; @@ -28,14 +28,11 @@ public class ReportingEventBus { } public static EventBus create(String identifier) { - return GuavaEventBusHijacker.newEventBus( - identifier, - (throwable, context) -> { - // Makes sense to append identifier to messageFormat because - // different EventBuses are completely unrelated - throw CrashReports.crash(throwable, "Unexpected exception in EventBus " + identifier); - } - ); + return GuavaEventBusHijacker.newEventBus(identifier, (throwable, context) -> { + // Makes sense to append identifier to messageFormat because + // different EventBuses are completely unrelated + throw CrashReports.crash(throwable, "Unexpected exception in EventBus " + identifier); + }); } } diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/analyzers/OutOfMemoryAnalyzer.java b/src/main/java/ru/windcorp/progressia/common/util/crash/analyzers/OutOfMemoryAnalyzer.java index c07152f..647e9b3 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/analyzers/OutOfMemoryAnalyzer.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/analyzers/OutOfMemoryAnalyzer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.analyzers; import ru.windcorp.progressia.common.util.crash.Analyzer; diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/ArgsContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/ArgsContextProvider.java index 6c16902..55786c5 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/ArgsContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/ArgsContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.providers; import ru.windcorp.progressia.ProgressiaLauncher; diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/JavaVersionContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/JavaVersionContextProvider.java index b8f4358..184a916 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/JavaVersionContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/JavaVersionContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.providers; import ru.windcorp.progressia.common.util.crash.ContextProvider; diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/LanguageContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/LanguageContextProvider.java index ca9d387..8de2668 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/LanguageContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/LanguageContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.providers; import ru.windcorp.progressia.client.localization.Localizer; diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OSContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OSContextProvider.java index 7fd4610..56752fd 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OSContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OSContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.providers; import ru.windcorp.progressia.common.util.crash.ContextProvider; diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OpenALContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OpenALContextProvider.java index ad31bba..77626b3 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OpenALContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/OpenALContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.providers; import ru.windcorp.progressia.client.audio.AudioManager; diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/RAMContextProvider.java b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/RAMContextProvider.java index 9c60921..47e9dd5 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/crash/providers/RAMContextProvider.java +++ b/src/main/java/ru/windcorp/progressia/common/util/crash/providers/RAMContextProvider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.crash.providers; import ru.windcorp.progressia.common.util.crash.ContextProvider; @@ -29,11 +29,8 @@ public class RAMContextProvider implements ContextProvider { output.put("Max Memory", Runtime.getRuntime().maxMemory() / 1024 / 1024 + " MB"); output.put("Total Memory", Runtime.getRuntime().totalMemory() / 1024 / 1024 + " MB"); output.put("Free Memory", Runtime.getRuntime().freeMemory() / 1024 / 1024 + " MB"); - output.put( - "Used Memory", - (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024 - + " MB" - ); + output.put("Used Memory", + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024 + " MB"); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/util/dynstr/DoubleFlusher.java b/src/main/java/ru/windcorp/progressia/common/util/dynstr/DoubleFlusher.java index 6068669..ab21b4b 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/dynstr/DoubleFlusher.java +++ b/src/main/java/ru/windcorp/progressia/common/util/dynstr/DoubleFlusher.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.dynstr; import gnu.trove.list.TCharList; diff --git a/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicString.java b/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicString.java index 8376a3d..89892c1 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicString.java +++ b/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicString.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.dynstr; import java.util.function.Supplier; @@ -45,8 +45,8 @@ public final class DynamicString implements CharSequence { } /** - * Causes the contents of this string to be reevaluated. - * This is not currently thread-safe, take caution. + * Causes the contents of this string to be reevaluated. This is not + * currently thread-safe, take caution. */ public void update() { chars.clear(); diff --git a/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicStrings.java b/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicStrings.java index 030cd9d..0b5745e 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicStrings.java +++ b/src/main/java/ru/windcorp/progressia/common/util/dynstr/DynamicStrings.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.dynstr; import java.util.ArrayList; diff --git a/src/main/java/ru/windcorp/progressia/common/util/dynstr/FloatFlusher.java b/src/main/java/ru/windcorp/progressia/common/util/dynstr/FloatFlusher.java index 0b245ee..26a727e 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/dynstr/FloatFlusher.java +++ b/src/main/java/ru/windcorp/progressia/common/util/dynstr/FloatFlusher.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.dynstr; import gnu.trove.list.TCharList; diff --git a/src/main/java/ru/windcorp/progressia/common/util/dynstr/IntFlusher.java b/src/main/java/ru/windcorp/progressia/common/util/dynstr/IntFlusher.java index 9924f81..937c9fa 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/dynstr/IntFlusher.java +++ b/src/main/java/ru/windcorp/progressia/common/util/dynstr/IntFlusher.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.dynstr; import gnu.trove.list.TCharList; @@ -61,211 +61,19 @@ class IntFlusher { /* * Copied from OpenJDK's Integer.DigitTens and Integer.DigitOnes */ - private static final char[] DIGIT_TENS = { - '0', - '0', - '0', - '0', - '0', - '0', - '0', - '0', - '0', - '0', - '1', - '1', - '1', - '1', - '1', - '1', - '1', - '1', - '1', - '1', - '2', - '2', - '2', - '2', - '2', - '2', - '2', - '2', - '2', - '2', - '3', - '3', - '3', - '3', - '3', - '3', - '3', - '3', - '3', - '3', - '4', - '4', - '4', - '4', - '4', - '4', - '4', - '4', - '4', - '4', - '5', - '5', - '5', - '5', - '5', - '5', - '5', - '5', - '5', - '5', - '6', - '6', - '6', - '6', - '6', - '6', - '6', - '6', - '6', - '6', - '7', - '7', - '7', - '7', - '7', - '7', - '7', - '7', - '7', - '7', - '8', - '8', - '8', - '8', - '8', - '8', - '8', - '8', - '8', - '8', - '9', - '9', - '9', - '9', - '9', - '9', - '9', - '9', - '9', - '9', - }; + private static final char[] DIGIT_TENS = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', + '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', + '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', + '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', + '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', + '9', '9', }; - private static final char[] DIGIT_ONES = { - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - }; + private static final char[] DIGIT_ONES = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', }; /* * Adapted from OpenJDK's Integer.getChars(int, int, byte[]) diff --git a/src/main/java/ru/windcorp/progressia/common/util/namespaces/IllegalIdException.java b/src/main/java/ru/windcorp/progressia/common/util/namespaces/IllegalIdException.java index d896bac..ba27e4a 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/namespaces/IllegalIdException.java +++ b/src/main/java/ru/windcorp/progressia/common/util/namespaces/IllegalIdException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.namespaces; public class IllegalIdException extends RuntimeException { @@ -26,12 +26,8 @@ public class IllegalIdException extends RuntimeException { super(); } - protected IllegalIdException( - String message, - Throwable cause, - boolean enableSuppression, - boolean writableStackTrace - ) { + protected IllegalIdException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } diff --git a/src/main/java/ru/windcorp/progressia/common/util/namespaces/Namespaced.java b/src/main/java/ru/windcorp/progressia/common/util/namespaces/Namespaced.java index 2d87007..557804b 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/namespaces/Namespaced.java +++ b/src/main/java/ru/windcorp/progressia/common/util/namespaces/Namespaced.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.namespaces; public abstract class Namespaced { diff --git a/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedFactoryRegistry.java b/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedFactoryRegistry.java index 2a94593..9f419fd 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedFactoryRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedFactoryRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.namespaces; import java.util.Collection; @@ -28,7 +28,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class NamespacedFactoryRegistry - implements Map> { + implements Map> { @FunctionalInterface public static interface Factory { @@ -86,8 +86,7 @@ public class NamespacedFactoryRegistry E result = factory.build(id); if (!result.getId().equals(id)) { throw new IllegalStateException( - "Requested ID " + id + " but factory " + factory + " returned an object with ID " + result.getId() - ); + "Requested ID " + id + " but factory " + factory + " returned an object with ID " + result.getId()); } return result; } diff --git a/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedInstanceRegistry.java b/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedInstanceRegistry.java index ce1f3cf..e748fe7 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedInstanceRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedInstanceRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.namespaces; import java.util.Collection; @@ -29,8 +29,7 @@ import org.apache.logging.log4j.Logger; import com.google.errorprone.annotations.DoNotCall; -public class NamespacedInstanceRegistry - implements Map { +public class NamespacedInstanceRegistry implements Map { private final Map backingMap = Collections.synchronizedMap(new HashMap<>()); @@ -87,9 +86,7 @@ public class NamespacedInstanceRegistry @DoNotCall @Deprecated public E put(String key, E value) { - throw new UnsupportedOperationException( - "Use NamespacedInstanceRegistry.register(E)" - ); + throw new UnsupportedOperationException("Use NamespacedInstanceRegistry.register(E)"); } @Override @@ -104,9 +101,7 @@ public class NamespacedInstanceRegistry @DoNotCall @Deprecated public void putAll(Map m) { - throw new UnsupportedOperationException( - "Use NamespacedInstanceRegistry.registerAll(Collection)" - ); + throw new UnsupportedOperationException("Use NamespacedInstanceRegistry.registerAll(Collection)"); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedUtil.java b/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedUtil.java index b969b8e..0796c50 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedUtil.java +++ b/src/main/java/ru/windcorp/progressia/common/util/namespaces/NamespacedUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.util.namespaces; import java.util.Objects; @@ -38,8 +38,8 @@ public class NamespacedUtil { public static final int MIN_NAME_LENGTH = MIN_PART_LENGTH; /* - * This is the definition of the accepted pattern, but the value of - * these constants is not actually consulted in the check* methods. + * This is the definition of the accepted pattern, but the value of these + * constants is not actually consulted in the check* methods. */ private static final String PART_CORE_REGEX = "[A-Z][a-zA-Z0-9]{2," + (MAX_PART_LENGTH - 1) + "}"; private static final String PART_REGEX = "^" + PART_CORE_REGEX + "$"; @@ -75,10 +75,8 @@ public class NamespacedUtil { if (areSeparatorsInvalid) { int separators = StringUtil.count(id, SEPARATOR); throw new IllegalIdException( - "ID \"" + id + "\" is invalid. " - + (separators == 0 ? "No " : "Too many (" + separators + ") ") - + "separators '" + SEPARATOR + "' found, exactly one required" - ); + "ID \"" + id + "\" is invalid. " + (separators == 0 ? "No " : "Too many (" + separators + ") ") + + "separators '" + SEPARATOR + "' found, exactly one required"); } checkPart(id, 0, firstSeparator, "namespace"); @@ -89,32 +87,20 @@ public class NamespacedUtil { Objects.requireNonNull(data, nameForErrors); if (length > MAX_PART_LENGTH) { - throw new IllegalIdException( - nameForErrors + " \"" + data.substring(offset, offset + length) + "\" is too long. " - + "Expected at most " + MAX_PART_LENGTH - + " characters" - ); + throw new IllegalIdException(nameForErrors + " \"" + data.substring(offset, offset + length) + + "\" is too long. " + "Expected at most " + MAX_PART_LENGTH + " characters"); } else if (length < MIN_PART_LENGTH) { - throw new IllegalIdException( - nameForErrors + " \"" + data.substring(offset, offset + length) + "\" is too short. " - + "Expected at lest " + MIN_PART_LENGTH - + " characters" - ); + throw new IllegalIdException(nameForErrors + " \"" + data.substring(offset, offset + length) + + "\" is too short. " + "Expected at lest " + MIN_PART_LENGTH + " characters"); } // Don't actually use *_REGEX for speed for (int i = 0; i < length; ++i) { char c = data.charAt(i + offset); - if ( - !((c >= 'A' && c <= 'Z') || - (i != 0 && c >= 'a' && c <= 'z') || - (i != 0 && c >= '0' && c <= '9')) - ) { - throw new IllegalIdException( - nameForErrors + " \"" + data.substring(offset, offset + length) + "\" is invalid. " - + "Allowed is: " + PART_REGEX - ); + if (!((c >= 'A' && c <= 'Z') || (i != 0 && c >= 'a' && c <= 'z') || (i != 0 && c >= '0' && c <= '9'))) { + throw new IllegalIdException(nameForErrors + " \"" + data.substring(offset, offset + length) + + "\" is invalid. " + "Allowed is: " + PART_REGEX); } } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java index 4d5f1f9..e94ec08 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java +++ b/src/main/java/ru/windcorp/progressia/common/world/BlockRay.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import glm.vec._3.Vec3; @@ -159,7 +159,8 @@ public class BlockRay { /** * Returns a smallest integer a such that a > c. * - * @param c the number to compute strict ceiling of + * @param c + * the number to compute strict ceiling of * @return the strict ceiling of c */ private static float strictCeil(float c) { @@ -169,7 +170,8 @@ public class BlockRay { /** * Returns a largest integer a such that a < c. * - * @param c the number to compute strict ceiling of + * @param c + * the number to compute strict ceiling of * @return the strict ceiling of c */ private static float strictFloor(float c) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 252429c..9a49545 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import static ru.windcorp.progressia.common.world.block.BlockFace.*; @@ -38,8 +38,7 @@ import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.common.world.tile.TileReference; import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; -public class ChunkData - implements GenericChunk { +public class ChunkData implements GenericChunk { public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; @@ -48,8 +47,8 @@ public class ChunkData private final BlockData[] blocks = new BlockData[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; - private final TileDataStack[] tiles = new TileDataStack[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * - BLOCK_FACE_COUNT]; + private final TileDataStack[] tiles = new TileDataStack[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + * BLOCK_FACE_COUNT]; private Object generationHint = null; @@ -90,14 +89,9 @@ public class ChunkData /** * Internal use only. Modify a list returned by * {@link #getTiles(Vec3i, BlockFace)} or - * {@link #getTilesOrNull(Vec3i, BlockFace)} - * to change tiles. + * {@link #getTilesOrNull(Vec3i, BlockFace)} to change tiles. */ - protected void setTiles( - Vec3i blockInChunk, - BlockFace face, - TileDataStack tiles - ) { + protected void setTiles(Vec3i blockInChunk, BlockFace face, TileDataStack tiles) { this.tiles[getTileIndex(blockInChunk, face)] = tiles; } @@ -137,51 +131,34 @@ public class ChunkData private static int getBlockIndex(Vec3i posInChunk) { checkLocalCoordinates(posInChunk); - return posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + - posInChunk.y * BLOCKS_PER_CHUNK + - posInChunk.x; + return posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + posInChunk.y * BLOCKS_PER_CHUNK + posInChunk.x; } private static int getTileIndex(Vec3i posInChunk, BlockFace face) { - return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + - face.getId(); + return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + face.getId(); } private static void checkLocalCoordinates(Vec3i posInChunk) { if (!isInBounds(posInChunk)) { throw new IllegalCoordinatesException( - "Coordinates " + str(posInChunk) + " " - + "are not legal chunk coordinates" - ); + "Coordinates " + str(posInChunk) + " " + "are not legal chunk coordinates"); } } public static boolean isInBounds(Vec3i posInChunk) { - return posInChunk.x >= 0 && posInChunk.x < BLOCKS_PER_CHUNK && - posInChunk.y >= 0 && posInChunk.y < BLOCKS_PER_CHUNK && - posInChunk.z >= 0 && posInChunk.z < BLOCKS_PER_CHUNK; + return posInChunk.x >= 0 && posInChunk.x < BLOCKS_PER_CHUNK && posInChunk.y >= 0 + && posInChunk.y < BLOCKS_PER_CHUNK && posInChunk.z >= 0 && posInChunk.z < BLOCKS_PER_CHUNK; } public boolean isBorder(Vec3i blockInChunk, BlockFace face) { final int min = 0, max = BLOCKS_PER_CHUNK - 1; - return (blockInChunk.x == min && face == SOUTH) || - (blockInChunk.x == max && face == NORTH) || - (blockInChunk.y == min && face == EAST) || - (blockInChunk.y == max && face == WEST) || - (blockInChunk.z == min && face == BOTTOM) || - (blockInChunk.z == max && face == TOP); + return (blockInChunk.x == min && face == SOUTH) || (blockInChunk.x == max && face == NORTH) + || (blockInChunk.y == min && face == EAST) || (blockInChunk.y == max && face == WEST) + || (blockInChunk.z == min && face == BOTTOM) || (blockInChunk.z == max && face == TOP); } public void forEachBlock(Consumer action) { - VectorUtil.iterateCuboid( - 0, - 0, - 0, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - action - ); + VectorUtil.iterateCuboid(0, 0, 0, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, action); } public void forEachTileStack(Consumer action) { @@ -198,8 +175,9 @@ public class ChunkData /** * Iterates over all tiles in this chunk. * - * @param action the action to perform. {@code TileLocation} refers to each - * tile using its primary block + * @param action + * the action to perform. {@code TileLocation} refers to each + * tile using its primary block */ public void forEachTile(BiConsumer action) { forEachTileStack(stack -> stack.forEach(tileData -> action.accept(stack, tileData))); @@ -243,10 +221,8 @@ public class ChunkData /** * Implementation of {@link TileDataStack} used internally by - * {@link ChunkData} to - * actually store the tiles. This is basically an array wrapper with - * reporting - * capabilities. + * {@link ChunkData} to actually store the tiles. This is basically an array + * wrapper with reporting capabilities. * * @author javapony */ @@ -412,8 +388,7 @@ public class ChunkData return; if (assignedTag == -1) { throw new IllegalArgumentException( - "Tag " + tag + " already used by tile at index " + getIndexByTag(tag) - ); + "Tag " + tag + " already used by tile at index " + getIndexByTag(tag)); } indicesByTag[tagsByIndex[size() - 1]] = -1; @@ -498,8 +473,7 @@ public class ChunkData if (index >= TILES_PER_FACE) throw new TileStackIsFullException( - "Index " + index + " is out of bounds: maximum tile stack size is " + TILES_PER_FACE - ); + "Index " + index + " is out of bounds: maximum tile stack size is " + TILES_PER_FACE); } private void report(TileData previous, TileData current) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java index 72008c4..f9a7fb2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import glm.vec._3.i.Vec3i; @@ -26,49 +26,50 @@ import ru.windcorp.progressia.common.world.tile.TileData; public interface ChunkDataListener { /** - * Invoked after a block has changed in a chunk. - * This is not triggered when a change is caused by chunk loading or - * unloading. + * Invoked after a block has changed in a chunk. This is not triggered when + * a change is caused by chunk loading or unloading. * - * @param chunk the chunk that has changed - * @param blockInChunk the {@linkplain Coordinates#blockInChunk chunk - * coordinates} of the change - * @param previous the previous occupant of {@code blockInChunk} - * @param current the current (new) occupant of {@code blockInChunk} + * @param chunk + * the chunk that has changed + * @param blockInChunk + * the {@linkplain Coordinates#blockInChunk chunk coordinates} of + * the change + * @param previous + * the previous occupant of {@code blockInChunk} + * @param current + * the current (new) occupant of {@code blockInChunk} */ default void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { } /** - * Invoked after a tile has been added or removed from a chunk. - * This is not triggered when a change is caused by chunk loading or - * unloading. + * Invoked after a tile has been added or removed from a chunk. This is not + * triggered when a change is caused by chunk loading or unloading. * - * @param chunk the chunk that has changed - * @param blockInChunk the {@linkplain Coordinates#blockInChunk chunk - * coordinates} of the change - * @param face the face that the changed tile belongs or belonged to - * @param tile the tile that has been added or removed - * @param wasAdded {@code true} iff the tile has been added, - * {@code false} iff the tile has been removed + * @param chunk + * the chunk that has changed + * @param blockInChunk + * the {@linkplain Coordinates#blockInChunk chunk coordinates} of + * the change + * @param face + * the face that the changed tile belongs or belonged to + * @param tile + * the tile that has been added or removed + * @param wasAdded + * {@code true} iff the tile has been added, {@code false} iff + * the tile has been removed */ - default void onChunkTilesChanged( - ChunkData chunk, - Vec3i blockInChunk, - BlockFace face, - TileData tile, - boolean wasAdded - ) { + default void onChunkTilesChanged(ChunkData chunk, Vec3i blockInChunk, BlockFace face, TileData tile, + boolean wasAdded) { } /** * Invoked whenever a chunk changes, loads or unloads. If some other method - * in this - * {@code ChunkDataListener} are to be invoked, e.g. is the change was - * caused by a - * block being removed, this method is called last. + * in this {@code ChunkDataListener} are to be invoked, e.g. is the change + * was caused by a block being removed, this method is called last. * - * @param chunk the chunk that has changed + * @param chunk + * the chunk that has changed */ default void onChunkChanged(ChunkData chunk) { } @@ -76,7 +77,8 @@ public interface ChunkDataListener { /** * Invoked whenever a chunk has been loaded. * - * @param chunk the chunk that has loaded + * @param chunk + * the chunk that has loaded */ default void onChunkLoaded(ChunkData chunk) { } @@ -84,7 +86,8 @@ public interface ChunkDataListener { /** * Invoked whenever a chunk is about to be unloaded. * - * @param chunk the chunk that is going to be loaded + * @param chunk + * the chunk that is going to be loaded */ default void beforeChunkUnloaded(ChunkData chunk) { } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java index b39437c..fdae0ab 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java b/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java index 55f2076..bc26afe 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java +++ b/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; @@ -29,20 +29,17 @@ import glm.vec._3.i.Vec3i; * Three types of coordinates are used in Progressia: *

        *
      • World coordinates, in code referred to as - * {@code blockInWorld} - - * coordinates relative to world origin. Every block in the world has unique - * world coordinates.
      • + * {@code blockInWorld} - coordinates relative to world origin. Every block in + * the world has unique world coordinates. *
      • Chunk coordinates, in code referred to as - * {@code blockInChunk} - - * coordinates relative some chunk's origin. Every block in the chunk has unique - * chunk coordinates, but blocks in different chunks may have identical chunk - * coordinates. These coordinates are only useful in combination with a chunk - * reference. Chunk coordinates are always + * {@code blockInChunk} - coordinates relative some chunk's origin. Every block + * in the chunk has unique chunk coordinates, but blocks in different chunks may + * have identical chunk coordinates. These coordinates are only useful in + * combination with a chunk reference. Chunk coordinates are always * [0; {@link #BLOCKS_PER_CHUNK}).
      • *
      • Coordinates of chunk, in code referred to as - * {@code chunk} - - * chunk coordinates relative to world origin. Every chunk in the world has - * unique coordinates of chunk.
      • + * {@code chunk} - chunk coordinates relative to world origin. Every chunk in + * the world has unique coordinates of chunk. *
      */ public class Coordinates { @@ -55,7 +52,8 @@ public class Coordinates { * Computes the coordinate of the chunk that the block specified by the * provided world coordinate belongs to. * - * @param blockInWorld world coordinate of the block + * @param blockInWorld + * world coordinate of the block * @return the corresponding coordinate of the chunk containing the block * @see #convertInWorldToChunk(Vec3i, Vec3i) */ @@ -67,15 +65,14 @@ public class Coordinates { * Computes the coordinates of the chunk that the block specified by the * provided world coordinates belongs to. * - * @param blockInWorld world coordinates of the block - * @param output a {@link Vec3i} to store the result in + * @param blockInWorld + * world coordinates of the block + * @param output + * a {@link Vec3i} to store the result in * @return {@code output} * @see #convertInWorldToChunk(int) */ - public static Vec3i convertInWorldToChunk( - Vec3i blockInWorld, - Vec3i output - ) { + public static Vec3i convertInWorldToChunk(Vec3i blockInWorld, Vec3i output) { if (output == null) output = new Vec3i(); @@ -87,10 +84,11 @@ public class Coordinates { } /** - * Computes the chunk coordinate that the block specified by the - * provided world coordinate has in its chunk. + * Computes the chunk coordinate that the block specified by the provided + * world coordinate has in its chunk. * - * @param blockInWorld world coordinate of the block + * @param blockInWorld + * world coordinate of the block * @return the corresponding chunk coordinate of the block * @see #convertInWorldToInChunk(Vec3i, Vec3i) */ @@ -99,18 +97,17 @@ public class Coordinates { } /** - * Computes the chunk coordinates that the block specified by the - * provided world coordinates has in its chunk. + * Computes the chunk coordinates that the block specified by the provided + * world coordinates has in its chunk. * - * @param blockInWorld world coordinates of the block - * @param output a {@link Vec3i} to store the result in + * @param blockInWorld + * world coordinates of the block + * @param output + * a {@link Vec3i} to store the result in * @return {@code output} * @see #convertInWorldToInChunk(int) */ - public static Vec3i convertInWorldToInChunk( - Vec3i blockInWorld, - Vec3i output - ) { + public static Vec3i convertInWorldToInChunk(Vec3i blockInWorld, Vec3i output) { if (output == null) output = new Vec3i(); @@ -125,8 +122,10 @@ public class Coordinates { * Computes the world coordinate of the block specified by its chunk * coordinate and the coordinate of its chunk. * - * @param chunk coordinate of chunk - * @param blockInChunk chunk coordinate of block + * @param chunk + * coordinate of chunk + * @param blockInChunk + * chunk coordinate of block * @return corresponding world coordinate * @see #getInWorld(int, int) */ @@ -138,17 +137,16 @@ public class Coordinates { * Computes the world coordinates of the block specified by its chunk * coordinates and the coordinates of its chunk. * - * @param chunk coordinate of chunk - * @param blockInChunk chunk coordinate of block - * @param output a {@link Vec3i} to store the result in + * @param chunk + * coordinate of chunk + * @param blockInChunk + * chunk coordinate of block + * @param output + * a {@link Vec3i} to store the result in * @return {@code output} * @see #getInWorld(int) */ - public static Vec3i getInWorld( - Vec3i chunk, - Vec3i blockInChunk, - Vec3i output - ) { + public static Vec3i getInWorld(Vec3i chunk, Vec3i blockInChunk, Vec3i output) { if (output == null) output = new Vec3i(); @@ -158,7 +156,7 @@ public class Coordinates { return output; } - + public static boolean isOnChunkBorder(int blockInChunk) { return blockInChunk == 0 || blockInChunk == BLOCKS_PER_CHUNK - 1; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/DecodingException.java b/src/main/java/ru/windcorp/progressia/common/world/DecodingException.java index 532d22f..410bfad 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/DecodingException.java +++ b/src/main/java/ru/windcorp/progressia/common/world/DecodingException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/IllegalCoordinatesException.java b/src/main/java/ru/windcorp/progressia/common/world/IllegalCoordinatesException.java index 69240cf..1c3a3d3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/IllegalCoordinatesException.java +++ b/src/main/java/ru/windcorp/progressia/common/world/IllegalCoordinatesException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; public class IllegalCoordinatesException extends RuntimeException { @@ -38,12 +38,8 @@ public class IllegalCoordinatesException extends RuntimeException { super(message, cause); } - public IllegalCoordinatesException( - String message, - Throwable cause, - boolean enableSuppression, - boolean writableStackTrace - ) { + public IllegalCoordinatesException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java index 95e6eab..fdd4ce3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java index 8433b9b..1432f1c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import ru.windcorp.progressia.common.comms.packets.Packet; diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java index c65b045..c1ab7e3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java index ca079ff..12a78c8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSetLocalPlayer.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSetLocalPlayer.java index f835614..625a4c5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSetLocalPlayer.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSetLocalPlayer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/PlayerData.java b/src/main/java/ru/windcorp/progressia/common/world/PlayerData.java index 2123e3f..ecd512b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PlayerData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PlayerData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import ru.windcorp.progressia.common.world.entity.EntityData; diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 85c6188..8b8db6b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.util.ArrayList; @@ -39,12 +39,10 @@ import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataStack; -public class WorldData - implements GenericWorld { +public class WorldData implements GenericWorld { private final ChunkMap chunksByPos = new LongBasedChunkMap<>( - TCollections.synchronizedMap(new TLongObjectHashMap<>()) - ); + TCollections.synchronizedMap(new TLongObjectHashMap<>())); private final Collection chunks = Collections.unmodifiableCollection(chunksByPos.values()); @@ -102,14 +100,8 @@ public class WorldData ChunkData previous = chunksByPos.get(chunk); if (previous != null) { - throw new IllegalArgumentException( - String.format( - "Chunk at (%d; %d; %d) already exists", - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ) - ); + throw new IllegalArgumentException(String.format("Chunk at (%d; %d; %d) already exists", + chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z)); } chunksByPos.put(chunk, chunk); @@ -128,11 +120,8 @@ public class WorldData public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { ChunkData chunk = getChunkByBlock(blockInWorld); if (chunk == null) - throw new IllegalCoordinatesException( - "Coordinates " - + "(" + blockInWorld.x + "; " + blockInWorld.y + "; " + blockInWorld.z + ") " - + "do not belong to a loaded chunk" - ); + throw new IllegalCoordinatesException("Coordinates " + "(" + blockInWorld.x + "; " + blockInWorld.y + "; " + + blockInWorld.z + ") " + "do not belong to a loaded chunk"); chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify); } @@ -167,8 +156,7 @@ public class WorldData if (entity == null) { throw new IllegalArgumentException( - "Entity with EntityID " + EntityData.formatEntityId(entityId) + " not present" - ); + "Entity with EntityID " + EntityData.formatEntityId(entityId) + " not present"); } else { removeEntity(entity); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java index 9211efd..875bb93 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.util.function.Consumer; @@ -27,19 +27,20 @@ public interface WorldDataListener { /** * Invoked when a new {@link ChunkData} instance is created. This method - * should be used to add - * {@link ChunkDataListener}s to a new chunk. When listeners are added with - * this method, - * their {@link ChunkDataListener#onChunkLoaded(ChunkData) onChunkLoaded} - * methods will be invoked. + * should be used to add {@link ChunkDataListener}s to a new chunk. When + * listeners are added with this method, their + * {@link ChunkDataListener#onChunkLoaded(ChunkData) onChunkLoaded} methods + * will be invoked. * - * @param world the world instance - * @param chunk the {@linkplain Coordinates#chunk coordinates of - * chunk} of the chunk about to load - * @param chunkListenerSink a sink for listeners. All listeners passed to - * its - * {@link Consumer#accept(Object) accept} method - * will be added to the chunk. + * @param world + * the world instance + * @param chunk + * the {@linkplain Coordinates#chunk coordinates of chunk} of the + * chunk about to load + * @param chunkListenerSink + * a sink for listeners. All listeners passed to its + * {@link Consumer#accept(Object) accept} method will be added to + * the chunk. */ default void getChunkListeners(WorldData world, Vec3i chunk, Consumer chunkListenerSink) { } @@ -47,8 +48,10 @@ public interface WorldDataListener { /** * Invoked whenever a {@link Chunk} has been loaded. * - * @param world the world instance - * @param chunk the chunk that has loaded + * @param world + * the world instance + * @param chunk + * the chunk that has loaded */ default void onChunkLoaded(WorldData world, ChunkData chunk) { } @@ -56,8 +59,10 @@ public interface WorldDataListener { /** * Invoked whenever a {@link Chunk} is about to be unloaded. * - * @param world the world instance - * @param chunk the chunk that is going to be unloaded + * @param world + * the world instance + * @param chunk + * the chunk that is going to be unloaded */ default void beforeChunkUnloaded(WorldData world, ChunkData chunk) { } @@ -65,8 +70,10 @@ public interface WorldDataListener { /** * Invoked whenever an {@link EntityData} has been added. * - * @param world the world instance - * @param entity the entity that has been added + * @param world + * the world instance + * @param entity + * the entity that has been added */ default void onEntityAdded(WorldData world, EntityData entity) { } @@ -74,8 +81,10 @@ public interface WorldDataListener { /** * Invoked whenever an {@link EntityData} is about to be removed. * - * @param world the world instance - * @param entity the entity that is going to be removed + * @param world + * the world instance + * @param entity + * the entity that is going to be removed */ default void beforeEntityRemoved(WorldData world, EntityData entity) { } diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java b/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java index e94f838..2c9d352 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.block; import ru.windcorp.progressia.common.collision.AABB; diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockDataRegistry.java b/src/main/java/ru/windcorp/progressia/common/world/block/BlockDataRegistry.java index ac1934c..68b7412 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockDataRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/BlockDataRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.block; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java b/src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java index 9023500..741a4d8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/BlockFace.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.block; import com.google.common.collect.ImmutableList; @@ -26,11 +26,9 @@ import glm.vec._3.i.Vec3i; public final class BlockFace extends BlockRelation { public static final BlockFace TOP = new BlockFace(0, 0, +1, true, "TOP"), - BOTTOM = new BlockFace(0, 0, -1, false, "BOTTOM"), - NORTH = new BlockFace(+1, 0, 0, true, "NORTH"), - SOUTH = new BlockFace(-1, 0, 0, false, "SOUTH"), - WEST = new BlockFace(0, +1, 0, false, "WEST"), - EAST = new BlockFace(0, -1, 0, true, "EAST"); + BOTTOM = new BlockFace(0, 0, -1, false, "BOTTOM"), NORTH = new BlockFace(+1, 0, 0, true, "NORTH"), + SOUTH = new BlockFace(-1, 0, 0, false, "SOUTH"), WEST = new BlockFace(0, +1, 0, false, "WEST"), + EAST = new BlockFace(0, -1, 0, true, "EAST"); private static final ImmutableList ALL_FACES = ImmutableList.of(TOP, BOTTOM, NORTH, SOUTH, WEST, EAST); @@ -41,10 +39,10 @@ public final class BlockFace extends BlockRelation { } private static final ImmutableList PRIMARY_FACES = ALL_FACES.stream().filter(BlockFace::isPrimary) - .collect(ImmutableList.toImmutableList()); + .collect(ImmutableList.toImmutableList()); private static final ImmutableList SECONDARY_FACES = ALL_FACES.stream().filter(BlockFace::isSecondary) - .collect(ImmutableList.toImmutableList()); + .collect(ImmutableList.toImmutableList()); public static final int BLOCK_FACE_COUNT = ALL_FACES.size(); public static final int PRIMARY_BLOCK_FACE_COUNT = PRIMARY_FACES.size(); @@ -67,22 +65,9 @@ public final class BlockFace extends BlockRelation { b.counterFace = a; } - public static ImmutableMap mapToFaces( - E top, - E bottom, - E north, - E south, - E east, - E west - ) { - return ImmutableMap.builderWithExpectedSize(6) - .put(TOP, top) - .put(BOTTOM, bottom) - .put(NORTH, north) - .put(SOUTH, south) - .put(EAST, east) - .put(WEST, west) - .build(); + public static ImmutableMap mapToFaces(E top, E bottom, E north, E south, E east, E west) { + return ImmutableMap.builderWithExpectedSize(6).put(TOP, top).put(BOTTOM, bottom).put(NORTH, north) + .put(SOUTH, south).put(EAST, east).put(WEST, west).build(); } private static int nextId = 0; diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java b/src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java index 659a5fa..ce6997e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/BlockRelation.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.block; import static java.lang.Math.abs; @@ -43,7 +43,7 @@ public class BlockRelation { public Vec3i getVector() { return vector; } - + public Vec3 getFloatVector() { return floatVector; } @@ -65,9 +65,9 @@ public class BlockRelation { /** * Returns the Manhattan distance, also known as the taxicab distance, * between the source and the destination blocks. Manhattan distance is - * defined as the sum of the absolute values of the coordinates, - * which is also the minimum amount of block faces that need to be crossed - * to move from source to destination. + * defined as the sum of the absolute values of the coordinates, which is + * also the minimum amount of block faces that need to be crossed to move + * from source to destination. * * @return the sum of the absolute values of the coordinates */ diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java b/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java index 2c1c8a2..5a4a3ac 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.block; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java index 55d0eb2..a29fa2e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.block; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index 7b3325c..3201972 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; @@ -40,8 +40,8 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn /** * The unique {@code long} value guaranteed to never be assigned to an - * entity as its entity ID. - * This can safely be used as a placeholder or a sentinel value. + * entity as its entity ID. This can safely be used as a placeholder or a + * sentinel value. */ public static final long NULL_ENTITY_ID = 0x0000_0000_0000_0000; @@ -153,22 +153,16 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn } public Vec3 getLookingAtVector(Vec3 output) { - output.set( - Math.cos(getPitch()) * Math.cos(getYaw()), - Math.cos(getPitch()) * Math.sin(getYaw()), - -Math.sin(getPitch()) - ); + output.set(Math.cos(getPitch()) * Math.cos(getYaw()), Math.cos(getPitch()) * Math.sin(getYaw()), + -Math.sin(getPitch())); return output; } @Override public String toString() { - return new StringBuilder(super.toString()) - .append(" (EntityID ") - .append(StringUtil.toFullHex(getEntityId())) - .append(")") - .toString(); + return new StringBuilder(super.toString()).append(" (EntityID ").append(StringUtil.toFullHex(getEntityId())) + .append(")").toString(); } public static String formatEntityId(long entityId) { @@ -197,22 +191,11 @@ public class EntityData extends StatefulObject implements Collideable, GenericEn @Override public void read(DataInput input, IOContext context) throws IOException { - Vec3 position = new Vec3( - input.readFloat(), - input.readFloat(), - input.readFloat() - ); + Vec3 position = new Vec3(input.readFloat(), input.readFloat(), input.readFloat()); - Vec3 velocity = new Vec3( - input.readFloat(), - input.readFloat(), - input.readFloat() - ); + Vec3 velocity = new Vec3(input.readFloat(), input.readFloat(), input.readFloat()); - Vec2 direction = new Vec2( - input.readFloat(), - input.readFloat() - ); + Vec2 direction = new Vec2(input.readFloat(), input.readFloat()); setPosition(position); setVelocity(velocity); diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataRegistry.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataRegistry.java index 26f219d..34271ae 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityDataRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import ru.windcorp.progressia.common.state.StatefulObjectRegistry; diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java index f3bf792..aefd64e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java index d09b0f3..515f1f0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java index 06dfc12..98b1d88 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java index 6604d4a..93d724c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.entity; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java index 6c35781..d298d69 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.Collection; @@ -97,10 +97,8 @@ public interface ChunkMap { return containsChunk(chunk) ? def : get(chunk); } - default > V compute( - C chunk, - BiFunction remappingFunction - ) { + default > V compute(C chunk, + BiFunction remappingFunction) { V newValue = remappingFunction.apply(chunk, get(chunk)); if (newValue == null) { @@ -128,10 +126,8 @@ public interface ChunkMap { void forEach(BiConsumer action); - default > void forEachIn( - GenericWorld world, - BiConsumer action - ) { + default > void forEachIn(GenericWorld world, + BiConsumer action) { forEach((pos, value) -> { C chunk = world.getChunk(pos); if (chunk == null) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java index 73c2267..9ee94af 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.Collection; @@ -87,10 +87,8 @@ public interface ChunkSet extends Iterable { return remove(chunk.getPosition()); } - default > void forEachIn( - GenericWorld world, - Consumer action - ) { + default > void forEachIn(GenericWorld world, + Consumer action) { forEach(position -> { C chunk = world.getChunk(position); if (chunk == null) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java index 93413e4..ac79696 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.Iterator; @@ -219,10 +219,8 @@ public class ChunkSets { } @Override - public > void forEachIn( - GenericWorld world, - Consumer action - ) { + public > void forEachIn(GenericWorld world, + Consumer action) { synchronized (mutex) { parent.forEachIn(world, action); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java index d669b07..1d2c252 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; public interface GenericBlock { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 656304f..cd93df6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.function.Consumer; @@ -75,9 +75,8 @@ public interface GenericChunk, B exten } default boolean containsBiC(Vec3i blockInChunk) { - return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK && - blockInChunk.y >= 0 && blockInChunk.y < BLOCKS_PER_CHUNK && - blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK; + return blockInChunk.x >= 0 && blockInChunk.x < BLOCKS_PER_CHUNK && blockInChunk.y >= 0 + && blockInChunk.y < BLOCKS_PER_CHUNK && blockInChunk.z >= 0 && blockInChunk.z < BLOCKS_PER_CHUNK; } default boolean containsBiW(Vec3i blockInWorld) { @@ -91,17 +90,20 @@ public interface GenericChunk, B exten Vectors.release(v); return result; } - + default boolean isSurfaceBiC(Vec3i blockInChunk) { int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - + + if (Coordinates.isOnChunkBorder(blockInChunk.x)) + hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.y)) + hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.z)) + hits++; + return hits >= 1; } - + default boolean isSurfaceBiW(Vec3i blockInWorld) { Vec3i v = Vectors.grab3i(); @@ -113,17 +115,20 @@ public interface GenericChunk, B exten Vectors.release(v); return result; } - + default boolean isEdgeBiC(Vec3i blockInChunk) { int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - + + if (Coordinates.isOnChunkBorder(blockInChunk.x)) + hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.y)) + hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.z)) + hits++; + return hits >= 2; } - + default boolean isEdgeBiW(Vec3i blockInWorld) { Vec3i v = Vectors.grab3i(); @@ -135,17 +140,20 @@ public interface GenericChunk, B exten Vectors.release(v); return result; } - + default boolean isVertexBiC(Vec3i blockInChunk) { int hits = 0; - - if (Coordinates.isOnChunkBorder(blockInChunk.x)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.y)) hits++; - if (Coordinates.isOnChunkBorder(blockInChunk.z)) hits++; - + + if (Coordinates.isOnChunkBorder(blockInChunk.x)) + hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.y)) + hits++; + if (Coordinates.isOnChunkBorder(blockInChunk.z)) + hits++; + return hits == 3; } - + default boolean isVertexBiW(Vec3i blockInWorld) { Vec3i v = Vectors.grab3i(); @@ -159,27 +167,12 @@ public interface GenericChunk, B exten } default void forEachBiC(Consumer action) { - VectorUtil.iterateCuboid( - 0, - 0, - 0, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - action - ); + VectorUtil.iterateCuboid(0, 0, 0, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, action); } default void forEachBiW(Consumer action) { - VectorUtil.iterateCuboid( - Coordinates.getInWorld(getX(), 0), - Coordinates.getInWorld(getY(), 0), - Coordinates.getInWorld(getZ(), 0), - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - BLOCKS_PER_CHUNK, - action - ); + VectorUtil.iterateCuboid(Coordinates.getInWorld(getX(), 0), Coordinates.getInWorld(getY(), 0), + Coordinates.getInWorld(getZ(), 0), BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, action); } default TS getTilesOrNull(Vec3i blockInChunk, BlockFace face) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java index c15bd39..ee802b9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import glm.vec._3.Vec3; diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java index e35aec2..73bf63b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; public interface GenericTile { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java index 31a5158..32a3786 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.AbstractList; @@ -28,8 +28,7 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockFace; public abstract class GenericTileStack, T extends GenericTile, C extends GenericChunk> - extends AbstractList - implements RandomAccess { + extends AbstractList implements RandomAccess { public static interface TSConsumer { void accept(int layer, T tile); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java index 943067e..e1b71fa 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.Collection; diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkMap.java b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkMap.java index 2fbc912..855f0d7 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkMap.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkMap.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.Collection; diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java index cd5a755..f5112c8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.generic; import java.util.Iterator; diff --git a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java index 7c2a35c..46207bb 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.io; import java.io.DataInputStream; @@ -47,8 +47,7 @@ public abstract class ChunkCodec extends Namespaced { } public abstract ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) - throws DecodingException, - IOException; + throws DecodingException, IOException; public abstract boolean shouldEncode(ChunkData chunk, IOContext context); diff --git a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java index 025738f..b02104d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.io; import java.io.DataInputStream; @@ -41,8 +41,7 @@ public class ChunkIO { private static final List CODECS_BY_PRIORITY = new ArrayList<>(); public static ChunkData load(WorldData world, Vec3i position, DataInputStream data, IOContext context) - throws DecodingException, - IOException { + throws DecodingException, IOException { if (CODECS_BY_ID.isEmpty()) throw new IllegalStateException("No codecs registered"); @@ -53,8 +52,7 @@ public class ChunkIO { ChunkCodec codec = getCodec((byte) signature); if (codec == null) { throw new DecodingException( - "Unknown codec signature " + Integer.toHexString(signature) + "; is it from the future?" - ); + "Unknown codec signature " + Integer.toHexString(signature) + "; is it from the future?"); } try { @@ -62,19 +60,12 @@ public class ChunkIO { } catch (IOException | DecodingException e) { throw e; } catch (Throwable t) { - throw CrashReports.report( - t, - "Codec %s has failed to decode chunk (%d; %d; %d)", - codec.getId(), - position.x, - position.y, - position.z - ); + throw CrashReports.report(t, "Codec %s has failed to decode chunk (%d; %d; %d)", codec.getId(), position.x, + position.y, position.z); } } - public static void save(ChunkData chunk, DataOutputStream output, IOContext context) - throws IOException { + public static void save(ChunkData chunk, DataOutputStream output, IOContext context) throws IOException { ChunkCodec codec = getCodec(chunk, context); try { @@ -83,14 +74,8 @@ public class ChunkIO { } catch (IOException e) { throw e; } catch (Throwable t) { - throw CrashReports.report( - t, - "Codec %s has failed to encode chunk (%d; %d; %d)", - codec.getId(), - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ); + throw CrashReports.report(t, "Codec %s has failed to encode chunk (%d; %d; %d)", codec.getId(), + chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z); } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java index 650b4a7..bfc47c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java index b12012c..07d9105 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import java.io.DataInput; diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java index 9a8ef6c..7e9fb47 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import java.io.DataInput; @@ -60,15 +60,8 @@ public class PacketRemoveTile extends PacketAffectTile { int index = stack.getIndexByTag(getTag()); if (index < 0) { - throw CrashReports.report( - null, - "Could not find tile with tag %d at (%d; %d; %d; %s)", - getTag(), - getBlockInWorld().x, - getBlockInWorld().y, - getBlockInWorld().z, - getFace() - ); + throw CrashReports.report(null, "Could not find tile with tag %d at (%d; %d; %d; %s)", getTag(), + getBlockInWorld().x, getBlockInWorld().y, getBlockInWorld().z, getFace()); } stack.remove(index); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java index d314445..b8f42aa 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataRegistry.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataRegistry.java index 110baea..5508ded 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java index 80f0ba4..d9a60b5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java @@ -15,26 +15,26 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.generic.GenericTileStack; -public abstract class TileDataStack - extends GenericTileStack { +public abstract class TileDataStack extends GenericTileStack { /** * Inserts the specified tile at the specified position in this stack. * Shifts the tile currently at that position (if any) and any tiles above - * to - * the top (adds one to their indices). + * to the top (adds one to their indices). * - * @param index index at which the specified tile is to be inserted - * @param tile tile to be inserted - * @throws TileStackIsFullException if this stack is {@linkplain #isFull() - * full} + * @param index + * index at which the specified tile is to be inserted + * @param tile + * tile to be inserted + * @throws TileStackIsFullException + * if this stack is {@linkplain #isFull() full} */ /* * Impl note: AbstractList provides a useless implementation of this method, @@ -45,15 +45,15 @@ public abstract class TileDataStack /** * Adds the specified tile at the end of this stack assigning it the - * provided tag. - * This method is useful for copying stacks when preserving tags is - * necessary. + * provided tag. This method is useful for copying stacks when preserving + * tags is necessary. * - * @param tile the tile to add - * @param tag the tag to assign the new tile - * @throws IllegalArgumentException if this stack already contains a tile - * with the - * provided tag + * @param tile + * the tile to add + * @param tag + * the tag to assign the new tile + * @throws IllegalArgumentException + * if this stack already contains a tile with the provided tag */ public abstract void load(TileData tile, int tag); @@ -61,8 +61,10 @@ public abstract class TileDataStack * Replaces the tile at the specified position in this stack with the * specified tile. * - * @param index index of the tile to replace - * @param tile tile to be stored at the specified position + * @param index + * index of the tile to replace + * @param tile + * tile to be stored at the specified position * @return the tile previously at the specified position */ /* @@ -74,12 +76,11 @@ public abstract class TileDataStack /** * Removes the tile at the specified position in this list. Shifts any - * subsequent tiles - * to the left (subtracts one from their indices). Returns the tile that was - * removed - * from the list. + * subsequent tiles to the left (subtracts one from their indices). Returns + * the tile that was removed from the list. * - * @param index the index of the tile to be removed + * @param index + * the index of the tile to be removed * @return the tile previously at the specified position */ /* @@ -108,12 +109,13 @@ public abstract class TileDataStack } /** - * Attempts to {@link #add(int, TileData) add} the provided {@code tile} - * at {@code index}. If the stack is {@linkplain #isFull() full}, does - * nothing. + * Attempts to {@link #add(int, TileData) add} the provided {@code tile} at + * {@code index}. If the stack is {@linkplain #isFull() full}, does nothing. * - * @param index the index to insert the tile at - * @param tile the tile to try to add + * @param index + * the index to insert the tile at + * @param tile + * the tile to try to add * @return {@code true} iff this stack has changed */ public boolean offer(int index, TileData tile) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java index 75fde58..b8d593f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileReference.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; public interface TileReference { diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileStackIsFullException.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileStackIsFullException.java index c9f6240..8db0b55 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileStackIsFullException.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileStackIsFullException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; public class TileStackIsFullException extends RuntimeException { @@ -26,12 +26,8 @@ public class TileStackIsFullException extends RuntimeException { } - public TileStackIsFullException( - String message, - Throwable cause, - boolean enableSuppression, - boolean writableStackTrace - ) { + public TileStackIsFullException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } diff --git a/src/main/java/ru/windcorp/progressia/server/ChunkLoader.java b/src/main/java/ru/windcorp/progressia/server/ChunkLoader.java index d708fe2..f2391a2 100644 --- a/src/main/java/ru/windcorp/progressia/server/ChunkLoader.java +++ b/src/main/java/ru/windcorp/progressia/server/ChunkLoader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java index b0b0777..685fe51 100644 --- a/src/main/java/ru/windcorp/progressia/server/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/ChunkManager.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.Collections; @@ -160,13 +160,7 @@ public class ChunkManager { ChunkData chunk = world.getChunk(chunkPos); if (chunk == null) { throw new IllegalStateException( - String.format( - "Chunk (%d; %d; %d) not loaded, cannot unload", - chunkPos.x, - chunkPos.y, - chunkPos.z - ) - ); + String.format("Chunk (%d; %d; %d) not loaded, cannot unload", chunkPos.x, chunkPos.y, chunkPos.z)); } world.removeChunk(chunk); @@ -180,13 +174,7 @@ public class ChunkManager { if (chunk == null) { throw new IllegalStateException( - String.format( - "Chunk (%d; %d; %d) is not loaded, cannot send", - chunkPos.x, - chunkPos.y, - chunkPos.z - ) - ); + String.format("Chunk (%d; %d; %d) is not loaded, cannot send", chunkPos.x, chunkPos.y, chunkPos.z)); } PacketSendChunk packet = new PacketSendChunk(); diff --git a/src/main/java/ru/windcorp/progressia/server/EntityManager.java b/src/main/java/ru/windcorp/progressia/server/EntityManager.java index d904c83..0e2a211 100644 --- a/src/main/java/ru/windcorp/progressia/server/EntityManager.java +++ b/src/main/java/ru/windcorp/progressia/server/EntityManager.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.Collections; @@ -145,9 +145,8 @@ public class EntityManager { EntityData entity = server.getWorld().getData().getEntity(entityId); if (entity == null) { - throw new IllegalStateException( - "Entity with entity ID " + new String(StringUtil.toFullHex(entityId)) + " is not loaded, cannot send" - ); + throw new IllegalStateException("Entity with entity ID " + new String(StringUtil.toFullHex(entityId)) + + " is not loaded, cannot send"); } PacketSendEntity packet = new PacketSendEntity(); diff --git a/src/main/java/ru/windcorp/progressia/server/Player.java b/src/main/java/ru/windcorp/progressia/server/Player.java index ea373a8..9b29918 100644 --- a/src/main/java/ru/windcorp/progressia/server/Player.java +++ b/src/main/java/ru/windcorp/progressia/server/Player.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java index 38d0f32..3e7bd40 100644 --- a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.ArrayList; @@ -61,12 +61,7 @@ public class PlayerManager { player.setEntityId(TestContent.PLAYER_ENTITY_ID); player.setPosition(TestContent.SPAWN); - player.setDirection( - new Vec2( - Math.toRadians(40), - Math.toRadians(10) - ) - ); + player.setDirection(new Vec2(Math.toRadians(40), Math.toRadians(10))); getServer().getWorld().getData().addEntity(player); diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 487616d..fba1857 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -83,8 +83,8 @@ public class Server { } /** - * Returns this server's {@link ClientManager}. - * Use this to deal with communications, e.g. send packets. + * Returns this server's {@link ClientManager}. Use this to deal with + * communications, e.g. send packets. * * @return the {@link ClientManager} that handles this server */ @@ -110,15 +110,16 @@ public class Server { } /** - * Requests that the provided task is executed once on next server tick. - * The task will be run in the main server thread. The task object is - * discarded after execution. + * Requests that the provided task is executed once on next server tick. The + * task will be run in the main server thread. The task object is discarded + * after execution. *

      * Use this method to request a one-time (rare) action that must necessarily * happen in the main server thread, such as initialization tasks or * reconfiguration. * - * @param task the task to run + * @param task + * the task to run * @see #invokeNow(Runnable) * @see #schedule(Consumer) */ @@ -129,15 +130,15 @@ public class Server { /** * Executes the tasks in the server main thread as soon as possible. *

      - * If this method is invoked in the server main thread, then the task is - * run immediately (the method blocks until the task finishes). Otherwise - * this method behaves exactly like {@link #invokeLater(Runnable)}. + * If this method is invoked in the server main thread, then the task is run + * immediately (the method blocks until the task finishes). Otherwise this + * method behaves exactly like {@link #invokeLater(Runnable)}. *

      * Use this method to make sure that a piece of code is run in the main - * server - * thread. + * server thread. * - * @param task the task to run + * @param task + * the task to run * @see #invokeLater(Runnable) * @see #schedule(Consumer) */ @@ -145,11 +146,7 @@ public class Server { taskQueue.invokeNow(task); } - public void waitAndInvoke( - ThrowingRunnable task - ) - throws InterruptedException, - E { + public void waitAndInvoke(ThrowingRunnable task) throws InterruptedException, E { taskQueue.waitAndInvoke(task); } @@ -197,8 +194,8 @@ public class Server { /** * Returns the {@link WorldAccessor} object for this server. Use the - * provided accessor to - * request common {@link Evaluation}s and {@link Change}s. + * provided accessor to request common {@link Evaluation}s and + * {@link Change}s. * * @return a {@link WorldAccessor} * @see #requestChange(Change) @@ -238,11 +235,10 @@ public class Server { /** * Shuts the server down, disconnecting the clients with the provided - * message. - * This method blocks until the shutdown is complete. + * message. This method blocks until the shutdown is complete. * - * @param message the message to send to the clients as the disconnect - * reason + * @param message + * the message to send to the clients as the disconnect reason */ public void shutdown(String message) { LogManager.getLogger().warn("Server.shutdown() is not yet implemented"); @@ -256,10 +252,9 @@ public class Server { /** * Returns an instance of {@link java.util.Random Random} that can be used - * as a source of indeterministic - * randomness. World generation and other algorithms that must have random - * but reproducible results should - * not use this. + * as a source of indeterministic randomness. World generation and other + * algorithms that must have random but reproducible results should not use + * this. * * @return a thread-safe indeterministic instance of * {@link java.util.Random}. diff --git a/src/main/java/ru/windcorp/progressia/server/ServerState.java b/src/main/java/ru/windcorp/progressia/server/ServerState.java index 774f17d..d252e0c 100644 --- a/src/main/java/ru/windcorp/progressia/server/ServerState.java +++ b/src/main/java/ru/windcorp/progressia/server/ServerState.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import ru.windcorp.progressia.common.world.WorldData; diff --git a/src/main/java/ru/windcorp/progressia/server/ServerThread.java b/src/main/java/ru/windcorp/progressia/server/ServerThread.java index 90f3ce9..2cf3296 100644 --- a/src/main/java/ru/windcorp/progressia/server/ServerThread.java +++ b/src/main/java/ru/windcorp/progressia/server/ServerThread.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import java.util.concurrent.Executors; @@ -51,9 +51,8 @@ public class ServerThread implements Runnable { } private final Server server; - private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor( - r -> new Thread(new ServerThreadTracker(r), "Server thread") - ); + private final ScheduledExecutorService executor = Executors + .newSingleThreadScheduledExecutor(r -> new Thread(new ServerThreadTracker(r), "Server thread")); private final TickerCoordinator ticker; diff --git a/src/main/java/ru/windcorp/progressia/server/TickingSettings.java b/src/main/java/ru/windcorp/progressia/server/TickingSettings.java index 743da10..8cb77d6 100644 --- a/src/main/java/ru/windcorp/progressia/server/TickingSettings.java +++ b/src/main/java/ru/windcorp/progressia/server/TickingSettings.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server; import ru.windcorp.progressia.common.Units; diff --git a/src/main/java/ru/windcorp/progressia/server/comms/Client.java b/src/main/java/ru/windcorp/progressia/server/comms/Client.java index f439e27..fdc1e98 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/Client.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/Client.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms; import ru.windcorp.progressia.common.comms.CommsChannel; diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java index 35b9ca2..3d46634 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms; public abstract class ClientChat extends Client { diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java index cb4b80b..56bdab3 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms; import java.util.Collection; @@ -91,7 +91,8 @@ public class ClientManager { /** * Sends the provided packet to all connected player clients. * - * @param packet the packet to broadcast + * @param packet + * the packet to broadcast */ public void broadcastToAllPlayers(Packet packet) { getClients().forEach(c -> { @@ -107,8 +108,10 @@ public class ClientManager { * Sends the provided packet to all connected player clients that can see * the chunk identified by {@code chunkPos}. * - * @param packet the packet to broadcast - * @param chunkPos the chunk coordinates of the chunk that must be visible + * @param packet + * the packet to broadcast + * @param chunkPos + * the chunk coordinates of the chunk that must be visible */ public void broadcastLocal(Packet packet, Vec3i chunkPos) { getClients().forEach(c -> { @@ -126,8 +129,10 @@ public class ClientManager { * Sends the provided packet to all connected player clients that can see * the entity identified by {@code entityId}. * - * @param packet the packet to broadcast - * @param entityId the ID of the entity that must be visible + * @param packet + * the packet to broadcast + * @param entityId + * the ID of the entity that must be visible */ public void broadcastLocal(Packet packet, long entityId) { getClients().forEach(c -> { diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java index c455b8e..d414524 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java b/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java index d570e01..bcc51ac 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms; import java.io.IOException; @@ -41,9 +41,8 @@ public class DefaultServerCommsListener implements CommsListener { if (packet instanceof PacketControl) { PacketControl packetControl = (PacketControl) packet; - ControlLogicRegistry.getInstance().get( - packetControl.getControl().getId() - ).apply(manager.getServer(), packetControl, client); + ControlLogicRegistry.getInstance().get(packetControl.getControl().getId()).apply(manager.getServer(), + packetControl, client); } } } diff --git a/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogic.java b/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogic.java index 31e97a2..713ada7 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms.controls; import ru.windcorp.progressia.common.comms.controls.PacketControl; @@ -27,22 +27,14 @@ public abstract class ControlLogic extends Namespaced { @FunctionalInterface public static interface Lambda { - void apply( - Server server, - PacketControl packet, - Client client - ); + void apply(Server server, PacketControl packet, Client client); } public ControlLogic(String id) { super(id); } - public abstract void apply( - Server server, - PacketControl packet, - Client client - ); + public abstract void apply(Server server, PacketControl packet, Client client); public static ControlLogic of(String id, Lambda logic) { return new ControlLogic(id) { diff --git a/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogicRegistry.java b/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogicRegistry.java index 18ece0a..92112e3 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogicRegistry.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/controls/ControlLogicRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.comms.controls; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index 37685d2..e9b1257 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import java.util.ArrayList; @@ -53,7 +53,7 @@ public class ChunkLogic implements GenericChunk tileLogicLists = Collections - .synchronizedMap(new WeakHashMap<>()); + .synchronizedMap(new WeakHashMap<>()); public ChunkLogic(WorldLogic world, ChunkData data) { this.world = world; @@ -69,9 +69,7 @@ public class ChunkLogic implements GenericChunk action) { tickingTiles.forEach(ref -> { - action.accept( - ref, - TileLogicRegistry.getInstance().get(ref.get().getId()) - ); + action.accept(ref, TileLogicRegistry.getInstance().get(ref.get().getId())); }); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java index 5eed263..c197706 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index 22d106e..bb7fb2e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; @@ -67,18 +67,18 @@ public class TickAndUpdateUtil { return; TileTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face) - .withLayer(layer); + .withLayer(layer); tickTile((TickableTile) tile, tickContext); } public static void tickTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() - .forEachTile(context -> { - TileLogic tile = context.getTile(); - if (tile instanceof TickableTile) { - tickTile((TickableTile) tile, context); - } - }); + .forEachTile(context -> { + TileLogic tile = context.getTile(); + if (tile instanceof TickableTile) { + tickTile((TickableTile) tile, context); + } + }); } public static void updateBlock(UpdateableBlock block, BlockTickContext context) { @@ -112,18 +112,18 @@ public class TickAndUpdateUtil { return; TileTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face) - .withLayer(layer); + .withLayer(layer); updateTile((UpdateableTile) tile, tickContext); } public static void updateTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() - .forEachTile(context -> { - TileLogic tile = context.getTile(); - if (tile instanceof UpdateableTile) { - updateTile((UpdateableTile) tile, context); - } - }); + .forEachTile(context -> { + TileLogic tile = context.getTile(); + if (tile instanceof UpdateableTile) { + updateTile((UpdateableTile) tile, context); + } + }); } public static void tickEntity(EntityLogic logic, EntityData data, TickContext context) { @@ -135,11 +135,8 @@ public class TickAndUpdateUtil { } public static void tickEntity(EntityData data, Server server) { - tickEntity( - EntityLogicRegistry.getInstance().get(data.getId()), - data, - TickContextMutable.start().withServer(server).build() - ); + tickEntity(EntityLogicRegistry.getInstance().get(data.getId()), data, + TickContextMutable.start().withServer(server).build()); } private TickAndUpdateUtil() { diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java index 50dda55..0997c65 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import java.util.Random; diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java index 68185d9..2c92857 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import java.util.Objects; @@ -138,9 +138,8 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont * Impl */ - public static class Impl - extends TickContextMutable - implements Builder.Empty, Builder.World, Builder.Chunk, Builder.Block, Builder.TileStack { + public static class Impl extends TickContextMutable + implements Builder.Empty, Builder.World, Builder.Chunk, Builder.Block, Builder.TileStack { protected Impl() { } @@ -214,8 +213,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } /* - * Builder - * memo: do NOT use Context getters, they throw ISEs + * Builder memo: do NOT use Context getters, they throw ISEs */ @Override @@ -425,8 +423,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont if ((role == null) || (requiredRole.compareTo(role) > 0)) { throw new IllegalStateException( - "This context is currently initialized as " + role + "; requested " + requiredRole - ); + "This context is currently initialized as " + role + "; requested " + requiredRole); } } @@ -442,8 +439,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } else { if (role != requiredRole) { throw new IllegalStateException( - "This context is currently initialized as " + role + "; requested " + requiredRole - ); + "This context is currently initialized as " + role + "; requested " + requiredRole); } } } @@ -474,17 +470,8 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont break; } - return String.format( - format, - this.chunk.x, - this.chunk.y, - this.chunk.z, - this.blockInWorld.x, - this.blockInWorld.y, - this.blockInWorld.z, - this.face, - this.layer - ); + return String.format(format, this.chunk.x, this.chunk.y, this.chunk.z, this.blockInWorld.x, + this.blockInWorld.y, this.blockInWorld.z, this.face, this.layer); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index 511170e..a7c122a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; @@ -36,23 +36,13 @@ public class UpdateTriggerer implements ChunkDataListener { } @Override - public void onChunkBlockChanged( - ChunkData chunk, - Vec3i blockInChunk, - BlockData previous, - BlockData current - ) { + public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { server.getWorldAccessor().triggerUpdates(Coordinates.getInWorld(chunk.getPosition(), blockInChunk, null)); } @Override - public void onChunkTilesChanged( - ChunkData chunk, - Vec3i blockInChunk, - BlockFace face, - TileData tile, - boolean wasAdded - ) { + public void onChunkTilesChanged(ChunkData chunk, Vec3i blockInChunk, BlockFace face, TileData tile, + boolean wasAdded) { server.getWorldAccessor().triggerUpdates(Coordinates.getInWorld(chunk.getPosition(), blockInChunk, null), face); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 93a1028..2f3a32b 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import java.util.Collection; @@ -38,14 +38,13 @@ import ru.windcorp.progressia.server.world.ticking.Evaluation; import ru.windcorp.progressia.server.world.tile.TileLogic; import ru.windcorp.progressia.server.world.tile.TileLogicStack; -public class WorldLogic - implements GenericWorld { private final WorldData data; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index 794259f..fcf141d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogicRegistry.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogicRegistry.java index df18ff7..b50b02f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogicRegistry.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogicRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java index a305b9a..d10f10c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.block; import java.util.Objects; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java b/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java index 56ba938..62b830f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java b/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java index 1497c92..12ae51c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.block; import org.apache.logging.log4j.LogManager; @@ -23,13 +23,8 @@ import org.apache.logging.log4j.LogManager; public interface UpdateableBlock { default void update(BlockTickContext context) { - LogManager.getLogger().info( - "Updating block {} @ ({}; {}; {})", - context.getBlock(), - context.getBlockInWorld().x, - context.getBlockInWorld().y, - context.getBlockInWorld().z - ); + LogManager.getLogger().info("Updating block {} @ ({}; {}; {})", context.getBlock(), context.getBlockInWorld().x, + context.getBlockInWorld().y, context.getBlockInWorld().z); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java b/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java index 7725612..0f33517 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.entity; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogicRegistry.java b/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogicRegistry.java index d8b05d4..a3ecd20 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogicRegistry.java +++ b/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogicRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.entity; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index ffb5c06..2753a8f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.generation; import java.io.DataInputStream; diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index afed281..41a7885 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.generation; import java.io.DataInputStream; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java index 6e9ea47..238a42f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java index 331a5c4..6d8d408 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java index b005285..62cedac 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChange.java index e1eb5ca..d5db70a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChange.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java index d98c001..ef4a8cf 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedEvaluation.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedEvaluation.java index da865b4..5fe1320 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedEvaluation.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedEvaluation.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java index 1b6cde2..7d27be0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.Objects; @@ -58,9 +58,8 @@ public class CachedTileChange

      extends CachedChunkCha if (my.getTag() == -1 || other.getTag() == -1) return false; - return Glm.equals(my.getBlockInWorld(), other.getBlockInWorld()) - && (my.getFace() == other.getFace()) - && (my.getTag() == other.getTag()); + return Glm.equals(my.getBlockInWorld(), other.getBlockInWorld()) && (my.getFace() == other.getFace()) + && (my.getTag() == other.getTag()); } @Override @@ -69,7 +68,7 @@ public class CachedTileChange

      extends CachedChunkCha Vec3i biw = packet.getBlockInWorld(); return getClass().getSimpleName() + " (" + biw.x + "; " + biw.y + "; " + biw.z + "; " + packet.getFace() - + "; tag: " + packet.getTag() + ")"; + + "; tag: " + packet.getTag() + ")"; } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java index 711bd5d..c01e83a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java index 08f1212..a7a7072 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java index 42dea30..0f811b1 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java index 330333b..e4cc4fb 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java index 93d5f08..4aa8c7c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; @FunctionalInterface diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index c0895e1..b9dd457 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.ArrayList; @@ -44,9 +44,8 @@ import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; public class TickChunk extends Evaluation { - private static final int CHUNK_VOLUME = ChunkData.BLOCKS_PER_CHUNK * - ChunkData.BLOCKS_PER_CHUNK * - ChunkData.BLOCKS_PER_CHUNK; + private static final int CHUNK_VOLUME = ChunkData.BLOCKS_PER_CHUNK * ChunkData.BLOCKS_PER_CHUNK + * ChunkData.BLOCKS_PER_CHUNK; private final List> randomTickMethods; @@ -106,9 +105,9 @@ public class TickChunk extends Evaluation { float ticks = computeRandomTicks(server); /* - * If we are expected to run 3.25 random ticks per tick - * on average, then run 3 random ticks unconditionally - * and run one extra random tick with 0.25 chance + * If we are expected to run 3.25 random ticks per tick on average, then + * run 3 random ticks unconditionally and run one extra random tick with + * 0.25 chance */ float unconditionalTicks = FloatMathUtil.floor(ticks); float extraTickChance = ticks - unconditionalTicks; @@ -124,19 +123,14 @@ public class TickChunk extends Evaluation { private void tickRandomOnce(Server server) { // Pick a target at random: a block or one of 3 primary block faces - randomTickMethods.get( - server.getAdHocRandom().nextInt(randomTickMethods.size()) - ).accept(server); + randomTickMethods.get(server.getAdHocRandom().nextInt(randomTickMethods.size())).accept(server); } private void tickRandomBlock(Server server) { Random random = server.getAdHocRandom(); - Vec3i blockInChunk = new Vec3i( - random.nextInt(BLOCKS_PER_CHUNK), - random.nextInt(BLOCKS_PER_CHUNK), - random.nextInt(BLOCKS_PER_CHUNK) - ); + Vec3i blockInChunk = new Vec3i(random.nextInt(BLOCKS_PER_CHUNK), random.nextInt(BLOCKS_PER_CHUNK), + random.nextInt(BLOCKS_PER_CHUNK)); BlockLogic block = this.chunk.getBlock(blockInChunk); @@ -154,11 +148,8 @@ public class TickChunk extends Evaluation { private void tickRandomTile(Server server, BlockFace face) { Random random = server.getAdHocRandom(); - Vec3i blockInChunk = new Vec3i( - random.nextInt(BLOCKS_PER_CHUNK), - random.nextInt(BLOCKS_PER_CHUNK), - random.nextInt(BLOCKS_PER_CHUNK) - ); + Vec3i blockInChunk = new Vec3i(random.nextInt(BLOCKS_PER_CHUNK), random.nextInt(BLOCKS_PER_CHUNK), + random.nextInt(BLOCKS_PER_CHUNK)); TileDataStack tiles = this.chunk.getData().getTilesOrNull(blockInChunk, face); if (tiles == null || tiles.isEmpty()) @@ -179,9 +170,8 @@ public class TickChunk extends Evaluation { } private float computeRandomTicks(Server server) { - return (float) (server.getTickingSettings().getRandomTickFrequency() * - CHUNK_VOLUME * randomTickMethods.size() * - server.getTickLength()); + return (float) (server.getTickingSettings().getRandomTickFrequency() * CHUNK_VOLUME * randomTickMethods.size() + * server.getTickLength()); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickEntitiesTask.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickEntitiesTask.java index 1e76b23..8376c8d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickEntitiesTask.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickEntitiesTask.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java index 76fc414..80b91bd 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java index 2c83ccd..28d91a4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; @@ -38,14 +38,13 @@ public class WorldAccessor { MultiLOC mloc = new MultiLOC(); Consumer disposer = mloc::release; - cache = mloc - .addClass(SetBlock.class, () -> new SetBlock(disposer)) - .addClass(AddTile.class, () -> new AddTile(disposer)) - .addClass(RemoveTile.class, () -> new RemoveTile(disposer)) - .addClass(ChangeEntity.class, () -> new ChangeEntity(disposer)) + cache = mloc.addClass(SetBlock.class, () -> new SetBlock(disposer)) + .addClass(AddTile.class, () -> new AddTile(disposer)) + .addClass(RemoveTile.class, () -> new RemoveTile(disposer)) + .addClass(ChangeEntity.class, () -> new ChangeEntity(disposer)) - .addClass(BlockTriggeredUpdate.class, () -> new BlockTriggeredUpdate(disposer)) - .addClass(TileTriggeredUpdate.class, () -> new TileTriggeredUpdate(disposer)); + .addClass(BlockTriggeredUpdate.class, () -> new BlockTriggeredUpdate(disposer)) + .addClass(TileTriggeredUpdate.class, () -> new TileTriggeredUpdate(disposer)); } private final Server server; @@ -80,10 +79,7 @@ public class WorldAccessor { server.requestChange(change); } - public void changeEntity( - T entity, - StateChange stateChange - ) { + public void changeEntity(T entity, StateChange stateChange) { ChangeEntity change = cache.grab(ChangeEntity.class); change.set(entity, stateChange); server.requestChange(change); diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java index b0fc7f2..c0cf115 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; import ru.windcorp.progressia.server.Server; @@ -32,14 +32,13 @@ public abstract class Change extends TickerTask { * Performs the changes on the provided server instance. *

      * This method will be executed when the world is in an inconsistent state - * and may not be queried, - * only changed. Therefore, all necessary inspection must be performed - * before this method is invoked, - * typically by an {@link Evaluation}. Failure to abide by this contract may - * lead to race conditions - * and/or devil invasions. + * and may not be queried, only changed. Therefore, all necessary inspection + * must be performed before this method is invoked, typically by an + * {@link Evaluation}. Failure to abide by this contract may lead to race + * conditions and/or devil invasions. * - * @param server the {@link Server} instance to affect + * @param server + * the {@link Server} instance to affect */ public abstract void affect(Server server); diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/DevilInvasionException.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/DevilInvasionException.java index 50ff69c..fd146bc 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/DevilInvasionException.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/DevilInvasionException.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; public class DevilInvasionException extends RuntimeException { diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/Evaluation.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/Evaluation.java index f4f3922..b541871 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/Evaluation.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/Evaluation.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; import ru.windcorp.progressia.server.Server; @@ -30,14 +30,15 @@ public abstract class Evaluation extends TickerTask { /** * Performs the analysis of the provided server instance. *

      - * This method will be executed when the world is in an consistent state - * and may be queried for meaningful information. However, other - * evaluations may be happening concurrently, so any world modification - * is prohibited. Evaluations are expected to request {@link Change}s - * to interact with the world. Failure to abide by this contract may - * lead to race conditions and/or devil invasions. + * This method will be executed when the world is in an consistent state and + * may be queried for meaningful information. However, other evaluations may + * be happening concurrently, so any world modification is prohibited. + * Evaluations are expected to request {@link Change}s to interact with the + * world. Failure to abide by this contract may lead to race conditions + * and/or devil invasions. * - * @param server the server instance to inspect + * @param server + * the server instance to inspect */ public abstract void evaluate(Server server); diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/Ticker.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/Ticker.java index 5c4b83e..4d0a22a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/Ticker.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/Ticker.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; import java.util.ArrayList; diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java index 7d58d6d..d4a9bba 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; import java.util.ArrayList; @@ -41,8 +41,7 @@ import ru.windcorp.progressia.server.Server; /** * Central control point for serverside ticking. This class provides an - * interface to - * interact with Tickers. + * interface to interact with Tickers. * * @author javapony */ @@ -66,8 +65,7 @@ public class TickerCoordinator { /** * All tasks that must be {@linkplain TickerTask#dispose() disposed of} at - * the end of the current - * tick. This list must be empty when not in + * the end of the current tick. This list must be empty when not in * {@link #runPassStage(Collection, String)}. */ private final Collection toDispose = new ArrayList<>(INITIAL_QUEUE_SIZE); @@ -152,7 +150,7 @@ public class TickerCoordinator { public double getTPS() { return 1 / tickLength; } - + public long getUptimeTicks() { return ticks; } @@ -168,7 +166,7 @@ public class TickerCoordinator { tickStart = System.currentTimeMillis(); } - + private void onTickEnd() { ticks++; } @@ -191,7 +189,7 @@ public class TickerCoordinator { logger.debug("Pass complete"); passes++; } - + onTickEnd(); logger.debug("Tick complete; run {} passes", passes); @@ -218,11 +216,8 @@ public class TickerCoordinator { runPassStage(pendingChanges, "CHANGE"); } - private synchronized void runPassStage( - Collection tasks, - String stageName - ) - throws InterruptedException { + private synchronized void runPassStage(Collection tasks, String stageName) + throws InterruptedException { if (!toDispose.isEmpty()) throw new IllegalStateException("toDispose is not empty: " + toDispose); @@ -238,11 +233,8 @@ public class TickerCoordinator { toDispose.clear(); } - private synchronized void startPassStage( - Collection tasks, - Collection toDispose, - String stageName - ) { + private synchronized void startPassStage(Collection tasks, Collection toDispose, + String stageName) { if (tasks.isEmpty()) { logger.debug("Skipping stage {}: tasks is empty", stageName); return; @@ -269,11 +261,8 @@ public class TickerCoordinator { logger.debug("Stage started"); } - private Collection selectTasks( - Ticker ticker, - Collection tasks, - Collection output - ) { + private Collection selectTasks(Ticker ticker, Collection tasks, + Collection output) { // TODO implement properly for (TickerTask task : tasks) { @@ -319,12 +308,8 @@ public class TickerCoordinator { logger.debug("javahorse kill urself"); } - throw CrashReports.crash( - t, - "Something has gone horribly wrong in server ticker code " - + "(thread %s) and it is (probably) not related to mods or devils.", - thread - ); + throw CrashReports.crash(t, "Something has gone horribly wrong in server ticker code " + + "(thread %s) and it is (probably) not related to mods or devils.", thread); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerTask.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerTask.java index 4a075c0..a5f9738 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerTask.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerTask.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; import glm.vec._3.i.Vec3i; @@ -23,11 +23,10 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.server.Server; /** - * A task that can be executed by a Ticker. - * This is a superinterface for {@link Change} and {@link Evaluation} and is not - * meant to be extended further. - * This interface is used to determine the Ticker that is suitable for the - * execution of this task. + * A task that can be executed by a Ticker. This is a superinterface for + * {@link Change} and {@link Evaluation} and is not meant to be extended + * further. This interface is used to determine the Ticker that is suitable for + * the execution of this task. * * @author javapony */ @@ -35,8 +34,8 @@ public abstract class TickerTask { /** * Returns {@code false} iff this task is thread-safe and may be executed by - * any Ticker. If and only if a task returns {@code true} in this method - * is its {@link #getRelevantChunk(Vec3i)} method invoked. + * any Ticker. If and only if a task returns {@code true} in this method is + * its {@link #getRelevantChunk(Vec3i)} method invoked. * * @implNote Default implementation returns {@code true}, making this task * thread-sensitive @@ -49,18 +48,18 @@ public abstract class TickerTask { /** * Sets {@code output} to be equal to the {@linkplain Coordinates#chunk - * coordinates of chunk} - * of the chunk that must be owned by the Ticker will execute this task. - * This method - * is not invoked iff {@link #isThreadSensitive()} returned {@code false}. + * coordinates of chunk} of the chunk that must be owned by the Ticker will + * execute this task. This method is not invoked iff + * {@link #isThreadSensitive()} returned {@code false}. * - * @param output a {@link Vec3i} to set to the requested value + * @param output + * a {@link Vec3i} to set to the requested value */ public abstract void getRelevantChunk(Vec3i output); /** - * Invoked when this task has completed and will no longer be used. - * This method is guaranteed to be invoked in the main server thread. + * Invoked when this task has completed and will no longer be used. This + * method is guaranteed to be invoked in the main server thread. * * @implNote Default implementation does nothing */ @@ -72,7 +71,8 @@ public abstract class TickerTask { * Executes this task. This method is provided for the convenience of * Tickers. * - * @param server the server to run on + * @param server + * the server to run on */ abstract void run(Server server); diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickingPolicy.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickingPolicy.java index a5836fe..87a6fc9 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickingPolicy.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickingPolicy.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.ticking; import ru.windcorp.progressia.server.world.block.TickableBlock; @@ -23,27 +23,24 @@ import ru.windcorp.progressia.server.world.tile.TickableTile; /** * Various ticking policies that {@link TickableBlock} or {@link TickableTile} - * can have. - * Ticking policy determines when, and if, the block or tile is ticked. + * can have. Ticking policy determines when, and if, the block or tile is + * ticked. * * @author javapony */ public enum TickingPolicy { /** - * The ticking policy that requests that no ticks happen. - * This is typically used for blocks or tiles that only tick under certain - * conditions, - * which are not meant at the moment. + * The ticking policy that requests that no ticks happen. This is typically + * used for blocks or tiles that only tick under certain conditions, which + * are not meant at the moment. */ NONE, /** * The ticking policy that requests that the object is ticked every server - * tick exactly once. - * This should not be used for objects that only change rarely; consider - * using {@link RANDOM} - * instead. + * tick exactly once. This should not be used for objects that only change + * rarely; consider using {@link RANDOM} instead. */ REGULAR, diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java index 745f289..fdd3a53 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.server.world.block.BlockLogic; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index 399f7b8..0e746ca 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import java.util.Objects; @@ -71,7 +71,7 @@ public interface TSTickContext extends BlockTickContext { default TileTickContext forLayer(int layer) { return TickContextMutable.start().withServer(getServer()).withBlock(getBlockInWorld()).withFace(getFace()) - .withLayer(layer); + .withLayer(layer); } default boolean forEachTile(Consumer action) { @@ -90,10 +90,8 @@ public interface TSTickContext extends BlockTickContext { } default TSTickContext getComplementary() { - return TickContextMutable.copyWorld(this) - .withBlock(getBlockInWorld().add_(getFace().getVector())) - .withFace(getFace().getCounter()) - .build(); + return TickContextMutable.copyWorld(this).withBlock(getBlockInWorld().add_(getFace().getVector())) + .withFace(getFace().getCounter()).build(); } default R evalComplementary(Function action) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java index 4def3b0..50a4b15 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java index 4a97ead..c623999 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java index d8bceaf..cc0fca6 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicRegistry.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java index 5e91963..ce94cfc 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java @@ -15,15 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.generic.GenericTileStack; import ru.windcorp.progressia.common.world.tile.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; -public abstract class TileLogicStack - extends GenericTileStack { +public abstract class TileLogicStack extends GenericTileStack { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java index 45f41ec..69dc77d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.tile.TileData; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java b/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java index bf114fa..0a5aca5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tile; public interface UpdateableTile { diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index 3cc0e9c..729d857 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -53,8 +53,9 @@ public class TestEntityLogicFallingBlock extends EntityLogic { return; } - //LogManager.getLogger().info("NotNull "+entity.toString()+" "+String.valueOf(entity!=null) + " " + - //context.toString()); + // LogManager.getLogger().info("NotNull "+entity.toString()+" + // "+String.valueOf(entity!=null) + " " + + // context.toString()); super.tick(entity, context); // friction @@ -66,13 +67,13 @@ public class TestEntityLogicFallingBlock extends EntityLogic { TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld() .getData().getEntity(entity.getEntityId()); // ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); // fallBlock = (TestEntityDataFallingBlock) entity; - - //LogManager.getLogger().info("NotNull FB "+String.valueOf(fallBlock!=null)); - if (fallBlock==null) - { + + // LogManager.getLogger().info("NotNull FB + // "+String.valueOf(fallBlock!=null)); + if (fallBlock == null) { return; } - + if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) { return; } @@ -101,14 +102,15 @@ public class TestEntityLogicFallingBlock extends EntityLogic { // "+String.valueOf(occupiedBlock.z)); // LogManager.getLogger().info("Block is of type " + // context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - - if (context.getWorldData().isBlockLoaded(occupiedBlock) && context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { + + if (context.getWorldData().isBlockLoaded(occupiedBlock) + && context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); // ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, // fallBlock.getBlock(),true); context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); fallBlock.setInvisible(); // Until I know how to properly delete it. - ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId());//context.getWorldData().removeEntity(entity.getEntityId()); + ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId());// context.getWorldData().removeEntity(entity.getEntityId()); } } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java index c4f5ec7..851845a 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test.gen; import kdotjpg.opensimplex2.areagen.OpenSimplex2S; @@ -34,45 +34,13 @@ class TestTerrainGenerator { public TestTerrainGenerator(TestWorldGenerator testWorldGenerator, WorldLogic world) { this.noise = new OpenSimplex2S("We're getting somewhere".hashCode()); - Func2D plainsHeight = tweak( - octaves( - tweak(primitive(), 0.01, 0.5), - 2, - 3 - ), - 1, - 0.2, - 0.2 - ); + Func2D plainsHeight = tweak(octaves(tweak(primitive(), 0.01, 0.5), 2, 3), 1, 0.2, 0.2); - Func2D mountainsHeight = tweak( - octaves( - ridge(tweak(primitive(), 0.01, 1)), - 2, - 1.5, - 12 - ), - 1, - 3 - ); + Func2D mountainsHeight = tweak(octaves(ridge(tweak(primitive(), 0.01, 1)), 2, 1.5, 12), 1, 3); - Func2D mountainousity = tweak( - octaves( - tweak(primitive(), 0.007, 1), - 2, - 3 - ), - 1, - 1, - -0.25 - ); + Func2D mountainousity = tweak(octaves(tweak(primitive(), 0.007, 1), 2, 3), 1, 1, -0.25); - shape = tweak( - add(multiply(squash(mountainousity, 10), mountainsHeight), plainsHeight), - 0.001, - 1000, - 0 - ); + shape = tweak(add(multiply(squash(mountainousity, 10), mountainsHeight), plainsHeight), 0.001, 1000, 0); } public void compute(int startX, int startY, double[][] heightMap, double[][] slopeMap) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 8ce6e45..96213fe 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -63,16 +63,16 @@ public class TestWorldGenerator extends AbstractWorldGenerator { public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); - - if (TestEntityLogicFallingBlock.FallingBlocks.contains(chunk.getWorld() - .getBlock(chunkWorldPos.add_(0, 0, 1)).getId())) { - chunk.getWorld().setBlock(chunkWorldPos.add_(0, 0, 1), BlockDataRegistry.getInstance().get(chunk.getWorld().getBlock(chunkWorldPos.add_(0,0,1)).getId()), true); + + if (TestEntityLogicFallingBlock.FallingBlocks + .contains(chunk.getWorld().getBlock(chunkWorldPos.add_(0, 0, 1)).getId())) { + chunk.getWorld().setBlock(chunkWorldPos.add_(0, 0, 1), BlockDataRegistry.getInstance() + .get(chunk.getWorld().getBlock(chunkWorldPos.add_(0, 0, 1)).getId()), true); } if (!TestEntityLogicFallingBlock.FallingBlocks.contains(current.getId())) { return; } - if (chunk.getWorld().getBlock(chunkWorldPos.add_(0, 0, -1)) - .getId() == "Test:Air") { + if (chunk.getWorld().getBlock(chunkWorldPos.add_(0, 0, -1)).getId() == "Test:Air") { LogManager.getLogger().info("Inserting FallingBlock"); TestEntityDataFallingBlock fallingBlock = new TestEntityDataFallingBlock(); @@ -87,7 +87,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { chunk.getWorld().addEntity(fallingBlock); chunk.setBlock(blockInChunk, previous, false); - + LogManager.getLogger().info(String.valueOf(chunkWorldPos.x) + " " + String.valueOf(chunkWorldPos.y) + " " + String.valueOf(chunkWorldPos.z)); } From e47fb3c4bd2ac56011ad8d885cd2845adfd2dbe6 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 7 Jul 2021 17:37:08 +0300 Subject: [PATCH 33/63] Added surface features. Tree generation is currently broken! - Added SurfaceFeature - Used to generate chunk features - Added SurfaceTopLayerFeature - A superclass for features that are only concerned with editing the surface - Added grass, temporary bushes and temporary trees - Bushes and trees do not generate properly due to bugs - Added Test:TemporaryLeaves - Added SurfaceWorld (a GenericWritableWorld wrapper) - Added some unit tests for rotation utilities - Fixed a whole lot of bugs --- .../common/world/generic/ChunkSet.java | 3 + .../common/world/generic/GenericChunk.java | 6 +- .../common/world/generic/GenericChunks.java | 19 ++- .../progressia/test/TestBushFeature.java | 47 +++++-- .../progressia/test/TestChunkCodec.java | 2 - .../windcorp/progressia/test/TestContent.java | 3 + .../progressia/test/TestGrassFeature.java | 68 +++++++++ .../progressia/test/TestTreeFeature.java | 103 ++++++++++++++ .../gen/planet/PlanetFeatureGenerator.java | 7 +- .../gen/planet/PlanetTerrainGenerator.java | 2 + .../test/gen/planet/TestPlanetGenerator.java | 3 +- .../test/gen/surface/SurfaceFeature.java | 130 ++++++++++-------- .../gen/surface/SurfaceFeatureGenerator.java | 2 +- .../gen/surface/SurfaceTopLayerFeature.java | 58 ++++++++ .../test/gen/surface/SurfaceWorld.java | 48 ++++--- .../textures/blocks/TemporaryLeaves.png | Bin 0 -> 13841 bytes .../textures/items/MoonTypeIceCream.png | Bin 0 -> 705 bytes .../generic/GenericChunkRotationsTest.java | 83 +++++++++++ .../common/world/rels/AxisRotationsTest.java | 100 ++++++++++++++ 19 files changed, 587 insertions(+), 97 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java create mode 100644 src/main/resources/assets/textures/blocks/TemporaryLeaves.png create mode 100644 src/main/resources/assets/textures/items/MoonTypeIceCream.png create mode 100644 src/test/java/ru/windcorp/progressia/common/world/generic/GenericChunkRotationsTest.java create mode 100644 src/test/java/ru/windcorp/progressia/common/world/rels/AxisRotationsTest.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java index 6f26ef0..199e780 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java @@ -56,6 +56,7 @@ public interface ChunkSet extends Iterable { default boolean contains(int x, int y, int z) { Vec3i v = Vectors.grab3i(); + v.set(x, y, z); boolean result = contains(v); Vectors.release(v); return result; @@ -63,6 +64,7 @@ public interface ChunkSet extends Iterable { default boolean add(int x, int y, int z) { Vec3i v = Vectors.grab3i(); + v.set(x, y, z); boolean result = add(v); Vectors.release(v); return result; @@ -70,6 +72,7 @@ public interface ChunkSet extends Iterable { default boolean remove(int x, int y, int z) { Vec3i v = Vectors.grab3i(); + v.set(x, y, z); boolean result = remove(v); Vectors.release(v); return result; diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java index 0748a34..3643564 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java @@ -106,7 +106,11 @@ public interface GenericChunk< boolean hasTiles(Vec3i blockInChunk, BlockFace face); default Vec3i resolve(Vec3i relativeCoords, Vec3i output) { - return GenericChunks.resolve(relativeCoords, output, getUp()); + return GenericChunks.resolve(relativeCoords, getUp(), output); + } + + default Vec3i relativize(Vec3i absoluteCoords, Vec3i output) { + return GenericChunks.relativize(absoluteCoords, getUp(), output); } default B getBlockRel(Vec3i relativeBlockInChunk) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java index ac97578..3d65785 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java @@ -29,7 +29,7 @@ import ru.windcorp.progressia.common.world.rels.AxisRotations; public class GenericChunks { - public static Vec3i resolve(Vec3i relativeCoords, Vec3i output, AbsFace up) { + public static Vec3i resolve(Vec3i relativeCoords, AbsFace up, Vec3i output) { if (output == null) { output = new Vec3i(); } @@ -46,6 +46,23 @@ public class GenericChunks { return output; } + public static Vec3i relativize(Vec3i absoluteCoords, AbsFace up, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1; + + output.set(absoluteCoords.x, absoluteCoords.y, absoluteCoords.z); + output.mul(2).sub(offset); + + AxisRotations.relativize(output, up, output); + + output.add(offset).div(2); + + return output; + } + private static int getBorderHits(Vec3i blockInChunk) { int hits = 0; diff --git a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java index 9e99314..50a56aa 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java @@ -18,28 +18,49 @@ package ru.windcorp.progressia.test; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.test.gen.surface.SurfaceFeature; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; +import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; -public class TestBushFeature extends SurfaceFeature { +public class TestBushFeature extends SurfaceTopLayerFeature { public TestBushFeature(String id) { super(id); } - - @Override - public void process(SurfaceWorld world, Request request) { - BlockData block = BlockDataRegistry.getInstance().get("Test:Log"); - - Vec3i location = new Vec3i(request.getRandom().nextInt(ChunkData.BLOCKS_PER_CHUNK), request.getRandom().nextInt(ChunkData.BLOCKS_PER_CHUNK), request.getRandom().nextInt(ChunkData.BLOCKS_PER_CHUNK)).add(request.getMin()); - if (world.getBlockSfc(location) == BlockDataRegistry.getInstance().get("Test:Air")) { - - world.setBlockSfc(location, block, false); - + + private void tryToSetLeaves(SurfaceWorld world, Vec3i posSfc, BlockData leaves) { + if (world.getBlockSfc(posSfc).getId().equals("Test:Air")) { + world.setBlockSfc(posSfc, leaves, false); } } + + @Override + protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) { + if (request.getRandom().nextInt(10*10) > 0) return; + + Vec3i center = topBlock.add_(0, 0, 1); + + BlockData log = BlockDataRegistry.getInstance().get("Test:Log"); + BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); + + world.setBlockSfc(center, log, false); + + VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 3, 3, 3, p -> { + tryToSetLeaves(world, p, leaves); + }); + + VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 5, 5, 1, p -> { + tryToSetLeaves(world, p, leaves); + }); + } + + @Override + protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) { + return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP); + } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index 0f4dcd2..caba6ea 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -93,8 +93,6 @@ public class TestChunkCodec extends ChunkCodec { ChunkData chunk = new ChunkData(position, world); - assert chunk.getUp() == ru.windcorp.progressia.server.ServerState.getInstance().getWorld().getData().getChunk(position).getUp(); - readBlocks(input, blockPalette, chunk); readTiles(input, tilePalette, chunk); diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index e65ae68..0c78b35 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -140,6 +140,9 @@ public class TestContent { ) ); register(new BlockLogic("Test:Log")); + register(new BlockData("Test:TemporaryLeaves")); + register(new BlockRenderTransparentCube("Test:TemporaryLeaves", getBlockTexture("TemporaryLeaves"))); + register(new TestBlockLogicGlass("Test:TemporaryLeaves")); // Sic, using Glass logic for leaves because Test register(new BlockData("Test:WoodenPlank")); register(new BlockRenderOpaqueCube("Test:WoodenPlank", getBlockTexture("WoodenPlank"))); diff --git a/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java b/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java new file mode 100644 index 0000000..3689998 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java @@ -0,0 +1,68 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test; + +import java.util.Set; + +import com.google.common.collect.ImmutableSet; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileDataRegistry; +import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; +import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; +import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; + +public class TestGrassFeature extends SurfaceTopLayerFeature { + + private static final Set WHITELIST = ImmutableSet.of( + "Test:Dirt", + "Test:Stone", + "Test:GraniteMonolith", + "Test:GraniteCracked", + "Test:GraniteGravel" + ); + + public TestGrassFeature(String id) { + super(id); + } + + @Override + protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) { + if (!WHITELIST.contains(world.getBlockSfc(topBlock).getId())) { + return; + } + + TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); + + for (RelFace face : RelFace.getFaces()) { + if (face == RelFace.DOWN) continue; + + if (BlockLogicRegistry.getInstance().get(world.getBlockSfc(topBlock.add_(face.getRelVector())).getId()).isTransparent()) { + world.getTilesSfc(topBlock, face).addFarthest(grass); + } + } + } + + @Override + protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) { + return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java new file mode 100644 index 0000000..5ca923a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java @@ -0,0 +1,103 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test; + +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; +import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; +import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; + +public class TestTreeFeature extends SurfaceTopLayerFeature { + + public TestTreeFeature(String id) { + super(id); + } + + private void tryToSetLeaves(SurfaceWorld world, Vec3i posSfc, BlockData leaves) { + if (world.getBlockSfc(posSfc).getId().equals("Test:Air")) { + world.setBlockSfc(posSfc, leaves, false); + } + } + + private void iterateSpheroid(Vec3i center, double horDiameter, double vertDiameter, Consumer action) { + VectorUtil.iterateCuboidAround( + center.x, center.y, center.z, + (int) Math.ceil(horDiameter) / 2 * 2 + 5, + (int) Math.ceil(horDiameter) / 2 * 2 + 5, + (int) Math.ceil(vertDiameter) / 2 * 2 + 5, + pos -> { + double sx = (pos.x - center.x) / horDiameter; + double sy = (pos.y - center.y) / horDiameter; + double sz = (pos.z - center.z) / vertDiameter; + + if (sx*sx + sy*sy + sz*sz <= 1) { + action.accept(pos); + } + } + ); + } + + @Override + protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) { + if (request.getRandom().nextInt(20*20) > 0) return; + + Vec3i start = topBlock.add_(0, 0, 1); + + BlockData log = BlockDataRegistry.getInstance().get("Test:Log"); + BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); + + Vec3i center = start.add_(0); + + int height = request.getRandom().nextInt(3) + 5; + for (; center.z < start.z + height; ++center.z) { + world.setBlockSfc(center, log, false); + } + + double branchHorDistance = 0; + + do { + double branchSize = 0.5 + 1 * request.getRandom().nextDouble(); + double branchHorAngle = 2 * Math.PI * request.getRandom().nextDouble(); + int branchVertOffset = -2 + request.getRandom().nextInt(3); + + Vec3i branchCenter = center.add_( + (int) (Math.sin(branchHorAngle) * branchHorDistance), + (int) (Math.cos(branchHorAngle) * branchHorDistance), + branchVertOffset + ); + + iterateSpheroid(branchCenter, 1.75 * branchSize, 2.5 * branchSize, p -> { + tryToSetLeaves(world, p, leaves); + }); + + branchHorDistance = 1 + 2 * request.getRandom().nextDouble(); + } while (request.getRandom().nextInt(8) > 1); + } + + @Override + protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) { + return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java index 1f69e00..6c14a2b 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java @@ -26,6 +26,8 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.test.TestBushFeature; +import ru.windcorp.progressia.test.TestGrassFeature; +import ru.windcorp.progressia.test.TestTreeFeature; import ru.windcorp.progressia.test.gen.surface.Surface; import ru.windcorp.progressia.test.gen.surface.SurfaceFeature; import ru.windcorp.progressia.test.gen.surface.SurfaceFeatureGenerator; @@ -41,6 +43,8 @@ public class PlanetFeatureGenerator { Collection features = new ArrayList<>(); features.add(new TestBushFeature("Test:BushFeature")); + features.add(new TestTreeFeature("Test:TreeFeature")); + features.add(new TestGrassFeature("Test:GrassFeature")); int seaLevel = (int) parent.getPlanet().getRadius(); this.surfaceGenerators = AbsFace.mapToFaces(face -> new SurfaceFeatureGenerator( @@ -59,6 +63,8 @@ public class PlanetFeatureGenerator { } else { generateBorderFeatures(chunk); } + + chunk.setGenerationHint(true); } private boolean isOrdinaryChunk(Vec3i chunkPos) { @@ -72,7 +78,6 @@ public class PlanetFeatureGenerator { private void generateBorderFeatures(ChunkData chunk) { // Do nothing - chunk.setGenerationHint(true); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index 649a6e9..e8307cb 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -69,6 +69,8 @@ class PlanetTerrainGenerator { } else { generateBorderTerrain(chunk); } + + chunk.setGenerationHint(false); return chunk; } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 82f0f55..1dbd5b8 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -72,7 +72,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { @Override protected boolean checkIsChunkReady(Boolean hint) { - return hint == Boolean.TRUE; // Avoid NPE + return Boolean.TRUE.equals(hint); // Avoid NPE } @Override @@ -91,7 +91,6 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { ChunkData chunk = getWorldData().getChunk(chunkPos); if (chunk == null) { - getServer().getLoadManager().getChunkManager().loadChunk(chunkPos); chunk = getWorldData().getChunk(chunkPos); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index aa0ef6c..69e6d8b 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -27,36 +27,44 @@ import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.rels.AxisRotations; public abstract class SurfaceFeature extends Namespaced { public static class Request { + private final SurfaceWorld world; private final ChunkData chunk; private final Vec3i minSfc = new Vec3i(); private final Vec3i maxSfc = new Vec3i(); private final Random random; - public Request(ChunkData chunk, Random random) { + public Request(SurfaceWorld world, ChunkData chunk, Random random) { + this.world = world; this.chunk = chunk; this.random = random; - Vec3i absMin = chunk.getMinBIW(null); - Vec3i absMax = chunk.getMaxBIW(null); + Vec3i tmpMin = chunk.getMinBIW(null); + Vec3i tmpMax = chunk.getMaxBIW(null); + + GenericChunks.relativize(tmpMin, chunk.getUp(), tmpMin); + GenericChunks.relativize(tmpMax, chunk.getUp(), tmpMax); - AxisRotations.relativize(absMin, chunk.getUp(), absMin); - AxisRotations.relativize(absMax, chunk.getUp(), absMax); - - Glm.min(absMin, absMax, minSfc); - Glm.max(absMin, absMax, maxSfc); + Glm.min(tmpMin, tmpMax, minSfc); + Glm.max(tmpMin, tmpMax, maxSfc); + + minSfc.z -= world.getSurface().getSeaLevel(); + maxSfc.z -= world.getSurface().getSeaLevel(); } public ChunkData getChunk() { return chunk; } + public SurfaceWorld getWorld() { + return world; + } + public Random getRandom() { return random; } @@ -93,56 +101,6 @@ public abstract class SurfaceFeature extends Namespaced { return maxSfc; } - public boolean contains(Vec3i surfaceBlockInWorld) { - Vec3i bic = Vectors.grab3i(); - bic.set(surfaceBlockInWorld.x, surfaceBlockInWorld.y, surfaceBlockInWorld.z); - bic.sub(minSfc); - boolean result = GenericChunks.containsBiC(bic); - Vectors.release(bic); - return result; - } - - public void forEach(Consumer action) { - VectorUtil.iterateCuboid( - minSfc.x, - minSfc.y, - minSfc.z, - maxSfc.x + 1, - maxSfc.y + 1, - maxSfc.z + 1, - action - ); - } - - /** - * Provided vectors have z set to {@link #getMinZ()}. - */ - public void forEachOnFloor(Consumer action) { - forEachOnLayer(action, getMinZ()); - } - - /** - * Provided vectors have z set to {@link #getMaxZ()}. - */ - public void forEachOnCeiling(Consumer action) { - forEachOnLayer(action, getMaxZ()); - } - - /** - * Provided vectors have z set to layer. - */ - public void forEachOnLayer(Consumer action, int layer) { - VectorUtil.iterateCuboid( - minSfc.x, - minSfc.y, - layer, - maxSfc.x + 1, - maxSfc.y + 1, - layer + 1, - action - ); - } - } public SurfaceFeature(String id) { @@ -150,5 +108,59 @@ public abstract class SurfaceFeature extends Namespaced { } public abstract void process(SurfaceWorld world, Request request); + + /* + * Utility methods + */ + + public boolean contains(Request request, Vec3i surfaceBlockInWorld) { + Vec3i bic = Vectors.grab3i(); + bic.set(surfaceBlockInWorld.x, surfaceBlockInWorld.y, surfaceBlockInWorld.z); + bic.sub(request.minSfc); + boolean result = GenericChunks.containsBiC(bic); + Vectors.release(bic); + return result; + } + + public void forEach(Request request, Consumer action) { + VectorUtil.iterateCuboid( + request.minSfc.x, + request.minSfc.y, + request.minSfc.z, + request.maxSfc.x + 1, + request.maxSfc.y + 1, + request.maxSfc.z + 1, + action + ); + } + + /** + * Provided vectors have z set to {@link #getMinZ()}. + */ + public void forEachOnFloor(Request request, Consumer action) { + forEachOnLayer(request, action, request.getMinZ()); + } + + /** + * Provided vectors have z set to {@link #getMaxZ()}. + */ + public void forEachOnCeiling(Request request, Consumer action) { + forEachOnLayer(request, action, request.getMaxZ()); + } + + /** + * Provided vectors have z set to layer. + */ + public void forEachOnLayer(Request request, Consumer action, int layer) { + VectorUtil.iterateCuboid( + request.minSfc.x, + request.minSfc.y, + layer, + request.maxSfc.x + 1, + request.maxSfc.y + 1, + layer + 1, + action + ); + } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java index ade7869..9a3c909 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java @@ -46,7 +46,7 @@ public class SurfaceFeatureGenerator { SurfaceWorld world = new SurfaceWorld(surface, chunk.getWorld()); Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); - SurfaceFeature.Request request = new SurfaceFeature.Request(chunk, random); + SurfaceFeature.Request request = new SurfaceFeature.Request(world, chunk, random); for (SurfaceFeature feature : features) { feature.process(world, request); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java new file mode 100644 index 0000000..5947950 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java @@ -0,0 +1,58 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.Vectors; + +public abstract class SurfaceTopLayerFeature extends SurfaceFeature { + + public SurfaceTopLayerFeature(String id) { + super(id); + } + + protected abstract void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock); + + protected abstract boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld); + + @Override + public void process(SurfaceWorld world, Request request) { + Vec3i cursor = Vectors.grab3i(); + + forEachOnLayer(request, pos -> { + + cursor.set(pos.x, pos.y, pos.z); + + if (!isSolid(world, cursor)) { + return; + } + + for (cursor.z += 1; cursor.z <= request.getMaxZ() + 1; ++cursor.z) { + if (!isSolid(world, cursor)) { + cursor.z -= 1; + processTopBlock(world, request, cursor); + return; + } + } + + }, request.getMinZ()); + + Vectors.release(cursor); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java index 740cc50..12ff59a 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java @@ -31,8 +31,9 @@ import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataReference; import ru.windcorp.progressia.common.world.tile.TileDataStack; -public class SurfaceWorld implements GenericWritableWorld { - +public class SurfaceWorld + implements GenericWritableWorld { + private final Surface surface; private final GenericWritableWorld parent; @@ -61,7 +62,7 @@ public class SurfaceWorld implements GenericWritableWorld getChunks() { return parent.getChunks(); @@ -76,37 +77,50 @@ public class SurfaceWorld implements GenericWritableWorld getEntities() { return parent.getEntities(); } - + @Override public EntityData getEntity(long entityId) { return parent.getEntity(entityId); } - + @Override public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { parent.setBlock(blockInWorld, block, notify); } - + @Override public void addEntity(EntityData entity) { parent.addEntity(entity); } - + @Override public void removeEntity(long entityId) { parent.removeEntity(entityId); } - + public Vec3i resolve(Vec3i surfacePosition, Vec3i output) { if (output == null) { - output = new Vec3i(); + output = new Vec3i(); } - + output.set(surfacePosition.x, surfacePosition.y, surfacePosition.z); + output.z += getSurface().getSeaLevel(); + + GenericChunks.resolve(output, getSurface().getUp(), output); + + return output; + } + + public Vec3i relativize(Vec3i absolutePosition, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + output.set(absolutePosition.x, absolutePosition.y, absolutePosition.z); + + GenericChunks.relativize(output, getSurface().getUp(), output); output.z -= getSurface().getSeaLevel(); - - GenericChunks.resolve(surfacePosition, output, getSurface().getUp()); - + return output; } @@ -117,7 +131,7 @@ public class SurfaceWorld implements GenericWritableWorld zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3>va%8)Xr2lgjwFJ(?ayXjx4tn|hIT@i;-uJ4k z%DV25Qieh&cnHAZ4uHq(|NDQA`H%nj4`*AoCZ`u)?{c>jEV z`TorP{kr-2f#;>b*YN&Y^XK)=>z?=f&+GGZozCm&*M-{t{9ye3gZ{aYub&V2y#D>5 z;NAz=&xK9@TqyX@C&%~q@ovlJR?F{On4kBb&(H5R@W0U?F%+Lub|vy>^tP1T_`Z4@ z3;VXT&@+A0@1^m%&_DiezHjxc$?xET< zlXL$05?f zN=QunXyIgof2V8CW5(m6Tdup~_We5DWQoylU-;_%#JJP&V#OHE&miMQ{p*e|p@oI1 zeVDjI;8p*#7I#0k-H)4u*s{x2gLgPCCeQf)`q%t--gJ%v$~jwq_KJ0RMH;J+<(xCt z@ir{t&Sz88-Qe%P|NKXG4OlSUZLZv4w?kLJ{3E$P&K0hq18+=xeF5ys`dol5Vg-rC zxPS$0b|Ja!Z1LU{=h(=KfjUd~A^L$?TuOeiNFPJU7>6j}v-zFk?puBG?`41xL!^)m z0a>w7$5=5Y{HMf<5A_sMOey75QcW%O9I_%T=aPk}y@V1=D!G(WODo;fP-9Is*HUY3 zwKv}ah?^Sm*lKI7cRsXp<<4(+-q8E-BaArG$fJxp+UV1p8D^Ym=2>Q)ZT96?Sj6$l ztE{@(>f3ExX~&&*-euR_c0ah<2`8R(@+qgDW={XH+Q+Q_^6&q^YVKn-e=VgqmLIF} zYAN4KIKfGh&9In{4ucn2zy;&IY-X#A(aUnOnQfk^NS;L|8D}|J3=78Xd^+yOc7H6F zOvwK`b~6~l|8H2%$aMb=%l)g}{+-oUzlknf3n>h>sWuROys4j%POa%2?@kS8kCn>d zXVI5Fx4x^X2h*3nou}`1^j+EOeyyX|b&_vmrp$}0OzcqnEN3)jQh?2tux4Y8na!?q zcfyMs%6+nby_GY|=(^b0;b5G}-(p(6OpmSmS}UZH=3JPp_L`%`4ki)07=KN7QeUj9 zrc}DH<*ePq;pQBF>NhI;*wS*odwx`p-F=Pa#@S&mqfg$0-`x0-GC<4gti!qjueroM zRevTKH*c)QuY`yx7G_%$!eHy}cSXJJJ@!fXS*|sY6xtX;mrrbmeqp2)@>uxd0G{_u ze&^NmXiBsezl(kLXfhyFhOZ~~U9_QGbh63*G`5d@o74B=`SIi)mSw48?!WBm5)3Kr}8#Z!g22p@K z{IO5&ZuPPqnQ+!#3jUMWc==SvD*=#&Llyj0CaGZU9BuhvVrYHgCf*TAqhqmE;BWK9;1FXO-fL}X5Tu&l}jSP-2g6#%mK#bxD_bl^i<-tD|`*cHe4Co z1wNv(Ms4kmZ)+Xz9B!31$_#sXzlio#c4^=l7*pkxXKqqmUDMQppZ2kQ?j2X05wmi; zv&iF)^ZJCCS$E%&$ZLJqGiN@)?40Z!<{-|A_!PVi4Ijj@6e&e+w2Gvfx_2sj!-;_Nf=V0kMG&LI8@9kw*Ze+kId z3Q$*i$?R5~rf2*J-XC($XVkDqvWv97c5G~Y5`TgOmg+EquUI@b5-Ynya!^DZVII^E zx~BWeY-a)T{MlSSg8_T8BOVD-LD@uHCZSeac&3{tj~6JrUROyA>UVrd6`TPk2#y&u z*2Aw3ur}~)J|TgXs||Y*v`01@m`-`c))OR;eBhlab0^-NmL-Yw3IQZcNg0Fq1(mA} z%a*YUtL7KVh0mc+DTgcz2u3iE#hSHtCAotn>?NScmibY00{_$Wq(9gsS86BA@IW0* zw%uI``{0%b0KR*42qwVW;^(q;+bsbyKDpu9=SW;*gqtY}Tl^BmOk8rE`#Q0*_>5*+ zSwt#s+eTd6b=rhEp$Gu2Op5aOG&%=2f)!&3ejPv{Y$ri^(-Nq%YB0)E?USdpdi)E& zjG!d;DKV~1#JRZY9u8CBHTmeKNvtsL)?A8q0<&h%cnI>q{R#Yf$HKV*w`A>+SqBTj z%SrKmoP3d1e%b`Hd2*X%`nyN?F_;6L@V=}CT8`A_>UU9{Eg~L{-*pujXiY#?X7_Q{ z3nvP$!Ht9FkcfEEhOJUCY&NxHKTtN{P~1`Q`YN!;h@+5)1DpW+oofXQkTIfzAJw?J zGBUS;^~w7M@mOrYAz2W2yUR!~$Dao=9W(3hNaz9C7f}S!Oxpt z;Nl^*HbD!U3YyI{z#}*cZxoG!7{T7fZNBd8aL*+v;`7}RU3xrv;qHgl&Rsa|Dk&TP zVK2NR`O1%PXx2!=y6b2g+~$@9bkKWd8=;+S`swwh=Y^+C zQvMlGbzuyy?evFu90-UX4IvZUAdg|$B{l~1+ISK0+y`h?*ujb8RTkjEF7UBM2! zL?;JGwcuMMc;o{x;6Qu%5qd3g!}jg-k~}C>;T=s2|~;V#^!25G~v9&y<<(V_yns0$vvim zOOx68%G-$i;5JcM@;5LGZ+Y@}WtK)Oc{ zp{2wF;Q<0VTcVMv$tX3f-KJv+v1E+vdrwPz#EFlLA>}q&a$psAjCx#<=XB-Qxd?4Y zs`bFqm&6s}TPI?FRChvI77|iO^Q>n*677TBm{g2ebFUF9y%Rim7PIZTMA#L1$=Sb% zFp`2uQBWKJ@(~;YVgh_v3)y(0s0>P##9`{%8w&4p5-D!!l42MwDg;B#6hcnQFnJ+e z4l#!2y?}E3^&>=f!lm(Sd@F4a@+~5j%kNE)aXmn4llp#0vC<##yqpw9&fMH3#PfM> zFcA2P57z(OYaL2~oJc+wVMR6KZ^+CLCFF;s2TlBG=d&_Z(N8&B$}1{?#s=J|KZe_8EACOrjaLJ3?BUzrLQIuVX2M zTX9{e46iDHzm4Z@UVMlHd&(^yxC4+KNRxi+T7c4c@0$;`t(Z%2{9Z<14l~2ZjYUX& zpyi46qUZtN@DV>T5(r*knh^gg;wC465pv57s3PP+NKnf_lu`zdGq_l{^@Q|*Qez^b z12c*y=pISZD8QIoXXH5GB~kKJd!NR8vyzA*v-XgODTy#z+x`S)i6^+dyKlos{F7 z42YX2Lm)#Zb;mAlnVev_VG{M@WeH2zQ;0*m3Qr;WYbePf))Uyd(LkUgv<9&8kVJB< zCxbcgJQkurS```zMxQDX>%DlJ#L?xjyIRSpk(>nKM)#P_wr~q# z1#N)2ky8>m+9H}HW>ZU&oY!64#~nrzy8 zX%#D~H&ky!)Iu7QpNTN$M_F_djXBSNI>3oZ*~rOj2UN3Dq+?m3g>Ghn{ToINiW6@0 zZcGmuG9F1B>UNMMqAW5yG7F9d$cTZX@<`FesaN81FP7Zysz6!=;cx;r;%|PdfIzZ_ zjkDLvQllF9B}oi)Ya|NMcxV(~#AO$#MY>mQQ&yJWxi?%Vro6wJj+8=!d`WY`vyYX znWREyJ0%u&L%=j58Z|k{x|b#oN?TBA+^pZ;!7jVwoB4N6zttMV$%+I|Y84vHYcTEV zRU6{26;WlEO9pof^R33)^?VPvevTPCp3UYX(Fq+bDn#r~99PH;5*pS52H=|s8Ueyp z(63p1JZY;%?{BSYk!g{^2@+Npp}$F+B;A*Q?B8Td)hd*1DH4BTJC$Xp=UD5O#R`$s4f{ND-sL6cA~q<)q@{#M8Mh)D?!e$lGINaulSe30 z!(9TsN}<6=|gE7q>;SB*Q2^FDGCrEi|`w)Kuux;O`7s(*!#;6@LP!U zzZ9B2b*6$7+ya|GlsKc&Xib=8^0rCDPUX~LPhMJOAkprsdAIp8~!a1h# zD)Q;plMD%L!oi_lgOn*6_-ZmJDj3}j&(rQJs7HxJfQ!{(YVx=x-?GLPPYnz{N9r#SK3fqhh*g$cyNRRNRs!YVN9}y&0^F~s1i;SZVJsxInUaGh7`R2QTp^fUnipWQTSl-ja%kJpFjl{&;pX$!)Zk%}l(sQ){yv=}W z>baEW)xRouqOY%l#&xgq+Y-tkp1v95(NPk|U zkk|Go4P5S{UZO#v#7-Vo$S6gT2ltw%1#z!iVul>RCL{^)E4UJJO$#oP_*>wGd?ES~ zmiz#0(e~Br`B;=q!*QV(B|^tnp8XcwBbtdA3u+$#B7j8OGY@WfnTVcU$zR%gL$V0* z;r+liyW*iNH{m=&r;vD*?p7va>Z%Tt;*zN_ShWe*8avdp6PSGJVqIOop_-stTf5>- z+ytMTCoFW5m4dB=W3jLiHIim)2s9LOfuUec7DkY;5O&pmiZf)f+ip7UC8AFT&j{GW zkD^h226c)G_~`2x@c#t!|G>r|GrHcN@2m?fquxp#9<^~t(kVJ(Y~#E*2tz|Ri^;_F zE?xY+S9U^pNZfWgg|tTuo4=3~k`-=npX2985XzonBSRa&KEUABlL<@c8p##tQP&_S z;2R`FH8KdwpH}McPU;|Sk${j{73Q99{Vc|2!OK@LWEa&NiQb>92XT1;vI@g+87MTN zRJoDBop2-E8jkR9i%j$3qF?z&eE|M~s^RHnJ<{0>Zd*re^LYz(L|`Bb;oHD3zy&ed zRTWj>hN~@=ue0(o`UzR@&zR4@NNwaaJP<-zvpG?}@6mE{UE&G#>p~F00U3)D}R3YR}hXCPKOSAZtN8b$L9X&ibD&W2CJJN0cypo3WT zUPBkI?X1R;Bfj{3yecJ?)CE)GOk8+_nn6?U?5!bDf zYqz^Ze2EF(n!A6%rUAJQymqA6sR7k7lsbtyh19F39nFBCdDe|luEu|*3JJ%2tAvd# z)eVn2xC`SPl{R~IFPH>(8ro3%CJ9q}o)KoqnwIRZpz6c}s&^R+M=Ne$?^WGAzM7so zDv}VW1*jq4j`D8hfU-9X&LuRg-UGxNqBX^`+A5$X3{^yH$2*KAfMO#{yA`OY_WDMm zlHnj1b!fa}LSh8&e7a%VvQ?$7E0j<6@zWogSGKd|FcLYbSCtZ85f;mC8drELd<`WM zhL$CgSene5s;@sja(h{9aJZqGplxwhgu&vifdJ`9M72K zV0@a-AoreOfAZJ56dF>3FgLy;i(t{8@)7u}I?!a|67!sbPfk@#K0*tpe zO#&yC>fxsu75eSIHi-F4`dOIg1-rAy(+p5V%b`{_>tBd4$s!;i7K6d3{0gQ%^Zb+h_P8c0+rOrP!JN0qP#99vVDl; zrmfcR9Skvjs$VK@LB7gCozhRHzjGnvD)tLsmx5Cr5>Jl*t_5sf4|vDOZC5fBi8j_~ z@0iDs(B>-P^>E)*6NzdyiRB61%}xUa7iuTW#0?~`$|$Wvnh~#T6v>3V&%Q%AQGuKH zb!pHGd1|stFN#9LTI8I@I?N1jf`;T0<=H6Cjc!+GS%no}l#A8+xbuA)IgB8#28(id zy;!1fnxVS33b+nn;!~O$kZ^z`4_7~|p}V3OT5})^++bFlT|4o zV%C(QjwXV{`+dI6B(&pacmUoqeKMQfQELXV(XwV{5H_SBLUJwuvGb!_1w~e*quD=F zgS$Cr-I^%C*|1YFDraTUvz!2DOR_*dSR5Z&&X$h{9AqW?h}RH65;ogw9PM@)!S%5; zfpELqP$1N2QnPF3*H?F{3~99Ltw5vJ2}Yt4y-X8PWv6ItMDoRGD#TBX(}0Xb*3qqy zk}ytDTd$GFi}Xo(y<-$gcnW1IZl)-CA#ThDUsEfZ7s*j2JH&F+$dp)zrlp4Fr6Bqm zl(IMJlTAT#buQj0-7UbHN4a|vLDhT&pTF-|!>1L%9c&*O3>#?wbe{Jwao<+5=%HXN zu!kr7heMo8pNBs_Z`>($C_1Z0B5@O zPSP~-HutAu`!lxm5hWvac{^&mo70Ml8QqcyB@Wf0f+RvQWo9T&Wq*=up3l_`=QVy{ zXOCtvl>qAPs+)Ry2N6VbI!XYMB)88Lhxc1VP7}p6L+iNW3@a=EMPs#O4JFkW=?uO+JE{5!3E5I{X)f9oB%kpj9 za%8y*&uXgHX1m4k9H9_6$F}Pba*tcll*w9e#I3@J)b>Z_Q z3ffi^9`itKARoq-P(3_Pw%^ati zxy?urr689#nX0SzEF!C#pTljkS3Mab6yLtUK1l`;r=ffbCQ8%7fPv4DJZuIm^cj~* zL}S8jx(>X!00HgaNvn_gPPdb(!n7MIvKocvsYF=t%Rhwp1Am~v2~yovBgOSqv_vuf zb?nNhTLQ2kuT;f}>oW{2yN0$X<;{2yai8f^dqK|X)EhB_mo;!=3o9nC2I(`Cya$mb1F_wSNYrk5-w1o^#eG)B4t zoHk&6sEv)uY62T7bc0(A%$K6FkwymRKSl=eR|$C%Bpee%MU`ZwH8q?RUNy7rH}8+z zWOq*>JTWZ91yfPnQ@!`2Vrh07Vn)4L@e_7us$o-=MF#RDp!&c|KhUQCxZiiT_g;HP zUELY>(h7eguZzxe_qg_e1?tq3=3f1sdo3whwavnC7jcNNKh=9yX_Cen;~jHu6<89- zMS4MJ3B4_v{3V?o`JwWxjjCw2d+o6nncLknlZ+^Z>t!sXyzh1{F67+8n2{xw^g~pVMZJ_d;0p16k)?jgTOCnsr zh>CG{8WLciiWcv}rE?lhxZ6p}%L2es^d_ z(ss9~kBew98kmus&f(4Y)=vzU`D)DYY|JQJIX{KBtOG58K=2aza?TB?YtleI00Tx$ zcJZF9<5aWaXO2W@7CWdJJCesfmr$Vblxw^2w5rSt<+^h1Lh4pcc}EQZpmmk|d6S>u z5j$98d7n(vIl>S<_?@bVoyqS;5MN~SenGeV_m1_i3fEf1+7 zwwyGxKBHo8+X|haAbsajx37@yaE}z)^?LCZ z8wW+OQS}7N)FR1q?wl}M?o~|O?U_Lw{laOun=b`=`YgRkHT$k9!KR(LBWT+-$fOTdb>oNh^_0&MhFbstg-I?7Us7v2yVTz!U`Vg3(u*-@AZBQ>F>8{~IcWC-axhU<55j>! zHL>D)HNY}w7`;*$!(g>S$1(ZEJt#6*# zmj?Th`z02goPu*z9jsCv_|8bde9#IIKzv?j6f}kN8H`!#Ws|*NWVyFHFBz=*hM>W4 zZRv2<_|8PDNQ$r{MZmrA^QBhKKxeD(S4|$0@= z-oLpR^CqrzoXuir`v$Il=B-pl8yaO5{ir%mqS2r&0z@D-)TN^!wKFJCFSn|{ zCau&lfJv{WsmyP~SRDOows3BXtUYA!-jHH5u9li+VzQ?Abc#<3GD!E|S*w%QNUDc( zgG(nW8tJtE8n&u$YD^l+NkVFx6_YmQImEz1+-rWRtAbwDXn8aQ5~9;SKEG2x5bb_N z&DiPBxrU}OL41-ZZyK@kI`nsJhR5q%QO<=uN*sdT*cq>i&xCw z8rF44OBf1k{Flj|Pbc!Ge#9?~6+c2tk%YWj*{Y#PYAUC%d}VN+Lc>qHL(L7ivT`SY z5Tm+J5L|YyneE=pgVJBDofTY)Do6bDniA>Om1{i^u4QyOWN+(y{PxTC`HO|%a^_23^vgF5F6Z~zv5 zSb}bb7^Q)MG4b{B*~{KaBt{|9WYJ9qD9c3PV4XXX7WBQEW-LAGjNcm!^$@CXyDFd4 zzy9~>-`-UUaNVe&4nt%iuNI=wgV$Rt0uOiKppvF+QBqSyNB+|IvP}nR!AWW^25Ohd z#%}4%_P(>1B>*1;g&q+QBsPX1K&N8%_gG$uKC2@X5nxZ{nm31dncO|=rbZT|_!hg@ zcMJy(;?!(Jjced)B@O(la-7vwhA+oy>aSs{eP@ar_y(H-QLNGvON#xD<2#^`n`F;a zq4Ve3Ey>x~-|LXKKl-6la32+=H5~`Yj`ZMVs$%Lid-ZcXMe(3B9X^5e))^8UTtka5 z@37}RLW8PRHw=zXN>6{LafTZA>C@F!RhRv5_r#SEZxF3W8l2nr438)A``ZIPTfQXu z4NJMRNSY!Vb*nx}@(}6Xfef*LT7*&2jKbp<8`O_;?5tzDApgE&^g4?B>CLngKTXm3 zori*k)?#KF&T23+}`#l+z34=ZNR7i6ZX>QrBCJgM*U`$U3aCs72Y>c}Y= zpEVw;U|rH!8n6M-xrqH%behHm1L${I1eCI95Q`2bBTeKkerqK#jXU&nfX!0GErXzv@@LEt>;hdXKu&Z7Bf>>iHI!lEK zU~}Y<+s>NE2ZI#$D%`&r<>EBZ%*VB4+0~-CEb;`-r&^Nk@s8rGtdSBh&*^lXrsmje zR2{5Fokgzrb9@ftRCS(_biyZ=4r;m;(%ZT8~~5>`E`4yqgvWY=Hi z0PzwHE0VIK9+r}t&JyCMlMEIwI^J{r+}wHR+T$CtB-KB{k@@zd5HwC&HMV6I6duD_ zNO*uZ!{$JWrU7C8XpO6U4{WFo7s}HC^>f~*+_F$0kC}t}=8c5VoP7ZmBa*liX|}_H z0&2bDKPX>t82r(hwB)KzTX#0sX#ieW>x_E$8k5(gY1ip3SO0l917BLZ)@^DY^_0~CZ4;Ux{Yz-vxykm<(<<%(XC3h;>Fd}4xfWndO_hl^VQ|+5 zZNa&?%oM*Q`@?5M=Fy;~nOj&x@~ChW*&5tg)8g-7q@E-NLzmPZK*t-fyBV$Dj0Ul~ zr3JseIrljpnptVmK++umP$$OJ8BrHZYC=0h}Anf_vx{ zK#BNlPg#iFeYqX@h~LFMHEI#=s0GOSIks_&QP4E3=DjNN@Sy~oDS}zvxvHqW>C>{g*3GS zpQ{o5Xr#}xPP0pI-NxnVfV(0gf!S5wAtbt3spCKAbKE)91c3=dPv1zAqS#OQGLFw7 zlkpw)Zt7(se{}pBF0I0ns@*KGFK=&`LPMK+BoFssAP4sm3{p5MBmQ}+Pa_~zYYRbh z>){?S;F>yK&~F+adNpgpJq530u*hnDi3AS0wzGrqaqA?``gkszKBfp1mV(-4A|@Qo zyrJ@xLJA)|%{>mLu{w3BXCK^MBVzi|t+TBJjvBX6wH3k}xH9Db?^*v9V)Zk-ve+ecogh$T5}>UbH8?t7-&TkA^_MZWnJ6biL;cy+dW>E)AZ?du+7(dB5V(E*(5c z(-p(SQT3o09VAPd7DaulqPY5f;*^rlJ1*e<7QbT2&fWQ-_e?DF+PW$#@>wc5wH0t? zlm#iUX;>(|xu>CnR=ghHi6J$Kl?-%FLil1rCUK^sw5&mis&mYmaVT%ZA*!X`bYKVK z$gim?qKV);fWW1ctQM)-8_SO0)xr_SJ8N(O<91KL7#%!vI#_p>&vzhbqZ~d1L7=Ff zxbzu4*E6y3Z%{LQi>dn^^KL)KykVqAe%iVw%oWUFE)Iga4bs^&nT9+oc7F~Htam<) zJh9cX0deN}l^PLSvM1|^LxX0ui~QX2Nb}|+vk1J}qDK+7L>f3RP!R=$s_+N-2Jvql-@Nfr%4Gtj*LW7JQgt0g5zf_&uPe| zu7L_(x6S(ZxivxCorNUD5PlPcgwozFrYRpHs0W3hhK{DbIv$@tLFN1(nlX#H2-k7v1#y6(`~anK@EDP=&c_9AQ5fxHaNKuGIn)r1=2cd z;59}sCR=ZF`U)3ub;Q0%8`4Je-hD{TSv_B0IYN7+Qy%~T00v@9M??Vs0RI60puMM)00009 za7bBm001r{001r{0eGc9b^rhX2XskIMF-^v0uKxyxRo)^0000PbVXQnLvL+uWo~o; zLvm$dbY)~9cWHEJAV*0}P*;Ht7XSbUXGugsR7l4)l>2jBbsa#@=ezgrBm2l}lQc=w z+N2>((>A3qEEE+L7{Ebblma3uBM*_5XL(4i5r$67Oa+1kL{X-KGQ|M}2Gn8f@DN*p zLYe?g+NMeKVw2s?zIX55z4z-69nU{-emQeQYt4@Sdl(%b)#=#+J*$>Vs0}?Go51H* zQ?8_$8MJwM-|O<=zO8!4b^UVn&6nvvKmAwP_3EAa@M|XtM!lq_3!HoLnNrSbg0%)m zVxQ{RdpXqg_g}5sR@CwQp1;VdHOpkzwtfOeog_c^Fm+^}k@r(ng~L4c_g$286)ySy zh5DRJ)(JqVsBtU@k5VjJ72){F5nb`vOr&RZXS9vB&M2yswHO>etbh5;?fT(6e#OuB zZPl4dLN~V6N!6@_CE?7kAUQ`B6!y)3kTD%c+43#f;1F zz=$@(a4b1Zu~X|>D_$XAOyD(59G@nv{Y)KlSaen$dtToGKA4J6XaJ8VK&9dUu>be3NcV!(l9^Pv z7AUP;UijrJf+a-HG%$T8o9+mdGC|OLKR%Rsh@f-lF}jWda7^ z_Yr@`ARGyE(Iw|eq3lqc@G?9+LRHu=I$K73ip~{FaBV&67-~h^!0n?&0_J`qi7nXIAiM)^$ovQ;;*dy5yRz zm&?F^KGL?gj5_$%A?+04`?cr3niQ^lLA^DF8P;bhS3> zh1m~^gu1-sMvK%g58;L^mV`Q_oU`@xa2z8y?vOr_$Agz8XL(7aEDpSRK(}<%W7`h) zQ4jU2lQr3l8n1eB2QOla?XBiVEs=YZmv0hYlrIF}zMLu5yAn2$H$KM${ zy%w~M*S7H+CKqqMP+LIe zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00JpVL_t(Y$JLb0OH^SLhoAS( zojc=vs3Q{vWvC^&X&ua>FP8~Hxi$#tFNhYkiwassxQYtJvPBRsB5)xslC~zIIO?c_ zALHma-0{xmz3+Y7xe0A_?#AEtJ?A|9&Uw#)(=Kt`gl}sFW%@LPE)iwPKxdoq1n?nU zRAEChziF|QUuCp6QCF^3PtbVQQt5nwO9C>xsk)2T<>1p+QKig1M5WB^+7@5#-Z)lU zk96>P&r#i)gK0VtZX%%jk3Hlg0a~fb__j$)EX2(062o^A!ZX0fWKR7~Wr#{YZp9|* z51i$l>PorHM|GU7Bed1*z8&kVa*`u7pyKPc@dmLL|bU8IYe$h5GQu< zviqDUmK4p+2BE0pen*U5p(BN0ZY5V&@&9h}z}H`@{Yn>IZLKV9W{@`QY_2oXf8D!N zF*yEHU2N~fj`)ZuLBY%uYmV`_=e#$^?o}|!N_v6HzRS(9ffkD4mTaC(udC%4( z=G3T?RhyaBEMxI<TeJ;ui?ZDl(|CUr}g=!M%73Q^hhHy2k5{Gomg)eqvZv?F#c- zIc^O;J&2o1t*fCwNdi*x@akpWFQ##E80qU3bvxLe98#_&SgGkG`X31z&_6TSnRugI nEyQfD)^PDdH97WHaa!~j!ua4Ld5*~=00000NkvXXu0mjfkFYs! literal 0 HcmV?d00001 diff --git a/src/test/java/ru/windcorp/progressia/common/world/generic/GenericChunkRotationsTest.java b/src/test/java/ru/windcorp/progressia/common/world/generic/GenericChunkRotationsTest.java new file mode 100644 index 0000000..ef3d4c3 --- /dev/null +++ b/src/test/java/ru/windcorp/progressia/common/world/generic/GenericChunkRotationsTest.java @@ -0,0 +1,83 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic; + +import static org.junit.Assert.fail; +import static ru.windcorp.progressia.common.world.generic.GenericChunks.*; + +import java.util.Random; + +import org.junit.Test; + +import glm.Glm; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.AbsFace; + +public class GenericChunkRotationsTest { + + private static void assertVecEquals(String message, AbsFace up, Vec3i a, Vec3i b) { + if (a == b) { + return; + } + + if (Glm.equals(a, b)) { + return; + } + + fail(String.format("%s. x = (%4d; %4d; %4d), got (%4d; %4d; %4d) (up = %s)", message, a.x, a.y, a.z, b.x, b.y, b.z, up)); + } + + private void check(int x, int y, int z) { + for (AbsFace up : AbsFace.getFaces()) { + + Vec3i veci = new Vec3i(x, y, z); + + assertVecEquals("Vec3i, x != resolve(relativize(x))", up, veci, resolve(relativize(veci, up, null), up, null)); + assertVecEquals("Vec3i, x != relativize(resolve(x))", up, veci, relativize(resolve(veci, up, null), up, null)); + + } + } + + @Test + public void specialCases() { + + for (int x = -1; x <= 1; ++x) { + for (int y = -1; y <= 1; ++y) { + for (int z = -1; z <= 1; ++z) { + check(x, y, z); + } + } + } + + } + + @Test + public void randomValues() { + + final int iterations = 2 << 16; + final long seed = 0; + + Random random = new Random(seed); + + for (int i = 0; i < iterations; ++i) { + check(random.nextInt(200) - 100, random.nextInt(200) - 100, random.nextInt(200) - 100); + } + + } + +} diff --git a/src/test/java/ru/windcorp/progressia/common/world/rels/AxisRotationsTest.java b/src/test/java/ru/windcorp/progressia/common/world/rels/AxisRotationsTest.java new file mode 100644 index 0000000..27d6368 --- /dev/null +++ b/src/test/java/ru/windcorp/progressia/common/world/rels/AxisRotationsTest.java @@ -0,0 +1,100 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.rels; + +import static org.junit.Assert.fail; +import static ru.windcorp.progressia.common.world.rels.AxisRotations.*; + +import java.util.Random; + +import org.junit.Test; + +import glm.Glm; +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; + +public class AxisRotationsTest { + + private static void assertVecEquals(String message, AbsFace up, Vec3i a, Vec3i b) { + if (a == b) { + return; + } + + if (Glm.equals(a, b)) { + return; + } + + fail(String.format("%s. x = (%4d; %4d; %4d), got (%4d; %4d; %4d) (up = %s)", message, a.x, a.y, a.z, b.x, b.y, b.z, up)); + } + + private static void assertVecEquals(String message, AbsFace up, Vec3 a, Vec3 b) { + if (a == b) { + return; + } + + if (b.sub_(a).length() <= 1e-3) { + return; + } + + fail(String.format("%s. x = (%4f; %4f; %4f), got (%4f; %4f; %4f), d = %f (up = %s)", message, a.x, a.y, a.z, b.x, b.y, b.z, b.sub_(a).length(), up)); + } + + private void check(int x, int y, int z) { + for (AbsFace up : AbsFace.getFaces()) { + + Vec3i veci = new Vec3i(x, y, z); + + assertVecEquals("Vec3i, x != resolve(relativize(x))", up, veci, resolve(relativize(veci, up, null), up, null)); + assertVecEquals("Vec3i, x != relativize(resolve(x))", up, veci, relativize(resolve(veci, up, null), up, null)); + + Vec3 vecf = new Vec3(x, y, z); + + assertVecEquals("Vec3, x != resolve(relativize(x))", up, vecf, resolve(relativize(vecf, up, null), up, null)); + assertVecEquals("Vec3, x != relativize(resolve(x))", up, vecf, relativize(resolve(vecf, up, null), up, null)); + + } + } + + @Test + public void specialCases() { + + for (int x = -1; x <= 1; ++x) { + for (int y = -1; y <= 1; ++y) { + for (int z = -1; z <= 1; ++z) { + check(x, y, z); + } + } + } + + } + + @Test + public void randomValues() { + + final int iterations = 2 << 16; + final long seed = 0; + + Random random = new Random(seed); + + for (int i = 0; i < iterations; ++i) { + check(random.nextInt(200) - 100, random.nextInt(200) - 100, random.nextInt(200) - 100); + } + + } + +} From d7afe39f00a7e50242ed3376b7e348bd02027232 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 15 Jul 2021 22:26:20 +0300 Subject: [PATCH 34/63] Added more generic Contexts. WIP. --- .../common/world/context/Context.java | 105 ++++++++++++ .../context/GenericROBlockContext.java | 119 ++++++++++++++ .../context/GenericROBlockFaceContext.java | 93 +++++++++++ .../generic/context/GenericROTileContext.java | 85 ++++++++++ .../context/GenericROWorldContext.java | 45 ++++++ .../context/GenericRWBlockContext.java | 92 +++++++++++ .../context/GenericRWBlockFaceContext.java | 78 +++++++++ .../generic/context/GenericRWTileContext.java | 50 ++++++ .../context/GenericRWWorldContext.java | 151 ++++++++++++++++++ .../server/world/context/ServerContext.java | 84 ++++++++++ 10 files changed, 902 insertions(+) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/Context.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/Context.java b/src/main/java/ru/windcorp/progressia/common/world/context/Context.java new file mode 100644 index 0000000..bfbd164 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/Context.java @@ -0,0 +1,105 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +/** + * A cursor-like object for retrieving information about an in-game environment. + * A context object typically holds a reference to some sort of data structure + * and a cursor pointing to a location in that data structure. The exact meaning + * of "environment" and "location" is defined by extending interfaces. + *

      + * Context objects are intended to be the primary way of interacting for in-game + * content. Wherever possible, context objects should be preferred over other + * means of accessing game structures. + *

      Context Validity

      + * Context objects may only be used while they are valid to avoid undefined + * behavior. There exists no programmatic way to determine a context's validity; + * it is the responsibility of the programmer to avoid interacting with invalid + * contexts. + *

      + * Contexts are usually acquired as method parameters. Unless stated otherwise, + * the context is valid until the invoked method returns; the only exception to + * this rule is subcontexting (see below). Consequently, contexts should never + * be stored outside their intended methods. + *

      + * In practice, context objects are typically highly volatile. They are not + * thread-safe and are often pooled and reused. + *

      + *

      Subcontexting

      + * Subcontexting is the invocation of user-provided code with a context + * object derived from an existing one. For example, block context provides a + * convenience method for referencing the block's neighbor: + * + *
      + * blockContextA.forNeighbor(RelFace.UP, blockContextB -> {
      + * 	foo(blockContextA); // undefined behavior!
      + * 	foo(blockContextB); // correct
      + * });
      + * 
      + * + * In this example, {@code forNeighbor} is a subcontexting method, + * {@code blockContextA} is the parent context, {@code blockContextB} is the + * subcontext, and the lambda is the context consumer. + *

      + * Parent contexts are invalid while the subcontexting method is + * running. Referencing {@code blockContextA} from inside the lambda + * creates undefined behavior. + *

      + * This restriction exists because some implementations of contexts may + * implement subcontexting by simply modifying the parent context for the + * duration of the call and presenting the temporarily modified parent context + * as the subcontext: + * + *

      + * public void forNeighbor(BlockFace face, Consumer<BlockContext> action) {
      + * 	this.position.add(face);
      + * 	action.accept(this);
      + * 	this.position.sub(face);
      + * }
      + * 
      + */ +public interface Context { + + /** + * Tests whether the environment is "real". Any actions carried out in an + * environment that is not "real" should not have any side effects outside + * of the environment. + *

      + * A typical "real" environment is the world of the client that is actually + * displayed or a world of the server that the clients actually interact + * with. An example of a non-"real" environment is a fake world used by + * developer tools to query the properties or behaviors of in-game content. + * While in-game events may well trigger global-scope actions, such as + * writing files, this may become an unintended or even harmful byproduct in + * some scenarios that are not actually linked to an actual in-game world. + *

      + * This flag should generally only be consulted before taking action through + * means other than a provided changer object. The interactions with the + * context should otherwise remain unaltered. + *

      + * When querying game content for purposes other than directly applying + * results in-game, {@code isReal()} should return {@code false}. In all + * other cases, where possible, the call should be delegated to a provided + * context object. + * + * @return {@code false} iff side effects outside the environment should be + * suppressed + */ + boolean isReal(); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java new file mode 100644 index 0000000..4411407 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java @@ -0,0 +1,119 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.GenericROChunk; +import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.GenericROTileReference; +import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.rels.BlockFace; + +/** + * A {@link Context} referencing a world with a block location specified. The + * location may or may not be loaded. + */ +//@formatter:off +public interface GenericROBlockContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericROTileStack , + TR extends GenericROTileReference , + C extends GenericROChunk , + E extends GenericEntity +> extends GenericROWorldContext { +//@formatter:on + + /** + * Returns the location of the block. + *

      + * The coordinate system in use is not specified, but it is consistent + * across all methods of this context. + *

      + * The object returned by this method must not be modified. It is only valid + * while the context is {@linkplain valid}. + * + * @return a vector describing the block's position + */ + Vec3i getLocation(); + + /** + * Determines whether the location relevant to this context is currently + * loaded. + * + * @return {@code true} iff the location is loaded + */ + default boolean isLoaded() { + return isBlockLoaded(getLocation()); + } + + /** + * Gets the block relevant in this context. + * + * @return the block or {@code null} if the location is not loaded + */ + default B getBlock() { + return getBlock(getLocation()); + } + + /** + * Gets the tile stack at the specified position; block location is implied + * by the context. + * + * @return the specified tile stack or {@code null} if the location is not + * loaded or the tile stack does not exist + */ + default TS getTilesOrNull(BlockFace face) { + return getTilesOrNull(getLocation(), face); + } + + /** + * Determines whether the location relevant to this context has a tile stack + * at the specified side. + * + * @return {@code true} iff the tile stack exists + */ + default boolean hasTiles(BlockFace face) { + return hasTiles(getLocation(), face); + } + + /** + * Determines whether the specified position has a tile; block location is + * implied by the context. + * + * @return {@code true} iff the tile exists + */ + default boolean hasTile(BlockFace face, int layer) { + return hasTile(getLocation(), face, layer); + } + + /** + * Gets the tile at the specified position; block location is implied by the + * context. + * + * @return the specified tile or {@code null} if the location is not loaded + * or the tile does not exist + */ + default T getTile(BlockFace face, int layer) { + return getTile(getLocation(), face, layer); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java new file mode 100644 index 0000000..430a4a3 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java @@ -0,0 +1,93 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.GenericROChunk; +import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.GenericROTileReference; +import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.rels.RelFace; + +/** + * A {@link Context} referencing a world with a block location and a block face + * specified, effectively pointing to a tile stack. The tile stack may or may + * not actually exist. + */ +//@formatter:off +public interface GenericROBlockFaceContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericROTileStack , + TR extends GenericROTileReference , + C extends GenericROChunk , + E extends GenericEntity +> extends GenericROBlockContext { +//@formatter:on + + /** + * Returns the face relevant to this context. + * + * @return the block face + */ + RelFace getFace(); + + /** + * Gets the tile stack at the relevant position. + * + * @return the specified tile stack or {@code null} if the location is not + * loaded or the tile stack does not exist + */ + default TS getTilesOrNull() { + return getTilesOrNull(getLocation(), getFace()); + } + + /** + * Determines whether the location relevant to this context has a tile + * stack. + * + * @return {@code true} iff the tile stack exists + */ + default boolean hasTiles() { + return hasTiles(getLocation(), getFace()); + } + + /** + * Determines whether the specified position has a tile; block location and + * face are implied by the context. + * + * @return {@code true} iff the tile exists + */ + default boolean hasTile(int layer) { + return hasTile(getLocation(), getFace(), layer); + } + + /** + * Gets the tile at the specified position; block location and face are + * implied by the context. + * + * @return the specified tile or {@code null} if the location is not loaded + * or the tile does not exist + */ + default T getTile(int layer) { + return getTile(getLocation(), getFace(), layer); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java new file mode 100644 index 0000000..0ebc768 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java @@ -0,0 +1,85 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.GenericROChunk; +import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.GenericROTileReference; +import ru.windcorp.progressia.common.world.generic.GenericROTileStack; + +/** + * A {@link Context} referencing a world with a block location, a block face and + * a tile layer specified, effectively pointing to a single tile. The tile may + * or may not actually exist. + */ +//@formatter:off +public interface GenericROTileContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericROTileStack , + TR extends GenericROTileReference , + C extends GenericROChunk , + E extends GenericEntity +> extends GenericROBlockFaceContext { +//@formatter:on + + /** + * Returns the tile layer relevant to this context. + * + * @return the tile layer + */ + int getLayer(); + + /** + * Determines whether the location relevant to this context has a tile. + * + * @return {@code true} iff the tile exists + */ + default boolean hasTile() { + return hasTile(getLocation(), getFace(), getLayer()); + } + + /** + * Gets the tile at the relevant position. + * + * @return the specified tile or {@code null} if the location is not loaded + * or the tile does not exist + */ + default T getTile() { + return getTile(getLocation(), getFace(), getLayer()); + } + + /** + * Gets the tag of the tile at the relevant position. + * + * @return the tag of the tile or {@code -1} if the location is not loaded + * or the tile does not exist + */ + default int getTag() { + TS tileStack = getTilesOrNull(); + if (tileStack == null) { + return -1; + } + + return tileStack.getTagByIndex(getLayer()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java new file mode 100644 index 0000000..09629da --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java @@ -0,0 +1,45 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.GenericROChunk; +import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.GenericROTileReference; +import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.generic.GenericROWorld; + +/** + * A {@link Context} with a world instance. + */ +// @formatter:off +public interface GenericROWorldContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericROTileStack , + TR extends GenericROTileReference , + C extends GenericROChunk , + E extends GenericEntity +> extends Context, GenericROWorld { +// @formatter:on + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java new file mode 100644 index 0000000..23fb6fe --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java @@ -0,0 +1,92 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.*; +import ru.windcorp.progressia.common.world.rels.BlockFace; + +/** + * A writable {@link Context} referencing a world with a block location + * specified. This context provides methods for affecting the world. The + * application of requested changes may or may not be immediate, see + * {@link #isImmediate()}. The location may or may not be loaded. + */ +//@formatter:off +public interface GenericRWBlockContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericRWTileStack , + TR extends GenericROTileReference , + C extends GenericRWChunk , + E extends GenericEntity +> extends GenericRWWorldContext, GenericROBlockContext { +//@formatter:on + + /** + * Requests that a block is changed. The object provided may be stored until + * the change is applied. The location of the block is implied by the + * context. + * + * @param block the new block + * @see #isImmediate() + */ + default void setBlock(B block) { + setBlock(getLocation(), block); + } + + /** + * Requests that a tile is added to the top of the tile stack at the given + * location. The object provided may be stored until the change is applied. + * If the tile could not be added at the time of application this method + * fails silently. The location of the block is implied by the context. + * + * @param face the face of the block to add the tile to + * @param tile the tile to add + */ + default void addTile(BlockFace face, T tile) { + addTile(getLocation(), face, tile); + } + + /** + * Requests that a tile identified by its tag is removed from the specified + * tile stack. If the tile could not be found at the time of application + * this method fails silently. The location of the block is implied by the + * context. + * + * @param face the of the block to remove the tile from + * @param tag the tag of the tile to remove + */ + default void removeTile(BlockFace face, int tag) { + removeTile(getLocation(), face, tag); + } + + /** + * Requests that the referenced tile is removed from the specified tile + * stack. If the tile could not be found at the time of application this + * method fails silently. The location of the block is implied by the + * context. + * + * @param face the of the block to remove the tile from + * @param tileReference a reference to the tile + */ + default void removeTile(BlockFace face, TR tileReference) { + removeTile(getLocation(), face, tileReference.getTag()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java new file mode 100644 index 0000000..b2152f8 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java @@ -0,0 +1,78 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.*; + +/** + * A writable {@link Context} referencing a world with a block location and a + * block face specified, effectively pointing to a tile stack. This context + * provides methods for affecting the world. The application of requested + * changes may or may not be immediate, see {@link #isImmediate()}. The tile + * stack may or may not actually exist. + */ +//@formatter:off +public interface GenericRWBlockFaceContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericRWTileStack , + TR extends GenericROTileReference , + C extends GenericRWChunk , + E extends GenericEntity +> extends GenericRWBlockContext, GenericROBlockFaceContext { +//@formatter:on + + /** + * Requests that a tile is added to the top of the tile stack at the given + * location. The object provided may be stored until the change is applied. + * If the tile could not be added at the time of application this method + * fails silently. The location and the face of the block are implied by the + * context. + * + * @param tile the tile to add + */ + default void addTile(T tile) { + addTile(getLocation(), getFace(), tile); + } + + /** + * Requests that a tile identified by its tag is removed from the specified + * tile stack. If the tile could not be found at the time of application + * this method fails silently. The location and the face of the block are + * implied by the context. + * + * @param tag the tag of the tile to remove + */ + default void removeTile(int tag) { + removeTile(getLocation(), getFace(), tag); + } + + /** + * Requests that the referenced tile is removed from the specified tile + * stack. If the tile could not be found at the time of application this + * method fails silently. The location and the face of the block are implied + * by the context. + * + * @param tileReference a reference to the tile + */ + default void removeTile(TR tileReference) { + removeTile(getLocation(), getFace(), tileReference.getTag()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java new file mode 100644 index 0000000..c7c0d5c --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java @@ -0,0 +1,50 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.*; + +/** + * A writable {@link Context} referencing a world with a block location, a block + * face and a tile layer specified, effectively pointing to a single tile. This + * context provides methods for affecting the world. The application of + * requested changes may or may not be immediate, see {@link #isImmediate()}. + * The tile may or may not actually exist. + */ +//@formatter:off +public interface GenericRWTileContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericRWTileStack , + TR extends GenericROTileReference , + C extends GenericRWChunk , + E extends GenericEntity +> extends GenericRWBlockFaceContext, GenericROTileContext { +//@formatter:on + + /** + * Requests that the tile relevant to this context be removed from its tile + * stack. If the tile could not be found at the time of application this + * method fails silently. + */ + default void removeTile() { + removeTile(getLocation(), getFace(), getTag()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java new file mode 100644 index 0000000..55d83ff --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java @@ -0,0 +1,151 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.generic.*; +import ru.windcorp.progressia.common.world.rels.BlockFace; + +/** + * A writable {@link Context} with a world instance. This context provides + * methods for affecting the world. The application of requested changes may or + * may not be immediate, see {@link #isImmediate()}. + */ +// @formatter:off +public interface GenericRWWorldContext< + B extends GenericBlock, + T extends GenericTile, + TS extends GenericRWTileStack , + TR extends GenericROTileReference , + C extends GenericRWChunk , + E extends GenericEntity +> extends GenericROWorldContext, GenericRWWorld { +// @formatter:on + + /** + * Queries whether changes requested with this context are guaranteed to be + * applied immediately. + *

      + * When the changes are applied immediately, all subsequent queries will + * reflect the change. When the changes are not applied immediately, none of + * the subsequent queries will be affected by the requests while the context + * is {@linkplain Context#validity valid}. Immediate mode does not change + * while the context is valid. + * + * @return {@code true} iff changes are visible immediately + */ + boolean isImmediate(); + + /** + * Requests that a block is changed. The object provided may be stored until + * the change is applied. + * + * @param location the location of the change + * @param block the new block + * @see #isImmediate() + */ + default void setBlock(Vec3i location, B block) { + setBlock(location, block); + } + + /** + * Requests that a tile is added to the top of the tile stack at the given + * location. The object provided may be stored until the change is applied. + * If the tile could not be added at the time of application this method + * fails silently. + * + * @param location the location of the block to which the tile is to be + * added + * @param face the face of the block to add the tile to + * @param tile the tile to add + */ + void addTile(Vec3i location, BlockFace face, T tile); + + /** + * Requests that a tile identified by its tag is removed from the specified + * tile stack. If the tile could not be found at the time of application + * this method fails silently. + * + * @param location the location of the block from which the tile is to be + * removed + * @param face the of the block to remove the tile from + * @param tag the tag of the tile to remove + */ + void removeTile(Vec3i location, BlockFace face, int tag); + + /** + * Requests that the referenced tile is removed from the specified tile + * stack. If the tile could not be found at the time of application this + * method fails silently. + * + * @param location the location of the block from which the tile is to + * be removed + * @param face the of the block to remove the tile from + * @param tileReference a reference to the tile + */ + default void removeTile(Vec3i location, BlockFace face, TR tileReference) { + removeTile(location, face, tileReference.getTag()); + } + + /** + * Requests that an entity is added to the world. The object provided may be + * stored until the change is applied. If the entity was already added to + * the world at the time of application this method does nothing. + * + * @param entity the entity to add + * @see #isImmediate() + */ + @Override + void addEntity(E entity); + + /** + * Requests that an entity with the given entity ID is removed from the + * world. If the entity did not exist at the time of application this method + * fails silently. + * + * @param entityId the ID of the entity to remove + * @see #isImmediate() + * @see #removeEntity(GenericEntity) + */ + @Override + void removeEntity(long entityId); + + /** + * Requests that the entity is removed from the world. If the entity did not + * exist at the time of application this method fails silently. + * + * @param entity the entity to remove + * @see #isImmediate() + * @see #removeEntity(long) + */ + @Override + void removeEntity(E entity); + + /** + * Requests that the specified change is applied to the given entity. The {@code change} object provided may be stored until the change is applied. + * + * @param entity the entity to change + * @param change the change to apply + */ + @Override + void changeEntity(SE entity, StateChange change); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java new file mode 100644 index 0000000..bb218ab --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java @@ -0,0 +1,84 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import java.util.Random; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.ServerState; + +/** + * A server-side {@link Context}. This context has a {@link Server} instance. + */ +public interface ServerContext extends Context { + + /** + * Gets the {@link Server} instance relevant to this context. This method + * should always be preferred to {@link ServerState#getInstance()} when + * possible. + * + * @return the server instance + */ + Server getServer(); + + /** + * Retrieves a context-appropriate source of randomness. This source should + * always be preferred to any other when possible. + * + * @return an intended {@link Random} instance + */ + Random getRandom(); + + /** + * Returns the duration of the last server tick. Server logic should assume + * that this much in-world time has passed. + * + * @return the length of the last server tick + */ + default double getTickLength() { + return getServer().getTickLength(); + } + + /** + * Adjusts the provided value according to tick length assuming the value + * scales linearly. The call {@code ctxt.adjustValue(x)} is equivalent to + * {@code ((float) ctxt.getTickLength()) * x}. + * + * @param valueForOneSecond the value to adjust, normalized to one second + * @return the value adjust to account for the actual tick length + * @see #getTickLength() + */ + default float adjustTime(float valueForOneSecond) { + return ((float) getTickLength()) * valueForOneSecond; + } + + /** + * Adjusts the provided value according to tick length assuming the value + * scales linearly. The call {@code ctxt.adjustValue(x)} is equivalent to + * {@code ctxt.getTickLength() * x}. + * + * @param valueForOneSecond the value to adjust, normalized to one second + * @return the value adjust to account for the actual tick length + * @see #getTickLength() + */ + default double adjustTime(double valueForOneSecond) { + return getTickLength() * valueForOneSecond; + } + +} From 9a326603cd9e4cb8d1f9a130d7cde62f861a0cd9 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 23 Jul 2021 22:46:49 +0300 Subject: [PATCH 35/63] Still working on Contexts. Introduced a billion interfaces. WIP. *takes a deep breath - Renamed Generic world structure interfaces to the following scheme: {Block,Tile,Chunk,World}Generic{,Stack,Reference}{RO,WO} (e.g. GenericWritableChunk -> ChunkGenericWO) - RO is Read Only, WO is Write Only - Generic writable interfaces no longer extend their read-only counterparts (thus Write Only) - TileGenericStack{RO,WO} are now interfaces; AbstractList is only introduced by final implementations - TileGenericReferenceRO now has a WO counterpart - Fixed compilation issues with the previous commit - Declared some additional functionality for Generic interfaces - Old ChunkData and WorldData renamed to DefaultChunkData and DefaultWorldData - Now considered to be an implementation detail; references will be minimized - Introduced TileDataStack{,RO}, TileDataReference{,RO}, ChunkData{,RO}, WorldData{,RO} interfaces - Suffix -RO indicates Read Only, no suffix means read-write - To be used in place of DefaultChunk and DefaultWorld - Designed to support wrappers and "fake" implementations - May need some refinement (fix return/parameter types, ...) - Surface world generator is now implemented poorly (WIP) - Should compile. May work fine. Unless Java inheritance rules have screwed me over. --- .../ru/windcorp/progressia/client/Client.java | 4 +- .../progressia/client/ClientState.java | 4 +- .../progressia/client/world/ChunkRender.java | 16 +- .../client/world/ChunkRenderModel.java | 10 +- .../client/world/ChunkUpdateListener.java | 14 +- .../progressia/client/world/WorldRender.java | 26 +- .../client/world/block/BlockRender.java | 8 +- .../client/world/block/BlockRenderNone.java | 4 +- .../world/block/BlockRenderTexturedCube.java | 8 +- .../cro/ChunkRenderOptimizerSurface.java | 8 +- .../client/world/entity/EntityRenderable.java | 4 +- .../client/world/tile/TileRender.java | 8 +- .../client/world/tile/TileRenderNone.java | 4 +- .../world/tile/TileRenderReference.java | 4 +- .../client/world/tile/TileRenderStack.java | 10 +- .../client/world/tile/TileRenderSurface.java | 8 +- .../collision/WorldCollisionHelper.java | 4 +- .../common/collision/colliders/Collider.java | 14 +- .../StateChange.java} | 11 +- .../progressia/common/world/ChunkData.java | 525 +----------------- .../common/world/ChunkDataListener.java | 10 +- .../common/world/ChunkDataListeners.java | 2 +- .../progressia/common/world/ChunkDataRO.java | 12 + .../progressia/common/world/Coordinates.java | 2 +- .../common/world/DefaultChunkData.java | 525 ++++++++++++++++++ .../common/world/DefaultWorldData.java | 262 +++++++++ .../common/world/PacketAffectWorld.java | 2 +- .../common/world/PacketRevokeChunk.java | 4 +- .../common/world/PacketSendChunk.java | 4 +- .../common/world/PacketSetGravityModel.java | 2 +- .../common/world/TileDataReference.java | 10 + .../common/world/TileDataReferenceRO.java | 12 + .../common/world/TileDataStack.java | 25 + .../common/world/TileDataStackRO.java | 12 + .../progressia/common/world/WorldData.java | 257 ++------- .../common/world/WorldDataListener.java | 14 +- .../progressia/common/world/WorldDataRO.java | 29 + .../common/world/block/BlockData.java | 4 +- .../common/world/block/PacketSetBlock.java | 4 +- .../common/world/entity/EntityData.java | 4 +- .../world/entity/PacketAffectEntity.java | 4 +- .../world/entity/PacketChangeEntity.java | 4 +- .../world/entity/PacketRevokeEntity.java | 4 +- .../common/world/entity/PacketSendEntity.java | 4 +- .../{GenericBlock.java => BlockGeneric.java} | 2 +- ...{GenericChunk.java => ChunkGenericRO.java} | 24 +- .../common/world/generic/ChunkGenericWO.java | 37 ++ .../common/world/generic/ChunkMap.java | 16 +- .../common/world/generic/ChunkMaps.java | 16 +- .../common/world/generic/ChunkSet.java | 18 +- .../common/world/generic/ChunkSets.java | 18 +- ...{GenericEntity.java => EntityGeneric.java} | 2 +- .../common/world/generic/GenericChunks.java | 18 +- .../world/generic/GenericWritableChunk.java | 43 -- .../world/generic/LongBasedChunkSet.java | 2 +- .../{GenericTile.java => TileGeneric.java} | 2 +- .../world/generic/TileGenericReferenceRO.java | 50 ++ ...rence.java => TileGenericReferenceWO.java} | 24 +- ...TileStack.java => TileGenericStackRO.java} | 48 +- ...TileStack.java => TileGenericStackWO.java} | 49 +- ...{GenericWorld.java => WorldGenericRO.java} | 25 +- ...WritableWorld.java => WorldGenericWO.java} | 34 +- ...xt.java => BlockFaceGenericContextRO.java} | 31 +- ...xt.java => BlockFaceGenericContextWO.java} | 28 +- ...ontext.java => BlockGenericContextRO.java} | 37 +- ...ontext.java => BlockGenericContextWO.java} | 29 +- ...Context.java => TileGenericContextRO.java} | 56 +- ...Context.java => TileGenericContextWO.java} | 16 +- .../world/generic/context/WorldContexts.java | 127 +++++ ...ontext.java => WorldGenericContextRO.java} | 24 +- ...ontext.java => WorldGenericContextWO.java} | 42 +- .../common/world/io/ChunkCodec.java | 10 +- .../progressia/common/world/io/ChunkIO.java | 10 +- .../common/world/tile/PacketAddTile.java | 4 +- .../common/world/tile/PacketRemoveTile.java | 5 +- .../common/world/tile/TileData.java | 4 +- .../common/world/tile/TileDataStack.java | 28 - .../ru/windcorp/progressia/server/Player.java | 4 +- .../ru/windcorp/progressia/server/Server.java | 4 +- .../progressia/server/ServerState.java | 4 +- .../server/management/load/ChunkManager.java | 16 +- .../progressia/server/world/ChunkLogic.java | 16 +- .../server/world/ChunkTickContext.java | 4 +- .../progressia/server/world/TickContext.java | 4 +- .../server/world/TickContextMutable.java | 16 +- .../server/world/UpdateTriggerer.java | 6 +- .../progressia/server/world/WorldLogic.java | 26 +- .../server/world/block/BlockLogic.java | 4 +- .../generation/AbstractWorldGenerator.java | 10 +- .../world/generation/WorldGenerator.java | 8 +- .../server/world/tasks/TickChunk.java | 12 +- .../world/ticking/TickerCoordinator.java | 4 +- .../server/world/tile/TSTickContext.java | 6 +- .../server/world/tile/TileLogic.java | 4 +- .../server/world/tile/TileLogicReference.java | 4 +- .../server/world/tile/TileLogicStack.java | 9 +- .../server/world/tile/TileTickContext.java | 4 +- .../progressia/test/TestChunkCodec.java | 24 +- .../progressia/test/TestWorldDiskIO.java | 18 +- .../progressia/test/gen/TerrainLayer.java | 4 +- .../test/gen/TestWorldGenerator.java | 42 +- .../progressia/test/gen/planet/Planet.java | 6 +- .../gen/planet/PlanetFeatureGenerator.java | 8 +- .../gen/planet/PlanetTerrainGenerator.java | 14 +- .../test/gen/planet/TestPlanetGenerator.java | 8 +- .../gen/planet/TestPlanetGravityModel.java | 8 +- .../test/gen/surface/SurfaceFeature.java | 8 +- .../gen/surface/SurfaceFeatureGenerator.java | 4 +- .../gen/surface/SurfaceTerrainGenerator.java | 19 +- .../test/gen/surface/SurfaceWorld.java | 39 +- 110 files changed, 1733 insertions(+), 1419 deletions(-) rename src/main/java/ru/windcorp/progressia/common/{world/tile/TileDataReference.java => state/StateChange.java} (66%) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericBlock.java => BlockGeneric.java} (96%) rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericChunk.java => ChunkGenericRO.java} (92%) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericEntity.java => EntityGeneric.java} (97%) delete mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericTile.java => TileGeneric.java} (96%) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericTileReference.java => TileGenericReferenceWO.java} (70%) rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericTileStack.java => TileGenericStackRO.java} (68%) rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericWritableTileStack.java => TileGenericStackWO.java} (80%) rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericWorld.java => WorldGenericRO.java} (90%) rename src/main/java/ru/windcorp/progressia/common/world/generic/{GenericWritableWorld.java => WorldGenericWO.java} (52%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericROBlockFaceContext.java => BlockFaceGenericContextRO.java} (70%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericRWBlockFaceContext.java => BlockFaceGenericContextWO.java} (72%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericROBlockContext.java => BlockGenericContextRO.java} (69%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericRWBlockContext.java => BlockGenericContextWO.java} (74%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericROTileContext.java => TileGenericContextRO.java} (62%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericRWTileContext.java => TileGenericContextWO.java} (80%) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericROWorldContext.java => WorldGenericContextRO.java} (54%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{GenericRWWorldContext.java => WorldGenericContextWO.java} (80%) delete mode 100644 src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java diff --git a/src/main/java/ru/windcorp/progressia/client/Client.java b/src/main/java/ru/windcorp/progressia/client/Client.java index d8800c7..f356954 100644 --- a/src/main/java/ru/windcorp/progressia/client/Client.java +++ b/src/main/java/ru/windcorp/progressia/client/Client.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.client.graphics.world.Camera; import ru.windcorp.progressia.client.graphics.world.EntityAnchor; import ru.windcorp.progressia.client.graphics.world.LocalPlayer; import ru.windcorp.progressia.client.world.WorldRender; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.entity.EntityData; public class Client { @@ -36,7 +36,7 @@ public class Client { private final ServerCommsChannel comms; - public Client(WorldData world, ServerCommsChannel comms) { + public Client(DefaultWorldData world, ServerCommsChannel comms) { this.world = new WorldRender(world, this); this.comms = comms; diff --git a/src/main/java/ru/windcorp/progressia/client/ClientState.java b/src/main/java/ru/windcorp/progressia/client/ClientState.java index 75f0f07..31c366e 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientState.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientState.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client; import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel; import ru.windcorp.progressia.client.graphics.GUI; import ru.windcorp.progressia.client.graphics.world.LayerWorld; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.ServerState; import ru.windcorp.progressia.test.LayerAbout; import ru.windcorp.progressia.test.LayerTestUI; @@ -41,7 +41,7 @@ public class ClientState { public static void connectToLocalServer() { - WorldData world = new WorldData(); + DefaultWorldData world = new DefaultWorldData(); LocalServerCommsChannel channel = new LocalServerCommsChannel( ServerState.getInstance() diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index c69fcf3..e96166d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -30,26 +30,26 @@ import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderReference; import ru.windcorp.progressia.client.world.tile.TileRenderRegistry; import ru.windcorp.progressia.client.world.tile.TileRenderStack; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -import ru.windcorp.progressia.common.world.tile.TileDataStack; public class ChunkRender - implements GenericChunk { + implements ChunkGenericRO { private final WorldRender world; - private final ChunkData data; + private final DefaultChunkData data; private final ChunkRenderModel model; private final Map tileRenderLists = Collections .synchronizedMap(new WeakHashMap<>()); - public ChunkRender(WorldRender world, ChunkData data) { + public ChunkRender(WorldRender world, DefaultChunkData data) { this.world = world; this.data = data; this.model = new ChunkRenderModel(this); @@ -93,7 +93,7 @@ public class ChunkRender return world; } - public ChunkData getData() { + public DefaultChunkData getData() { return data; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java index 832a7ee..cd8a1d8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRenderModel.java @@ -35,7 +35,7 @@ import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerRegistry; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.client.world.tile.TileRenderNone; import ru.windcorp.progressia.client.world.tile.TileRenderStack; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -55,12 +55,12 @@ public class ChunkRenderModel implements Renderable { public void render(ShapeRenderHelper renderer) { if (model == null) return; - float offset = ChunkData.BLOCKS_PER_CHUNK / 2 - 0.5f; + float offset = DefaultChunkData.BLOCKS_PER_CHUNK / 2 - 0.5f; renderer.pushTransform().translate( - chunk.getX() * ChunkData.BLOCKS_PER_CHUNK, - chunk.getY() * ChunkData.BLOCKS_PER_CHUNK, - chunk.getZ() * ChunkData.BLOCKS_PER_CHUNK + chunk.getX() * DefaultChunkData.BLOCKS_PER_CHUNK, + chunk.getY() * DefaultChunkData.BLOCKS_PER_CHUNK, + chunk.getZ() * DefaultChunkData.BLOCKS_PER_CHUNK ).translate(offset, offset, offset) .mul(AxisRotations.getResolutionMatrix4(chunk.getUp())) .translate(-offset, -offset, -offset); diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java index da3d10d..1e854f2 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkUpdateListener.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AbsFace; @@ -37,12 +37,12 @@ class ChunkUpdateListener implements ChunkDataListener { } @Override - public void onChunkChanged(ChunkData chunk) { + public void onChunkChanged(DefaultChunkData chunk) { world.getChunk(chunk).markForUpdate(); } @Override - public void onChunkLoaded(ChunkData chunk) { + public void onChunkLoaded(DefaultChunkData chunk) { Vec3i cursor = new Vec3i(); for (AbsFace face : AbsFace.getFaces()) { cursor.set(chunk.getX(), chunk.getY(), chunk.getZ()); @@ -52,13 +52,13 @@ class ChunkUpdateListener implements ChunkDataListener { } @Override - public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { + public void onChunkBlockChanged(DefaultChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { onLocationChanged(chunk, blockInChunk); } @Override public void onChunkTilesChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace face, TileData tile, @@ -67,7 +67,7 @@ class ChunkUpdateListener implements ChunkDataListener { onLocationChanged(chunk, blockInChunk); } - private void onLocationChanged(ChunkData chunk, Vec3i blockInChunk) { + private void onLocationChanged(DefaultChunkData chunk, Vec3i blockInChunk) { Vec3i chunkPos = Vectors.grab3i().set(chunk.getX(), chunk.getY(), chunk.getZ()); checkCoordinate(blockInChunk, chunkPos, VectorUtil.Axis.X); @@ -83,7 +83,7 @@ class ChunkUpdateListener implements ChunkDataListener { if (block == 0) { diff = -1; - } else if (block == ChunkData.BLOCKS_PER_CHUNK - 1) { + } else if (block == DefaultChunkData.BLOCKS_PER_CHUNK - 1) { diff = +1; } else { return; diff --git a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java index 7ff4df6..2ab9e7d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/WorldRender.java @@ -38,54 +38,54 @@ import ru.windcorp.progressia.client.world.tile.TileRenderReference; import ru.windcorp.progressia.client.world.tile.TileRenderStack; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListeners; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.ChunkSet; import ru.windcorp.progressia.common.world.generic.ChunkSets; -import ru.windcorp.progressia.common.world.generic.GenericWorld; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; public class WorldRender - implements GenericWorld { + implements WorldGenericRO { - private final WorldData data; + private final DefaultWorldData data; private final Client client; - private final Map chunks = Collections.synchronizedMap(new HashMap<>()); + private final Map chunks = Collections.synchronizedMap(new HashMap<>()); private final Map entityModels = Collections.synchronizedMap(new WeakHashMap<>()); private final ChunkSet chunksToUpdate = ChunkSets.newSyncHashSet(); - public WorldRender(WorldData data, Client client) { + public WorldRender(DefaultWorldData data, Client client) { this.data = data; this.client = client; data.addListener(ChunkDataListeners.createAdder(new ChunkUpdateListener(this))); data.addListener(new WorldDataListener() { @Override - public void onChunkLoaded(WorldData world, ChunkData chunk) { + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { addChunk(chunk); } @Override - public void beforeChunkUnloaded(WorldData world, ChunkData chunk) { + public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { removeChunk(chunk); } }); } - protected void addChunk(ChunkData chunk) { + protected void addChunk(DefaultChunkData chunk) { chunks.put(chunk, new ChunkRender(WorldRender.this, chunk)); markChunkForUpdate(chunk.getPosition()); } - protected void removeChunk(ChunkData chunk) { + protected void removeChunk(DefaultChunkData chunk) { chunks.remove(chunk); } - public WorldData getData() { + public DefaultWorldData getData() { return data; } @@ -93,7 +93,7 @@ public class WorldRender return client; } - public ChunkRender getChunk(ChunkData chunkData) { + public ChunkRender getChunk(DefaultChunkData chunkData) { return chunks.get(chunkData); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java index 2a3c8e1..6adbfde 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRender.java @@ -19,18 +19,18 @@ package ru.windcorp.progressia.client.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Renderable; -public abstract class BlockRender extends Namespaced implements GenericBlock { +public abstract class BlockRender extends Namespaced implements BlockGeneric { public BlockRender(String id) { super(id); } - public Renderable createRenderable(ChunkData chunk, Vec3i relBlockInChunk) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i relBlockInChunk) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java index 84a2c4b..e9c10a8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderNone.java @@ -21,7 +21,7 @@ package ru.windcorp.progressia.client.world.block; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; public class BlockRenderNone extends BlockRender { @@ -30,7 +30,7 @@ public class BlockRenderNone extends BlockRender { } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk) { return EmptyModel.getInstance(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java index 6ed7ef7..91d05e1 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/block/BlockRenderTexturedCube.java @@ -36,7 +36,7 @@ import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.BlockOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -69,7 +69,7 @@ public abstract class BlockRenderTexturedCube @Override public final void getShapeParts( - ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -78,7 +78,7 @@ public abstract class BlockRenderTexturedCube } private ShapePart createFace( - ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Vec3 offset ) { @@ -93,7 +93,7 @@ public abstract class BlockRenderTexturedCube } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk) { boolean opaque = isBlockOpaque(); ShapePart[] faces = new ShapePart[BLOCK_FACE_COUNT + (opaque ? BLOCK_FACE_COUNT : 0)]; diff --git a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java index 26ee23c..296e7b8 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/cro/ChunkRenderOptimizerSurface.java @@ -18,8 +18,8 @@ package ru.windcorp.progressia.client.world.cro; -import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; -import static ru.windcorp.progressia.common.world.generic.GenericTileStack.TILES_PER_FACE; +import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.generic.TileGenericStackRO.TILES_PER_FACE; import static ru.windcorp.progressia.common.world.rels.AbsFace.BLOCK_FACE_COUNT; import java.util.ArrayList; @@ -37,7 +37,7 @@ import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; import ru.windcorp.progressia.client.world.tile.TileRender; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -71,7 +71,7 @@ public class ChunkRenderOptimizerSurface extends ChunkRenderOptimizer { * vertices */ void getShapeParts( - ChunkData chunk, + DefaultChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, boolean inner, diff --git a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java index fcd50f6..1749ffb 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java +++ b/src/main/java/ru/windcorp/progressia/client/world/entity/EntityRenderable.java @@ -23,9 +23,9 @@ import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; -public abstract class EntityRenderable implements Renderable, GenericEntity { +public abstract class EntityRenderable implements Renderable, EntityGeneric { private final EntityData data; diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java index 38c4ae9..dcb6c54 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRender.java @@ -22,17 +22,17 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizer; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.generic.TileGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; -public class TileRender extends Namespaced implements GenericTile { +public class TileRender extends Namespaced implements TileGeneric { public TileRender(String id) { super(id); } - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace face) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk, RelFace face) { return null; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java index f8ad55b..894a42d 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderNone.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.client.world.tile; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.EmptyModel; import ru.windcorp.progressia.client.graphics.model.Renderable; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.RelFace; public class TileRenderNone extends TileRender { @@ -30,7 +30,7 @@ public class TileRenderNone extends TileRender { } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace face) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk, RelFace face) { return EmptyModel.getInstance(); } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java index 3def556..9ec5194 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderReference.java @@ -19,9 +19,9 @@ package ru.windcorp.progressia.client.world.tile; import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; -import ru.windcorp.progressia.common.world.generic.GenericTileReference; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; public interface TileRenderReference - extends GenericTileReference { + extends TileGenericReferenceRO { } diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java index ca95cd2..b0c6b65 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderStack.java @@ -18,13 +18,15 @@ package ru.windcorp.progressia.client.world.tile; +import java.util.AbstractList; + import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.block.BlockRender; -import ru.windcorp.progressia.common.world.generic.GenericTileStack; -import ru.windcorp.progressia.common.world.tile.TileDataStack; - +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; public abstract class TileRenderStack - extends GenericTileStack { + extends AbstractList + implements TileGenericStackRO { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java index 91eeb00..604bf69 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java +++ b/src/main/java/ru/windcorp/progressia/client/world/tile/TileRenderSurface.java @@ -33,7 +33,7 @@ import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSurface.TileOptimizedSurface; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.RelFace; @@ -60,7 +60,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi @Override public final void getShapeParts( - ChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i relBlockInChunk, RelFace blockFace, boolean inner, Consumer output, Vec3 offset @@ -69,7 +69,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } private ShapePart createFace( - ChunkData chunk, Vec3i blockInChunk, RelFace blockFace, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace, boolean inner, Vec3 offset ) { @@ -84,7 +84,7 @@ public abstract class TileRenderSurface extends TileRender implements TileOptimi } @Override - public Renderable createRenderable(ChunkData chunk, Vec3i blockInChunk, RelFace blockFace) { + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk, RelFace blockFace) { return new Shape( Usage.STATIC, WorldRenderProgram.getDefault(), diff --git a/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java b/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java index 69d2d4a..69b157d 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/WorldCollisionHelper.java @@ -24,7 +24,7 @@ import java.util.Collection; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.LowOverheadCache; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class WorldCollisionHelper { @@ -79,7 +79,7 @@ public class WorldCollisionHelper { * checked against * @param maxTime maximum collision time */ - public void tuneToCollideable(WorldData world, Collideable collideable, float maxTime) { + public void tuneToCollideable(DefaultWorldData world, Collideable collideable, float maxTime) { activeBlockModels.forEach(blockModelCache::release); activeBlockModels.clear(); CollisionPathComputer.forEveryBlockInCollisionPath( diff --git a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java index 62a7808..9b97e40 100644 --- a/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java +++ b/src/main/java/ru/windcorp/progressia/common/collision/colliders/Collider.java @@ -27,7 +27,7 @@ import glm.vec._3.Vec3; import ru.windcorp.progressia.common.collision.*; import ru.windcorp.progressia.common.util.LowOverheadCache; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class Collider { @@ -36,7 +36,7 @@ public class Collider { /** * Dear Princess Celestia, *

      - * When {@linkplain #advanceTime(Collection, Collision, WorldData, float) + * When {@linkplain #advanceTime(Collection, Collision, DefaultWorldData, float) * advancing time}, * time step for all entities except currently colliding bodies is * the current @@ -61,7 +61,7 @@ public class Collider { public static void performCollisions( List colls, - WorldData world, + DefaultWorldData world, float tickLength, ColliderWorkspace workspace ) { @@ -96,7 +96,7 @@ public class Collider { private static Collision getFirstCollision( List colls, float tickLength, - WorldData world, + DefaultWorldData world, ColliderWorkspace workspace ) { Collision result = null; @@ -126,7 +126,7 @@ public class Collider { private static void tuneWorldCollisionHelper( Collideable coll, float tickLength, - WorldData world, + DefaultWorldData world, ColliderWorkspace workspace ) { WorldCollisionHelper wch = workspace.worldCollisionHelper; @@ -194,7 +194,7 @@ public class Collider { Collision collision, Collection colls, - WorldData world, + DefaultWorldData world, float tickLength, ColliderWorkspace workspace ) { @@ -361,7 +361,7 @@ public class Collider { private static void advanceTime( Collection colls, Collision exceptions, - WorldData world, + DefaultWorldData world, float step ) { world.advanceTime(step); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java b/src/main/java/ru/windcorp/progressia/common/state/StateChange.java similarity index 66% rename from src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java rename to src/main/java/ru/windcorp/progressia/common/state/StateChange.java index b9699c2..38638a7 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataReference.java +++ b/src/main/java/ru/windcorp/progressia/common/state/StateChange.java @@ -16,12 +16,9 @@ * along with this program. If not, see . */ -package ru.windcorp.progressia.common.world.tile; - -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericTileReference; - -public interface TileDataReference extends GenericTileReference { +package ru.windcorp.progressia.common.state; +@FunctionalInterface +public interface StateChange { + void change(T object); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 728bc80..ab55863 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -1,527 +1,14 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.rels.BlockFace.BLOCK_FACE_COUNT; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; - -import glm.vec._3.i.Vec3i; - import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.generic.GenericWritableChunk; -import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.generic.ChunkGenericWO; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; -public class ChunkData - implements GenericWritableChunk { - - public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; - public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; - - private final Vec3i position = new Vec3i(); - private final WorldData world; - - private final BlockData[] blocks = new BlockData[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; - - private final TileDataStack[] tiles = new TileDataStack[ - BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCK_FACE_COUNT - ]; +public interface ChunkData extends ChunkDataRO, ChunkGenericWO { - private final AbsFace up; - - private Object generationHint = null; - - private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); - - public ChunkData(Vec3i position, WorldData world) { - this.position.set(position.x, position.y, position.z); - this.world = world; - this.up = world.getGravityModel().getDiscreteUp(position); - } - - @Override - public Vec3i getPosition() { - return position; - } - - @Override - public AbsFace getUp() { - return up; - } - - @Override - public BlockData getBlock(Vec3i posInChunk) { - return blocks[getBlockIndex(posInChunk)]; - } - - @Override - public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) { - BlockData previous = blocks[getBlockIndex(posInChunk)]; - blocks[getBlockIndex(posInChunk)] = block; - - if (notify) { - getListeners().forEach(l -> { - l.onChunkBlockChanged(this, posInChunk, previous, block); - l.onChunkChanged(this); - }); - } - } - - @Override - public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { - return tiles[getTileIndex(blockInChunk, face)]; - } - - /** - * Internal use only. Modify a list returned by - * {@link #getTiles(Vec3i, BlockFace)} or - * {@link #getTilesOrNull(Vec3i, BlockFace)} - * to change tiles. - */ - protected void setTiles( - Vec3i blockInChunk, - BlockFace face, - TileDataStack tiles - ) { - this.tiles[getTileIndex(blockInChunk, face)] = tiles; - } - - @Override - public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { - return getTilesOrNull(blockInChunk, face) != null; - } - - @Override - public TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { - int index = getTileIndex(blockInChunk, face); - - if (tiles[index] == null) { - createTileStack(blockInChunk, face); - } - - return tiles[index]; - } - - private void createTileStack(Vec3i blockInChunk, BlockFace face) { - Vec3i independentBlockInChunk = conjureIndependentBlockInChunkVec3i(blockInChunk); - TileDataStackImpl stack = new TileDataStackImpl(independentBlockInChunk, face); - setTiles(blockInChunk, face, stack); - } - - private Vec3i conjureIndependentBlockInChunkVec3i(Vec3i blockInChunk) { - for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { - TileDataStack stack = getTilesOrNull(blockInChunk, AbsFace.getFaces().get(i)); - if (stack instanceof TileDataStackImpl) { - return ((TileDataStackImpl) stack).blockInChunk; - } - } - - return new Vec3i(blockInChunk); - } - - private static int getBlockIndex(Vec3i posInChunk) { - checkLocalCoordinates(posInChunk); - - return posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + - posInChunk.y * BLOCKS_PER_CHUNK + - posInChunk.x; - } - - private int getTileIndex(Vec3i posInChunk, BlockFace face) { - return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + - face.resolve(getUp()).getId(); - } - - private static void checkLocalCoordinates(Vec3i posInChunk) { - if (!GenericChunks.containsBiC(posInChunk)) { - throw new IllegalCoordinatesException( - "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " - + "are not legal chunk coordinates" - ); - } - } - - public WorldData getWorld() { - return world; - } - - public Collection getListeners() { - return listeners; - } - - public void addListener(ChunkDataListener listener) { - this.listeners.add(listener); - } - - public void removeListener(ChunkDataListener listener) { - this.listeners.remove(listener); - } - - protected void onLoaded() { - getListeners().forEach(l -> l.onChunkLoaded(this)); - } - - protected void beforeUnloaded() { - getListeners().forEach(l -> l.beforeChunkUnloaded(this)); - } - - public Object getGenerationHint() { - return generationHint; - } - - public void setGenerationHint(Object generationHint) { - this.generationHint = generationHint; - } - - /** - * Implementation of {@link TileDataStack} used internally by - * {@link ChunkData} to - * actually store the tiles. This is basically an array wrapper with - * reporting - * capabilities. - * - * @author javapony - */ - private class TileDataStackImpl extends TileDataStack { - private class TileDataReferenceImpl implements TileDataReference { - private int index; - - public TileDataReferenceImpl(int index) { - this.index = index; - } - - public void incrementIndex() { - this.index++; - } - - public void decrementIndex() { - this.index--; - } - - public void invalidate() { - this.index = 0; - } - - @Override - public TileData get() { - if (!isValid()) - return null; - return TileDataStackImpl.this.get(this.index); - } - - @Override - public int getIndex() { - return index; - } - - @Override - public TileDataStack getStack() { - return TileDataStackImpl.this; - } - - @Override - public boolean isValid() { - return this.index >= 0; - } - } - - private final TileData[] tiles = new TileData[TILES_PER_FACE]; - private int size = 0; - - private final TileDataReferenceImpl[] references = new TileDataReferenceImpl[tiles.length]; - private final int[] indicesByTag = new int[tiles.length]; - private final int[] tagsByIndex = new int[tiles.length]; - - { - Arrays.fill(indicesByTag, -1); - Arrays.fill(tagsByIndex, -1); - } - - /* - * Potentially shared - */ - private final Vec3i blockInChunk; - private final RelFace face; - - public TileDataStackImpl(Vec3i blockInChunk, BlockFace face) { - this.blockInChunk = blockInChunk; - this.face = face.relativize(getUp()); - } - - @Override - public Vec3i getBlockInChunk(Vec3i output) { - if (output == null) - output = new Vec3i(); - output.set(blockInChunk.x, blockInChunk.y, blockInChunk.z); - return output; - } - - @Override - public RelFace getFace() { - return face; - } - - @Override - public ChunkData getChunk() { - return ChunkData.this; - } - - @Override - public int size() { - return size; - } - - @Override - public TileData get(int index) { - checkIndex(index, false); - - return tiles[index]; - } - - @Override - public TileData set(int index, TileData tile) { - Objects.requireNonNull(tile, "tile"); - TileData previous = get(index); // checks index - - tiles[index] = tile; - - if (references[index] != null) { - references[index].invalidate(); - references[index] = null; - } - - assert checkConsistency(); - - report(previous, tile); - return previous; - } - - @Override - public void add(int index, TileData tile) { - Objects.requireNonNull(tile, "tile"); - checkIndex(index, true); - - if (index != size()) { - System.arraycopy(tiles, index + 1, tiles, index + 2, size - index); - - for (int i = index; i < size; ++i) { - if (references[i] != null) { - references[i].incrementIndex(); - } - - indicesByTag[tagsByIndex[i]]++; - } - - System.arraycopy(references, index + 1, references, index + 2, size - index); - System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index + 2, size - index); - } - - size++; - tiles[index] = tile; - references[index] = null; - - for (int tag = 0; tag < indicesByTag.length; ++tag) { - if (indicesByTag[tag] == -1) { - indicesByTag[tag] = index; - tagsByIndex[index] = tag; - break; - } - } - - modCount++; - assert checkConsistency(); - - report(null, tile); - } - - @Override - public void load(TileData tile, int tag) { - addFarthest(tile); - - int assignedIndex = size() - 1; - - // Skip if we already have the correct tag - int assignedTag = getTagByIndex(assignedIndex); - if (assignedTag == tag) { - return; - } - assert assignedTag != -1 : "Adding farthest tile resulted in -1 tag"; - - // Make sure we aren't trying to assign a tag already in use - int tileWithRequestedTag = getIndexByTag(tag); - if (tileWithRequestedTag != -1) { - throw new IllegalArgumentException( - "Tag " + tag + " already used by tile at index " + tileWithRequestedTag - ); - } - assert tileWithRequestedTag != assignedIndex : "tag == assignedTag yet tileWithRequestedTag != assignedIndex"; - - // Do the tag editing - indicesByTag[assignedTag] = -1; // Release assigned tag - tagsByIndex[assignedIndex] = tag; // Reroute assigned index to requested tag - indicesByTag[tag] = assignedIndex; // Claim requested tag - assert checkConsistency(); - } - - @Override - public TileData remove(int index) { - TileData previous = get(index); // checks index - - if (references[index] != null) { - references[index].invalidate(); - } - - indicesByTag[tagsByIndex[index]] = -1; - - if (index != size() - 1) { - System.arraycopy(tiles, index + 1, tiles, index, size - index - 1); - - for (int i = index + 1; i < size; ++i) { - if (references[i] != null) { - references[i].decrementIndex(); - } - - indicesByTag[tagsByIndex[i]]--; - } - - System.arraycopy(references, index + 1, references, index, size - index - 1); - System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index, size - index - 1); - } - - size--; - tiles[size] = null; - references[size] = null; - tagsByIndex[size] = -1; - - modCount++; - assert checkConsistency(); - - report(previous, null); - return previous; - } - - @Override - public TileDataReference getReference(int index) { - checkIndex(index, false); - - if (references[index] == null) { - references[index] = new TileDataReferenceImpl(index); - } - - return references[index]; - } - - @Override - public int getIndexByTag(int tag) { - return indicesByTag[tag]; - } - - @Override - public int getTagByIndex(int index) { - checkIndex(index, false); - return tagsByIndex[index]; - } - - @Override - public void clear() { - while (!isEmpty()) { - removeFarthest(); - } - } - - private void checkIndex(int index, boolean isSizeAllowed) { - if (isSizeAllowed ? (index > size()) : (index >= size())) - throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: size is " + size); - - if (index < 0) - throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: index cannot be negative"); - - if (index >= TILES_PER_FACE) - throw new TileStackIsFullException( - "Index " + index + " is out of bounds: maximum tile stack size is " + TILES_PER_FACE - ); - } - - private void report(TileData previous, TileData current) { - ChunkData.this.getListeners().forEach(l -> { - if (previous != null) { - l.onChunkTilesChanged(ChunkData.this, blockInChunk, face, previous, false); - } - - if (current != null) { - l.onChunkTilesChanged(ChunkData.this, blockInChunk, face, current, true); - } - - l.onChunkChanged(ChunkData.this); - }); - } - - private boolean checkConsistency() { - int index; - - for (index = 0; index < size(); ++index) { - if (get(index) == null) - throw new AssertionError("get(index) is null"); - - if (references[index] != null) { - TileDataReference ref = getReference(index); - if (ref == null) - throw new AssertionError("references[index] is not null but getReference(index) is"); - if (!ref.isValid()) - throw new AssertionError("Reference is not valid"); - if (ref.get() != get(index)) - throw new AssertionError("Reference points to " + (ref.get() == null ? "null" : "wrong tile")); - if (ref.getIndex() != index) - throw new AssertionError("Reference has invalid index"); - if (ref.getStack() != this) - throw new AssertionError("Reference has invalid TDS"); - } - - if (index != indicesByTag[tagsByIndex[index]]) - throw new AssertionError("Tag mapping is inconsistent"); - if (index != getIndexByTag(getTagByIndex(index))) - throw new AssertionError("Tag methods are inconsistent with tag mapping"); - } - - for (; index < tiles.length; ++index) { - if (tiles[index] != null) - throw new AssertionError("Leftover tile detected"); - if (references[index] != null) - throw new AssertionError("Leftover reference detected"); - if (tagsByIndex[index] != -1) - throw new AssertionError("Leftover tags detected"); - } - - return true; - } - - } +// @Override +// default TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { +// return null; +// } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java index 0dc7088..22b4fb3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListener.java @@ -36,7 +36,7 @@ public interface ChunkDataListener { * @param previous the previous occupant of {@code blockInChunk} * @param current the current (new) occupant of {@code blockInChunk} */ - default void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { + default void onChunkBlockChanged(DefaultChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { } /** @@ -53,7 +53,7 @@ public interface ChunkDataListener { * {@code false} iff the tile has been removed */ default void onChunkTilesChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace face, TileData tile, @@ -70,7 +70,7 @@ public interface ChunkDataListener { * * @param chunk the chunk that has changed */ - default void onChunkChanged(ChunkData chunk) { + default void onChunkChanged(DefaultChunkData chunk) { } /** @@ -78,7 +78,7 @@ public interface ChunkDataListener { * * @param chunk the chunk that has loaded */ - default void onChunkLoaded(ChunkData chunk) { + default void onChunkLoaded(DefaultChunkData chunk) { } /** @@ -86,7 +86,7 @@ public interface ChunkDataListener { * * @param chunk the chunk that is going to be loaded */ - default void beforeChunkUnloaded(ChunkData chunk) { + default void beforeChunkUnloaded(DefaultChunkData chunk) { } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java index b39437c..a9a4168 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataListeners.java @@ -28,7 +28,7 @@ public class ChunkDataListeners { public static WorldDataListener createAdder(Supplier listenerSupplier) { return new WorldDataListener() { @Override - public void getChunkListeners(WorldData world, Vec3i chunk, Consumer chunkListenerSink) { + public void getChunkListeners(DefaultWorldData world, Vec3i chunk, Consumer chunkListenerSink) { chunkListenerSink.accept(listenerSupplier.get()); } }; diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java new file mode 100644 index 0000000..08ce159 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkDataRO.java @@ -0,0 +1,12 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface ChunkDataRO + extends ChunkGenericRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java b/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java index 55f2076..b43231b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java +++ b/src/main/java/ru/windcorp/progressia/common/world/Coordinates.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world; -import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; import glm.vec._3.i.Vec3i; diff --git a/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java new file mode 100644 index 0000000..5c1cd08 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java @@ -0,0 +1,525 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world; + +import static ru.windcorp.progressia.common.world.rels.BlockFace.BLOCK_FACE_COUNT; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; + +import glm.vec._3.i.Vec3i; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.GenericChunks; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; + +public class DefaultChunkData implements ChunkData { + + public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; + public static final int CHUNK_RADIUS = BLOCKS_PER_CHUNK / 2; + + private final Vec3i position = new Vec3i(); + private final DefaultWorldData world; + + private final BlockData[] blocks = new BlockData[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK]; + + private final TileDataStack[] tiles = new TileDataStack[BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + * BLOCK_FACE_COUNT]; + + private final AbsFace up; + + private Object generationHint = null; + + private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); + + public DefaultChunkData(Vec3i position, DefaultWorldData world) { + this.position.set(position.x, position.y, position.z); + this.world = world; + this.up = world.getGravityModel().getDiscreteUp(position); + } + + @Override + public Vec3i getPosition() { + return position; + } + + @Override + public AbsFace getUp() { + return up; + } + + @Override + public BlockData getBlock(Vec3i posInChunk) { + return blocks[getBlockIndex(posInChunk)]; + } + + @Override + public void setBlock(Vec3i posInChunk, BlockData block, boolean notify) { + BlockData previous = blocks[getBlockIndex(posInChunk)]; + blocks[getBlockIndex(posInChunk)] = block; + + if (notify) { + getListeners().forEach(l -> { + l.onChunkBlockChanged(this, posInChunk, previous, block); + l.onChunkChanged(this); + }); + } + } + + @Override + public TileDataStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { + return tiles[getTileIndex(blockInChunk, face)]; + } + + /** + * Internal use only. Modify a list returned by + * {@link #getTiles(Vec3i, BlockFace)} or + * {@link #getTilesOrNull(Vec3i, BlockFace)} + * to change tiles. + */ + protected void setTiles( + Vec3i blockInChunk, + BlockFace face, + TileDataStack tiles + ) { + this.tiles[getTileIndex(blockInChunk, face)] = tiles; + } + + @Override + public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { + return getTilesOrNull(blockInChunk, face) != null; + } + + @Override + public TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { + int index = getTileIndex(blockInChunk, face); + + if (tiles[index] == null) { + createTileStack(blockInChunk, face); + } + + return tiles[index]; + } + + private void createTileStack(Vec3i blockInChunk, BlockFace face) { + Vec3i independentBlockInChunk = conjureIndependentBlockInChunkVec3i(blockInChunk); + TileDataStackImpl stack = new TileDataStackImpl(independentBlockInChunk, face); + setTiles(blockInChunk, face, stack); + } + + private Vec3i conjureIndependentBlockInChunkVec3i(Vec3i blockInChunk) { + for (int i = 0; i < AbsFace.BLOCK_FACE_COUNT; ++i) { + TileDataStack stack = getTilesOrNull(blockInChunk, AbsFace.getFaces().get(i)); + if (stack instanceof TileDataStackImpl) { + return ((TileDataStackImpl) stack).blockInChunk; + } + } + + return new Vec3i(blockInChunk); + } + + private static int getBlockIndex(Vec3i posInChunk) { + checkLocalCoordinates(posInChunk); + + return posInChunk.z * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK + + posInChunk.y * BLOCKS_PER_CHUNK + + posInChunk.x; + } + + private int getTileIndex(Vec3i posInChunk, BlockFace face) { + return getBlockIndex(posInChunk) * BLOCK_FACE_COUNT + + face.resolve(getUp()).getId(); + } + + private static void checkLocalCoordinates(Vec3i posInChunk) { + if (!GenericChunks.containsBiC(posInChunk)) { + throw new IllegalCoordinatesException( + "Coordinates (" + posInChunk.x + "; " + posInChunk.y + "; " + posInChunk.z + ") " + + "are not legal chunk coordinates" + ); + } + } + + public DefaultWorldData getWorld() { + return world; + } + + public Collection getListeners() { + return listeners; + } + + public void addListener(ChunkDataListener listener) { + this.listeners.add(listener); + } + + public void removeListener(ChunkDataListener listener) { + this.listeners.remove(listener); + } + + protected void onLoaded() { + getListeners().forEach(l -> l.onChunkLoaded(this)); + } + + protected void beforeUnloaded() { + getListeners().forEach(l -> l.beforeChunkUnloaded(this)); + } + + public Object getGenerationHint() { + return generationHint; + } + + public void setGenerationHint(Object generationHint) { + this.generationHint = generationHint; + } + + /** + * Implementation of {@link TileDataStack} used internally by + * {@link DefaultChunkData} to + * actually store the tiles. This is basically an array wrapper with + * reporting + * capabilities. + * + * @author javapony + */ + private class TileDataStackImpl extends AbstractList implements TileDataStack { + private class TileDataReferenceImpl implements TileDataReference { + private int index; + + public TileDataReferenceImpl(int index) { + this.index = index; + } + + public void incrementIndex() { + this.index++; + } + + public void decrementIndex() { + this.index--; + } + + public void invalidate() { + this.index = 0; + } + + @Override + public TileData get() { + if (!isValid()) + return null; + return TileDataStackImpl.this.get(this.index); + } + + @Override + public int getIndex() { + return index; + } + + @Override + public TileDataStack getStack() { + return TileDataStackImpl.this; + } + + @Override + public boolean isValid() { + return this.index >= 0; + } + } + + private final TileData[] tiles = new TileData[TILES_PER_FACE]; + private int size = 0; + + private final TileDataReferenceImpl[] references = new TileDataReferenceImpl[tiles.length]; + private final int[] indicesByTag = new int[tiles.length]; + private final int[] tagsByIndex = new int[tiles.length]; + + { + Arrays.fill(indicesByTag, -1); + Arrays.fill(tagsByIndex, -1); + } + + /* + * Potentially shared + */ + private final Vec3i blockInChunk; + private final RelFace face; + + public TileDataStackImpl(Vec3i blockInChunk, BlockFace face) { + this.blockInChunk = blockInChunk; + this.face = face.relativize(getUp()); + } + + @Override + public Vec3i getBlockInChunk(Vec3i output) { + if (output == null) + output = new Vec3i(); + output.set(blockInChunk.x, blockInChunk.y, blockInChunk.z); + return output; + } + + @Override + public RelFace getFace() { + return face; + } + + @Override + public DefaultChunkData getChunk() { + return DefaultChunkData.this; + } + + @Override + public int size() { + return size; + } + + @Override + public TileData get(int index) { + checkIndex(index, false); + + return tiles[index]; + } + + @Override + public TileData set(int index, TileData tile) { + Objects.requireNonNull(tile, "tile"); + TileData previous = get(index); // checks index + + tiles[index] = tile; + + if (references[index] != null) { + references[index].invalidate(); + references[index] = null; + } + + assert checkConsistency(); + + report(previous, tile); + return previous; + } + + @Override + public void add(int index, TileData tile) { + Objects.requireNonNull(tile, "tile"); + checkIndex(index, true); + + if (index != size()) { + System.arraycopy(tiles, index + 1, tiles, index + 2, size - index); + + for (int i = index; i < size; ++i) { + if (references[i] != null) { + references[i].incrementIndex(); + } + + indicesByTag[tagsByIndex[i]]++; + } + + System.arraycopy(references, index + 1, references, index + 2, size - index); + System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index + 2, size - index); + } + + size++; + tiles[index] = tile; + references[index] = null; + + for (int tag = 0; tag < indicesByTag.length; ++tag) { + if (indicesByTag[tag] == -1) { + indicesByTag[tag] = index; + tagsByIndex[index] = tag; + break; + } + } + + modCount++; + assert checkConsistency(); + + report(null, tile); + } + + @Override + public void load(TileData tile, int tag) { + addFarthest(tile); + + int assignedIndex = size() - 1; + + // Skip if we already have the correct tag + int assignedTag = getTagByIndex(assignedIndex); + if (assignedTag == tag) { + return; + } + assert assignedTag != -1 : "Adding farthest tile resulted in -1 tag"; + + // Make sure we aren't trying to assign a tag already in use + int tileWithRequestedTag = getIndexByTag(tag); + if (tileWithRequestedTag != -1) { + throw new IllegalArgumentException( + "Tag " + tag + " already used by tile at index " + tileWithRequestedTag + ); + } + assert tileWithRequestedTag != assignedIndex + : "tag == assignedTag yet tileWithRequestedTag != assignedIndex"; + + // Do the tag editing + indicesByTag[assignedTag] = -1; // Release assigned tag + tagsByIndex[assignedIndex] = tag; // Reroute assigned index to + // requested tag + indicesByTag[tag] = assignedIndex; // Claim requested tag + assert checkConsistency(); + } + + @Override + public TileData remove(int index) { + TileData previous = get(index); // checks index + + if (references[index] != null) { + references[index].invalidate(); + } + + indicesByTag[tagsByIndex[index]] = -1; + + if (index != size() - 1) { + System.arraycopy(tiles, index + 1, tiles, index, size - index - 1); + + for (int i = index + 1; i < size; ++i) { + if (references[i] != null) { + references[i].decrementIndex(); + } + + indicesByTag[tagsByIndex[i]]--; + } + + System.arraycopy(references, index + 1, references, index, size - index - 1); + System.arraycopy(tagsByIndex, index + 1, tagsByIndex, index, size - index - 1); + } + + size--; + tiles[size] = null; + references[size] = null; + tagsByIndex[size] = -1; + + modCount++; + assert checkConsistency(); + + report(previous, null); + return previous; + } + + @Override + public TileDataReference getReference(int index) { + checkIndex(index, false); + + if (references[index] == null) { + references[index] = new TileDataReferenceImpl(index); + } + + return references[index]; + } + + @Override + public int getIndexByTag(int tag) { + return indicesByTag[tag]; + } + + @Override + public int getTagByIndex(int index) { + checkIndex(index, false); + return tagsByIndex[index]; + } + + @Override + public void clear() { + while (!isEmpty()) { + removeFarthest(); + } + } + + private void checkIndex(int index, boolean isSizeAllowed) { + if (isSizeAllowed ? (index > size()) : (index >= size())) + throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: size is " + size); + + if (index < 0) + throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: index cannot be negative"); + + if (index >= TILES_PER_FACE) + throw new TileStackIsFullException( + "Index " + index + " is out of bounds: maximum tile stack size is " + TILES_PER_FACE + ); + } + + private void report(TileData previous, TileData current) { + DefaultChunkData.this.getListeners().forEach(l -> { + if (previous != null) { + l.onChunkTilesChanged(DefaultChunkData.this, blockInChunk, face, previous, false); + } + + if (current != null) { + l.onChunkTilesChanged(DefaultChunkData.this, blockInChunk, face, current, true); + } + + l.onChunkChanged(DefaultChunkData.this); + }); + } + + private boolean checkConsistency() { + int index; + + for (index = 0; index < size(); ++index) { + if (get(index) == null) + throw new AssertionError("get(index) is null"); + + if (references[index] != null) { + TileDataReference ref = getReference(index); + if (ref == null) + throw new AssertionError("references[index] is not null but getReference(index) is"); + if (!ref.isValid()) + throw new AssertionError("Reference is not valid"); + if (ref.get() != get(index)) + throw new AssertionError("Reference points to " + (ref.get() == null ? "null" : "wrong tile")); + if (ref.getIndex() != index) + throw new AssertionError("Reference has invalid index"); + if (ref.getStack() != this) + throw new AssertionError("Reference has invalid TDS"); + } + + if (index != indicesByTag[tagsByIndex[index]]) + throw new AssertionError("Tag mapping is inconsistent"); + if (index != getIndexByTag(getTagByIndex(index))) + throw new AssertionError("Tag methods are inconsistent with tag mapping"); + } + + for (; index < tiles.length; ++index) { + if (tiles[index] != null) + throw new AssertionError("Leftover tile detected"); + if (references[index] != null) + throw new AssertionError("Leftover reference detected"); + if (tagsByIndex[index] != -1) + throw new AssertionError("Leftover tags detected"); + } + + return true; + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java b/src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java new file mode 100644 index 0000000..1de79a6 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/DefaultWorldData.java @@ -0,0 +1,262 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Objects; +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import gnu.trove.TCollections; +import gnu.trove.map.TLongObjectMap; +import gnu.trove.map.hash.TLongObjectHashMap; +import gnu.trove.set.TLongSet; +import ru.windcorp.progressia.common.collision.CollisionModel; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.ChunkMap; +import ru.windcorp.progressia.common.world.generic.ChunkSet; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; + +public class DefaultWorldData implements WorldData { + + private final ChunkMap chunksByPos = new LongBasedChunkMap<>( + TCollections.synchronizedMap(new TLongObjectHashMap<>()) + ); + + private final Collection chunks = Collections.unmodifiableCollection(chunksByPos.values()); + + private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); + + private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); + + private GravityModel gravityModel = null; + + private float time = 0; + + private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); + + public DefaultWorldData() { + + } + + @Override + public DefaultChunkData getChunk(Vec3i pos) { + return chunksByPos.get(pos); + } + + @Override + public DefaultChunkData getChunkByBlock(Vec3i blockInWorld) { + return (DefaultChunkData) WorldData.super.getChunkByBlock(blockInWorld); + } + + @Override + public Collection getChunks() { + return chunks; + } + + public ChunkSet getLoadedChunks() { + return chunksByPos.keys(); + } + + @Override + public Collection getEntities() { + return entities; + } + + @Override + public void forEachEntity(Consumer action) { + synchronized (entitiesById) { // TODO HORRIBLY MUTILATE THE CORPSE OF + // TROVE4J so that + // gnu.trove.impl.sync.SynchronizedCollection.forEach + // is synchronized + getEntities().forEach(action); + } + } + + public TLongSet getLoadedEntities() { + return entitiesById.keySet(); + } + + private void addChunkListeners(DefaultChunkData chunk) { + getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener)); + } + + public synchronized void addChunk(DefaultChunkData chunk) { + addChunkListeners(chunk); + + DefaultChunkData previous = chunksByPos.get(chunk); + if (previous != null) { + throw new IllegalArgumentException( + String.format( + "Chunk at (%d; %d; %d) already exists", + chunk.getPosition().x, + chunk.getPosition().y, + chunk.getPosition().z + ) + ); + } + + chunksByPos.put(chunk, chunk); + + chunk.onLoaded(); + getListeners().forEach(l -> l.onChunkLoaded(this, chunk)); + } + + public synchronized void removeChunk(DefaultChunkData chunk) { + getListeners().forEach(l -> l.beforeChunkUnloaded(this, chunk)); + chunk.beforeUnloaded(); + + chunksByPos.remove(chunk); + } + + @Override + public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { + DefaultChunkData chunk = getChunkByBlock(blockInWorld); + if (chunk == null) + throw new IllegalCoordinatesException( + "Coordinates " + + "(" + blockInWorld.x + "; " + blockInWorld.y + "; " + blockInWorld.z + ") " + + "do not belong to a loaded chunk" + ); + + chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify); + } + + @Override + public TileDataStack getTiles(Vec3i blockInWorld, BlockFace face) { + return WorldData.super.getTiles(blockInWorld, face); + } + + @Override + public EntityData getEntity(long entityId) { + return entitiesById.get(entityId); + } + + @Override + public void addEntity(EntityData entity) { + Objects.requireNonNull(entity, "entity"); + + EntityData previous = entitiesById.putIfAbsent(entity.getEntityId(), entity); + + if (previous != null) { + String message = "Cannot add entity " + entity + ": "; + + if (previous == entity) { + message += "already present"; + } else { + message += "entity with the same EntityID already present (" + previous + ")"; + } + + throw new IllegalStateException(message); + } + + getListeners().forEach(l -> l.onEntityAdded(this, entity)); + } + + @Override + public void removeEntity(long entityId) { + synchronized (entitiesById) { + EntityData entity = entitiesById.get(entityId); + + if (entity == null) { + throw new IllegalArgumentException( + "Entity with EntityID " + EntityData.formatEntityId(entityId) + " not present" + ); + } else { + removeEntity(entity); + } + } + } + + @Override + public void removeEntity(EntityData entity) { + Objects.requireNonNull(entity, "entity"); + + getListeners().forEach(l -> l.beforeEntityRemoved(this, entity)); + entitiesById.remove(entity.getEntityId()); + } + + @Override + public void changeEntity(SE entity, StateChange change) { + change.change(entity); + } + + @Override + public float getTime() { + return time; + } + + @Override + public void advanceTime(float change) { + this.time += change; + } + + public CollisionModel getCollisionModelOfBlock(Vec3i blockInWorld) { + DefaultChunkData chunk = getChunkByBlock(blockInWorld); + if (chunk == null) + return null; + + BlockData block = chunk.getBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null)); + if (block == null) + return null; + return block.getCollisionModel(); + } + + /** + * @return the gravity model + */ + @Override + public GravityModel getGravityModel() { + return gravityModel; + } + + /** + * @param gravityModel the gravity model to set + */ + public void setGravityModel(GravityModel gravityModel) { + if (!chunks.isEmpty()) { + throw new IllegalStateException( + "Attempted to change gravity model to " + gravityModel + " while " + chunks.size() + + " chunks were loaded" + ); + } + + this.gravityModel = gravityModel; + } + + public Collection getListeners() { + return listeners; + } + + public void addListener(WorldDataListener e) { + listeners.add(e); + } + + public void removeListener(WorldDataListener o) { + listeners.remove(o); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java index 8433b9b..27731ab 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java @@ -26,6 +26,6 @@ public abstract class PacketAffectWorld extends Packet { super(id); } - public abstract void apply(WorldData world); + public abstract void apply(DefaultWorldData world); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java index c65b045..4849876 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java @@ -53,9 +53,9 @@ public class PacketRevokeChunk extends PacketAffectChunk { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { synchronized (world) { - ChunkData chunk = world.getChunk(position); + DefaultChunkData chunk = world.getChunk(position); if (chunk != null) { world.removeChunk(chunk); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java index ca079ff..71f2de6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java @@ -41,7 +41,7 @@ public class PacketSendChunk extends PacketAffectChunk { super(id); } - public void set(ChunkData chunk) { + public void set(DefaultChunkData chunk) { this.position.set(chunk.getX(), chunk.getY(), chunk.getZ()); try { @@ -67,7 +67,7 @@ public class PacketSendChunk extends PacketAffectChunk { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { try { world.addChunk(ChunkIO.load(world, position, data.getReader(), IOContext.COMMS)); } catch (DecodingException | IOException e) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java index 2fd30a6..454a1fa 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java @@ -61,7 +61,7 @@ public class PacketSetGravityModel extends PacketAffectWorld { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { GravityModel model = GravityModelRegistry.getInstance().create(gravityModelId); world.setGravityModel(model); try { diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java new file mode 100644 index 0000000..ccc118b --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataReference.java @@ -0,0 +1,10 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataReference extends TileDataReferenceRO, + TileGenericReferenceWO { + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java new file mode 100644 index 0000000..59257ec --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataReferenceRO.java @@ -0,0 +1,12 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataReferenceRO + extends TileGenericReferenceRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java new file mode 100644 index 0000000..0c17ae4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataStack.java @@ -0,0 +1,25 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericStackWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataStack + extends TileDataStackRO, TileGenericStackWO { + + @Override + default boolean isFull() { + return TileDataStackRO.super.isFull(); + } + + /* + * Method specialization + */ + + @Override + TileDataReference getReference(int index); + + @Override + ChunkData getChunk(); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java b/src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java new file mode 100644 index 0000000..ca74bc4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/TileDataStackRO.java @@ -0,0 +1,12 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataStackRO + extends TileGenericStackRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 13138c5..65f13be 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -1,245 +1,52 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package ru.windcorp.progressia.common.world; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.function.Consumer; import glm.vec._3.i.Vec3i; -import gnu.trove.TCollections; -import gnu.trove.map.TLongObjectMap; -import gnu.trove.map.hash.TLongObjectHashMap; -import gnu.trove.set.TLongSet; -import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.ChunkMap; -import ru.windcorp.progressia.common.world.generic.ChunkSet; -import ru.windcorp.progressia.common.world.generic.GenericWritableWorld; -import ru.windcorp.progressia.common.world.generic.LongBasedChunkMap; +import ru.windcorp.progressia.common.world.generic.WorldGenericWO; +import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -public class WorldData - implements GenericWritableWorld { - - private final ChunkMap chunksByPos = new LongBasedChunkMap<>( - TCollections.synchronizedMap(new TLongObjectHashMap<>()) - ); - - private final Collection chunks = Collections.unmodifiableCollection(chunksByPos.values()); - - private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); - - private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); - - private GravityModel gravityModel = null; - - private float time = 0; - - private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); - - public WorldData() { - - } +public interface WorldData + extends WorldDataRO, WorldGenericWO { @Override - public ChunkData getChunk(Vec3i pos) { - return chunksByPos.get(pos); - } - - @Override - public Collection getChunks() { - return chunks; - } - - public ChunkSet getLoadedChunks() { - return chunksByPos.keys(); - } - - @Override - public Collection getEntities() { - return entities; - } - - @Override - public void forEachEntity(Consumer action) { - synchronized (entitiesById) { // TODO HORRIBLY MUTILATE THE CORPSE OF - // TROVE4J so that - // gnu.trove.impl.sync.SynchronizedCollection.forEach - // is synchronized - getEntities().forEach(action); - } - } - - public TLongSet getLoadedEntities() { - return entitiesById.keySet(); - } - - private void addChunkListeners(ChunkData chunk) { - getListeners().forEach(l -> l.getChunkListeners(this, chunk.getPosition(), chunk::addListener)); - } - - public synchronized void addChunk(ChunkData chunk) { - addChunkListeners(chunk); - - ChunkData previous = chunksByPos.get(chunk); - if (previous != null) { - throw new IllegalArgumentException( - String.format( - "Chunk at (%d; %d; %d) already exists", - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ) - ); - } - - chunksByPos.put(chunk, chunk); - - chunk.onLoaded(); - getListeners().forEach(l -> l.onChunkLoaded(this, chunk)); - } - - public synchronized void removeChunk(ChunkData chunk) { - getListeners().forEach(l -> l.beforeChunkUnloaded(this, chunk)); - chunk.beforeUnloaded(); - - chunksByPos.remove(chunk); - } - - @Override - public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { - ChunkData chunk = getChunkByBlock(blockInWorld); - if (chunk == null) - throw new IllegalCoordinatesException( - "Coordinates " - + "(" + blockInWorld.x + "; " + blockInWorld.y + "; " + blockInWorld.z + ") " - + "do not belong to a loaded chunk" - ); - - chunk.setBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null), block, notify); - } - - @Override - public EntityData getEntity(long entityId) { - return entitiesById.get(entityId); - } - - @Override - public void addEntity(EntityData entity) { - Objects.requireNonNull(entity, "entity"); - - EntityData previous = entitiesById.putIfAbsent(entity.getEntityId(), entity); - - if (previous != null) { - String message = "Cannot add entity " + entity + ": "; - - if (previous == entity) { - message += "already present"; - } else { - message += "entity with the same EntityID already present (" + previous + ")"; - } - - throw new IllegalStateException(message); - } - - getListeners().forEach(l -> l.onEntityAdded(this, entity)); - } - - @Override - public void removeEntity(long entityId) { - synchronized (entitiesById) { - EntityData entity = entitiesById.get(entityId); - - if (entity == null) { - throw new IllegalArgumentException( - "Entity with EntityID " + EntityData.formatEntityId(entityId) + " not present" - ); - } else { - removeEntity(entity); - } - } - } - - @Override - public void removeEntity(EntityData entity) { - Objects.requireNonNull(entity, "entity"); - - getListeners().forEach(l -> l.beforeEntityRemoved(this, entity)); - entitiesById.remove(entity.getEntityId()); - } - - public float getTime() { - return time; - } - - public void advanceTime(float change) { - this.time += change; - } - - public CollisionModel getCollisionModelOfBlock(Vec3i blockInWorld) { - ChunkData chunk = getChunkByBlock(blockInWorld); - if (chunk == null) - return null; - - BlockData block = chunk.getBlock(Coordinates.convertInWorldToInChunk(blockInWorld, null)); - if (block == null) - return null; - return block.getCollisionModel(); + default TileDataStack getTiles(Vec3i blockInWorld, BlockFace face) { + return (TileDataStack) WorldDataRO.super.getTiles(blockInWorld, face); } /** - * @return the gravity model + * Increases in-game time of this world by {@code change}. Total time is + * decreased when {@code change} is negative. + * + * @param change the amount of time to add to current world time. May be + * negative. + * @see #getTime() */ - public GravityModel getGravityModel() { - return gravityModel; - } - - /** - * @param gravityModel the gravity model to set + void advanceTime(float change); + + /* + * Method specialization */ - public void setGravityModel(GravityModel gravityModel) { - if (!chunks.isEmpty()) { - throw new IllegalStateException( - "Attempted to change gravity model to " + gravityModel + " while " + chunks.size() - + " chunks were loaded" - ); - } - - this.gravityModel = gravityModel; + + @Override + ChunkData getChunk(Vec3i pos); + + @Override + Collection getChunks(); + + // TODO: rename WGRO.forEachChunk -> forEachChunkRO and define WGWO.forEachChunk + + @Override + default ChunkData getChunkByBlock(Vec3i blockInWorld) { + return (ChunkData) WorldDataRO.super.getChunkByBlock(blockInWorld); } - - public Collection getListeners() { - return listeners; - } - - public void addListener(WorldDataListener e) { - listeners.add(e); - } - - public void removeListener(WorldDataListener o) { - listeners.remove(o); + + @Override + default TileDataStack getTilesOrNull(Vec3i blockInWorld, BlockFace face) { + return (TileDataStack) WorldDataRO.super.getTilesOrNull(blockInWorld, face); } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java b/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java index 9211efd..0949566 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldDataListener.java @@ -26,11 +26,11 @@ import ru.windcorp.progressia.common.world.entity.EntityData; public interface WorldDataListener { /** - * Invoked when a new {@link ChunkData} instance is created. This method + * Invoked when a new {@link DefaultChunkData} instance is created. This method * should be used to add * {@link ChunkDataListener}s to a new chunk. When listeners are added with * this method, - * their {@link ChunkDataListener#onChunkLoaded(ChunkData) onChunkLoaded} + * their {@link ChunkDataListener#onChunkLoaded(DefaultChunkData) onChunkLoaded} * methods will be invoked. * * @param world the world instance @@ -41,7 +41,7 @@ public interface WorldDataListener { * {@link Consumer#accept(Object) accept} method * will be added to the chunk. */ - default void getChunkListeners(WorldData world, Vec3i chunk, Consumer chunkListenerSink) { + default void getChunkListeners(DefaultWorldData world, Vec3i chunk, Consumer chunkListenerSink) { } /** @@ -50,7 +50,7 @@ public interface WorldDataListener { * @param world the world instance * @param chunk the chunk that has loaded */ - default void onChunkLoaded(WorldData world, ChunkData chunk) { + default void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { } /** @@ -59,7 +59,7 @@ public interface WorldDataListener { * @param world the world instance * @param chunk the chunk that is going to be unloaded */ - default void beforeChunkUnloaded(WorldData world, ChunkData chunk) { + default void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { } /** @@ -68,7 +68,7 @@ public interface WorldDataListener { * @param world the world instance * @param entity the entity that has been added */ - default void onEntityAdded(WorldData world, EntityData entity) { + default void onEntityAdded(DefaultWorldData world, EntityData entity) { } /** @@ -77,7 +77,7 @@ public interface WorldDataListener { * @param world the world instance * @param entity the entity that is going to be removed */ - default void beforeEntityRemoved(WorldData world, EntityData entity) { + default void beforeEntityRemoved(DefaultWorldData world, EntityData entity) { } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java b/src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java new file mode 100644 index 0000000..0fdfcbc --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldDataRO.java @@ -0,0 +1,29 @@ +package ru.windcorp.progressia.common.world; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface WorldDataRO + extends WorldGenericRO { + + /** + * Returns in-world time since creation. World time is zero before and + * during first tick. + *

      + * Game logic should assume that this value mostly increases uniformly. + * However, it is not guaranteed that in-world time always increments. + * + * @return time, in in-game seconds, since the world was created + */ + float getTime(); + + /** + * Gets the {@link GravityModel} used by this world. + * + * @return the gravity model + */ + GravityModel getGravityModel(); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java b/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java index e94f838..e2337c5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/BlockData.java @@ -21,9 +21,9 @@ package ru.windcorp.progressia.common.world.block; import ru.windcorp.progressia.common.collision.AABB; import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; -public class BlockData extends Namespaced implements GenericBlock { +public class BlockData extends Namespaced implements BlockGeneric { public BlockData(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java index 55d0eb2..eec2c46 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java @@ -24,7 +24,7 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketSetBlock extends PacketAffectBlock { @@ -60,7 +60,7 @@ public class PacketSetBlock extends PacketAffectBlock { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { BlockData block = BlockDataRegistry.getInstance().get(getBlockId()); world.setBlock(getBlockInWorld(), block, true); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java index ed6876d..bc00974 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/EntityData.java @@ -32,10 +32,10 @@ import ru.windcorp.progressia.common.collision.CollisionModel; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.util.Matrices; -import ru.windcorp.progressia.common.world.generic.GenericEntity; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.rels.AbsFace; -public class EntityData extends StatefulObject implements Collideable, GenericEntity { +public class EntityData extends StatefulObject implements Collideable, EntityGeneric { private final Vec3 position = new Vec3(); private final Vec3 velocity = new Vec3(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java index f3bf792..252ca6c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java @@ -24,7 +24,7 @@ import java.io.IOException; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.PacketAffectWorld; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketAffectEntity extends PacketAffectWorld { @@ -53,7 +53,7 @@ public class PacketAffectEntity extends PacketAffectWorld { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { world.removeEntity(this.entityId); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java index d09b0f3..25eb94f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java @@ -26,7 +26,7 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketChangeEntity extends PacketAffectEntity { @@ -68,7 +68,7 @@ public class PacketChangeEntity extends PacketAffectEntity { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { EntityData entity = world.getEntity(getEntityId()); if (entity == null) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java index 06dfc12..b006abf 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java @@ -23,7 +23,7 @@ import java.io.DataOutput; import java.io.IOException; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketRevokeEntity extends PacketAffectEntity { @@ -51,7 +51,7 @@ public class PacketRevokeEntity extends PacketAffectEntity { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { world.removeEntity(getEntityId()); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java index 6604d4a..1d1c792 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java @@ -26,7 +26,7 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class PacketSendEntity extends PacketAffectEntity { @@ -85,7 +85,7 @@ public class PacketSendEntity extends PacketAffectEntity { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { EntityData entity = EntityDataRegistry.getInstance().create(getEntityTypeId()); entity.setEntityId(getEntityId()); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java b/src/main/java/ru/windcorp/progressia/common/world/generic/BlockGeneric.java similarity index 96% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/BlockGeneric.java index d669b07..b8b05b2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/BlockGeneric.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world.generic; -public interface GenericBlock { +public interface BlockGeneric { String getId(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java similarity index 92% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java index 3643564..56482b5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java @@ -32,37 +32,37 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; /** * An unmodifiable chunk representation. Per default, it is usually one of - * {@link ru.windcorp.progressia.common.world.ChunkData ChunkData}, + * {@link ru.windcorp.progressia.common.world.DefaultChunkData ChunkData}, * {@link ru.windcorp.progressia.client.world.ChunkRender ChunkRender} or * {@link ru.windcorp.progressia.server.world.ChunkLogic ChunkLogic}, but this * interface may be implemented differently for various reasons. *

      - * A generic chunk contains {@linkplain GenericBlock blocks} and - * {@linkplain GenericTileStack tile stacks} and is characterized by its + * A generic chunk contains {@linkplain BlockGeneric blocks} and + * {@linkplain TileGenericStackRO tile stacks} and is characterized by its * location. It also bears a discrete up direction. Note that no - * {@linkplain GenericWorld world} object is directly accessible through this + * {@linkplain WorldGenericRO world} object is directly accessible through this * interface. *

      * This interface defines the most common methods for examining a chunk and * implements many of them as default methods. It also contains several static * methods useful when dealing with chunks. {@code GenericChunk} does not - * provide a way to modify a chunk; use {@link GenericWritableChunk} methods + * provide a way to modify a chunk; use {@link ChunkGenericWO} methods * when applicable. * * @param a reference to itself (required to properly reference a - * {@link GenericTileStack}) + * {@link TileGenericStackRO}) * @param block type * @param tile type * @param tile stack type * @author javapony */ // @formatter:off -public interface GenericChunk< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk +public interface ChunkGenericRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO > { // @formatter:on diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java new file mode 100644 index 0000000..1005454 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericWO.java @@ -0,0 +1,37 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.generic; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.BlockFace; + +// @formatter:off +public interface ChunkGenericWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO +> { +// @formatter:on + + void setBlock(Vec3i posInChunk, B block, boolean notify); + + TS getTiles(Vec3i blockInChunk, BlockFace face); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java index 5b4f6f6..695ba91 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMap.java @@ -77,27 +77,27 @@ public interface ChunkMap { // TODO implement (int, int, int) and GenericChunk versions of all of the // above - default boolean containsChunk(GenericChunk chunk) { + default boolean containsChunk(ChunkGenericRO chunk) { return containsKey(chunk.getPosition()); } - default V get(GenericChunk chunk) { + default V get(ChunkGenericRO chunk) { return get(chunk.getPosition()); } - default V put(GenericChunk chunk, V obj) { + default V put(ChunkGenericRO chunk, V obj) { return put(chunk.getPosition(), obj); } - default V remove(GenericChunk chunk) { + default V remove(ChunkGenericRO chunk) { return remove(chunk.getPosition()); } - default V getOrDefault(GenericChunk chunk, V def) { + default V getOrDefault(ChunkGenericRO chunk, V def) { return containsChunk(chunk) ? def : get(chunk); } - default > V compute( + default > V compute( C chunk, BiFunction remappingFunction ) { @@ -128,8 +128,8 @@ public interface ChunkMap { void forEach(BiConsumer action); - default > void forEachIn( - GenericWorld world, + default > void forEachIn( + WorldGenericRO world, BiConsumer action ) { forEach((pos, value) -> { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java index c194351..658f9ea 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkMaps.java @@ -174,42 +174,42 @@ public class ChunkMaps { } @Override - public boolean containsChunk(GenericChunk chunk) { + public boolean containsChunk(ChunkGenericRO chunk) { synchronized (mutex) { return parent.containsChunk(chunk); } } @Override - public V get(GenericChunk chunk) { + public V get(ChunkGenericRO chunk) { synchronized (mutex) { return parent.get(chunk); } } @Override - public V put(GenericChunk chunk, V obj) { + public V put(ChunkGenericRO chunk, V obj) { synchronized (mutex) { return parent.put(chunk, obj); } } @Override - public V remove(GenericChunk chunk) { + public V remove(ChunkGenericRO chunk) { synchronized (mutex) { return parent.remove(chunk); } } @Override - public V getOrDefault(GenericChunk chunk, V def) { + public V getOrDefault(ChunkGenericRO chunk, V def) { synchronized (mutex) { return parent.getOrDefault(chunk, def); } } @Override - public > V compute( + public > V compute( C chunk, BiFunction remappingFunction ) { @@ -247,8 +247,8 @@ public class ChunkMaps { } @Override - public > void forEachIn( - GenericWorld world, + public > void forEachIn( + WorldGenericRO world, BiConsumer action ) { synchronized (mutex) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java index 199e780..9b75d3c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSet.java @@ -78,20 +78,20 @@ public interface ChunkSet extends Iterable { return result; } - default boolean contains(GenericChunk chunk) { + default boolean contains(ChunkGenericRO chunk) { return contains(chunk.getPosition()); } - default boolean add(GenericChunk chunk) { + default boolean add(ChunkGenericRO chunk) { return add(chunk.getPosition()); } - default boolean remove(GenericChunk chunk) { + default boolean remove(ChunkGenericRO chunk) { return remove(chunk.getPosition()); } - default > void forEachIn( - GenericWorld world, + default > void forEachIn( + WorldGenericRO world, Consumer action ) { forEach(position -> { @@ -210,7 +210,7 @@ public interface ChunkSet extends Iterable { } } - default boolean containsAllChunks(Iterable> chunks) { + default boolean containsAllChunks(Iterable> chunks) { boolean[] hasMissing = new boolean[] { false }; chunks.forEach(c -> { @@ -222,7 +222,7 @@ public interface ChunkSet extends Iterable { return hasMissing[0]; } - default boolean containsAnyChunks(Iterable> chunks) { + default boolean containsAnyChunks(Iterable> chunks) { boolean[] hasPresent = new boolean[] { false }; chunks.forEach(c -> { @@ -234,11 +234,11 @@ public interface ChunkSet extends Iterable { return hasPresent[0]; } - default void addAllChunks(Iterable> chunks) { + default void addAllChunks(Iterable> chunks) { chunks.forEach(this::add); } - default void removeAllChunks(Iterable> chunks) { + default void removeAllChunks(Iterable> chunks) { chunks.forEach(this::remove); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java index 4ee643b..8123cbc 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkSets.java @@ -198,29 +198,29 @@ public class ChunkSets { } @Override - public boolean contains(GenericChunk chunk) { + public boolean contains(ChunkGenericRO chunk) { synchronized (mutex) { return parent.contains(chunk); } } @Override - public boolean add(GenericChunk chunk) { + public boolean add(ChunkGenericRO chunk) { synchronized (mutex) { return parent.add(chunk); } } @Override - public boolean remove(GenericChunk chunk) { + public boolean remove(ChunkGenericRO chunk) { synchronized (mutex) { return parent.remove(chunk); } } @Override - public > void forEachIn( - GenericWorld world, + public > void forEachIn( + WorldGenericRO world, Consumer action ) { synchronized (mutex) { @@ -320,28 +320,28 @@ public class ChunkSets { } @Override - public boolean containsAllChunks(Iterable> chunks) { + public boolean containsAllChunks(Iterable> chunks) { synchronized (mutex) { return parent.containsAllChunks(chunks); } } @Override - public boolean containsAnyChunks(Iterable> chunks) { + public boolean containsAnyChunks(Iterable> chunks) { synchronized (mutex) { return parent.containsAnyChunks(chunks); } } @Override - public void addAllChunks(Iterable> chunks) { + public void addAllChunks(Iterable> chunks) { synchronized (mutex) { parent.addAllChunks(chunks); } } @Override - public void removeAllChunks(Iterable> chunks) { + public void removeAllChunks(Iterable> chunks) { synchronized (mutex) { parent.removeAllChunks(chunks); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java b/src/main/java/ru/windcorp/progressia/common/world/generic/EntityGeneric.java similarity index 97% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/EntityGeneric.java index 3acfc23..481191f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/EntityGeneric.java @@ -22,7 +22,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.Coordinates; -public interface GenericEntity { +public interface EntityGeneric { String getId(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java index 3d65785..83ba89a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericChunks.java @@ -34,7 +34,7 @@ public class GenericChunks { output = new Vec3i(); } - final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1; + final int offset = ChunkGenericRO.BLOCKS_PER_CHUNK - 1; output.set(relativeCoords.x, relativeCoords.y, relativeCoords.z); output.mul(2).sub(offset); @@ -51,7 +51,7 @@ public class GenericChunks { output = new Vec3i(); } - final int offset = GenericChunk.BLOCKS_PER_CHUNK - 1; + final int offset = ChunkGenericRO.BLOCKS_PER_CHUNK - 1; output.set(absoluteCoords.x, absoluteCoords.y, absoluteCoords.z); output.mul(2).sub(offset); @@ -73,7 +73,7 @@ public class GenericChunks { return hits; } - static boolean testBiC(Vec3i blockInWorld, GenericChunk chunk, Predicate test) { + static boolean testBiC(Vec3i blockInWorld, ChunkGenericRO chunk, Predicate test) { Vec3i v = Vectors.grab3i(); v = Coordinates.getInWorld(chunk.getPosition(), Vectors.ZERO_3i, v); @@ -87,9 +87,9 @@ public class GenericChunks { } public static boolean containsBiC(Vec3i blockInChunk) { - return blockInChunk.x >= 0 && blockInChunk.x < GenericChunk.BLOCKS_PER_CHUNK && - blockInChunk.y >= 0 && blockInChunk.y < GenericChunk.BLOCKS_PER_CHUNK && - blockInChunk.z >= 0 && blockInChunk.z < GenericChunk.BLOCKS_PER_CHUNK; + return blockInChunk.x >= 0 && blockInChunk.x < ChunkGenericRO.BLOCKS_PER_CHUNK && + blockInChunk.y >= 0 && blockInChunk.y < ChunkGenericRO.BLOCKS_PER_CHUNK && + blockInChunk.z >= 0 && blockInChunk.z < ChunkGenericRO.BLOCKS_PER_CHUNK; } public static boolean isSurfaceBiC(Vec3i blockInChunk) { @@ -109,9 +109,9 @@ public class GenericChunks { 0, 0, 0, - GenericChunk.BLOCKS_PER_CHUNK, - GenericChunk.BLOCKS_PER_CHUNK, - GenericChunk.BLOCKS_PER_CHUNK, + ChunkGenericRO.BLOCKS_PER_CHUNK, + ChunkGenericRO.BLOCKS_PER_CHUNK, + ChunkGenericRO.BLOCKS_PER_CHUNK, action ); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java b/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java deleted file mode 100644 index 40fb010..0000000 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableChunk.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.common.world.generic; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.Vectors; - -// @formatter:off -public interface GenericWritableChunk< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericWritableTileStack , - TR extends GenericTileReference , - C extends GenericWritableChunk -> - extends GenericChunk { -// @formatter:on - - void setBlock(Vec3i posInChunk, B block, boolean notify); - - default void setBlockRel(Vec3i relativeBlockInChunk, B block, boolean notify) { - Vec3i absoluteBlockInChunk = Vectors.grab3i(); - resolve(relativeBlockInChunk, absoluteBlockInChunk); - setBlock(absoluteBlockInChunk, block, notify); - Vectors.release(absoluteBlockInChunk); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java index 11559ca..bed628e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/LongBasedChunkSet.java @@ -45,7 +45,7 @@ public class LongBasedChunkSet implements ChunkSet { addAll(copyFrom); } - public LongBasedChunkSet(TLongSet impl, GenericWorld copyFrom) { + public LongBasedChunkSet(TLongSet impl, WorldGenericRO copyFrom) { this(impl); addAllChunks(copyFrom.getChunks()); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGeneric.java similarity index 96% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGeneric.java index e35aec2..4a2b2e3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGeneric.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world.generic; -public interface GenericTile { +public interface TileGeneric { String getId(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java new file mode 100644 index 0000000..64f7cfb --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java @@ -0,0 +1,50 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic; + +// @formatter:off +public interface TileGenericReferenceRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO +> { +// @formatter:on + + T get(); + + int getIndex(); + + TS getStack(); + + default boolean isValid() { + return get() != null; + } + + default int getTag() { + TS tileStack = getStack(); + if (tileStack == null) { + return -1; + } else { + return tileStack.getTagByIndex(getIndex()); + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceWO.java similarity index 70% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceWO.java index b3e7289..f31eca8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileReference.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceWO.java @@ -19,23 +19,15 @@ package ru.windcorp.progressia.common.world.generic; // @formatter:off -public interface GenericTileReference< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk +public interface TileGenericReferenceWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO > { // @formatter:on - - T get(); - - int getIndex(); - - TS getStack(); - - default boolean isValid() { - return get() != null; - } + + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackRO.java similarity index 68% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackRO.java index ddf7e00..0a08fac 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackRO.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.common.world.generic; -import java.util.AbstractList; +import java.util.List; import java.util.Objects; import java.util.RandomAccess; import java.util.function.Consumer; @@ -28,13 +28,13 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.RelFace; // @formatter:off -public abstract class GenericTileStack< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk -> extends AbstractList implements RandomAccess { +public interface TileGenericStackRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO +> extends List, RandomAccess { // @formatter:on public static interface TSConsumer { @@ -43,36 +43,36 @@ public abstract class GenericTileStack< public static final int TILES_PER_FACE = 8; - public abstract Vec3i getBlockInChunk(Vec3i output); + Vec3i getBlockInChunk(Vec3i output); - public abstract C getChunk(); + C getChunk(); - public abstract RelFace getFace(); + RelFace getFace(); - public abstract TR getReference(int index); + TR getReference(int index); - public abstract int getIndexByTag(int tag); + int getIndexByTag(int tag); - public abstract int getTagByIndex(int index); + int getTagByIndex(int index); - public Vec3i getBlockInWorld(Vec3i output) { + default Vec3i getBlockInWorld(Vec3i output) { // This is safe return Coordinates.getInWorld(getChunk().getPosition(), getBlockInChunk(output), output); } - public boolean isFull() { + default boolean isFull() { return size() >= TILES_PER_FACE; } - public T getClosest() { + default T getClosest() { return get(0); } - public T getFarthest() { + default T getFarthest() { return get(size() - 1); } - public void forEach(TSConsumer action) { + default void forEach(TSConsumer action) { Objects.requireNonNull(action, "action"); for (int i = 0; i < size(); ++i) { action.accept(i, get(i)); @@ -80,14 +80,14 @@ public abstract class GenericTileStack< } @Override - public void forEach(Consumer action) { + default void forEach(Consumer action) { Objects.requireNonNull(action, "action"); for (int i = 0; i < size(); ++i) { action.accept(get(i)); } } - public T findClosest(String id) { + default T findClosest(String id) { Objects.requireNonNull(id, "id"); for (int i = 0; i < size(); ++i) { @@ -100,7 +100,7 @@ public abstract class GenericTileStack< return null; } - public T findFarthest(String id) { + default T findFarthest(String id) { Objects.requireNonNull(id, "id"); for (int i = 0; i < size(); ++i) { @@ -113,11 +113,11 @@ public abstract class GenericTileStack< return null; } - public boolean contains(String id) { + default boolean contains(String id) { return findClosest(id) != null; } - public B getHost() { + default B getHost() { return getChunk().getBlock(getBlockInChunk(null)); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackWO.java similarity index 80% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackWO.java index b2363e3..ec5073e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableTileStack.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericStackWO.java @@ -18,15 +18,18 @@ package ru.windcorp.progressia.common.world.generic; +import java.util.List; +import java.util.RandomAccess; + // @formatter:off -public abstract class GenericWritableTileStack< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericWritableTileStack, - TR extends GenericTileReference, - C extends GenericWritableChunk +public interface TileGenericStackWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO > - extends GenericTileStack { + extends List, RandomAccess { // @formatter:on /** @@ -45,7 +48,7 @@ public abstract class GenericWritableTileStack< * make sure to override it in subclass */ @Override - public abstract void add(int index, T tile); + void add(int index, T tile); /** * Adds the specified tile at the end of this stack assigning it the @@ -59,7 +62,7 @@ public abstract class GenericWritableTileStack< * with the * provided tag */ - public abstract void load(T tile, int tag); + void load(T tile, int tag); /** * Replaces the tile at the specified position in this stack with the @@ -74,7 +77,7 @@ public abstract class GenericWritableTileStack< * make sure to override it in subclass */ @Override - public abstract T set(int index, T tile); + T set(int index, T tile); /** * Removes the tile at the specified position in this list. Shifts any @@ -91,19 +94,21 @@ public abstract class GenericWritableTileStack< * make sure to override it in subclass */ @Override - public abstract T remove(int index); + T remove(int index); /* * Aliases and overloads */ - public void addClosest(T tile) { + default void addClosest(T tile) { add(0, tile); } - public void addFarthest(T tile) { + default void addFarthest(T tile) { add(size(), tile); } + + boolean isFull(); /** * Attempts to {@link #add(int, TileData) add} the provided {@code tile} @@ -114,45 +119,45 @@ public abstract class GenericWritableTileStack< * @param tile the tile to try to add * @return {@code true} iff this stack has changed */ - public boolean offer(int index, T tile) { + default boolean offer(int index, T tile) { if (isFull()) return false; add(index, tile); return true; } - public boolean offerClosest(T tile) { + default boolean offerClosest(T tile) { return offer(0, tile); } - public boolean offerFarthest(T tile) { + default boolean offerFarthest(T tile) { return offer(size(), tile); } - public T removeClosest() { + default T removeClosest() { return remove(0); } - public T removeFarthest() { + default T removeFarthest() { return remove(size() - 1); } - public T poll(int index) { + default T poll(int index) { if (size() <= index) return null; return remove(index); } - public T pollClosest() { + default T pollClosest() { return poll(0); } - public T pollFarthest() { + default T pollFarthest() { return poll(size() - 1); } @Override - public boolean add(T tile) { + default boolean add(T tile) { addFarthest(tile); return true; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java similarity index 90% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java index e17cf66..75ad1c3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java @@ -30,17 +30,17 @@ import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; // @formatter:off -public interface GenericWorld< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericTileStack , - TR extends GenericTileReference , - C extends GenericChunk , - E extends GenericEntity +public interface WorldGenericRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric > { // @formatter:on - Collection getChunks(); + Collection getChunks(); C getChunk(Vec3i pos); @@ -131,6 +131,15 @@ public interface GenericWorld< return stack.get(layer); } + /** + * Determines whether the specified position has a tile. + * + * @return {@code true} iff the tile exists + */ + default boolean hasTile(Vec3i location, BlockFace face, int layer) { + return hasTile(location, face, layer); + } + default boolean isChunkLoaded(Vec3i chunkPos) { return getChunk(chunkPos) != null; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericWO.java similarity index 52% rename from src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericWO.java index b970f89..3b9a81b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/GenericWritableWorld.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericWO.java @@ -18,21 +18,24 @@ package ru.windcorp.progressia.common.world.generic; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.rels.BlockFace; //@formatter:off -public interface GenericWritableWorld< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericWritableTileStack , - TR extends GenericTileReference , - C extends GenericWritableChunk , - E extends GenericEntity -> - extends GenericWorld { +public interface WorldGenericWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> { //@formatter:on - void setBlock(Vec3i blockInWorld, BlockData block, boolean notify); + void setBlock(Vec3i blockInWorld, B block, boolean notify); + + TS getTiles(Vec3i blockInWorld, BlockFace face); void addEntity(E entity); @@ -42,4 +45,13 @@ public interface GenericWritableWorld< removeEntity(entity.getEntityId()); } + /** + * Requests that the specified change is applied to the given entity. The + * {@code change} object provided may be stored until the change is applied. + * + * @param entity the entity to change + * @param change the change to apply + */ + void changeEntity(SE entity, StateChange change); + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java similarity index 70% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java index 430a4a3..212cc9b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java @@ -18,13 +18,7 @@ package ru.windcorp.progressia.common.world.generic.context; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; -import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.generic.*; /** * A {@link Context} referencing a world with a block location and a block face @@ -32,23 +26,16 @@ import ru.windcorp.progressia.common.world.rels.RelFace; * not actually exist. */ //@formatter:off -public interface GenericROBlockFaceContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends GenericROBlockContext { +public interface BlockFaceGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.BlockFace, BlockGenericContextRO { //@formatter:on - /** - * Returns the face relevant to this context. - * - * @return the block face - */ - RelFace getFace(); - /** * Gets the tile stack at the relevant position. * diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java similarity index 72% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java index b2152f8..bcaa226 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java @@ -28,14 +28,14 @@ import ru.windcorp.progressia.common.world.generic.*; * stack may or may not actually exist. */ //@formatter:off -public interface GenericRWBlockFaceContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericRWBlockContext, GenericROBlockFaceContext { +public interface BlockFaceGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.BlockFace, BlockGenericContextWO { //@formatter:on /** @@ -63,16 +63,4 @@ public interface GenericRWBlockFaceContext< removeTile(getLocation(), getFace(), tag); } - /** - * Requests that the referenced tile is removed from the specified tile - * stack. If the tile could not be found at the time of application this - * method fails silently. The location and the face of the block are implied - * by the context. - * - * @param tileReference a reference to the tile - */ - default void removeTile(TR tileReference) { - removeTile(getLocation(), getFace(), tileReference.getTag()); - } - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java similarity index 69% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index 4411407..91ac3d3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -17,14 +17,8 @@ */ package ru.windcorp.progressia.common.world.generic.context; -import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.generic.*; import ru.windcorp.progressia.common.world.rels.BlockFace; /** @@ -32,29 +26,16 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * location may or may not be loaded. */ //@formatter:off -public interface GenericROBlockContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends GenericROWorldContext { +public interface BlockGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.Block, WorldGenericContextRO { //@formatter:on - /** - * Returns the location of the block. - *

      - * The coordinate system in use is not specified, but it is consistent - * across all methods of this context. - *

      - * The object returned by this method must not be modified. It is only valid - * while the context is {@linkplain valid}. - * - * @return a vector describing the block's position - */ - Vec3i getLocation(); - /** * Determines whether the location relevant to this context is currently * loaded. diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java similarity index 74% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index 23fb6fe..f7a0eea 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -28,14 +28,14 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * {@link #isImmediate()}. The location may or may not be loaded. */ //@formatter:off -public interface GenericRWBlockContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericRWWorldContext, GenericROBlockContext { +public interface BlockGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.Block, WorldGenericContextWO { //@formatter:on /** @@ -76,17 +76,4 @@ public interface GenericRWBlockContext< removeTile(getLocation(), face, tag); } - /** - * Requests that the referenced tile is removed from the specified tile - * stack. If the tile could not be found at the time of application this - * method fails silently. The location of the block is implied by the - * context. - * - * @param face the of the block to remove the tile from - * @param tileReference a reference to the tile - */ - default void removeTile(BlockFace face, TR tileReference) { - removeTile(getLocation(), face, tileReference.getTag()); - } - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java similarity index 62% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java index 0ebc768..0bc04d0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROTileContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java @@ -18,12 +18,7 @@ package ru.windcorp.progressia.common.world.generic.context; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; +import ru.windcorp.progressia.common.world.generic.*; /** * A {@link Context} referencing a world with a block location, a block face and @@ -31,23 +26,16 @@ import ru.windcorp.progressia.common.world.generic.GenericROTileStack; * or may not actually exist. */ //@formatter:off -public interface GenericROTileContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends GenericROBlockFaceContext { +public interface TileGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.Tile, BlockFaceGenericContextRO { //@formatter:on - /** - * Returns the tile layer relevant to this context. - * - * @return the tile layer - */ - int getLayer(); - /** * Determines whether the location relevant to this context has a tile. * @@ -67,12 +55,7 @@ public interface GenericROTileContext< return getTile(getLocation(), getFace(), getLayer()); } - /** - * Gets the tag of the tile at the relevant position. - * - * @return the tag of the tile or {@code -1} if the location is not loaded - * or the tile does not exist - */ + @Override default int getTag() { TS tileStack = getTilesOrNull(); if (tileStack == null) { @@ -82,4 +65,23 @@ public interface GenericROTileContext< return tileStack.getTagByIndex(getLayer()); } + /** + * Gets the {@link TileGenericReferenceRO TileReference} to the relevant + * tile. + * + * @return the reference to the tile relevant to this context or + * {@code null} if the location is not loaded or the tile does not + * exist + * + * @see TileGenericStackRO#getReference(int) + */ + default TR getTileReference() { + TS tileStack = getTilesOrNull(); + if (tileStack == null) { + return null; + } + + return tileStack.getReference(getLayer()); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java similarity index 80% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java index c7c0d5c..01a27d1 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWTileContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java @@ -28,14 +28,14 @@ import ru.windcorp.progressia.common.world.generic.*; * The tile may or may not actually exist. */ //@formatter:off -public interface GenericRWTileContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericRWBlockFaceContext, GenericROTileContext { +public interface TileGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.Tile, BlockFaceGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java new file mode 100644 index 0000000..69c5f94 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -0,0 +1,127 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.generic.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.rels.RelFace; + +/** + * This class defines several {@link Context} subinterfaces that are further + * extended by Generic contexts. These interfaces declare methods for + * determining which location is "relevant" to the context. Since they are not + * Java generics they can safely be extended more than once. + *

      + * Do not reuse these interfaces outside the Generic contexts' package; consider + * them to be an implementation detail. + * + * @author javapony + * + */ +class WorldContexts { + + /** + * A {@link Context} with a world instance. This interface should not be + * implemented directly; see {@link WorldGenericContextRO} or + * {@link WorldGenericContextWO}. + * + * @author javapony + * + */ + public static interface World extends Context { + + // currently empty + + } + + /** + * A {@link Context} with a world instance and a block location. This interface + * should not be implemented directly; see {@link BlockGenericContextRO} or + * {@link BlockGenericContextWO}. + * + * @author javapony + * + */ + public static interface Block extends World { + + /** + * Returns the location of the block. + *

      + * The coordinate system in use is not specified, but it is consistent across + * all methods of this context. + *

      + * The object returned by this method must not be modified. It is only valid + * while the context is {@linkplain valid}. + * + * @return a vector describing the block's position + */ + Vec3i getLocation(); + + } + + /** + * A {@link Context} with a world instance, a block location and a block face + * (block side). This interface should not be implemented directly; see + * {@link BlockFaceGenericContextRO} or {@link BlockFaceGenericContextWO}. + * + * @author javapony + * + */ + public static interface BlockFace extends Block { + + /** + * Returns the face relevant to this context. + * + * @return the block face + */ + RelFace getFace(); + + } + + /** + * A {@link Context} with a world instance, a block location, a block face + * (block side) and a tile layer. This interface should not be implemented + * directly; see {@link TileGenericContextRO} or {@link TileGenericContextWO}. + * + * @author javapony + * + */ + public static interface Tile extends BlockFace { + + /** + * Returns the tile layer relevant to this context. + * + * @return the tile layer + */ + int getLayer(); + + /** + * Gets the tag of the tile at the relevant position. + * + * @return the tag of the tile or {@code -1} if the location is not loaded + * or the tile does not exist + */ + int getTag(); + + } + + WorldContexts() { + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java similarity index 54% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java index 09629da..588c98f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericROWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java @@ -18,26 +18,20 @@ package ru.windcorp.progressia.common.world.generic.context; import ru.windcorp.progressia.common.world.context.Context; -import ru.windcorp.progressia.common.world.generic.GenericBlock; -import ru.windcorp.progressia.common.world.generic.GenericROChunk; -import ru.windcorp.progressia.common.world.generic.GenericEntity; -import ru.windcorp.progressia.common.world.generic.GenericTile; -import ru.windcorp.progressia.common.world.generic.GenericROTileReference; -import ru.windcorp.progressia.common.world.generic.GenericROTileStack; -import ru.windcorp.progressia.common.world.generic.GenericROWorld; +import ru.windcorp.progressia.common.world.generic.*; /** * A {@link Context} with a world instance. */ // @formatter:off -public interface GenericROWorldContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericROTileStack , - TR extends GenericROTileReference , - C extends GenericROChunk , - E extends GenericEntity -> extends Context, GenericROWorld { +public interface WorldGenericContextRO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackRO , + TR extends TileGenericReferenceRO , + C extends ChunkGenericRO , + E extends EntityGeneric +> extends WorldContexts.World, WorldGenericRO { // @formatter:on // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java similarity index 80% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index 55d83ff..ddac83d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/GenericRWWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -30,14 +30,14 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * may not be immediate, see {@link #isImmediate()}. */ // @formatter:off -public interface GenericRWWorldContext< - B extends GenericBlock, - T extends GenericTile, - TS extends GenericRWTileStack , - TR extends GenericROTileReference , - C extends GenericRWChunk , - E extends GenericEntity -> extends GenericROWorldContext, GenericRWWorld { +public interface WorldGenericContextWO< + B extends BlockGeneric, + T extends TileGeneric, + TS extends TileGenericStackWO , + TR extends TileGenericReferenceWO , + C extends ChunkGenericWO , + E extends EntityGeneric +> extends WorldContexts.World, WorldGenericWO { // @formatter:on /** @@ -92,17 +92,20 @@ public interface GenericRWWorldContext< void removeTile(Vec3i location, BlockFace face, int tag); /** - * Requests that the referenced tile is removed from the specified tile - * stack. If the tile could not be found at the time of application this - * method fails silently. + * Requests that the referenced tile is removed from its tile stack. If the + * tile could not be found at the time of application this method fails + * silently. * - * @param location the location of the block from which the tile is to - * be removed - * @param face the of the block to remove the tile from * @param tileReference a reference to the tile */ - default void removeTile(Vec3i location, BlockFace face, TR tileReference) { - removeTile(location, face, tileReference.getTag()); + default void removeTile(TileGenericReferenceRO tileReference) { + TileGenericStackRO tileStack = tileReference.getStack(); + + if (tileStack == null) { + return; + } + + removeTile(tileStack.getBlockInWorld(null), tileStack.getFace(), tileReference.getTag()); } /** @@ -123,7 +126,7 @@ public interface GenericRWWorldContext< * * @param entityId the ID of the entity to remove * @see #isImmediate() - * @see #removeEntity(GenericEntity) + * @see #removeEntity(EntityGeneric) */ @Override void removeEntity(long entityId); @@ -140,12 +143,13 @@ public interface GenericRWWorldContext< void removeEntity(E entity); /** - * Requests that the specified change is applied to the given entity. The {@code change} object provided may be stored until the change is applied. + * Requests that the specified change is applied to the given entity. The + * {@code change} object provided may be stored until the change is applied. * * @param entity the entity to change * @param change the change to apply */ @Override - void changeEntity(SE entity, StateChange change); + void changeEntity(SE entity, StateChange change); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java index 7c2a35c..df47640 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkCodec.java @@ -25,9 +25,9 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public abstract class ChunkCodec extends Namespaced { @@ -46,12 +46,12 @@ public abstract class ChunkCodec extends Namespaced { return signature; } - public abstract ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) + public abstract DefaultChunkData decode(DefaultWorldData world, Vec3i position, DataInputStream input, IOContext context) throws DecodingException, IOException; - public abstract boolean shouldEncode(ChunkData chunk, IOContext context); + public abstract boolean shouldEncode(DefaultChunkData chunk, IOContext context); - public abstract void encode(ChunkData chunk, DataOutputStream output, IOContext context) throws IOException; + public abstract void encode(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java index 025738f..b2a1cd2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/io/ChunkIO.java @@ -31,16 +31,16 @@ import gnu.trove.map.TByteObjectMap; import gnu.trove.map.hash.TByteObjectHashMap; import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class ChunkIO { private static final TByteObjectMap CODECS_BY_ID = new TByteObjectHashMap<>(); private static final List CODECS_BY_PRIORITY = new ArrayList<>(); - public static ChunkData load(WorldData world, Vec3i position, DataInputStream data, IOContext context) + public static DefaultChunkData load(DefaultWorldData world, Vec3i position, DataInputStream data, IOContext context) throws DecodingException, IOException { if (CODECS_BY_ID.isEmpty()) @@ -73,7 +73,7 @@ public class ChunkIO { } } - public static void save(ChunkData chunk, DataOutputStream output, IOContext context) + public static void save(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException { ChunkCodec codec = getCodec(chunk, context); @@ -100,7 +100,7 @@ public class ChunkIO { return CODECS_BY_ID.get(signature); } - public static ChunkCodec getCodec(ChunkData chunk, IOContext context) { + public static ChunkCodec getCodec(DefaultChunkData chunk, IOContext context) { for (ChunkCodec codec : CODECS_BY_PRIORITY) { if (codec.shouldEncode(chunk, context)) { return codec; diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java index 4a1e7a0..1655446 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java @@ -24,7 +24,7 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.rels.AbsFace; public class PacketAddTile extends PacketAffectTile { @@ -61,7 +61,7 @@ public class PacketAddTile extends PacketAffectTile { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { TileData tile = TileDataRegistry.getInstance().get(getTileId()); world.getTiles(getBlockInWorld(), getFace()).add(tile); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java index 9bb66af..6935368 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java @@ -25,7 +25,8 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; +import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.rels.AbsFace; public class PacketRemoveTile extends PacketAffectTile { @@ -54,7 +55,7 @@ public class PacketRemoveTile extends PacketAffectTile { } @Override - public void apply(WorldData world) { + public void apply(DefaultWorldData world) { TileDataStack stack = world.getTiles(getBlockInWorld(), getFace()); int index = stack.getIndexByTag(getTag()); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java index d314445..54f09a9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/TileData.java @@ -19,9 +19,9 @@ package ru.windcorp.progressia.common.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.TileGeneric; -public class TileData extends Namespaced implements GenericTile { +public class TileData extends Namespaced implements TileGeneric { public TileData(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java b/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java deleted file mode 100644 index 7e88402..0000000 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/TileDataStack.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.common.world.tile; - -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.generic.GenericWritableTileStack; - -public abstract class TileDataStack - extends GenericWritableTileStack { - -} diff --git a/src/main/java/ru/windcorp/progressia/server/Player.java b/src/main/java/ru/windcorp/progressia/server/Player.java index 734783f..008c000 100644 --- a/src/main/java/ru/windcorp/progressia/server/Player.java +++ b/src/main/java/ru/windcorp/progressia/server/Player.java @@ -22,7 +22,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.Units; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.PlayerData; import ru.windcorp.progressia.common.world.entity.EntityData; @@ -55,7 +55,7 @@ public class Player extends PlayerData implements ChunkLoader { Coordinates.convertInWorldToChunk(start, start); Vec3i cursor = new Vec3i(); - float radius = getServer().getLoadDistance(this) / Units.get(ChunkData.BLOCKS_PER_CHUNK, "m"); + float radius = getServer().getLoadDistance(this) / Units.get(DefaultChunkData.BLOCKS_PER_CHUNK, "m"); float radiusSq = radius * radius; int iRadius = (int) Math.ceil(radius); diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index a0febbf..9da227f 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -28,7 +28,7 @@ import ru.windcorp.jputil.functions.ThrowingRunnable; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.TaskQueue; import ru.windcorp.progressia.common.util.crash.ReportingEventBus; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.comms.ClientManager; import ru.windcorp.progressia.server.events.ServerEvent; import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon; @@ -68,7 +68,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); - public Server(WorldData world) { + public Server(DefaultWorldData world) { this.world = new WorldLogic( world, this, diff --git a/src/main/java/ru/windcorp/progressia/server/ServerState.java b/src/main/java/ru/windcorp/progressia/server/ServerState.java index 774f17d..de505f5 100644 --- a/src/main/java/ru/windcorp/progressia/server/ServerState.java +++ b/src/main/java/ru/windcorp/progressia/server/ServerState.java @@ -18,7 +18,7 @@ package ru.windcorp.progressia.server; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; public class ServerState { @@ -33,7 +33,7 @@ public class ServerState { } public static void startServer() { - Server server = new Server(new WorldData()); + Server server = new Server(new DefaultWorldData()); setInstance(server); server.start(); } diff --git a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java index baf68f6..3071530 100644 --- a/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java +++ b/src/main/java/ru/windcorp/progressia/server/management/load/ChunkManager.java @@ -18,10 +18,10 @@ package ru.windcorp.progressia.server.management.load; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.PacketRevokeChunk; import ru.windcorp.progressia.common.world.PacketSendChunk; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Player; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.test.TestWorldDiskIO; @@ -113,9 +113,9 @@ public class ChunkManager { return LoadResult.ALREADY_LOADED; } - WorldData world = getServer().getWorld().getData(); + DefaultWorldData world = getServer().getWorld().getData(); - ChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); + DefaultChunkData chunk = TestWorldDiskIO.tryToLoad(chunkPos, world, getServer()); if (chunk != null) { world.addChunk(chunk); return LoadResult.LOADED_FROM_DISK; @@ -133,8 +133,8 @@ public class ChunkManager { * this method */ public boolean unloadChunk(Vec3i chunkPos) { - WorldData world = getServer().getWorld().getData(); - ChunkData chunk = world.getChunk(chunkPos); + DefaultWorldData world = getServer().getWorld().getData(); + DefaultChunkData chunk = world.getChunk(chunkPos); if (chunk == null) { return false; @@ -147,7 +147,7 @@ public class ChunkManager { } public void sendChunk(Player player, Vec3i chunkPos) { - ChunkData chunk = getServer().getWorld().getData().getChunk(chunkPos); + DefaultChunkData chunk = getServer().getWorld().getData().getChunk(chunkPos); if (chunk == null) { throw new IllegalStateException( @@ -180,7 +180,7 @@ public class ChunkManager { /** * Checks whether or not the chunk at the specified location is loaded. A - * loaded chunk is accessible through the server's {@link WorldData} object. + * loaded chunk is accessible through the server's {@link DefaultWorldData} object. * * @param chunkPos the position of the chunk * @return {@code true} iff the chunk is loaded diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index a5177fe..f633179 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -26,14 +26,14 @@ import java.util.WeakHashMap; import java.util.function.BiConsumer; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.generic.GenericChunk; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataReference; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.server.world.block.TickableBlock; @@ -45,10 +45,10 @@ import ru.windcorp.progressia.server.world.tile.TileLogicReference; import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; import ru.windcorp.progressia.server.world.tile.TileLogicStack; -public class ChunkLogic implements GenericChunk { +public class ChunkLogic implements ChunkGenericRO { private final WorldLogic world; - private final ChunkData data; + private final DefaultChunkData data; private final Collection tickingBlocks = new ArrayList<>(); private final Collection tickingTiles = new ArrayList<>(); @@ -58,7 +58,7 @@ public class ChunkLogic implements GenericChunk tileLogicLists = Collections .synchronizedMap(new WeakHashMap<>()); - public ChunkLogic(WorldLogic world, ChunkData data) { + public ChunkLogic(WorldLogic world, DefaultChunkData data) { this.world = world; this.data = data; @@ -103,7 +103,7 @@ public class ChunkLogic implements GenericChunk tileStack); + TileStack withTS(TileGenericStackRO tileStack); - default Builder.Chunk withChunk(ChunkData chunk) { + default Builder.Chunk withChunk(DefaultChunkData chunk) { Objects.requireNonNull(chunk, "chunk"); return withChunk(chunk.getPosition()); } @@ -259,7 +259,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont } @Override - public TileStack withTS(GenericTileStack tileStack) { + public TileStack withTS(TileGenericStackRO tileStack) { Objects.requireNonNull(tileStack, "tileStack"); return withBlock( @@ -324,7 +324,7 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont final int minX = Coordinates.getInWorld(chunk.x, 0); final int minY = Coordinates.getInWorld(chunk.y, 0); final int minZ = Coordinates.getInWorld(chunk.z, 0); - final int size = ChunkData.BLOCKS_PER_CHUNK; + final int size = DefaultChunkData.BLOCKS_PER_CHUNK; for (v.x = minX; v.x < minX + size; ++v.x) { for (v.y = minY; v.y < minY + size; ++v.y) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index d0b9562..fc22047 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; @@ -37,7 +37,7 @@ public class UpdateTriggerer implements ChunkDataListener { @Override public void onChunkBlockChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current @@ -47,7 +47,7 @@ public class UpdateTriggerer implements ChunkDataListener { @Override public void onChunkTilesChanged( - ChunkData chunk, + DefaultChunkData chunk, Vec3i blockInChunk, RelFace face, TileData tile, diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index d080551..7028573 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -25,12 +25,12 @@ import java.util.Map; import glm.Glm; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListeners; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.GenericWorld; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.generation.WorldGenerator; @@ -41,20 +41,20 @@ import ru.windcorp.progressia.server.world.tile.TileLogicReference; import ru.windcorp.progressia.server.world.tile.TileLogicStack; public class WorldLogic - implements GenericWorld { - private final WorldData data; + private final DefaultWorldData data; private final Server server; private final WorldGenerator generator; - private final Map chunks = new HashMap<>(); + private final Map chunks = new HashMap<>(); private final Evaluation tickEntitiesTask = new TickEntitiesTask(); - public WorldLogic(WorldData data, Server server, WorldGenerator generator) { + public WorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) { this.data = data; this.server = server; @@ -63,12 +63,12 @@ public class WorldLogic data.addListener(new WorldDataListener() { @Override - public void onChunkLoaded(WorldData world, ChunkData chunk) { + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { chunks.put(chunk, new ChunkLogic(WorldLogic.this, chunk)); } @Override - public void beforeChunkUnloaded(WorldData world, ChunkData chunk) { + public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { chunks.remove(chunk); } }); @@ -104,7 +104,7 @@ public class WorldLogic return server; } - public WorldData getData() { + public DefaultWorldData getData() { return data; } @@ -112,8 +112,8 @@ public class WorldLogic return generator; } - public ChunkData generate(Vec3i chunkPos) { - ChunkData chunk = getGenerator().generate(chunkPos); + public DefaultChunkData generate(Vec3i chunkPos) { + DefaultChunkData chunk = getGenerator().generate(chunkPos); if (!Glm.equals(chunkPos, chunk.getPosition())) { throw CrashReports.report(null, "Generator %s has generated a chunk at (%d; %d; %d) when requested to generate a chunk at (%d; %d; %d)", @@ -147,7 +147,7 @@ public class WorldLogic return chunk; } - public ChunkLogic getChunk(ChunkData chunkData) { + public ChunkLogic getChunk(DefaultChunkData chunkData) { return chunks.get(chunkData); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index fdc35e2..1d08194 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -19,10 +19,10 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericBlock; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; -public class BlockLogic extends Namespaced implements GenericBlock { +public class BlockLogic extends Namespaced implements BlockGeneric { public BlockLogic(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index e765d85..bd244a0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -23,11 +23,11 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.Objects; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.GravityModelRegistry; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.WorldLogic; @@ -71,11 +71,11 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { protected abstract boolean checkIsChunkReady(H hint); - protected H getHint(ChunkData chunk) { + protected H getHint(DefaultChunkData chunk) { return hintClass.cast(chunk.getGenerationHint()); } - protected void setHint(ChunkData chunk, H hint) { + protected void setHint(DefaultChunkData chunk, H hint) { chunk.setGenerationHint(hint); } @@ -95,7 +95,7 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { } @Override - public WorldData getWorldData() { + public DefaultWorldData getWorldData() { return server.getWorld().getData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index f05674d..a7c9753 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -25,10 +25,10 @@ import java.io.IOException; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.WorldLogic; @@ -39,7 +39,7 @@ public abstract class WorldGenerator extends Namespaced { // package-private constructor; extend AbstractWorldGeneration } - public abstract ChunkData generate(Vec3i chunkPos); + public abstract DefaultChunkData generate(Vec3i chunkPos); public abstract Object readGenerationHint(DataInputStream input) throws IOException, DecodingException; @@ -53,6 +53,6 @@ public abstract class WorldGenerator extends Namespaced { public abstract Server getServer(); public abstract WorldLogic getWorldLogic(); - public abstract WorldData getWorldData(); + public abstract DefaultWorldData getWorldData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index 186fa55..df92442 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -27,9 +27,9 @@ import com.google.common.collect.ImmutableList; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatMathUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; @@ -40,13 +40,13 @@ import ru.windcorp.progressia.server.world.ticking.TickingPolicy; import ru.windcorp.progressia.server.world.tile.TSTickContext; import ru.windcorp.progressia.server.world.tile.TickableTile; import ru.windcorp.progressia.server.world.tile.TileLogic; -import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; public class TickChunk extends Evaluation { - private static final int CHUNK_VOLUME = ChunkData.BLOCKS_PER_CHUNK * - ChunkData.BLOCKS_PER_CHUNK * - ChunkData.BLOCKS_PER_CHUNK; + private static final int CHUNK_VOLUME = DefaultChunkData.BLOCKS_PER_CHUNK * + DefaultChunkData.BLOCKS_PER_CHUNK * + DefaultChunkData.BLOCKS_PER_CHUNK; private final List> randomTickMethods; diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java index 7d58d6d..25dc4db 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java @@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableList; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.ChunkDataListener; import ru.windcorp.progressia.common.world.ChunkDataListeners; import ru.windcorp.progressia.server.Server; @@ -105,7 +105,7 @@ public class TickerCoordinator { server.getWorld().getData().addListener(ChunkDataListeners.createAdder(new ChunkDataListener() { @Override - public void onChunkChanged(ChunkData chunk) { + public void onChunkChanged(DefaultChunkData chunk) { if (!canChange.get()) { throw CrashReports.report(null, "A change has been detected during evaluation phase"); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index e965ffb..4272919 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -22,9 +22,9 @@ import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.block.BlockTickContext; @@ -54,7 +54,7 @@ public interface TSTickContext extends BlockTickContext { } default TileDataStack getTDSOrNull() { - ChunkData chunkData = getChunkData(); + DefaultChunkData chunkData = getChunkData(); if (chunkData == null) return null; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java index 2bd43f5..67466b5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -19,10 +19,10 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.generic.GenericTile; +import ru.windcorp.progressia.common.world.generic.TileGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; -public class TileLogic extends Namespaced implements GenericTile { +public class TileLogic extends Namespaced implements TileGeneric { public TileLogic(String id) { super(id); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java index 97bf35c..36d4c2d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java @@ -17,11 +17,11 @@ */ package ru.windcorp.progressia.server.world.tile; -import ru.windcorp.progressia.common.world.generic.GenericTileReference; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.block.BlockLogic; public interface TileLogicReference - extends GenericTileReference { + extends TileGenericReferenceRO { } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java index b38a6f6..83d7d9a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java @@ -18,13 +18,16 @@ package ru.windcorp.progressia.server.world.tile; -import ru.windcorp.progressia.common.world.generic.GenericTileStack; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import java.util.AbstractList; + +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.block.BlockLogic; public abstract class TileLogicStack - extends GenericTileStack { + extends AbstractList + implements TileGenericStackRO { public abstract TileDataStack getData(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java index 7e7ae88..c3003d8 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java @@ -19,8 +19,8 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataStack; -import ru.windcorp.progressia.common.world.tile.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataReference; public interface TileTickContext extends TSTickContext { diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index caba6ea..f4e81c5 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -33,9 +33,9 @@ import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TObjectIntHashMap; import ru.windcorp.jputil.functions.ThrowingConsumer; import ru.windcorp.progressia.common.state.IOContext; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.generic.GenericChunks; @@ -76,7 +76,7 @@ public class TestChunkCodec extends ChunkCodec { } @Override - public boolean shouldEncode(ChunkData chunk, IOContext context) { + public boolean shouldEncode(DefaultChunkData chunk, IOContext context) { return true; } @@ -85,13 +85,13 @@ public class TestChunkCodec extends ChunkCodec { */ @Override - public ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) + public DefaultChunkData decode(DefaultWorldData world, Vec3i position, DataInputStream input, IOContext context) throws DecodingException, IOException { BlockData[] blockPalette = readBlockPalette(input); TileData[] tilePalette = readTilePalette(input); - ChunkData chunk = new ChunkData(position, world); + DefaultChunkData chunk = new DefaultChunkData(position, world); readBlocks(input, blockPalette, chunk); readTiles(input, tilePalette, chunk); @@ -121,7 +121,7 @@ public class TestChunkCodec extends ChunkCodec { return palette; } - private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException { + private void readBlocks(DataInput input, BlockData[] blockPalette, DefaultChunkData chunk) throws IOException { try { GenericChunks.forEachBiC(guard(v -> { chunk.setBlock(v, blockPalette[input.readInt()], false); @@ -131,7 +131,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void readTiles(DataInput input, TileData[] tilePalette, ChunkData chunk) throws IOException { + private void readTiles(DataInput input, TileData[] tilePalette, DefaultChunkData chunk) throws IOException { Vec3i bic = new Vec3i(); while (true) { @@ -157,7 +157,7 @@ public class TestChunkCodec extends ChunkCodec { */ @Override - public void encode(ChunkData chunk, DataOutputStream output, IOContext context) throws IOException { + public void encode(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException { Palette blockPalette = createBlockPalette(chunk); Palette tilePalette = createTilePalette(chunk); @@ -168,13 +168,13 @@ public class TestChunkCodec extends ChunkCodec { writeTiles(chunk, tilePalette, output); } - private Palette createBlockPalette(ChunkData chunk) { + private Palette createBlockPalette(DefaultChunkData chunk) { Palette blockPalette = new Palette<>(); GenericChunks.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); return blockPalette; } - private Palette createTilePalette(ChunkData chunk) { + private Palette createTilePalette(DefaultChunkData chunk) { Palette tilePalette = new Palette<>(); chunk.forEachTile((ts, t) -> tilePalette.add(t)); return tilePalette; @@ -196,7 +196,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void writeBlocks(ChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { + private void writeBlocks(DefaultChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { try { GenericChunks.forEachBiC(guard(v -> { output.writeInt(blockPalette.getNid(chunk.getBlock(v))); @@ -206,7 +206,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void writeTiles(ChunkData chunk, Palette tilePalette, DataOutput output) throws IOException { + private void writeTiles(DefaultChunkData chunk, Palette tilePalette, DataOutput output) throws IOException { Vec3i bic = new Vec3i(); try { diff --git a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java index 97a0d99..ebfafde 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java +++ b/src/main/java/ru/windcorp/progressia/test/TestWorldDiskIO.java @@ -34,9 +34,9 @@ import org.apache.logging.log4j.Logger; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.state.IOContext; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.io.ChunkIO; import ru.windcorp.progressia.server.Server; @@ -47,7 +47,7 @@ public class TestWorldDiskIO { private static final boolean ENABLE = false; - public static void saveChunk(ChunkData chunk, Server server) { + public static void saveChunk(DefaultChunkData chunk, Server server) { if (!ENABLE) return; @@ -83,12 +83,12 @@ public class TestWorldDiskIO { } } - private static void writeGenerationHint(ChunkData chunk, DataOutputStream output, Server server) + private static void writeGenerationHint(DefaultChunkData chunk, DataOutputStream output, Server server) throws IOException { server.getWorld().getGenerator().writeGenerationHint(output, chunk.getGenerationHint()); } - public static ChunkData tryToLoad(Vec3i chunkPos, WorldData world, Server server) { + public static DefaultChunkData tryToLoad(Vec3i chunkPos, DefaultWorldData world, Server server) { if (!ENABLE) return null; @@ -113,7 +113,7 @@ public class TestWorldDiskIO { } try { - ChunkData result = load(path, chunkPos, world, server); + DefaultChunkData result = load(path, chunkPos, world, server); LOG.debug( "Loaded {} {} {}", @@ -135,7 +135,7 @@ public class TestWorldDiskIO { } } - private static ChunkData load(Path path, Vec3i chunkPos, WorldData world, Server server) + private static DefaultChunkData load(Path path, Vec3i chunkPos, DefaultWorldData world, Server server) throws IOException, DecodingException { try ( @@ -143,13 +143,13 @@ public class TestWorldDiskIO { new InflaterInputStream(new BufferedInputStream(Files.newInputStream(path))) ) ) { - ChunkData chunk = ChunkIO.load(world, chunkPos, input, IOContext.SAVE); + DefaultChunkData chunk = ChunkIO.load(world, chunkPos, input, IOContext.SAVE); readGenerationHint(chunk, input, server); return chunk; } } - private static void readGenerationHint(ChunkData chunk, DataInputStream input, Server server) + private static void readGenerationHint(DefaultChunkData chunk, DataInputStream input, Server server) throws IOException, DecodingException { chunk.setGenerationHint(server.getWorld().getGenerator().readGenerationHint(input)); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java index 74e3335..21c1809 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java @@ -19,12 +19,12 @@ package ru.windcorp.progressia.test.gen; import java.util.Random; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; @FunctionalInterface public interface TerrainLayer { - BlockData get(float north, float west, float depth, Random random, ChunkData chunk); + BlockData get(float north, float west, float depth, Random random, DefaultChunkData chunk); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index e8c8641..75d4eb0 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -27,10 +27,10 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.WorldDataListener; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; @@ -50,7 +50,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { getWorldData().addListener(new WorldDataListener() { @Override - public void onChunkLoaded(WorldData world, ChunkData chunk) { + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { findAndPopulate(chunk.getPosition(), world); } }); @@ -77,17 +77,17 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } @Override - public ChunkData generate(Vec3i chunkPos) { - ChunkData chunk = generateUnpopulated(chunkPos, getWorldData()); + public DefaultChunkData generate(Vec3i chunkPos) { + DefaultChunkData chunk = generateUnpopulated(chunkPos, getWorldData()); getWorldData().addChunk(chunk); return chunk; } - private ChunkData generateUnpopulated(Vec3i chunkPos, WorldData world) { - ChunkData chunk = new ChunkData(chunkPos, world); + private DefaultChunkData generateUnpopulated(Vec3i chunkPos, DefaultWorldData world) { + DefaultChunkData chunk = new DefaultChunkData(chunkPos, world); chunk.setGenerationHint(false); - final int bpc = ChunkData.BLOCKS_PER_CHUNK; + final int bpc = DefaultChunkData.BLOCKS_PER_CHUNK; Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z); BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); @@ -130,7 +130,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { return chunk; } - private void findAndPopulate(Vec3i changePos, WorldData world) { + private void findAndPopulate(Vec3i changePos, DefaultWorldData world) { VectorUtil.iterateCuboidAround(changePos, 3, candidatePos -> { if (canBePopulated(candidatePos, world)) { populate(candidatePos, world); @@ -138,10 +138,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { }); } - private boolean canBePopulated(Vec3i candidatePos, WorldData world) { + private boolean canBePopulated(Vec3i candidatePos, DefaultWorldData world) { Vec3i cursor = Vectors.grab3i(); - ChunkData candidate = world.getChunk(candidatePos); + DefaultChunkData candidate = world.getChunk(candidatePos); if (candidate == null || isChunkReady(candidate.getGenerationHint())) return false; @@ -156,7 +156,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { cursor.z = candidatePos.z + dz; - ChunkData chunk = world.getChunk(cursor); + DefaultChunkData chunk = world.getChunk(cursor); if (chunk == null) { return false; } @@ -169,10 +169,10 @@ public class TestWorldGenerator extends AbstractWorldGenerator { return true; } - private void populate(Vec3i chunkPos, WorldData world) { + private void populate(Vec3i chunkPos, DefaultWorldData world) { Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z); - ChunkData chunk = world.getChunk(chunkPos); + DefaultChunkData chunk = world.getChunk(chunkPos); assert chunk != null : "Something went wrong when populating chunk at (" + chunkPos.x + "; " + chunkPos.y + "; " + chunkPos.z + ")"; @@ -188,7 +188,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { int minZ = chunk.getMinZ(); int maxZ = chunk.getMaxZ() + 1; - final int bpc = ChunkData.BLOCKS_PER_CHUNK; + final int bpc = DefaultChunkData.BLOCKS_PER_CHUNK; double[][] heightMap = new double[bpc][bpc]; double[][] gradMap = new double[bpc][bpc]; @@ -226,9 +226,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } private void addTiles( - ChunkData chunk, + DefaultChunkData chunk, Vec3i biw, - WorldData world, + DefaultWorldData world, Random random, boolean isDirt, double height, @@ -240,7 +240,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { addSnow(chunk, biw, world, random, isDirt, height, grad); } - private void addGrass(ChunkData chunk, Vec3i biw, WorldData world, Random random) { + private void addGrass(DefaultChunkData chunk, Vec3i biw, DefaultWorldData world, Random random) { BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); @@ -260,7 +260,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } } - private void addDecor(ChunkData chunk, Vec3i biw, WorldData world, Random random, boolean isDirt) { + private void addDecor(DefaultChunkData chunk, Vec3i biw, DefaultWorldData world, Random random, boolean isDirt) { if (isDirt) { if (random.nextInt(8) == 0) { world.getTiles(biw, AbsFace.POS_Z).addFarthest( @@ -289,9 +289,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { } private void addSnow( - ChunkData chunk, + DefaultChunkData chunk, Vec3i biw, - WorldData world, + DefaultWorldData world, Random random, boolean isDirt, double height, diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java index 38b9d94..3637078 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java @@ -17,7 +17,7 @@ */ package ru.windcorp.progressia.test.gen.planet; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; public class Planet { @@ -47,7 +47,7 @@ public class Planet { } public float getRadius() { - return radiusInChunks * ChunkData.BLOCKS_PER_CHUNK + ChunkData.CHUNK_RADIUS; + return radiusInChunks * DefaultChunkData.BLOCKS_PER_CHUNK + DefaultChunkData.CHUNK_RADIUS; } public int getDiameterInChunks() { @@ -55,7 +55,7 @@ public class Planet { } public float getDiameter() { - return getDiameterInChunks() * ChunkData.BLOCKS_PER_CHUNK; + return getDiameterInChunks() * DefaultChunkData.BLOCKS_PER_CHUNK; } /** diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java index 6c14a2b..a33cb87 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java @@ -23,7 +23,7 @@ import java.util.Map; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.test.TestBushFeature; import ru.windcorp.progressia.test.TestGrassFeature; @@ -57,7 +57,7 @@ public class PlanetFeatureGenerator { return parent; } - public void generateFeatures(ChunkData chunk) { + public void generateFeatures(DefaultChunkData chunk) { if (isOrdinaryChunk(chunk.getPosition())) { generateOrdinaryFeatures(chunk); } else { @@ -72,11 +72,11 @@ public class PlanetFeatureGenerator { return sorted.x != sorted.y; } - private void generateOrdinaryFeatures(ChunkData chunk) { + private void generateOrdinaryFeatures(DefaultChunkData chunk) { surfaceGenerators.get(chunk.getUp()).generateFeatures(chunk); } - private void generateBorderFeatures(ChunkData chunk) { + private void generateBorderFeatures(DefaultChunkData chunk) { // Do nothing } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java index e8307cb..227187d 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java @@ -22,7 +22,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; import ru.windcorp.progressia.common.util.FloatRangeMap; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; @@ -40,7 +40,7 @@ class PlanetTerrainGenerator { this.parent = generator; SurfaceFloatField heightMap = new TestHeightMap( - generator.getPlanet().getRadius() - ChunkData.BLOCKS_PER_CHUNK, + generator.getPlanet().getRadius() - DefaultChunkData.BLOCKS_PER_CHUNK, generator.getPlanet().getRadius() / 4, 5, 6 @@ -61,8 +61,8 @@ class PlanetTerrainGenerator { return parent; } - public ChunkData generateTerrain(Vec3i chunkPos) { - ChunkData chunk = new ChunkData(chunkPos, getGenerator().getWorldData()); + public DefaultChunkData generateTerrain(Vec3i chunkPos) { + DefaultChunkData chunk = new DefaultChunkData(chunkPos, getGenerator().getWorldData()); if (isOrdinaryChunk(chunkPos)) { generateOrdinaryTerrain(chunk); @@ -80,11 +80,11 @@ class PlanetTerrainGenerator { return sorted.x != sorted.y; } - private void generateOrdinaryTerrain(ChunkData chunk) { + private void generateOrdinaryTerrain(DefaultChunkData chunk) { surfaceGenerator.generateTerrain(chunk); } - private void generateBorderTerrain(ChunkData chunk) { + private void generateBorderTerrain(DefaultChunkData chunk) { BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); @@ -100,7 +100,7 @@ class PlanetTerrainGenerator { Coordinates.getInWorld(chunk.getZ(), bic.z) ); - biw.sub(ChunkData.CHUNK_RADIUS - 0.5f); + biw.sub(DefaultChunkData.CHUNK_RADIUS - 0.5f); VectorUtil.sortAfterAbs(biw, biw); chunk.setBlock(bic, biw.x <= radius ? stone : air, false); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 1dbd5b8..8b92470 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -24,7 +24,7 @@ import java.io.IOException; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; @@ -76,9 +76,9 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { } @Override - public ChunkData generate(Vec3i chunkPos) { + public DefaultChunkData generate(Vec3i chunkPos) { VectorUtil.iterateCuboidAround(chunkPos, 3, r -> conjureTerrain(r)); - ChunkData chunk = getWorldData().getChunk(chunkPos); + DefaultChunkData chunk = getWorldData().getChunk(chunkPos); if (!isChunkReady(chunk.getGenerationHint())) { featureGenerator.generateFeatures(chunk); @@ -88,7 +88,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { } private void conjureTerrain(Vec3i chunkPos) { - ChunkData chunk = getWorldData().getChunk(chunkPos); + DefaultChunkData chunk = getWorldData().getChunk(chunkPos); if (chunk == null) { chunk = getWorldData().getChunk(chunkPos); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java index cb5fc34..a7fb334 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.test.gen.planet; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.rels.AbsFace; @@ -93,9 +93,9 @@ public class TestPlanetGravityModel extends GravityModel { float g = getSurfaceGravitationalAcceleration(); // Change to a CS where (0;0;0) is the center of the center chunk - float px = pos.x - ChunkData.CHUNK_RADIUS + 0.5f; - float py = pos.y - ChunkData.CHUNK_RADIUS + 0.5f; - float pz = pos.z - ChunkData.CHUNK_RADIUS + 0.5f; + float px = pos.x - DefaultChunkData.CHUNK_RADIUS + 0.5f; + float py = pos.y - DefaultChunkData.CHUNK_RADIUS + 0.5f; + float pz = pos.z - DefaultChunkData.CHUNK_RADIUS + 0.5f; // Assume weightlessness when too close to center if ((px*px + py*py + pz*pz) < r*r) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index 69e6d8b..0510d98 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -25,7 +25,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; public abstract class SurfaceFeature extends Namespaced { @@ -33,13 +33,13 @@ public abstract class SurfaceFeature extends Namespaced { public static class Request { private final SurfaceWorld world; - private final ChunkData chunk; + private final DefaultChunkData chunk; private final Vec3i minSfc = new Vec3i(); private final Vec3i maxSfc = new Vec3i(); private final Random random; - public Request(SurfaceWorld world, ChunkData chunk, Random random) { + public Request(SurfaceWorld world, DefaultChunkData chunk, Random random) { this.world = world; this.chunk = chunk; this.random = random; @@ -57,7 +57,7 @@ public abstract class SurfaceFeature extends Namespaced { maxSfc.z -= world.getSurface().getSeaLevel(); } - public ChunkData getChunk() { + public DefaultChunkData getChunk() { return chunk; } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java index 9a3c909..54b582e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java @@ -22,7 +22,7 @@ import java.util.Collection; import java.util.Random; import ru.windcorp.progressia.common.util.CoordinatePacker; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; public class SurfaceFeatureGenerator { @@ -42,7 +42,7 @@ public class SurfaceFeatureGenerator { return surface; } - public void generateFeatures(ChunkData chunk) { + public void generateFeatures(DefaultChunkData chunk) { SurfaceWorld world = new SurfaceWorld(surface, chunk.getWorld()); Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java index b05df5a..ec93d58 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java @@ -23,7 +23,7 @@ import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.util.FloatRangeMap; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.test.gen.TerrainLayer; @@ -38,35 +38,38 @@ public class SurfaceTerrainGenerator { this.layers = layers; } - public void generateTerrain(ChunkData chunk) { + public void generateTerrain(DefaultChunkData chunk) { Vec3i relBIC = new Vec3i(); Vec3 offset = new Vec3(chunk.getMinX(), chunk.getMinY(), chunk.getMinZ()); AxisRotations.relativize(offset, chunk.getUp(), offset); - offset.sub(ChunkData.CHUNK_RADIUS - 0.5f); + offset.sub(DefaultChunkData.CHUNK_RADIUS - 0.5f); Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); - for (relBIC.x = 0; relBIC.x < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.x) { - for (relBIC.y = 0; relBIC.y < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.y) { + for (relBIC.x = 0; relBIC.x < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.x) { + for (relBIC.y = 0; relBIC.y < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.y) { generateColumn(chunk, relBIC, offset, random); } } } - public void generateColumn(ChunkData chunk, Vec3i relBIC, Vec3 offset, Random random) { + public void generateColumn(DefaultChunkData chunk, Vec3i relBIC, Vec3 offset, Random random) { float north = relBIC.x + offset.x; float west = relBIC.y + offset.y; float relSurface = heightMap.get(chunk.getUp(), north, west) - offset.z; - for (relBIC.z = 0; relBIC.z < ChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { + for (relBIC.z = 0; relBIC.z < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { float depth = relSurface - relBIC.z; BlockData block = layers.get(depth).get(north, west, depth, random, chunk); - chunk.setBlockRel(relBIC, block, false); + + chunk.resolve(relBIC, relBIC); + chunk.setBlock(relBIC, block, false); + chunk.relativize(relBIC, relBIC); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java index 12ff59a..7d3ec10 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java @@ -20,26 +20,29 @@ package ru.windcorp.progressia.test.gen.surface; import java.util.Collection; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.generic.GenericWritableWorld; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataReference; -import ru.windcorp.progressia.common.world.tile.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.WorldData; public class SurfaceWorld - implements GenericWritableWorld { + implements WorldData { private final Surface surface; - private final GenericWritableWorld parent; + private final WorldData parent; public SurfaceWorld( Surface surface, - GenericWritableWorld parent + WorldData parent ) { this.surface = surface; this.parent = parent; @@ -55,7 +58,7 @@ public class SurfaceWorld /** * @return the parent */ - public GenericWritableWorld getParent() { + public WorldData getParent() { return parent; } @@ -64,7 +67,7 @@ public class SurfaceWorld */ @Override - public Collection getChunks() { + public Collection getChunks() { return parent.getChunks(); } @@ -179,4 +182,24 @@ public class SurfaceWorld return result; } + @Override + public float getTime() { + return parent.getTime(); + } + + @Override + public GravityModel getGravityModel() { + return parent.getGravityModel(); + } + + @Override + public void changeEntity(SE entity, StateChange change) { + parent.changeEntity(entity, change); + } + + @Override + public void advanceTime(float change) { + parent.advanceTime(change); + } + } From a338a00f1d83c1ec36130ac5a80bcf72f168d046 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sat, 31 Jul 2021 16:01:25 +0300 Subject: [PATCH 36/63] A change to the class hierarchy of WorldLogic similar to prev commit - Renamed ChunkLogic -> DefaultChunkLogic, WorldLogic -> DefaultWorldLogic - Created/rewritten TileLogicReference{,RO}, TileLogicStack{,RO}, ChunkLogic{,RO} - Drafted up something for ServerWorldContext & friends, WIP (see commit 9a32660 for more details) --- .../progressia/common/world/ChunkData.java | 8 +- .../common/world/DefaultChunkData.java | 6 +- .../common/world/generic/ChunkGenericRO.java | 2 +- .../world/generic/TileGenericReferenceRO.java | 49 +++- .../ru/windcorp/progressia/server/Server.java | 10 +- .../progressia/server/world/ChunkLogic.java | 225 +--------------- .../progressia/server/world/ChunkLogicRO.java | 15 ++ .../server/world/ChunkTickContext.java | 4 +- .../server/world/DefaultChunkLogic.java | 249 ++++++++++++++++++ .../server/world/DefaultWorldLogic.java | 146 ++++++++++ .../server/world/TickAndUpdateUtil.java | 12 +- .../progressia/server/world/TickContext.java | 2 +- .../server/world/TickContextMutable.java | 4 +- .../server/world/TileLogicReference.java | 44 ++++ .../server/world/TileLogicReferenceRO.java | 82 ++++++ .../server/world/TileLogicStack.java | 37 +++ ...eLogicStack.java => TileLogicStackRO.java} | 15 +- .../progressia/server/world/WorldLogic.java | 134 ++-------- ...eLogicReference.java => WorldLogicRO.java} | 11 +- .../world/context/ServerWorldContext.java | 35 +++ .../world/context/ServerWorldContextRO.java | 16 ++ .../generation/AbstractWorldGenerator.java | 4 +- .../world/generation/WorldGenerator.java | 4 +- .../world/tasks/BlockTriggeredUpdate.java | 4 +- .../server/world/tasks/TickChunk.java | 6 +- .../world/tasks/TileTriggeredUpdate.java | 4 +- .../server/world/tile/TSTickContext.java | 9 +- .../server/world/tile/TileTickContext.java | 3 +- .../test/gen/TestTerrainGenerator.java | 4 +- 29 files changed, 754 insertions(+), 390 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/ChunkLogicRO.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/TileLogicReference.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/TileLogicReferenceRO.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/TileLogicStack.java rename src/main/java/ru/windcorp/progressia/server/world/{tile/TileLogicStack.java => TileLogicStackRO.java} (67%) rename src/main/java/ru/windcorp/progressia/server/world/{tile/TileLogicReference.java => WorldLogicRO.java} (67%) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index ab55863..fe84518 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -4,11 +4,9 @@ import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.generic.ChunkGenericWO; import ru.windcorp.progressia.common.world.tile.TileData; -public interface ChunkData extends ChunkDataRO, ChunkGenericWO { +public interface ChunkData + extends ChunkDataRO, ChunkGenericWO { -// @Override -// default TileDataStack getTiles(Vec3i blockInChunk, BlockFace face) { -// return null; -// } + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java index 5c1cd08..e11509b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/DefaultChunkData.java @@ -37,6 +37,10 @@ import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileStackIsFullException; +/** + * The implementation of {@link ChunkData} used to store the actual game world. + * This class should be considered an implementation detail. + */ public class DefaultChunkData implements ChunkData { public static final int BLOCKS_PER_CHUNK = Coordinates.CHUNK_SIZE; @@ -222,7 +226,7 @@ public class DefaultChunkData implements ChunkData { } public void invalidate() { - this.index = 0; + this.index = -1; } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java index 56482b5..cd648c5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/ChunkGenericRO.java @@ -34,7 +34,7 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * An unmodifiable chunk representation. Per default, it is usually one of * {@link ru.windcorp.progressia.common.world.DefaultChunkData ChunkData}, * {@link ru.windcorp.progressia.client.world.ChunkRender ChunkRender} or - * {@link ru.windcorp.progressia.server.world.ChunkLogic ChunkLogic}, but this + * {@link ru.windcorp.progressia.server.world.DefaultChunkLogic ChunkLogic}, but this * interface may be implemented differently for various reasons. *

      * A generic chunk contains {@linkplain BlockGeneric blocks} and diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java index 64f7cfb..6f49630 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/TileGenericReferenceRO.java @@ -18,6 +18,16 @@ package ru.windcorp.progressia.common.world.generic; +/** + * A reference to a single tile in a tile stack. A {@code TileReference} remains + * valid until the tile is removed from its stack. + *

      + * Tile reference objects may be reused for other tiles; {@link #isValid()} only + * shows if there exists some tile that this object references; it may + * or may not be the tile this reference was acquired for. It is the + * responsibility of the programmer to discard references when the tile is + * removed. + */ // @formatter:off public interface TileGenericReferenceRO< B extends BlockGeneric, @@ -28,16 +38,49 @@ public interface TileGenericReferenceRO< > { // @formatter:on - T get(); - + /** + * Gets the index that the referenced tile currently occupies. This value + * may change as tiles are added to or removed from the stack. + * + * @return the index of the tile or {@code -1} if this reference is invalid + */ int getIndex(); + /** + * Gets the tile stack that contains the referenced tile. + * + * @return the tile stack of the relevant tile or {@code null} if this + * reference is invalid. + */ TS getStack(); + /** + * Gets the tile that this object references. + * + * @return the relevant tile or {@code null} if this reference is invalid + */ + default T get() { + return getStack().get(getIndex()); + } + + /** + * Checks whether this reference is valid. A reference is valid if it points + * to some tile; it may or may not be the tile that this reference + * was acquired for. (A tile reference can only change the referenced tile + * after the previous tile is removed from the stack.) + * + * @return {@code true} iff there exists a tile that this reference points + * to. + */ default boolean isValid() { return get() != null; } - + + /** + * Gets the tag of the referenced tile. + * + * @return the tag or {@code -1} iff this reference is invalid. + */ default int getTag() { TS tileStack = getStack(); if (tileStack == null) { diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 9da227f..0896caa 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -34,7 +34,7 @@ import ru.windcorp.progressia.server.events.ServerEvent; import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon; import ru.windcorp.progressia.server.management.load.EntityRequestDaemon; import ru.windcorp.progressia.server.management.load.LoadManager; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.DefaultWorldLogic; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; @@ -53,7 +53,7 @@ public class Server { return ServerThread.getCurrentServer(); } - private final WorldLogic world; + private final DefaultWorldLogic world; private final WorldAccessor worldAccessor = new WorldAccessor(this); private final ServerThread serverThread; @@ -69,7 +69,7 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); public Server(DefaultWorldData world) { - this.world = new WorldLogic( + this.world = new DefaultWorldLogic( world, this, new TestPlanetGenerator("Test:PlanetGenerator", this, new Planet(4, 9.8f, 16f, 16f)) @@ -91,9 +91,9 @@ public class Server { /** * Returns this server's world. * - * @return this server's {@link WorldLogic} + * @return this server's {@link DefaultWorldLogic} */ - public WorldLogic getWorld() { + public DefaultWorldLogic getWorld() { return world; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java index f633179..a9c3392 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogic.java @@ -15,230 +15,27 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package ru.windcorp.progressia.server.world; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.function.BiConsumer; - import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.server.world.block.BlockLogic; -import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; -import ru.windcorp.progressia.server.world.block.TickableBlock; -import ru.windcorp.progressia.server.world.tasks.TickChunk; -import ru.windcorp.progressia.server.world.ticking.TickingPolicy; -import ru.windcorp.progressia.server.world.tile.TickableTile; -import ru.windcorp.progressia.server.world.tile.TileLogic; -import ru.windcorp.progressia.server.world.tile.TileLogicReference; -import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; -import ru.windcorp.progressia.server.world.tile.TileLogicStack; -public class ChunkLogic implements ChunkGenericRO { +public interface ChunkLogic extends ChunkLogicRO { - private final WorldLogic world; - private final DefaultChunkData data; - - private final Collection tickingBlocks = new ArrayList<>(); - private final Collection tickingTiles = new ArrayList<>(); - - private final TickChunk tickTask = new TickChunk(this); - - private final Map tileLogicLists = Collections - .synchronizedMap(new WeakHashMap<>()); - - public ChunkLogic(WorldLogic world, DefaultChunkData data) { - this.world = world; - this.data = data; - - tmp_generateTickLists(); - } - - @Override - public Vec3i getPosition() { - return getData().getPosition(); - } + /* + * Override return type + */ @Override - public AbsFace getUp() { - return getData().getUp(); + ChunkData getData(); + + @Override + default TileLogicStack getTilesOrNull(Vec3i blockInChunk, BlockFace face) { + return (TileLogicStack) ChunkLogicRO.super.getTilesOrNull(blockInChunk, face); } @Override - public BlockLogic getBlock(Vec3i blockInChunk) { - return BlockLogicRegistry.getInstance().get( - getData().getBlock(blockInChunk).getId() - ); - } - - @Override - public TileLogicStack getTiles(Vec3i blockInChunk, BlockFace face) { - return getTileStackWrapper(getData().getTiles(blockInChunk, face)); - } - - @Override - public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { - return getData().hasTiles(blockInChunk, face); - } - - private TileLogicStack getTileStackWrapper(TileDataStack tileDataList) { - return tileLogicLists.computeIfAbsent( - tileDataList, - TileLogicStackImpl::new - ); - } - - public WorldLogic getWorld() { - return world; - } - - public DefaultChunkData getData() { - return data; - } - - public boolean isReady() { - return getWorld().getGenerator().isChunkReady(getData().getGenerationHint()); - } - - public boolean hasTickingBlocks() { - return !tickingBlocks.isEmpty(); - } - - public boolean hasTickingTiles() { - return !tickingTiles.isEmpty(); - } - - public void forEachTickingBlock(BiConsumer action) { - tickingBlocks.forEach(blockInChunk -> { - action.accept(blockInChunk, getBlock(blockInChunk)); - }); - } - - public void forEachTickingTile(BiConsumer action) { - tickingTiles.forEach(ref -> { - action.accept( - ref, - TileLogicRegistry.getInstance().get(ref.get().getId()) - ); - }); - } - - public TickChunk getTickTask() { - return tickTask; - } - - private class TileLogicStackImpl extends TileLogicStack { - private class TileLogicReferenceImpl implements TileLogicReference { - private final TileDataReference parent; - - public TileLogicReferenceImpl (TileDataReference parent) { - this.parent = parent; - } - - @Override - public TileLogic get() { - return TileLogicRegistry.getInstance().get(parent.get().getId()); - } - - @Override - public int getIndex() { - return parent.getIndex(); - } - - @Override - public TileLogicStack getStack() { - return TileLogicStackImpl.this; - } - } - - private final TileDataStack parent; - - public TileLogicStackImpl(TileDataStack parent) { - this.parent = parent; - } - - @Override - public Vec3i getBlockInChunk(Vec3i output) { - return parent.getBlockInChunk(output); - } - - @Override - public ChunkLogic getChunk() { - return ChunkLogic.this; - } - - @Override - public RelFace getFace() { - return parent.getFace(); - } - - @Override - public TileLogicReference getReference(int index) { - return new TileLogicReferenceImpl(parent.getReference(index)); - } - - @Override - public int getIndexByTag(int tag) { - return parent.getIndexByTag(tag); - } - - @Override - public int getTagByIndex(int index) { - return parent.getTagByIndex(index); - } - - @Override - public TileLogic get(int index) { - return TileLogicRegistry.getInstance().get(parent.get(index).getId()); - } - - @Override - public int size() { - return parent.size(); - } - - @Override - public TileDataStack getData() { - return parent; - } - - } - - private void tmp_generateTickLists() { - ChunkTickContext context = TickContextMutable.start().withChunk(this).build(); - - context.forEachBlock(bctxt -> { - BlockLogic block = bctxt.getBlock(); - - if (!(block instanceof TickableBlock)) - return; - - if (((TickableBlock) block).getTickingPolicy(bctxt) == TickingPolicy.REGULAR) { - tickingBlocks.add(Coordinates.convertInWorldToInChunk(bctxt.getBlockInWorld(), null)); - } - - bctxt.forEachFace(fctxt -> fctxt.forEachTile(tctxt -> { - TileLogic tile = tctxt.getTile(); - - if (!(tile instanceof TickableTile)) - return; - - if (((TickableTile) tile).getTickingPolicy(tctxt) == TickingPolicy.REGULAR) { - tickingTiles.add(tctxt.getReference()); - } - })); - }); - } + TileLogicStack getTiles(Vec3i blockInChunk, BlockFace face); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkLogicRO.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogicRO.java new file mode 100644 index 0000000..5631027 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkLogicRO.java @@ -0,0 +1,15 @@ +package ru.windcorp.progressia.server.world; + +import ru.windcorp.progressia.common.world.ChunkDataRO; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; + +public interface ChunkLogicRO + extends ChunkGenericRO { + + ChunkDataRO getData(); + + boolean isReady(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java index 09cf0e6..aec68fe 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java @@ -30,12 +30,12 @@ public interface ChunkTickContext extends TickContext { Vec3i getChunk(); - default ChunkLogic getChunkLogic() { + default DefaultChunkLogic getChunkLogic() { return getWorld().getChunk(getChunk()); } default DefaultChunkData getChunkData() { - ChunkLogic chunkLogic = getChunkLogic(); + DefaultChunkLogic chunkLogic = getChunkLogic(); return chunkLogic == null ? null : chunkLogic.getData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java new file mode 100644 index 0000000..69fed5e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java @@ -0,0 +1,249 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.server.world; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.function.BiConsumer; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; +import ru.windcorp.progressia.server.world.block.TickableBlock; +import ru.windcorp.progressia.server.world.tasks.TickChunk; +import ru.windcorp.progressia.server.world.ticking.TickingPolicy; +import ru.windcorp.progressia.server.world.tile.TickableTile; +import ru.windcorp.progressia.server.world.tile.TileLogic; +import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; + +public class DefaultChunkLogic implements ChunkLogic { + + private final DefaultWorldLogic world; + private final DefaultChunkData data; + + private final Collection tickingBlocks = new ArrayList<>(); + private final Collection tickingTiles = new ArrayList<>(); + + private final TickChunk tickTask = new TickChunk(this); + + private final Map tileLogicLists = Collections + .synchronizedMap(new WeakHashMap<>()); + + public DefaultChunkLogic(DefaultWorldLogic world, DefaultChunkData data) { + this.world = world; + this.data = data; + + tmp_generateTickLists(); + } + + @Override + public Vec3i getPosition() { + return getData().getPosition(); + } + + @Override + public AbsFace getUp() { + return getData().getUp(); + } + + @Override + public BlockLogic getBlock(Vec3i blockInChunk) { + return BlockLogicRegistry.getInstance().get( + getData().getBlock(blockInChunk).getId() + ); + } + + @Override + public TileLogicStack getTiles(Vec3i blockInChunk, BlockFace face) { + return getTileStackWrapper(getData().getTiles(blockInChunk, face)); + } + + @Override + public boolean hasTiles(Vec3i blockInChunk, BlockFace face) { + return getData().hasTiles(blockInChunk, face); + } + + private TileLogicStack getTileStackWrapper(TileDataStack tileDataList) { + return tileLogicLists.computeIfAbsent( + tileDataList, + TileLogicStackImpl::new + ); + } + + public DefaultWorldLogic getWorld() { + return world; + } + + @Override + public DefaultChunkData getData() { + return data; + } + + @Override + public boolean isReady() { + return getWorld().getGenerator().isChunkReady(getData().getGenerationHint()); + } + + public boolean hasTickingBlocks() { + return !tickingBlocks.isEmpty(); + } + + public boolean hasTickingTiles() { + return !tickingTiles.isEmpty(); + } + + public void forEachTickingBlock(BiConsumer action) { + tickingBlocks.forEach(blockInChunk -> { + action.accept(blockInChunk, getBlock(blockInChunk)); + }); + } + + public void forEachTickingTile(BiConsumer action) { + tickingTiles.forEach(ref -> { + action.accept( + ref, + TileLogicRegistry.getInstance().get(ref.get().getId()) + ); + }); + } + + public TickChunk getTickTask() { + return tickTask; + } + + private class TileLogicStackImpl extends AbstractList implements TileLogicStack { + private class TileLogicReferenceImpl implements TileLogicReference { + private final TileDataReference parent; + + public TileLogicReferenceImpl (TileDataReference parent) { + this.parent = parent; + } + + @Override + public TileDataReference getDataReference() { + return parent; + } + + @Override + public TileLogic get() { + return TileLogicRegistry.getInstance().get(parent.get().getId()); + } + + @Override + public int getIndex() { + return parent.getIndex(); + } + + @Override + public TileLogicStack getStack() { + return TileLogicStackImpl.this; + } + } + + private final TileDataStack parent; + + public TileLogicStackImpl(TileDataStack parent) { + this.parent = parent; + } + + @Override + public Vec3i getBlockInChunk(Vec3i output) { + return parent.getBlockInChunk(output); + } + + @Override + public DefaultChunkLogic getChunk() { + return DefaultChunkLogic.this; + } + + @Override + public RelFace getFace() { + return parent.getFace(); + } + + @Override + public TileLogicReference getReference(int index) { + return new TileLogicReferenceImpl(parent.getReference(index)); + } + + @Override + public int getIndexByTag(int tag) { + return parent.getIndexByTag(tag); + } + + @Override + public int getTagByIndex(int index) { + return parent.getTagByIndex(index); + } + + @Override + public TileLogic get(int index) { + return TileLogicRegistry.getInstance().get(parent.get(index).getId()); + } + + @Override + public int size() { + return parent.size(); + } + + @Override + public TileDataStack getData() { + return parent; + } + + } + + private void tmp_generateTickLists() { + ChunkTickContext context = TickContextMutable.start().withChunk(this).build(); + + context.forEachBlock(bctxt -> { + BlockLogic block = bctxt.getBlock(); + + if (!(block instanceof TickableBlock)) + return; + + if (((TickableBlock) block).getTickingPolicy(bctxt) == TickingPolicy.REGULAR) { + tickingBlocks.add(Coordinates.convertInWorldToInChunk(bctxt.getBlockInWorld(), null)); + } + + bctxt.forEachFace(fctxt -> fctxt.forEachTile(tctxt -> { + TileLogic tile = tctxt.getTile(); + + if (!(tile instanceof TickableTile)) + return; + + if (((TickableTile) tile).getTickingPolicy(tctxt) == TickingPolicy.REGULAR) { + tickingTiles.add(tctxt.getReference()); + } + })); + }); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java new file mode 100644 index 0000000..e38559d --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java @@ -0,0 +1,146 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.server.world; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import glm.Glm; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.crash.CrashReports; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.ChunkDataListeners; +import ru.windcorp.progressia.common.world.DefaultWorldData; +import ru.windcorp.progressia.common.world.WorldDataListener; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.generation.WorldGenerator; +import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask; +import ru.windcorp.progressia.server.world.ticking.Evaluation; + +public class DefaultWorldLogic implements WorldLogic { + + private final DefaultWorldData data; + private final Server server; + + private final WorldGenerator generator; + + private final Map chunks = new HashMap<>(); + + private final Evaluation tickEntitiesTask = new TickEntitiesTask(); + + public DefaultWorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) { + this.data = data; + this.server = server; + + this.generator = generator; + data.setGravityModel(getGenerator().getGravityModel()); + + data.addListener(new WorldDataListener() { + @Override + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { + chunks.put(chunk, new DefaultChunkLogic(DefaultWorldLogic.this, chunk)); + } + + @Override + public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { + chunks.remove(chunk); + } + }); + + data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server))); + } + + @Override + public DefaultChunkLogic getChunk(Vec3i pos) { + return chunks.get(getData().getChunk(pos)); + } + + @Override + public Collection getChunks() { + return chunks.values(); + } + + @Override + public Collection getEntities() { + return getData().getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return getData().getEntity(entityId); + } + + public Evaluation getTickEntitiesTask() { + return tickEntitiesTask; + } + + public Server getServer() { + return server; + } + + public DefaultWorldData getData() { + return data; + } + + public WorldGenerator getGenerator() { + return generator; + } + + public DefaultChunkData generate(Vec3i chunkPos) { + DefaultChunkData chunk = getGenerator().generate(chunkPos); + + if (!Glm.equals(chunkPos, chunk.getPosition())) { + throw CrashReports.report(null, "Generator %s has generated a chunk at (%d; %d; %d) when requested to generate a chunk at (%d; %d; %d)", + getGenerator(), + chunk.getX(), chunk.getY(), chunk.getZ(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } + + if (getData().getChunk(chunk.getPosition()) != chunk) { + if (isChunkLoaded(chunkPos)) { + throw CrashReports.report(null, "Generator %s has returned a chunk different to the chunk that is located at (%d; %d; %d)", + getGenerator(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } else { + throw CrashReports.report(null, "Generator %s has returned a chunk that is not loaded when requested to generate a chunk at (%d; %d; %d)", + getGenerator(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } + } + + if (!getChunk(chunk).isReady()) { + throw CrashReports.report(null, "Generator %s has returned a chunk that is not ready when requested to generate a chunk at (%d; %d; %d)", + getGenerator(), + chunkPos.x, chunkPos.y, chunkPos.z + ); + } + + return chunk; + } + + public DefaultChunkLogic getChunk(DefaultChunkData chunkData) { + return chunks.get(chunkData); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index 9f8f265..fd3e0ec 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -44,7 +44,7 @@ public class TickAndUpdateUtil { } } - public static void tickBlock(WorldLogic world, Vec3i blockInWorld) { + public static void tickBlock(DefaultWorldLogic world, Vec3i blockInWorld) { BlockLogic block = world.getBlock(blockInWorld); if (!(block instanceof TickableBlock)) return; // also checks nulls @@ -61,7 +61,7 @@ public class TickAndUpdateUtil { } } - public static void tickTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { + public static void tickTile(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { TileLogic tile = world.getTile(blockInWorld, face, layer); if (!(tile instanceof TickableTile)) { return; @@ -72,7 +72,7 @@ public class TickAndUpdateUtil { tickTile((TickableTile) tile, tickContext); } - public static void tickTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { + public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { if (!world.isBlockLoaded(blockInWorld)) { return; } @@ -94,7 +94,7 @@ public class TickAndUpdateUtil { } } - public static void updateBlock(WorldLogic world, Vec3i blockInWorld) { + public static void updateBlock(DefaultWorldLogic world, Vec3i blockInWorld) { BlockLogic block = world.getBlock(blockInWorld); if (!(block instanceof UpdateableBlock)) return; // also checks nulls @@ -111,7 +111,7 @@ public class TickAndUpdateUtil { } } - public static void updateTile(WorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { + public static void updateTile(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { TileLogic tile = world.getTile(blockInWorld, face, layer); if (!(tile instanceof UpdateableTile)) { return; @@ -122,7 +122,7 @@ public class TickAndUpdateUtil { updateTile((UpdateableTile) tile, tickContext); } - public static void updateTiles(WorldLogic world, Vec3i blockInWorld, BlockFace face) { + public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { if (!world.isBlockLoaded(blockInWorld)) { return; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java index 9d59699..5d92f4a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java @@ -30,7 +30,7 @@ public interface TickContext { Server getServer(); - default WorldLogic getWorld() { + default DefaultWorldLogic getWorld() { return getServer().getWorld(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java index d8ba535..a5eb592 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java @@ -93,12 +93,12 @@ public abstract class TickContextMutable implements BlockTickContext, TSTickCont public static interface Empty /* does not extend Builder */ { World withServer(Server server); - default Builder.World withWorld(WorldLogic world) { + default Builder.World withWorld(DefaultWorldLogic world) { Objects.requireNonNull(world, "world"); return withServer(world.getServer()); } - default Builder.Chunk withChunk(ChunkLogic chunk) { + default Builder.Chunk withChunk(DefaultChunkLogic chunk) { Objects.requireNonNull(chunk, "chunk"); return withWorld(chunk.getWorld()).withChunk(chunk.getPosition()); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TileLogicReference.java b/src/main/java/ru/windcorp/progressia/server/world/TileLogicReference.java new file mode 100644 index 0000000..e56cffb --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/TileLogicReference.java @@ -0,0 +1,44 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world; + +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.world.tile.TileLogic; + +/** + * A read-only {@link TileGenericReferenceRO TileReference} for a + * {@link TileData} that provides convenient read-write access to the matching + * {@link TileLogic} instance. + *

      + * For all methods other than {@link #get()}, {@link #getStack()} and + * {@link #getDataReference()}, + * logicRef.method() == logicRef.getDataReference().method(). + */ +public interface TileLogicReference + extends TileLogicReferenceRO { + + /* + * Override return type + */ + + @Override + TileDataReference getDataReference(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/TileLogicReferenceRO.java b/src/main/java/ru/windcorp/progressia/server/world/TileLogicReferenceRO.java new file mode 100644 index 0000000..2a92764 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/TileLogicReferenceRO.java @@ -0,0 +1,82 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world; + +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataReferenceRO; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; + +/** + * A {@link TileGenericReferenceRO TileReference} for a {@link TileData} that + * provides convenient access to the matching {@link TileLogic} instance. + *

      + * For all methods other than {@link #get()}, {@link #getStack()} and + * {@link #getDataReference()}, + * logicRef.method() == logicRef.getDataReference().method(). + */ +public interface TileLogicReferenceRO + extends TileGenericReferenceRO { + + /** + * Returns a reference to the {@link TileData} that this object references. + * + * @return a {@link TileDataReference} equivalent to this object + */ + TileDataReferenceRO getDataReference(); + + /** + * Returns the {@link TileData} that is referenced by this object, or + * {@code null} if the tile does not exist. + * + * @return the relevant {@link TileData} + */ + default TileData getData() { + return getDataReference().get(); + } + + /** + * {@inheritDoc} + * + * @see #getData() + */ + @Override + TileLogic get(); + + /* + * Refer to #getDataReference() by default + */ + + @Override + default int getIndex() { + return getDataReference().getIndex(); + } + + @Override + default int getTag() { + return getDataReference().getTag(); + } + + @Override + default boolean isValid() { + return getDataReference().isValid(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/TileLogicStack.java b/src/main/java/ru/windcorp/progressia/server/world/TileLogicStack.java new file mode 100644 index 0000000..3b8ef2f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/TileLogicStack.java @@ -0,0 +1,37 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world; + +import ru.windcorp.progressia.common.world.TileDataStack; + +public interface TileLogicStack extends TileLogicStackRO { + + /* + * Override return types + */ + + @Override + TileDataStack getData(); + + @Override + ChunkLogic getChunk(); + + @Override + TileLogicReference getReference(int index); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java b/src/main/java/ru/windcorp/progressia/server/world/TileLogicStackRO.java similarity index 67% rename from src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java rename to src/main/java/ru/windcorp/progressia/server/world/TileLogicStackRO.java index 83d7d9a..3561663 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicStack.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TileLogicStackRO.java @@ -15,20 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -package ru.windcorp.progressia.server.world.tile; -import java.util.AbstractList; +package ru.windcorp.progressia.server.world; -import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; -import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; -public abstract class TileLogicStack - extends AbstractList - implements TileGenericStackRO { +public interface TileLogicStackRO + extends TileGenericStackRO { - public abstract TileDataStack getData(); + public abstract TileDataStackRO getData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 7028573..0995ce4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -15,140 +15,38 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package ru.windcorp.progressia.server.world; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import glm.Glm; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.crash.CrashReports; -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.ChunkDataListeners; -import ru.windcorp.progressia.common.world.DefaultWorldData; -import ru.windcorp.progressia.common.world.WorldDataListener; -import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.WorldGenericRO; -import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.block.BlockLogic; -import ru.windcorp.progressia.server.world.generation.WorldGenerator; -import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask; -import ru.windcorp.progressia.server.world.ticking.Evaluation; -import ru.windcorp.progressia.server.world.tile.TileLogic; -import ru.windcorp.progressia.server.world.tile.TileLogicReference; -import ru.windcorp.progressia.server.world.tile.TileLogicStack; +import ru.windcorp.progressia.common.world.rels.BlockFace; -public class WorldLogic - implements WorldGenericRO { +public interface WorldLogic extends WorldLogicRO { - private final DefaultWorldData data; - private final Server server; + /* + * Override return types + */ - private final WorldGenerator generator; + @Override + ChunkLogic getChunk(Vec3i pos); - private final Map chunks = new HashMap<>(); + @Override + Collection getChunks(); - private final Evaluation tickEntitiesTask = new TickEntitiesTask(); - - public WorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) { - this.data = data; - this.server = server; - - this.generator = generator; - data.setGravityModel(getGenerator().getGravityModel()); - - data.addListener(new WorldDataListener() { - @Override - public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { - chunks.put(chunk, new ChunkLogic(WorldLogic.this, chunk)); - } - - @Override - public void beforeChunkUnloaded(DefaultWorldData world, DefaultChunkData chunk) { - chunks.remove(chunk); - } - }); - - data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server))); + @Override + default ChunkLogic getChunkByBlock(Vec3i blockInWorld) { + return (ChunkLogic) WorldLogicRO.super.getChunkByBlock(blockInWorld); } @Override - public ChunkLogic getChunk(Vec3i pos) { - return chunks.get(getData().getChunk(pos)); + default TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face) { + return (TileLogicStack) WorldLogicRO.super.getTiles(blockInWorld, face); } @Override - public Collection getChunks() { - return chunks.values(); - } - - @Override - public Collection getEntities() { - return getData().getEntities(); - } - - @Override - public EntityData getEntity(long entityId) { - return getData().getEntity(entityId); - } - - public Evaluation getTickEntitiesTask() { - return tickEntitiesTask; - } - - public Server getServer() { - return server; - } - - public DefaultWorldData getData() { - return data; - } - - public WorldGenerator getGenerator() { - return generator; - } - - public DefaultChunkData generate(Vec3i chunkPos) { - DefaultChunkData chunk = getGenerator().generate(chunkPos); - - if (!Glm.equals(chunkPos, chunk.getPosition())) { - throw CrashReports.report(null, "Generator %s has generated a chunk at (%d; %d; %d) when requested to generate a chunk at (%d; %d; %d)", - getGenerator(), - chunk.getX(), chunk.getY(), chunk.getZ(), - chunkPos.x, chunkPos.y, chunkPos.z - ); - } - - if (getData().getChunk(chunk.getPosition()) != chunk) { - if (isChunkLoaded(chunkPos)) { - throw CrashReports.report(null, "Generator %s has returned a chunk different to the chunk that is located at (%d; %d; %d)", - getGenerator(), - chunkPos.x, chunkPos.y, chunkPos.z - ); - } else { - throw CrashReports.report(null, "Generator %s has returned a chunk that is not loaded when requested to generate a chunk at (%d; %d; %d)", - getGenerator(), - chunkPos.x, chunkPos.y, chunkPos.z - ); - } - } - - if (!getChunk(chunk).isReady()) { - throw CrashReports.report(null, "Generator %s has returned a chunk that is not ready when requested to generate a chunk at (%d; %d; %d)", - getGenerator(), - chunkPos.x, chunkPos.y, chunkPos.z - ); - } - - return chunk; - } - - public ChunkLogic getChunk(DefaultChunkData chunkData) { - return chunks.get(chunkData); + default TileLogicStack getTilesOrNull(Vec3i blockInWorld, BlockFace face) { + return (TileLogicStack) WorldLogicRO.super.getTilesOrNull(blockInWorld, face); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java similarity index 67% rename from src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java rename to src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java index 36d4c2d..1fc1549 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogicReference.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java @@ -15,13 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.server.world.tile; +package ru.windcorp.progressia.server.world; -import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; -import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.WorldGenericRO; import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; -public interface TileLogicReference - extends TileGenericReferenceRO { +public interface WorldLogicRO + extends WorldGenericRO { } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java new file mode 100644 index 0000000..1b281c9 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java @@ -0,0 +1,35 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.server.world.WorldLogic; + +public interface ServerWorldContext extends WorldData, ServerWorldContextRO { + + public interface Logic extends ServerWorldContextRO.Logic, WorldLogic { + + @Override + ServerWorldContext data(); + + } + + @Override + ServerWorldContext.Logic logic(); + +} \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java new file mode 100644 index 0000000..7672a12 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java @@ -0,0 +1,16 @@ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.WorldDataRO; +import ru.windcorp.progressia.server.world.WorldLogicRO; + +public interface ServerWorldContextRO extends WorldDataRO, ServerContext { + + public interface Logic extends WorldLogicRO { + + ServerWorldContextRO data(); + + } + + ServerWorldContextRO.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index bd244a0..d52e6a2 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -29,7 +29,7 @@ import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.GravityModelRegistry; import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.DefaultWorldLogic; public abstract class AbstractWorldGenerator extends WorldGenerator { @@ -90,7 +90,7 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { } @Override - public WorldLogic getWorldLogic() { + public DefaultWorldLogic getWorldLogic() { return server.getWorld(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index a7c9753..05dc4ea 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -30,7 +30,7 @@ import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.DefaultWorldLogic; public abstract class WorldGenerator extends Namespaced { @@ -52,7 +52,7 @@ public abstract class WorldGenerator extends Namespaced { public abstract Vec3 suggestSpawnLocation(); public abstract Server getServer(); - public abstract WorldLogic getWorldLogic(); + public abstract DefaultWorldLogic getWorldLogic(); public abstract DefaultWorldData getWorldData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java index 5ddd08f..120cd22 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java @@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.DefaultWorldLogic; class BlockTriggeredUpdate extends CachedEvaluation { @@ -39,7 +39,7 @@ class BlockTriggeredUpdate extends CachedEvaluation { public void evaluate(Server server) { Vec3i cursor = new Vec3i(blockInWorld.x, blockInWorld.y, blockInWorld.z); - WorldLogic world = server.getWorld(); + DefaultWorldLogic world = server.getWorld(); for (AbsFace face : AbsFace.getFaces()) { TickAndUpdateUtil.updateTiles(world, cursor, face); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index df92442..336f166 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -31,7 +31,7 @@ import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.server.world.DefaultChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.TickableBlock; @@ -61,9 +61,9 @@ public class TickChunk extends Evaluation { this.randomTickMethods = ImmutableList.copyOf(randomTickMethods); } - private final ChunkLogic chunk; + private final DefaultChunkLogic chunk; - public TickChunk(ChunkLogic chunk) { + public TickChunk(DefaultChunkLogic chunk) { this.chunk = chunk; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java index bb9d480..66e95a1 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java @@ -25,7 +25,7 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.DefaultWorldLogic; class TileTriggeredUpdate extends CachedEvaluation { @@ -40,7 +40,7 @@ class TileTriggeredUpdate extends CachedEvaluation { public void evaluate(Server server) { Vec3i cursor = new Vec3i(blockInWorld.x, blockInWorld.y, blockInWorld.z); - WorldLogic world = server.getWorld(); + DefaultWorldLogic world = server.getWorld(); TickAndUpdateUtil.updateTiles(world, cursor, face); // Update facemates // (also self) diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java index 4272919..d805607 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java @@ -25,8 +25,9 @@ import java.util.function.Function; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.server.world.DefaultChunkLogic; import ru.windcorp.progressia.server.world.TickContextMutable; +import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockTickContext; public interface TSTickContext extends BlockTickContext { @@ -41,15 +42,15 @@ public interface TSTickContext extends BlockTickContext { * Getters */ - default TileLogicStack getTLSOrNull() { - ChunkLogic chunkLogic = getChunkLogic(); + default TileLogicStackRO getTLSOrNull() { + DefaultChunkLogic chunkLogic = getChunkLogic(); if (chunkLogic == null) return null; return chunkLogic.getTilesOrNull(getBlockInChunk(), getFace()); } - default TileLogicStack getTLS() { + default TileLogicStackRO getTLS() { return getChunkLogic().getTiles(getBlockInChunk(), getFace()); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java index c3003d8..597291a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java @@ -19,6 +19,7 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.TileDataReference; @@ -40,7 +41,7 @@ public interface TileTickContext extends TSTickContext { */ default TileLogic getTile() { - TileLogicStack stack = getTLSOrNull(); + TileLogicStackRO stack = getTLSOrNull(); if (stack == null) return null; return stack.get(getLayer()); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java index c4f5ec7..8112105 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.test.gen; import kdotjpg.opensimplex2.areagen.OpenSimplex2S; -import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.DefaultWorldLogic; class TestTerrainGenerator { @@ -31,7 +31,7 @@ class TestTerrainGenerator { private final OpenSimplex2S noise; private final Func2D shape; - public TestTerrainGenerator(TestWorldGenerator testWorldGenerator, WorldLogic world) { + public TestTerrainGenerator(TestWorldGenerator testWorldGenerator, DefaultWorldLogic world) { this.noise = new OpenSimplex2S("We're getting somewhere".hashCode()); Func2D plainsHeight = tweak( From 1ee9a55d19d6be50bda073c5b5f4d4b437faf2ba Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sat, 31 Jul 2021 20:47:23 +0300 Subject: [PATCH 37/63] Defined Data and Server context interfaces Server read-write (not RO) interfaces do not extend the complimentary *GenericContextWO interfaces by design. It makes no sense to set a BlockLogic, but it makes plenty of sense to refer to a ChunkData rather than a ChunkDataRO. --- .../world/context/BlockDataContext.java | 35 ++++++++++++++++ .../world/context/BlockDataContextRO.java | 34 +++++++++++++++ .../world/context/BlockFaceDataContext.java | 35 ++++++++++++++++ .../world/context/BlockFaceDataContextRO.java | 34 +++++++++++++++ .../common/world/context/TileDataContext.java | 35 ++++++++++++++++ .../world/context/TileDataContextRO.java | 34 +++++++++++++++ .../world/context/WorldDataContext.java | 36 ++++++++++++++++ .../world/context/WorldDataContextRO.java | 36 ++++++++++++++++ .../world/context/ServerBlockContext.java | 41 ++++++++++++++++++ .../world/context/ServerBlockContextRO.java | 42 +++++++++++++++++++ .../world/context/ServerBlockFaceContext.java | 40 ++++++++++++++++++ .../context/ServerBlockFaceContextRO.java | 42 +++++++++++++++++++ .../world/context/ServerTileContext.java | 40 ++++++++++++++++++ .../world/context/ServerTileContextRO.java | 42 +++++++++++++++++++ .../world/context/ServerWorldContext.java | 21 ++++++---- .../world/context/ServerWorldContextRO.java | 31 ++++++++++++-- 16 files changed, 568 insertions(+), 10 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java create mode 100644 src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java new file mode 100644 index 0000000..4ebb85a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java @@ -0,0 +1,35 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface BlockDataContext + extends BlockGenericContextWO, + WorldDataContext, + BlockDataContextRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java new file mode 100644 index 0000000..f910fa1 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java @@ -0,0 +1,34 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkDataRO; +import ru.windcorp.progressia.common.world.TileDataReferenceRO; +import ru.windcorp.progressia.common.world.TileDataStackRO; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface BlockDataContextRO + extends BlockGenericContextRO, + WorldDataContextRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java new file mode 100644 index 0000000..45ce045 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java @@ -0,0 +1,35 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface BlockFaceDataContext + extends BlockFaceGenericContextWO, + BlockDataContext, + BlockFaceDataContextRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java new file mode 100644 index 0000000..ddf7089 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java @@ -0,0 +1,34 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkDataRO; +import ru.windcorp.progressia.common.world.TileDataReferenceRO; +import ru.windcorp.progressia.common.world.TileDataStackRO; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface BlockFaceDataContextRO + extends BlockFaceGenericContextRO, + BlockDataContext { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java new file mode 100644 index 0000000..c3e1321 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java @@ -0,0 +1,35 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.TileGenericContextWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataContext + extends TileGenericContextWO, + BlockFaceDataContext, + TileDataContextRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java new file mode 100644 index 0000000..b7f2b4d --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java @@ -0,0 +1,34 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkDataRO; +import ru.windcorp.progressia.common.world.TileDataReferenceRO; +import ru.windcorp.progressia.common.world.TileDataStackRO; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface TileDataContextRO + extends TileGenericContextRO, + BlockFaceDataContextRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java new file mode 100644 index 0000000..31dbef1 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java @@ -0,0 +1,36 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextWO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface WorldDataContext + extends WorldGenericContextWO, + WorldDataContextRO, + WorldData { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java new file mode 100644 index 0000000..c474ea4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java @@ -0,0 +1,36 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ru.windcorp.progressia.common.world.context; + +import ru.windcorp.progressia.common.world.ChunkDataRO; +import ru.windcorp.progressia.common.world.TileDataReferenceRO; +import ru.windcorp.progressia.common.world.TileDataStackRO; +import ru.windcorp.progressia.common.world.WorldDataRO; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; +import ru.windcorp.progressia.common.world.tile.TileData; + +public interface WorldDataContextRO + extends WorldGenericContextRO, + WorldDataRO { + + // currently empty + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java new file mode 100644 index 0000000..a1fbbf5 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java @@ -0,0 +1,41 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.context.BlockDataContext; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.server.world.TileLogicStack; + +public interface ServerBlockContext extends BlockDataContext, ServerWorldContext, ServerBlockContextRO { + + public interface Logic extends ServerBlockContextRO.Logic, ServerWorldContext.Logic { + + @Override + ServerBlockContext data(); + + @Override + default TileLogicStack getTilesOrNull(BlockFace face) { + return (TileLogicStack) ServerBlockContextRO.Logic.super.getTilesOrNull(face); + } + + } + + @Override + ServerBlockContext.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java new file mode 100644 index 0000000..1ffb30d --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java @@ -0,0 +1,42 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.context.BlockDataContextRO; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; +import ru.windcorp.progressia.server.world.ChunkLogicRO; +import ru.windcorp.progressia.server.world.TileLogicReferenceRO; +import ru.windcorp.progressia.server.world.TileLogicStackRO; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; + +public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataContextRO { + + public interface Logic extends ServerWorldContextRO.Logic, + BlockGenericContextRO { + + @Override + ServerBlockContextRO data(); + + } + + @Override + ServerBlockContextRO.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java new file mode 100644 index 0000000..335e15f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java @@ -0,0 +1,40 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.context.BlockFaceDataContext; +import ru.windcorp.progressia.server.world.TileLogicStack; + +public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBlockContext, ServerBlockFaceContextRO { + + public interface Logic extends ServerBlockFaceContextRO.Logic, ServerBlockContext.Logic { + + @Override + ServerBlockFaceContext data(); + + @Override + default TileLogicStack getTilesOrNull() { + return (TileLogicStack) ServerBlockFaceContextRO.Logic.super.getTilesOrNull(); + } + + } + + @Override + ServerBlockFaceContext.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java new file mode 100644 index 0000000..7fca1db --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java @@ -0,0 +1,42 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.context.BlockFaceDataContextRO; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; +import ru.windcorp.progressia.server.world.ChunkLogicRO; +import ru.windcorp.progressia.server.world.TileLogicReferenceRO; +import ru.windcorp.progressia.server.world.TileLogicStackRO; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; + +public interface ServerBlockFaceContextRO extends ServerBlockContextRO, BlockFaceDataContextRO { + + public interface Logic extends ServerBlockContextRO.Logic, + BlockFaceGenericContextRO { + + @Override + ServerBlockFaceContextRO data(); + + } + + @Override + ServerBlockFaceContextRO.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java new file mode 100644 index 0000000..5d5a3c0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java @@ -0,0 +1,40 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.context.TileDataContext; +import ru.windcorp.progressia.server.world.TileLogicReference; + +public interface ServerTileContext extends TileDataContext, ServerBlockFaceContext, ServerTileContextRO { + + public interface Logic extends ServerTileContextRO.Logic, ServerBlockFaceContext.Logic { + + @Override + ServerTileContext data(); + + @Override + default TileLogicReference getTileReference() { + return (TileLogicReference) ServerTileContextRO.Logic.super.getTileReference(); + } + + } + + @Override + ServerTileContext.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java new file mode 100644 index 0000000..73b8d2c --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java @@ -0,0 +1,42 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import ru.windcorp.progressia.common.world.context.TileDataContextRO; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; +import ru.windcorp.progressia.server.world.ChunkLogicRO; +import ru.windcorp.progressia.server.world.TileLogicReferenceRO; +import ru.windcorp.progressia.server.world.TileLogicStackRO; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; + +public interface ServerTileContextRO extends ServerBlockFaceContextRO, TileDataContextRO { + + public interface Logic extends ServerBlockFaceContextRO.Logic, + TileGenericContextRO { + + @Override + ServerTileContextRO data(); + + } + + @Override + ServerTileContextRO.Logic logic(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java index 1b281c9..ee04242 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java @@ -17,19 +17,26 @@ */ package ru.windcorp.progressia.server.world.context; -import ru.windcorp.progressia.common.world.WorldData; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.context.WorldDataContext; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.server.world.TileLogicStack; import ru.windcorp.progressia.server.world.WorldLogic; -public interface ServerWorldContext extends WorldData, ServerWorldContextRO { - - public interface Logic extends ServerWorldContextRO.Logic, WorldLogic { - +public interface ServerWorldContext extends WorldDataContext, ServerWorldContextRO { + + public interface Logic extends ServerWorldContextRO.Logic, + WorldLogic { + @Override ServerWorldContext data(); + @Override + TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face); + } - + @Override ServerWorldContext.Logic logic(); - + } \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java index 7672a12..43eeedc 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java @@ -1,16 +1,41 @@ package ru.windcorp.progressia.server.world.context; -import ru.windcorp.progressia.common.world.WorldDataRO; +import ru.windcorp.progressia.common.world.context.WorldDataContextRO; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; +import ru.windcorp.progressia.server.world.ChunkLogicRO; +import ru.windcorp.progressia.server.world.TileLogicReferenceRO; +import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.WorldLogicRO; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.tile.TileLogic; -public interface ServerWorldContextRO extends WorldDataRO, ServerContext { +public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext { - public interface Logic extends WorldLogicRO { + public interface Logic + extends + WorldGenericContextRO, + WorldLogicRO, + ServerContext { + /** + * Acquires the data view of this context. Use this method to + * conveniently access data content. The returned object is linked to + * this context and operates on the same data. + * + * @return a view of this context that returns data objects + */ ServerWorldContextRO data(); } + /** + * Acquires the logic view of this context. Use this method to conveniently + * access logic content. The returned object is linked to this context and + * operates on the same data. + * + * @return a view of this context that returns appropriate logic objects + */ ServerWorldContextRO.Logic logic(); } From c2a2cc074ae87774848e7e489c2e6ff10bdafa7c Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Tue, 3 Aug 2021 14:44:52 -0400 Subject: [PATCH 38/63] Some Stuff to Fix Bugs -Improved debug info of Fallingblock ticking -Fixed unsynchronized access as per OLEGSHA -Maybe better server side deletion of blocks --- .../progressia/client/graphics/world/LayerWorld.java | 4 ++-- .../progressia/test/TestEntityLogicFallingBlock.java | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java index ccc052a..4af53e9 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LayerWorld.java @@ -110,11 +110,11 @@ public class LayerWorld extends Layer { tmp_testControls.applyPlayerControls(); - for (EntityData data : this.client.getWorld().getData().getEntities()) { + this.client.getWorld().getData().getEntities().forEach(data -> { tmp_applyFriction(data, tickLength); tmp_applyGravity(data, tickLength); tmp_renderCollisionModel(data); - } + }); } catch (Throwable e) { e.printStackTrace(); System.err.println("OLEGSHA is to blame. Tell him he vry stupiDD!!"); diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index 729d857..0730d63 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -10,6 +10,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickContext; import ru.windcorp.progressia.server.world.entity.EntityLogic; @@ -57,7 +58,7 @@ public class TestEntityLogicFallingBlock extends EntityLogic { // "+String.valueOf(entity!=null) + " " + // context.toString()); super.tick(entity, context); - + // friction Vec3 vel = entity.getVelocity(); float friction = 0f; @@ -105,12 +106,14 @@ public class TestEntityLogicFallingBlock extends EntityLogic { if (context.getWorldData().isBlockLoaded(occupiedBlock) && context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { - LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x)); + LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x) + " " + String.valueOf(occupiedBlock.y) + " " + String.valueOf(occupiedBlock.z)); // ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, // fallBlock.getBlock(),true); context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); fallBlock.setInvisible(); // Until I know how to properly delete it. - ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId());// context.getWorldData().removeEntity(entity.getEntityId()); + //ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId());// context.getWorldData().removeEntity(entity.getEntityId()); + Server server = context.getServer(); + server.invokeLater(() -> server.getWorld().getData().removeEntity(entity.getEntityId())); } } } From dccfcc9419488c80457ef545f21f6494aa42520c Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Tue, 3 Aug 2021 15:05:05 -0400 Subject: [PATCH 39/63] Better /Stuff -Uses Coordinates a little in TestWorldGenerator. Ill do more eventually I think -Better sprite getting for FallingBlocks --- .../progressia/test/TestEntityRenderFallingBlock.java | 8 ++------ .../windcorp/progressia/test/gen/TestWorldGenerator.java | 5 +++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java index 0adaa34..dc789df 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java @@ -3,14 +3,11 @@ package ru.windcorp.progressia.test; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.Shapes; -import ru.windcorp.progressia.client.graphics.texture.Atlases; -import ru.windcorp.progressia.client.graphics.texture.SimpleTexture; import ru.windcorp.progressia.client.graphics.texture.Texture; -import ru.windcorp.progressia.client.graphics.texture.Atlases.AtlasGroup; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.world.block.BlockRenderRegistry; import ru.windcorp.progressia.client.world.entity.EntityRender; import ru.windcorp.progressia.client.world.entity.EntityRenderable; -import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.world.entity.EntityData; /** @@ -24,8 +21,7 @@ public class TestEntityRenderFallingBlock extends EntityRender { public TestEntityRenderFallingBlock(String id) { super(id); - cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), new SimpleTexture(Atlases - .getSprite(ResourceManager.getTextureResource("blocks/Sand"), new AtlasGroup("Blocks", 1 << 12)))) + cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), BlockRenderRegistry.getBlockTexture(id) ) .create(); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 96213fe..de9e38d 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -62,8 +62,9 @@ public class TestWorldGenerator extends AbstractWorldGenerator { @Override public void onChunkBlockChanged(ChunkData chunk, Vec3i blockInChunk, BlockData previous, BlockData current) { - Vec3i chunkWorldPos = chunk.getPosition().mul_(16).add_(blockInChunk); - + Vec3i chunkWorldPos = new Vec3i(0,0,0); + Coordinates.getInWorld(chunk.getPosition(), blockInChunk, chunkWorldPos); //chunk.getPosition().mul_(16).add_(blockInChunk); + if (TestEntityLogicFallingBlock.FallingBlocks .contains(chunk.getWorld().getBlock(chunkWorldPos.add_(0, 0, 1)).getId())) { chunk.getWorld().setBlock(chunkWorldPos.add_(0, 0, 1), BlockDataRegistry.getInstance() From fbc803d6e27d911970ac15aa29a9f19c06504062 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 4 Aug 2021 18:42:16 +0300 Subject: [PATCH 40/63] Laid some groundwork for context implementation; rewrite incoming - ReusableServerContext will be the default context implementation. It is sort of implemented, but not really - WorldLogic{,RO} now declare getData() method - WorldGenericContextWO.removeEntity(EntityGeneric) received a default implementation - TileDataContext.getTag() received a default implementation --- .../common/world/context/TileDataContext.java | 7 +- .../context/WorldGenericContextWO.java | 4 +- .../server/world/DefaultWorldLogic.java | 1 + .../progressia/server/world/WorldLogic.java | 4 + .../progressia/server/world/WorldLogicRO.java | 3 + .../context/impl/ReusableServerContext.java | 122 ++++ .../impl/ReusableServerContextBuilders.java | 87 +++ .../impl/ReusableServerContextImpl.java | 519 ++++++++++++++++++ 8 files changed, 744 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextBuilders.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java index c3e1321..79e8d51 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java @@ -29,7 +29,10 @@ public interface TileDataContext extends TileGenericContextWO, BlockFaceDataContext, TileDataContextRO { - - // currently empty + + @Override + default int getTag() { + return getTileReference().getTag(); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index ddac83d..27bbb1a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -140,7 +140,9 @@ public interface WorldGenericContextWO< * @see #removeEntity(long) */ @Override - void removeEntity(E entity); + default void removeEntity(E entity) { + removeEntity(entity.getEntityId()); + } /** * Requests that the specified change is applied to the given entity. The diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java index e38559d..d578fa7 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java @@ -96,6 +96,7 @@ public class DefaultWorldLogic implements WorldLogic { return server; } + @Override public DefaultWorldData getData() { return data; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index 0995ce4..f0cdb0a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -20,6 +20,7 @@ package ru.windcorp.progressia.server.world; import java.util.Collection; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.rels.BlockFace; public interface WorldLogic extends WorldLogicRO { @@ -27,6 +28,9 @@ public interface WorldLogic extends WorldLogicRO { /* * Override return types */ + + @Override + WorldData getData(); @Override ChunkLogic getChunk(Vec3i pos); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java index 1fc1549..7f98ef9 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogicRO.java @@ -17,6 +17,7 @@ */ package ru.windcorp.progressia.server.world; +import ru.windcorp.progressia.common.world.WorldDataRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.WorldGenericRO; import ru.windcorp.progressia.server.world.block.BlockLogic; @@ -24,5 +25,7 @@ import ru.windcorp.progressia.server.world.tile.TileLogic; public interface WorldLogicRO extends WorldGenericRO { + + WorldDataRO getData(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java new file mode 100644 index 0000000..fdffd22 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java @@ -0,0 +1,122 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.WorldLogicRO; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerBlockContextRO; +import ru.windcorp.progressia.server.world.context.ServerBlockFaceContext; +import ru.windcorp.progressia.server.world.context.ServerBlockFaceContextRO; +import ru.windcorp.progressia.server.world.context.ServerContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileContextRO; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; +import ru.windcorp.progressia.server.world.context.ServerWorldContextRO; + +/** + * An implementation of the entire {@link ServerContext} tree. The objects of + * this class are designed to be highly reusable, including reusability in + * {@linkplain Context#subcontexting subcontexting}. Use this implementation + * when a {@link WorldLogic} (or a {@link WorldLogicRO}) instance requires a + * context wrapper. + *

      + * Use other unutilized instances of {@link ReusableServerContext} or + * {@link #empty()} static method to acquire a usable instance. + *

      + * This class defines the outward-facing safe interface of the actual + * implementation located in {@link ReusableServerContextImpl}. The reasoning + * for creating a subclass is to allow a single instance to implement both + * {@linkplain ReusableServerContextBuilders builder interfaces} and the context + * interface without causing confusion around object states. + * + * @author javapony + */ +public abstract class ReusableServerContext implements ServerTileContext { + + /** + * An RSC can conform to a variety of different {@link Context} interfaces. + * Each compliance mode is identified by a Role. + */ + public enum Role { + /** + * This object has not been configured yet. + */ + NONE, + /** + * This object conforms to {@link ServerWorldContext} or + * {@link ServerWorldContextRO}. + */ + WORLD, + /** + * This object conforms to {@link ServerBlockContext} or + * {@link ServerBlockContextRO}. + */ + LOCATION, + /** + * This object conforms to {@link ServerBlockFaceContext} or + * {@link ServerBlockFaceContextRO}. + */ + TILE_STACK, + /** + * This object conforms to {@link ServerTileContext} or + * {@link ServerTileContextRO}. + */ + TILE + } + + /** + * Do not extend ReusableServerContext directly. Use + * {@link ReusableServerContextImpl} if this is truly necessary. + */ + ReusableServerContext() { + // do nothing + } + + /** + * Resets this object to its uninitialized state and returns a builder to + * reinitialize it. + * + * @return a {@link ReusableServerContextBuilders.Empty} instance that may + * be used to reinitialize this object + * @throws IllegalStateException if active subcontexting is detected. + * Detection is done on a best-effort basis; + * do not rely this exception + */ + public abstract ReusableServerContextBuilders.Empty reuse() throws IllegalStateException; + + /** + * Returns the {@link Role} currently assumed by this object. + * + * @return the role + */ + public abstract Role getRole(); + + /** + * Instantiates a new {@link ReusableServerContext} using an appropriate + * implementation. + * + * @return a {@link ReusableServerContextBuilders.Empty} instance that can + * be used to initialize this object + */ + public static ReusableServerContextBuilders.Empty empty() { + return new ReusableServerContextImpl(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextBuilders.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextBuilders.java new file mode 100644 index 0000000..349c66a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextBuilders.java @@ -0,0 +1,87 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; +import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.WorldLogic; + +public interface ReusableServerContextBuilders { + + ReusableServerContext build(); + + public interface Empty /* does not extend RSCB */ { + + WithWorld in(Server server, WorldLogic world); + + default WithWorld inRealWorldOf(Server server) { + return in(server, server.getWorld()); + } + + } + + public interface WithWorld extends ReusableServerContextBuilders { + + WithLocation at(Vec3i location); + + default ReusableServerContext at(TileGenericReferenceRO reference) { + if (!reference.isValid()) { + throw new IllegalArgumentException("Reference " + reference + " is invalid"); + } + + TileGenericStackRO stack = reference.getStack(); + return at(stack.getBlockInWorld(null)).on(stack.getFace()).index(reference.getIndex()); + } + + } + + public interface WithLocation extends ReusableServerContextBuilders { + + WithTileStack on(RelFace side); + WithTileStack on(BlockFace side); + + default ReusableServerContext on(TileGenericReferenceRO reference) { + if (!reference.isValid()) { + throw new IllegalArgumentException("Reference " + reference + " is invalid"); + } + + TileGenericStackRO stack = reference.getStack(); + return on(stack.getFace()).index(reference.getIndex()); + } + + } + + public interface WithTileStack extends ReusableServerContextBuilders { + + ReusableServerContext index(int index); + + default ReusableServerContext index(TileGenericReferenceRO reference) { + if (!reference.isValid()) { + throw new IllegalArgumentException("Reference " + reference + " is invalid"); + } + + return index(reference.getIndex()); + } + + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java new file mode 100644 index 0000000..2336937 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java @@ -0,0 +1,519 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import java.util.Collection; +import java.util.Random; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.GravityModel; +import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.ChunkLogic; +import ru.windcorp.progressia.server.world.TileLogicStack; +import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.context.ServerTileContext; + +class ReusableServerContextImpl extends ReusableServerContext + implements ReusableServerContextBuilders.Empty, ReusableServerContextBuilders.WithWorld, + ReusableServerContextBuilders.WithLocation, ReusableServerContextBuilders.WithTileStack { + + /* + * STATE MANAGEMENT & UTIL + */ + + public ReusableServerContextImpl() { + reuse(); + } + + /** + * The relevant {@link Server} instance. If this is {@code null}, the role + * is {@link Role#NONE}. + */ + protected Server server; + + /** + * The relevant {@link WorldLogic} instance. If this is {@code null}, the + * role is {@link Role#NONE}. + */ + protected WorldLogic world; + + /** + * The relevant location. If this is {@code null}, the role is + * {@link Role#WORLD} or {@link Role#NONE}. + */ + protected Vec3i location; + + /** + * A {@code final} reference to the {@link Vec3i} instance used by + * {@link #location}. + */ + protected final Vec3i locationVectorContainer = new Vec3i(); + + /** + * The relevant {@link RelFace}. If the role is {@link Role#TILE_STACK} or + * {@link Role#TILE}, this is not {@code null}. + */ + protected RelFace blockFace; + + /** + * The index of the relevant tile. This value is {@code -1} unless the role + * is {@link Role#TILE}. + */ + protected int index; + + /** + * Determines whether this object currently acts as a builder or a context. + */ + protected boolean isBuilder; + + /** + * Counts the instances of subcontexting that are currently active. This + * value increases by 1 when subcontexting begins and decreases by 1 when it + * ends. This is always 0 when the object is a builder. + */ + protected int subcontextDepth = 0; + + /** + * The Logic view returned by {@link #logic()}. + */ + protected final ReusableServerContextImpl.Logic logic = new Logic(); + + /** + * Returns the Role currently assumed by this object. + * + * @return the role + */ + @Override + public Role getRole() { + if (server == null) + return Role.NONE; + if (location == null) + return Role.WORLD; + if (blockFace == null) + return Role.LOCATION; + if (index == -1) + return Role.TILE_STACK; + return Role.TILE; + } + + /** + * Throws an {@link IllegalStateException} iff this object does not conform + * to the specified role. The object must not be a builder to pass the + * check. + * + * @param role the required role + * @return {@code true} (for convenience with {@code assert}) + * @throws IllegalStateException when the check fails + */ + public boolean requireContextRole(Role role) throws IllegalStateException { + + boolean ok = !isBuilder && getRole().compareTo(role) <= 0; + if (!ok) { + complainAboutIllegalState(role, false); + } + return true; + + } + + /** + * Throws an {@link IllegalStateException} iff this object does not conform + * to the specified role. The object must be a builder to pass the check. If + * {@code role} is {@code null}, any role except {@link Role#NONE} passes. + * + * @param role the required role or {@code null}, see above + * @return {@code true} (for convenience with {@code assert}) + * @throws IllegalStateException when the check fails + */ + public boolean requireBuilderRole(Role role) { + + boolean ok = isBuilder && role == null ? (getRole() != Role.NONE) : (getRole() == role); + if (!ok) { + complainAboutIllegalState(role, true); + } + return true; + + } + + private void complainAboutIllegalState(Role role, boolean builder) { + throw new IllegalStateException( + "Required " + (builder ? "builder for" : "context") + " " + role + + ", but I am currently " + this + ); + } + + @Override + public String toString() { + String result; + + switch (getRole()) { + case TILE: + result = String.format( + "ServerTileContext[x=%d, y=%d, z=%d, %s, index=%d]", + location.x, + location.y, + location.z, + blockFace, + index + ); + break; + case TILE_STACK: + result = String + .format("ServerBlockFaceContext[x=%d, y=%d, z=%d, %s]", location.x, location.y, location.z, blockFace); + break; + case LOCATION: + result = String.format("ServerBlockContext[x=%d, y=%d, z=%d]", location.x, location.y, location.z); + break; + case WORLD: + result = String.format("ServerWorldContext"); + break; + default: + result = "Uninitialized ReusableServerContext"; + break; + } + + if (isBuilder) { + result = "Builder for " + result; + } + + return result; + } + + /* + * RSC INTERFACE + */ + + @Override + public Empty reuse() { + + if (subcontextDepth != 0) { + throw new IllegalStateException("Resetting is not allowed when subcontexting"); + } + + server = null; + world = null; + location = null; + blockFace = null; + index = -1; + + isBuilder = true; + + return this; + + } + + /* + * BUILDER INTERFACE + */ + + @Override + public ReusableServerContext build() { + assert requireBuilderRole(null); + isBuilder = false; + return this; + } + + /* + * Empty + */ + + @Override + public WithWorld in(Server server, WorldLogic world) { + requireBuilderRole(Role.NONE); + this.server = server; + this.world = world; + return this; + } + + /* + * WithWorld + */ + + @Override + public WithLocation at(Vec3i location) { + requireBuilderRole(Role.WORLD); + this.location = this.locationVectorContainer; + this.location.set(location.x, location.y, location.z); + return this; + } + + /* + * WithLocation + */ + + @Override + public WithTileStack on(RelFace side) { + requireBuilderRole(Role.LOCATION); + this.blockFace = side; + return this; + } + + @Override + public WithTileStack on(BlockFace side) { + requireBuilderRole(Role.LOCATION); + this.blockFace = side.relativize(world.getData().getUp(location)); + return this; + } + + /* + * WithTileStack + */ + + @Override + public ReusableServerContext index(int index) { + requireBuilderRole(Role.TILE_STACK); + this.index = index; + return build(); + } + + /* + * ServerWorldContext.Logic STUFF + */ + + private class Logic implements ServerTileContext.Logic { + @Override + public boolean isReal() { + return ReusableServerContextImpl.this.isReal(); + } + + @Override + public Collection getChunks() { + return world.getChunks(); + } + + @Override + public Collection getEntities() { + return ReusableServerContextImpl.this.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return ReusableServerContextImpl.this.getEntity(entityId); + } + + @Override + public Server getServer() { + return ReusableServerContextImpl.this.getServer(); + } + + @Override + public Random getRandom() { + return ReusableServerContextImpl.this.getRandom(); + } + + @Override + public Vec3i getLocation() { + return ReusableServerContextImpl.this.getLocation(); + } + + @Override + public RelFace getFace() { + return ReusableServerContextImpl.this.getFace(); + } + + @Override + public int getLayer() { + return ReusableServerContextImpl.this.getLayer(); + } + + @Override + public TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face) { + return world.getTiles(blockInWorld, face); + } + + @Override + public ChunkLogic getChunk(Vec3i pos) { + return world.getChunk(pos); + } + + @Override + public WorldData getData() { + return world.getData(); + } + + @Override + public ServerTileContext data() { + return ReusableServerContextImpl.this; + } + + @Override + public String toString() { + return ReusableServerContextImpl.this + ".Logic"; + } + } + + @Override + public Logic logic() { + return logic; + } + + /* + * LOCATION GETTERS + */ + + @Override + public Server getServer() { + assert requireContextRole(Role.WORLD); + return server; + } + + @Override + public Vec3i getLocation() { + assert requireContextRole(Role.LOCATION); + return location; + } + + @Override + public RelFace getFace() { + assert requireContextRole(Role.TILE_STACK); + return blockFace; + } + + @Override + public int getLayer() { + assert requireContextRole(Role.TILE); + return index; + } + + /* + * RO CONTEXT INTERFACE + */ + + @Override + public boolean isReal() { + assert requireContextRole(Role.WORLD); + return true; + } + + @Override + public Random getRandom() { + assert requireContextRole(Role.WORLD); + return server.getAdHocRandom(); + } + + @Override + public ChunkData getChunk(Vec3i pos) { + assert requireContextRole(Role.WORLD); + return world.getData().getChunk(pos); + } + + @Override + public Collection getChunks() { + assert requireContextRole(Role.WORLD); + return world.getData().getChunks(); + } + + @Override + public Collection getEntities() { + assert requireContextRole(Role.WORLD); + return world.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + assert requireContextRole(Role.WORLD); + return world.getEntity(entityId); + } + + @Override + public GravityModel getGravityModel() { + assert requireContextRole(Role.WORLD); + return world.getData().getGravityModel(); + } + + @Override + public float getTime() { + assert requireContextRole(Role.WORLD); + return world.getData().getTime(); + } + + /* + * RO CONTEXT OPTIMIZATIONS + */ + + /* + * RW CONTEXT INTERFACE + */ + + @Override + public boolean isImmediate() { + assert requireContextRole(Role.WORLD); + return true; + } + + @Override + public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { + assert requireContextRole(Role.WORLD); + world.getData().setBlock(blockInWorld, block, notify); + } + + @Override + public void addTile(Vec3i location, BlockFace face, TileData tile) { + assert requireContextRole(Role.WORLD); + world.getData().getTiles(location, face).addFarthest(tile); + } + + @Override + public void removeTile(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileDataStack stack = world.getData().getTilesOrNull(location, face); + if (stack == null) return; + int index = stack.getIndexByTag(tag); + if (index == -1) return; + stack.remove(index); + } + + @Override + public void addEntity(EntityData entity) { + assert requireContextRole(Role.WORLD); + world.getData().addEntity(entity); + } + + @Override + public void removeEntity(long entityId) { + assert requireContextRole(Role.WORLD); + world.getData().removeEntity(entityId); + } + + @Override + public void changeEntity(SE entity, StateChange change) { + assert requireContextRole(Role.WORLD); + world.getData().changeEntity(entity, change); + } + + @Override + public void advanceTime(float change) { + assert requireContextRole(Role.WORLD); + world.getData().advanceTime(change); + } + + /* + * RW CONTEXT OPTIMIZATIONS + */ + +} From 0f60d45ffa547fe9e196f216ccc60b912158164e Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 5 Aug 2021 16:42:21 +0300 Subject: [PATCH 41/63] Contexts no longer expose to World, Chunks, TileStacks or TileReferences The intention is to bottleneck all read queries and write requests through context objects without the need to create practically useless Chunk, TileStack and TileRef wrappers. - WorldGenericContext{RO,WO} no longer extend WorldGeneric{RO,WO} - Added tag access for tiles to contexts - Documented almost all context methods - Renamed isBlockLoaded() to isLocationLoaded() - I found some inner peace --- .../world/context/BlockDataContext.java | 7 +- .../world/context/BlockDataContextRO.java | 5 +- .../world/context/BlockFaceDataContext.java | 7 +- .../world/context/BlockFaceDataContextRO.java | 5 +- .../common/world/context/TileDataContext.java | 10 +- .../world/context/TileDataContextRO.java | 5 +- .../world/context/WorldDataContext.java | 21 +- .../world/context/WorldDataContextRO.java | 27 +- .../common/world/generic/WorldGenericRO.java | 2 +- .../context/BlockFaceGenericContextRO.java | 84 ++-- .../context/BlockFaceGenericContextWO.java | 5 +- .../context/BlockGenericContextRO.java | 97 +++-- .../context/BlockGenericContextWO.java | 5 +- .../generic/context/TileGenericContextRO.java | 47 +-- .../generic/context/TileGenericContextWO.java | 5 +- .../context/WorldGenericContextRO.java | 166 +++++++- .../context/WorldGenericContextWO.java | 12 +- .../server/world/TickAndUpdateUtil.java | 4 +- .../world/context/ServerBlockContext.java | 7 - .../world/context/ServerBlockContextRO.java | 7 +- .../world/context/ServerBlockFaceContext.java | 6 - .../context/ServerBlockFaceContextRO.java | 7 +- .../server/world/context/ServerContext.java | 4 +- .../world/context/ServerTileContext.java | 6 - .../world/context/ServerTileContextRO.java | 7 +- .../world/context/ServerWorldContext.java | 10 +- .../world/context/ServerWorldContextRO.java | 10 +- .../context/impl/ReusableServerContext.java | 7 +- .../impl/ReusableServerContextImpl.java | 399 ++++++++++++------ .../test/gen/surface/SurfaceWorld.java | 2 +- 30 files changed, 613 insertions(+), 373 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java index 4ebb85a..3462048 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java @@ -17,19 +17,16 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContext - extends BlockGenericContextWO, + extends BlockGenericContextWO, WorldDataContext, BlockDataContextRO { - + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java index f910fa1..70ad8f4 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java @@ -17,16 +17,13 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContextRO - extends BlockGenericContextRO, + extends BlockGenericContextRO, WorldDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java index 45ce045..b12c36c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java @@ -17,19 +17,16 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockFaceDataContext - extends BlockFaceGenericContextWO, + extends BlockFaceGenericContextWO, BlockDataContext, BlockFaceDataContextRO { - + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java index ddf7089..a20355a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java @@ -17,16 +17,13 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockFaceDataContextRO - extends BlockFaceGenericContextRO, + extends BlockFaceGenericContextRO, BlockDataContext { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java index 79e8d51..3f4a0d6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java @@ -17,22 +17,16 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface TileDataContext - extends TileGenericContextWO, + extends TileGenericContextWO, BlockFaceDataContext, TileDataContextRO { - @Override - default int getTag() { - return getTileReference().getTag(); - } + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java index b7f2b4d..e143e03 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java @@ -17,16 +17,13 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; public interface TileDataContextRO - extends TileGenericContextRO, + extends TileGenericContextRO, BlockFaceDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java index 31dbef1..68965b5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java @@ -17,20 +17,23 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface WorldDataContext - extends WorldGenericContextWO, - WorldDataContextRO, - WorldData { - - // currently empty + extends WorldGenericContextWO, + WorldDataContextRO { + + /** + * Increases in-game time of this world by {@code change}. Total time is + * decreased when {@code change} is negative. + * + * @param change the amount of time to add to current world time. May be + * negative. + * @see #getTime() + */ + void advanceTime(float change); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java index c474ea4..8201738 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java @@ -18,19 +18,30 @@ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; -import ru.windcorp.progressia.common.world.WorldDataRO; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; -public interface WorldDataContextRO - extends WorldGenericContextRO, - WorldDataRO { +public interface WorldDataContextRO extends WorldGenericContextRO { - // currently empty + /** + * Returns in-world time since creation. World time is zero before and + * during first tick. + *

      + * Game logic should assume that this value mostly increases uniformly. + * However, it is not guaranteed that in-world time always increments. + * + * @return time, in in-game seconds, since the world was created + */ + float getTime(); + + /** + * Gets the {@link GravityModel} used by this world. + * + * @return the gravity model + */ + GravityModel getGravityModel(); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java index 75ad1c3..eac2a0c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java @@ -144,7 +144,7 @@ public interface WorldGenericRO< return getChunk(chunkPos) != null; } - default boolean isBlockLoaded(Vec3i blockInWorld) { + default boolean isLocationLoaded(Vec3i blockInWorld) { return getChunkByBlock(blockInWorld) != null; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java index 212cc9b..0ca350a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java @@ -29,37 +29,15 @@ import ru.windcorp.progressia.common.world.generic.*; public interface BlockFaceGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.BlockFace, BlockGenericContextRO { +> extends WorldContexts.BlockFace, BlockGenericContextRO { //@formatter:on /** - * Gets the tile stack at the relevant position. - * - * @return the specified tile stack or {@code null} if the location is not - * loaded or the tile stack does not exist - */ - default TS getTilesOrNull() { - return getTilesOrNull(getLocation(), getFace()); - } - - /** - * Determines whether the location relevant to this context has a tile - * stack. - * - * @return {@code true} iff the tile stack exists - */ - default boolean hasTiles() { - return hasTiles(getLocation(), getFace()); - } - - /** - * Determines whether the specified position has a tile; block location and - * face are implied by the context. + * Determines whether the specified position has a tile. Block location and + * block face are implied by the context. * + * @param layer the layer of the tile * @return {@code true} iff the tile exists */ default boolean hasTile(int layer) { @@ -67,14 +45,60 @@ public interface BlockFaceGenericContextRO< } /** - * Gets the tile at the specified position; block location and face are - * implied by the context. + * Determines whether the specified position has a tile with the given tag. + * Block location and block face are implied by the context. * - * @return the specified tile or {@code null} if the location is not loaded - * or the tile does not exist + * @param tag the tag of the tile + * @return {@code true} iff the tile exists + */ + default boolean isTagValid(int tag) { + return isTagValid(getLocation(), getFace(), tag); + } + + /** + * Retrieves the tile at the specified position. Block location and block + * face are implied by the context. This method may return {@code null} in + * one of three cases: + *

        + *
      • the location is not loaded, + *
      • there is no tile stack on the relevant face, or + *
      • {@code layer} is not less than the amount of tiles in the tile stack. + *
      + * + * @return the tile or {@code null} if the position does not contain a tile */ default T getTile(int layer) { return getTile(getLocation(), getFace(), layer); } + /** + * Retrieves the tile at the specified position and the tile's tag. Block + * location and block face are implied by the context. This + * method may return {@code null} in one of three cases: + *
        + *
      • the location is not loaded, + *
      • there is no tile stack on the relevant face, or + *
      • there is no tile with the specified tag in the tile stack. + *
      + * + * @param tag the tag of the tile + * @return the tile or {@code null} if the position does not contain a tile + */ + default T getTileByTag(int tag) { + return getTileByTag(getLocation(), getFace(), tag); + } + + /** + * Counts the amount of tiles in the specified tile stack. Block location + * and block face are implied by the context. + *

      + * This method returns {@code 0} in case the location is not loaded. + * + * @return the count of tiles in the tile stack or {@code -1} if the tile + * stack could not exist + */ + default int getTileCount() { + return getTileCount(getLocation(), getFace()); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java index bcaa226..dd6c5ad 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java @@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.generic.*; public interface BlockFaceGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.BlockFace, BlockGenericContextWO { +> extends WorldContexts.BlockFace, BlockGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index 91ac3d3..239a02e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -29,11 +29,8 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; public interface BlockGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.Block, WorldGenericContextRO { +> extends WorldContexts.Block, WorldGenericContextRO { //@formatter:on /** @@ -43,11 +40,16 @@ public interface BlockGenericContextRO< * @return {@code true} iff the location is loaded */ default boolean isLoaded() { - return isBlockLoaded(getLocation()); + return isLocationLoaded(getLocation()); } /** - * Gets the block relevant in this context. + * Retrieves the block at the relevant location. This method may return + * {@code null} in one of two cases: + *

        + *
      • the location that the block would occupy is not loaded, or + *
      • the corresponding chunk's terrain has not yet generated. + *
      * * @return the block or {@code null} if the location is not loaded */ @@ -56,30 +58,11 @@ public interface BlockGenericContextRO< } /** - * Gets the tile stack at the specified position; block location is implied - * by the context. - * - * @return the specified tile stack or {@code null} if the location is not - * loaded or the tile stack does not exist - */ - default TS getTilesOrNull(BlockFace face) { - return getTilesOrNull(getLocation(), face); - } - - /** - * Determines whether the location relevant to this context has a tile stack - * at the specified side. - * - * @return {@code true} iff the tile stack exists - */ - default boolean hasTiles(BlockFace face) { - return hasTiles(getLocation(), face); - } - - /** - * Determines whether the specified position has a tile; block location is + * Determines whether the specified position has a tile. Block location is * implied by the context. * + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile * @return {@code true} iff the tile exists */ default boolean hasTile(BlockFace face, int layer) { @@ -87,14 +70,64 @@ public interface BlockGenericContextRO< } /** - * Gets the tile at the specified position; block location is implied by the - * context. + * Determines whether the specified position has a tile with the given tag. + * Block location is implied by context. * - * @return the specified tile or {@code null} if the location is not loaded - * or the tile does not exist + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return {@code true} iff the tile exists + */ + default boolean isTagValid(BlockFace face, int tag) { + return isTagValid(getLocation(), face, tag); + } + + /** + * Retrieves the tile at the specified position. Block location is implied + * by context. This method may return {@code null} in one of three cases: + *
        + *
      • the location is not loaded, + *
      • there is no tile stack on the specified face, or + *
      • {@code layer} is not less than the amount of tiles in the tile stack. + *
      + * + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile stack that the tile occupies + * @return the tile or {@code null} if the position does not contain a tile */ default T getTile(BlockFace face, int layer) { return getTile(getLocation(), face, layer); } + /** + * Retrieves the tile at the specified position and the tile's tag. Block + * location is implied by the context. This + * method may return {@code null} in one of three cases: + *
        + *
      • the location is not loaded, + *
      • there is no tile stack on the specified face, or + *
      • there is no tile with the specified tag in the tile stack. + *
      + * + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return the tile or {@code null} if the position does not contain a tile + */ + default T getTileByTag(BlockFace face, int tag) { + return getTileByTag(getLocation(), face, tag); + } + + /** + * Counts the amount of tiles in the specified tile stack. Block location is + * implied by the context + *

      + * This method returns {@code 0} in case the location is not loaded. + * + * @param face the face of the block that the tile stack occupies + * @return the count of tiles in the tile stack or {@code -1} if the tile + * stack could not exist + */ + default int getTileCount(BlockFace face) { + return getTileCount(face); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index f7a0eea..ffdb969 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; public interface BlockGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.Block, WorldGenericContextWO { +> extends WorldContexts.Block, WorldGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java index 0bc04d0..daf7fb8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java @@ -29,15 +29,12 @@ import ru.windcorp.progressia.common.world.generic.*; public interface TileGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.Tile, BlockFaceGenericContextRO { +> extends WorldContexts.Tile, BlockFaceGenericContextRO { //@formatter:on /** - * Determines whether the location relevant to this context has a tile. + * Determines whether the relevant position has a tile. * * @return {@code true} iff the tile exists */ @@ -46,42 +43,18 @@ public interface TileGenericContextRO< } /** - * Gets the tile at the relevant position. + * Retrieves the tile at the relevant position. This method may return + * {@code null} in one of three cases: + *

        + *
      • the location is not loaded, + *
      • there is no tile stack on the relevant face, or + *
      • {@code layer} is not less than the amount of tiles in the tile stack. + *
      * - * @return the specified tile or {@code null} if the location is not loaded - * or the tile does not exist + * @return the tile or {@code null} if the position does not contain a tile */ default T getTile() { return getTile(getLocation(), getFace(), getLayer()); } - @Override - default int getTag() { - TS tileStack = getTilesOrNull(); - if (tileStack == null) { - return -1; - } - - return tileStack.getTagByIndex(getLayer()); - } - - /** - * Gets the {@link TileGenericReferenceRO TileReference} to the relevant - * tile. - * - * @return the reference to the tile relevant to this context or - * {@code null} if the location is not loaded or the tile does not - * exist - * - * @see TileGenericStackRO#getReference(int) - */ - default TR getTileReference() { - TS tileStack = getTilesOrNull(); - if (tileStack == null) { - return null; - } - - return tileStack.getReference(getLayer()); - } - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java index 01a27d1..4c2b4dd 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java @@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.generic.*; public interface TileGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.Tile, BlockFaceGenericContextWO { +> extends WorldContexts.Tile, BlockFaceGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java index 588c98f..d604d62 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java @@ -17,23 +17,175 @@ */ package ru.windcorp.progressia.common.world.generic.context; +import java.util.Collection; +import java.util.function.Consumer; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; +import ru.windcorp.progressia.common.world.rels.BlockFace; /** * A {@link Context} with a world instance. + *

      + * This interfaces defines the entirety of world query methods supported by the + * default contexts. */ // @formatter:off public interface WorldGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.World, WorldGenericRO { +> extends WorldContexts.World { // @formatter:on - - // currently empty - + + /** + * Retrieves the block at the specified location. This method may return + * {@code null} in one of two cases: + *

        + *
      • the location that the block would occupy is not loaded, or + *
      • the corresponding chunk's terrain has not yet generated. + *
      + * + * @param location the location to query + * @return the block or {@code null} if the location is not loaded + */ + B getBlock(Vec3i location); + + /** + * Determines whether the specified location is loaded. + * + * @param location the location to query + * @return {@code true} iff the location is loaded + */ + boolean isLocationLoaded(Vec3i location); + + /** + * Retrieves the tile at the specified position. This method may return + * {@code null} in one of three cases: + *
        + *
      • the location is not loaded, + *
      • there is no tile stack on the specified face, or + *
      • {@code layer} is not less than the amount of tiles in the tile stack. + *
      + * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile stack that the tile occupies + * @return the tile or {@code null} if the position does not contain a tile + */ + T getTile(Vec3i location, BlockFace face, int layer); + + /** + * Retrieves the tile at the specified position and the tile's tag. This + * method may return {@code null} in one of three cases: + *
        + *
      • the location is not loaded, + *
      • there is no tile stack on the specified face, or + *
      • there is no tile with the specified tag in the tile stack. + *
      + * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return the tile or {@code null} if the position does not contain a tile + */ + T getTileByTag(Vec3i location, BlockFace face, int tag); + + /** + * Determines whether the specified position has a tile. + * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile + * @return {@code true} iff the tile exists + */ + boolean hasTile(Vec3i location, BlockFace face, int layer); + + /** + * Determines whether the specified position has a tile with the given tag. + * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return {@code true} iff the tile exists + */ + boolean isTagValid(Vec3i location, BlockFace face, int tag); + + /** + * Counts the amount of tiles in the specified tile stack. + *

      + * This method returns {@code 0} in case the location is not loaded. + * + * @param location location of the host block + * @param face the face of the block that the tile stack occupies + * @return the count of tiles in the tile stack or {@code -1} if the tile + * stack could not exist + */ + int getTileCount(Vec3i location, BlockFace face); + + /** + * Retrieves a listing of all entities. {@link #forEachEntity(Consumer)} + * should be used to iterate the collection. The collection is not + * modifiable. + * + * @return all loaded entities + */ + Collection getEntities(); + + /** + * Retrieves the entity with the specified entity ID. + * + * @param entityId the entity ID to look up + * @return the entity found or {@code null} + */ + E getEntity(long entityId); + + /* + * Convenience methods + */ + + /** + * Iterates all entities safely + */ + default void forEachEntity(Consumer action) { + getEntities().forEach(action); + } + + /** + * Iterates all entities in cuboid safely + */ + default void forEachEntityIn(Vec3i min, Vec3i max, Consumer action) { + forEachEntity(e -> { + Vec3 pos = e.getPosition(); + if (pos.x < min.x || pos.y < min.y || pos.z < min.z || pos.x > max.x || pos.y > max.y || pos.z > max.z) { + action.accept(e); + } + }); + } + + /** + * Iterates all entities in cuboid safely + */ + default void forEachEntityIn(Vec3 min, Vec3 max, Consumer action) { + forEachEntity(e -> { + Vec3 pos = e.getPosition(); + if (pos.x < min.x || pos.y < min.y || pos.z < min.z || pos.x > max.x || pos.y > max.y || pos.z > max.z) { + action.accept(e); + } + }); + } + + /** + * Iterates all entities with ID safely + */ + default void forEachEntityWithId(String id, Consumer action) { + forEachEntity(e -> { + if (id.equals(e.getId())) { + action.accept(e); + } + }); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index 27bbb1a..ad1291e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -28,16 +28,16 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * A writable {@link Context} with a world instance. This context provides * methods for affecting the world. The application of requested changes may or * may not be immediate, see {@link #isImmediate()}. + *

      + * This interfaces defines the entirety of world modification methods supported + * by the default contexts. */ // @formatter:off public interface WorldGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.World, WorldGenericWO { +> extends WorldContexts.World { // @formatter:on /** @@ -116,7 +116,6 @@ public interface WorldGenericContextWO< * @param entity the entity to add * @see #isImmediate() */ - @Override void addEntity(E entity); /** @@ -128,7 +127,6 @@ public interface WorldGenericContextWO< * @see #isImmediate() * @see #removeEntity(EntityGeneric) */ - @Override void removeEntity(long entityId); /** @@ -139,7 +137,6 @@ public interface WorldGenericContextWO< * @see #isImmediate() * @see #removeEntity(long) */ - @Override default void removeEntity(E entity) { removeEntity(entity.getEntityId()); } @@ -151,7 +148,6 @@ public interface WorldGenericContextWO< * @param entity the entity to change * @param change the change to apply */ - @Override void changeEntity(SE entity, StateChange change); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index fd3e0ec..112d722 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -73,7 +73,7 @@ public class TickAndUpdateUtil { } public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { - if (!world.isBlockLoaded(blockInWorld)) { + if (!world.isLocationLoaded(blockInWorld)) { return; } @@ -123,7 +123,7 @@ public class TickAndUpdateUtil { } public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { - if (!world.isBlockLoaded(blockInWorld)) { + if (!world.isLocationLoaded(blockInWorld)) { return; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java index a1fbbf5..4130b50 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java @@ -18,8 +18,6 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockDataContext; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.server.world.TileLogicStack; public interface ServerBlockContext extends BlockDataContext, ServerWorldContext, ServerBlockContextRO { @@ -28,11 +26,6 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext @Override ServerBlockContext data(); - @Override - default TileLogicStack getTilesOrNull(BlockFace face) { - return (TileLogicStack) ServerBlockContextRO.Logic.super.getTilesOrNull(face); - } - } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java index 1ffb30d..ca2e09f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java @@ -20,16 +20,13 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataContextRO { - public interface Logic extends ServerWorldContextRO.Logic, - BlockGenericContextRO { + public interface Logic + extends ServerWorldContextRO.Logic, BlockGenericContextRO { @Override ServerBlockContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java index 335e15f..499408d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java @@ -18,7 +18,6 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockFaceDataContext; -import ru.windcorp.progressia.server.world.TileLogicStack; public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBlockContext, ServerBlockFaceContextRO { @@ -27,11 +26,6 @@ public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBloc @Override ServerBlockFaceContext data(); - @Override - default TileLogicStack getTilesOrNull() { - return (TileLogicStack) ServerBlockFaceContextRO.Logic.super.getTilesOrNull(); - } - } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java index 7fca1db..b1a3f05 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java @@ -20,16 +20,13 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockFaceDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerBlockFaceContextRO extends ServerBlockContextRO, BlockFaceDataContextRO { - public interface Logic extends ServerBlockContextRO.Logic, - BlockFaceGenericContextRO { + public interface Logic + extends ServerBlockContextRO.Logic, BlockFaceGenericContextRO { @Override ServerBlockFaceContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java index bb218ab..052718f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java @@ -51,9 +51,7 @@ public interface ServerContext extends Context { * * @return the length of the last server tick */ - default double getTickLength() { - return getServer().getTickLength(); - } + double getTickLength(); /** * Adjusts the provided value according to tick length assuming the value diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java index 5d5a3c0..7682287 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java @@ -18,7 +18,6 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.TileDataContext; -import ru.windcorp.progressia.server.world.TileLogicReference; public interface ServerTileContext extends TileDataContext, ServerBlockFaceContext, ServerTileContextRO { @@ -27,11 +26,6 @@ public interface ServerTileContext extends TileDataContext, ServerBlockFaceConte @Override ServerTileContext data(); - @Override - default TileLogicReference getTileReference() { - return (TileLogicReference) ServerTileContextRO.Logic.super.getTileReference(); - } - } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java index 73b8d2c..b5a42df 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java @@ -20,16 +20,13 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.TileDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerTileContextRO extends ServerBlockFaceContextRO, TileDataContextRO { - public interface Logic extends ServerBlockFaceContextRO.Logic, - TileGenericContextRO { + public interface Logic + extends ServerBlockFaceContextRO.Logic, TileGenericContextRO { @Override ServerTileContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java index ee04242..b8504c4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java @@ -17,22 +17,14 @@ */ package ru.windcorp.progressia.server.world.context; -import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.WorldDataContext; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.server.world.TileLogicStack; -import ru.windcorp.progressia.server.world.WorldLogic; public interface ServerWorldContext extends WorldDataContext, ServerWorldContextRO { - public interface Logic extends ServerWorldContextRO.Logic, - WorldLogic { + public interface Logic extends ServerWorldContextRO.Logic { @Override ServerWorldContext data(); - - @Override - TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java index 43eeedc..0202024 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java @@ -3,20 +3,12 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.WorldDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; -import ru.windcorp.progressia.server.world.WorldLogicRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext { - public interface Logic - extends - WorldGenericContextRO, - WorldLogicRO, - ServerContext { + public interface Logic extends WorldGenericContextRO, ServerContext { /** * Acquires the data view of this context. Use this method to diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java index fdffd22..6131776 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java @@ -37,9 +37,14 @@ import ru.windcorp.progressia.server.world.context.ServerWorldContextRO; * when a {@link WorldLogic} (or a {@link WorldLogicRO}) instance requires a * context wrapper. *

      - * Use other unutilized instances of {@link ReusableServerContext} or + * Use other unutilized instances of {@code ReusableServerContext} or * {@link #empty()} static method to acquire a usable instance. *

      + * {@code ReusableServerContext} asserts that is it {@linkplain #isReal() real} + * and {@linkplain #isImmediate() immediate}. It creates and provides an + * independent randomness source. The tick length is consulted with the server. + * Use wrappers to alter these properties. + *

      * This class defines the outward-facing safe interface of the actual * implementation located in {@link ReusableServerContextImpl}. The reasoning * for creating a subclass is to allow a single instance to implement both diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java index 2336937..7e4545d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java @@ -23,7 +23,6 @@ import java.util.Random; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.state.StateChange; import ru.windcorp.progressia.common.state.StatefulObject; -import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.WorldData; @@ -34,10 +33,11 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TileLogicStack; import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.tile.TileLogic; class ReusableServerContextImpl extends ReusableServerContext implements ReusableServerContextBuilders.Empty, ReusableServerContextBuilders.WithWorld, @@ -61,7 +61,13 @@ class ReusableServerContextImpl extends ReusableServerContext * The relevant {@link WorldLogic} instance. If this is {@code null}, the * role is {@link Role#NONE}. */ - protected WorldLogic world; + protected WorldLogic worldLogic; + + /** + * The {@link WorldData} accessible through {@link #worldLogic}. This field + * is kept always in sync with {@link #worldLogic}. + */ + protected WorldData worldData; /** * The relevant location. If this is {@code null}, the role is @@ -85,7 +91,12 @@ class ReusableServerContextImpl extends ReusableServerContext * The index of the relevant tile. This value is {@code -1} unless the role * is {@link Role#TILE}. */ - protected int index; + protected int layer; + + /** + * The {@link Random} instance exposed with {@link #getRandom()}. + */ + protected final Random random = new Random(); /** * Determines whether this object currently acts as a builder or a context. @@ -98,7 +109,7 @@ class ReusableServerContextImpl extends ReusableServerContext * ends. This is always 0 when the object is a builder. */ protected int subcontextDepth = 0; - + /** * The Logic view returned by {@link #logic()}. */ @@ -117,7 +128,7 @@ class ReusableServerContextImpl extends ReusableServerContext return Role.WORLD; if (blockFace == null) return Role.LOCATION; - if (index == -1) + if (layer == -1) return Role.TILE_STACK; return Role.TILE; } @@ -179,7 +190,7 @@ class ReusableServerContextImpl extends ReusableServerContext location.y, location.z, blockFace, - index + layer ); break; case TILE_STACK: @@ -216,10 +227,11 @@ class ReusableServerContextImpl extends ReusableServerContext } server = null; - world = null; + worldLogic = null; + worldData = null; location = null; blockFace = null; - index = -1; + layer = -1; isBuilder = true; @@ -246,7 +258,8 @@ class ReusableServerContextImpl extends ReusableServerContext public WithWorld in(Server server, WorldLogic world) { requireBuilderRole(Role.NONE); this.server = server; - this.world = world; + this.worldLogic = world; + this.worldData = world.getData(); return this; } @@ -272,11 +285,11 @@ class ReusableServerContextImpl extends ReusableServerContext this.blockFace = side; return this; } - + @Override public WithTileStack on(BlockFace side) { requireBuilderRole(Role.LOCATION); - this.blockFace = side.relativize(world.getData().getUp(location)); + this.blockFace = side.relativize(worldLogic.getData().getUp(location)); return this; } @@ -287,91 +300,10 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public ReusableServerContext index(int index) { requireBuilderRole(Role.TILE_STACK); - this.index = index; + this.layer = index; return build(); } - /* - * ServerWorldContext.Logic STUFF - */ - - private class Logic implements ServerTileContext.Logic { - @Override - public boolean isReal() { - return ReusableServerContextImpl.this.isReal(); - } - - @Override - public Collection getChunks() { - return world.getChunks(); - } - - @Override - public Collection getEntities() { - return ReusableServerContextImpl.this.getEntities(); - } - - @Override - public EntityData getEntity(long entityId) { - return ReusableServerContextImpl.this.getEntity(entityId); - } - - @Override - public Server getServer() { - return ReusableServerContextImpl.this.getServer(); - } - - @Override - public Random getRandom() { - return ReusableServerContextImpl.this.getRandom(); - } - - @Override - public Vec3i getLocation() { - return ReusableServerContextImpl.this.getLocation(); - } - - @Override - public RelFace getFace() { - return ReusableServerContextImpl.this.getFace(); - } - - @Override - public int getLayer() { - return ReusableServerContextImpl.this.getLayer(); - } - - @Override - public TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face) { - return world.getTiles(blockInWorld, face); - } - - @Override - public ChunkLogic getChunk(Vec3i pos) { - return world.getChunk(pos); - } - - @Override - public WorldData getData() { - return world.getData(); - } - - @Override - public ServerTileContext data() { - return ReusableServerContextImpl.this; - } - - @Override - public String toString() { - return ReusableServerContextImpl.this + ".Logic"; - } - } - - @Override - public Logic logic() { - return logic; - } - /* * LOCATION GETTERS */ @@ -381,139 +313,326 @@ class ReusableServerContextImpl extends ReusableServerContext assert requireContextRole(Role.WORLD); return server; } - + @Override public Vec3i getLocation() { assert requireContextRole(Role.LOCATION); return location; } - + @Override public RelFace getFace() { assert requireContextRole(Role.TILE_STACK); return blockFace; } - + @Override public int getLayer() { assert requireContextRole(Role.TILE); - return index; + return layer; } /* * RO CONTEXT INTERFACE */ - + @Override public boolean isReal() { assert requireContextRole(Role.WORLD); return true; } - + @Override public Random getRandom() { assert requireContextRole(Role.WORLD); - return server.getAdHocRandom(); + return random; } - + @Override - public ChunkData getChunk(Vec3i pos) { + public double getTickLength() { assert requireContextRole(Role.WORLD); - return world.getData().getChunk(pos); + return server.getTickLength(); } - + @Override - public Collection getChunks() { + public BlockData getBlock(Vec3i location) { assert requireContextRole(Role.WORLD); - return world.getData().getChunks(); + return worldData.getBlock(location); } - + + @Override + public boolean isLocationLoaded(Vec3i location) { + assert requireContextRole(Role.WORLD); + return worldData.isLocationLoaded(location); + } + + @Override + public TileData getTile(Vec3i location, BlockFace face, int layer) { + assert requireContextRole(Role.WORLD); + return worldData.getTile(location, face, layer); + } + + @Override + public boolean hasTile(Vec3i location, BlockFace face, int layer) { + assert requireContextRole(Role.WORLD); + return worldData.hasTile(location, face, layer); + } + + @Override + public TileData getTileByTag(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileDataStack stack = worldData.getTilesOrNull(location, face); + if (stack == null) + return null; + int layer = stack.getIndexByTag(tag); + if (layer == -1) + return null; + return stack.get(layer); + } + + @Override + public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileDataStack stack = worldData.getTilesOrNull(location, face); + if (stack == null) + return false; + return stack.getIndexByTag(tag) != -1; + } + + @Override + public int getTag() { + assert requireContextRole(Role.TILE); + TileDataStack stack = worldData.getTilesOrNull(location, blockFace); + if (stack == null) + return -1; + return stack.getTagByIndex(layer); + } + + @Override + public int getTileCount(Vec3i location, BlockFace face) { + assert requireContextRole(Role.TILE_STACK); + TileDataStack stack = worldData.getTilesOrNull(location, blockFace); + if (stack == null) + return 0; + return stack.size(); + } + @Override public Collection getEntities() { assert requireContextRole(Role.WORLD); - return world.getEntities(); + return worldData.getEntities(); } - + @Override public EntityData getEntity(long entityId) { assert requireContextRole(Role.WORLD); - return world.getEntity(entityId); + return worldData.getEntity(entityId); } - + @Override public GravityModel getGravityModel() { assert requireContextRole(Role.WORLD); - return world.getData().getGravityModel(); + return worldData.getGravityModel(); } - + @Override public float getTime() { assert requireContextRole(Role.WORLD); - return world.getData().getTime(); + return worldData.getTime(); } - /* - * RO CONTEXT OPTIMIZATIONS - */ - /* * RW CONTEXT INTERFACE */ - + @Override public boolean isImmediate() { assert requireContextRole(Role.WORLD); return true; } - + @Override - public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { + public void setBlock(Vec3i blockInWorld, BlockData block) { assert requireContextRole(Role.WORLD); - world.getData().setBlock(blockInWorld, block, notify); + worldData.setBlock(blockInWorld, block, true); } - + @Override public void addTile(Vec3i location, BlockFace face, TileData tile) { assert requireContextRole(Role.WORLD); - world.getData().getTiles(location, face).addFarthest(tile); + worldData.getTiles(location, face).addFarthest(tile); } - + @Override public void removeTile(Vec3i location, BlockFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = world.getData().getTilesOrNull(location, face); - if (stack == null) return; - int index = stack.getIndexByTag(tag); - if (index == -1) return; - stack.remove(index); + TileDataStack stack = worldData.getTilesOrNull(location, face); + if (stack == null) + return; + int layer = stack.getIndexByTag(tag); + if (layer == -1) + return; + stack.remove(layer); } - + @Override public void addEntity(EntityData entity) { assert requireContextRole(Role.WORLD); - world.getData().addEntity(entity); + worldData.addEntity(entity); } - + @Override public void removeEntity(long entityId) { assert requireContextRole(Role.WORLD); - world.getData().removeEntity(entityId); + worldData.removeEntity(entityId); } - + @Override public void changeEntity(SE entity, StateChange change) { assert requireContextRole(Role.WORLD); - world.getData().changeEntity(entity, change); + worldData.changeEntity(entity, change); } - + @Override public void advanceTime(float change) { assert requireContextRole(Role.WORLD); - world.getData().advanceTime(change); + worldData.advanceTime(change); } /* - * RW CONTEXT OPTIMIZATIONS + * ServerWorldContext.Logic STUFF */ + private class Logic implements ServerTileContext.Logic { + + /* + * LOCATION GETTERS + */ + + @Override + public Server getServer() { + return server; + } + + @Override + public Vec3i getLocation() { + return location; + } + + @Override + public RelFace getFace() { + return blockFace; + } + + @Override + public int getLayer() { + return layer; + } + + /* + * RO CONTEXT INTERFACE + */ + + @Override + public boolean isReal() { + return true; + } + + @Override + public Random getRandom() { + return random; + } + + @Override + public double getTickLength() { + return server.getTickLength(); + } + + @Override + public BlockLogic getBlock(Vec3i location) { + assert requireContextRole(Role.WORLD); + return worldLogic.getBlock(location); + } + + @Override + public boolean isLocationLoaded(Vec3i location) { + return worldData.isLocationLoaded(location); + } + + @Override + public boolean hasTile(Vec3i location, BlockFace face, int layer) { + return worldData.hasTile(location, face, layer); + } + + @Override + public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + return ReusableServerContextImpl.this.isTagValid(location, face, tag); + } + + @Override + public TileLogic getTile(Vec3i location, BlockFace face, int layer) { + assert requireContextRole(Role.WORLD); + return worldLogic.getTile(location, face, layer); + } + + @Override + public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileLogicStack stack = worldLogic.getTilesOrNull(location, face); + if (stack == null) { + return null; + } + int layer = stack.getIndexByTag(tag); + if (layer == -1) { + return null; + } + return stack.get(layer); + } + + @Override + public int getTileCount(Vec3i location, BlockFace face) { + assert requireContextRole(Role.WORLD); + TileLogicStack stack = worldLogic.getTilesOrNull(location, face); + if (stack == null) { + return 0; + } + return stack.size(); + } + + @Override + public int getTag() { + return ReusableServerContextImpl.this.getTag(); + } + + @Override + public Collection getEntities() { + return worldLogic.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return worldLogic.getEntity(entityId); + } + + /* + * MISC + */ + + @Override + public ReusableServerContext data() { + return ReusableServerContextImpl.this; + } + + @Override + public String toString() { + return ReusableServerContextImpl.this + ".Logic"; + } + } + + @Override + public Logic logic() { + assert requireContextRole(Role.WORLD); + return logic; + } + } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java index 7d3ec10..43a218e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java @@ -177,7 +177,7 @@ public class SurfaceWorld public boolean isBlockLoadedSfc(Vec3i surfaceBlockInWorld) { Vec3i blockInWorld = Vectors.grab3i(); resolve(surfaceBlockInWorld, blockInWorld); - boolean result = parent.isBlockLoaded(blockInWorld); + boolean result = parent.isLocationLoaded(blockInWorld); Vectors.release(blockInWorld); return result; } From 80541eafc3f5a415b95cd057afea5e8b9141cfe5 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 5 Aug 2021 19:39:39 +0300 Subject: [PATCH 42/63] Renamed BlockFace contexts into TileStack contexts --- .../common/world/context/TileDataContext.java | 2 +- .../common/world/context/TileDataContextRO.java | 2 +- ...eDataContext.java => TileStackDataContext.java} | 8 ++++---- ...aContextRO.java => TileStackDataContextRO.java} | 6 +++--- .../generic/context/TileGenericContextRO.java | 2 +- .../generic/context/TileGenericContextWO.java | 2 +- ...ntextRO.java => TileStackGenericContextRO.java} | 2 +- ...ntextWO.java => TileStackGenericContextWO.java} | 2 +- .../world/generic/context/WorldContexts.java | 2 +- .../server/world/context/ServerTileContext.java | 4 ++-- .../server/world/context/ServerTileContextRO.java | 4 ++-- ...aceContext.java => ServerTileStackContext.java} | 10 +++++----- ...ontextRO.java => ServerTileStackContextRO.java} | 12 ++++++------ .../world/context/impl/ReusableServerContext.java | 14 +++----------- 14 files changed, 32 insertions(+), 40 deletions(-) rename src/main/java/ru/windcorp/progressia/common/world/context/{BlockFaceDataContext.java => TileStackDataContext.java} (82%) rename src/main/java/ru/windcorp/progressia/common/world/context/{BlockFaceDataContextRO.java => TileStackDataContextRO.java} (84%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{BlockFaceGenericContextRO.java => TileStackGenericContextRO.java} (98%) rename src/main/java/ru/windcorp/progressia/common/world/generic/context/{BlockFaceGenericContextWO.java => TileStackGenericContextWO.java} (98%) rename src/main/java/ru/windcorp/progressia/server/world/context/{ServerBlockFaceContext.java => ServerTileStackContext.java} (73%) rename src/main/java/ru/windcorp/progressia/server/world/context/{ServerBlockFaceContextRO.java => ServerTileStackContextRO.java} (73%) diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java index 3f4a0d6..78538c4 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.common.world.tile.TileData; public interface TileDataContext extends TileGenericContextWO, - BlockFaceDataContext, + TileStackDataContext, TileDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java index e143e03..e9f2d41 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java @@ -24,7 +24,7 @@ import ru.windcorp.progressia.common.world.tile.TileData; public interface TileDataContextRO extends TileGenericContextRO, - BlockFaceDataContextRO { + TileStackDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java similarity index 82% rename from src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java rename to src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java index b12c36c..12ded3c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java @@ -19,13 +19,13 @@ package ru.windcorp.progressia.common.world.context; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextWO; +import ru.windcorp.progressia.common.world.generic.context.TileStackGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; -public interface BlockFaceDataContext - extends BlockFaceGenericContextWO, +public interface TileStackDataContext + extends TileStackGenericContextWO, BlockDataContext, - BlockFaceDataContextRO { + TileStackDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java similarity index 84% rename from src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java rename to src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java index a20355a..1e3a46d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java @@ -19,11 +19,11 @@ package ru.windcorp.progressia.common.world.context; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; +import ru.windcorp.progressia.common.world.generic.context.TileStackGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; -public interface BlockFaceDataContextRO - extends BlockFaceGenericContextRO, +public interface TileStackDataContextRO + extends TileStackGenericContextRO, BlockDataContext { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java index daf7fb8..bdc5b69 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java @@ -30,7 +30,7 @@ public interface TileGenericContextRO< B extends BlockGeneric, T extends TileGeneric, E extends EntityGeneric -> extends WorldContexts.Tile, BlockFaceGenericContextRO { +> extends WorldContexts.Tile, TileStackGenericContextRO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java index 4c2b4dd..ae8a2ff 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java @@ -32,7 +32,7 @@ public interface TileGenericContextWO< B extends BlockGeneric, T extends TileGeneric, E extends EntityGeneric -> extends WorldContexts.Tile, BlockFaceGenericContextWO { +> extends WorldContexts.Tile, TileStackGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java index 0ca350a..082788b 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java @@ -26,7 +26,7 @@ import ru.windcorp.progressia.common.world.generic.*; * not actually exist. */ //@formatter:off -public interface BlockFaceGenericContextRO< +public interface TileStackGenericContextRO< B extends BlockGeneric, T extends TileGeneric, E extends EntityGeneric diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java rename to src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java index dd6c5ad..28c87ee 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java @@ -28,7 +28,7 @@ import ru.windcorp.progressia.common.world.generic.*; * stack may or may not actually exist. */ //@formatter:off -public interface BlockFaceGenericContextWO< +public interface TileStackGenericContextWO< B extends BlockGeneric, T extends TileGeneric, E extends EntityGeneric diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java index 69c5f94..4dd8c19 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -78,7 +78,7 @@ class WorldContexts { /** * A {@link Context} with a world instance, a block location and a block face * (block side). This interface should not be implemented directly; see - * {@link BlockFaceGenericContextRO} or {@link BlockFaceGenericContextWO}. + * {@link TileStackGenericContextRO} or {@link TileStackGenericContextWO}. * * @author javapony * diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java index 7682287..bc5fe6c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java @@ -19,9 +19,9 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.TileDataContext; -public interface ServerTileContext extends TileDataContext, ServerBlockFaceContext, ServerTileContextRO { +public interface ServerTileContext extends TileDataContext, ServerTileStackContext, ServerTileContextRO { - public interface Logic extends ServerTileContextRO.Logic, ServerBlockFaceContext.Logic { + public interface Logic extends ServerTileContextRO.Logic, ServerTileStackContext.Logic { @Override ServerTileContext data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java index b5a42df..87faf0c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java @@ -23,10 +23,10 @@ import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; -public interface ServerTileContextRO extends ServerBlockFaceContextRO, TileDataContextRO { +public interface ServerTileContextRO extends ServerTileStackContextRO, TileDataContextRO { public interface Logic - extends ServerBlockFaceContextRO.Logic, TileGenericContextRO { + extends ServerTileStackContextRO.Logic, TileGenericContextRO { @Override ServerTileContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java similarity index 73% rename from src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java rename to src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java index 499408d..938271b 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java @@ -17,18 +17,18 @@ */ package ru.windcorp.progressia.server.world.context; -import ru.windcorp.progressia.common.world.context.BlockFaceDataContext; +import ru.windcorp.progressia.common.world.context.TileStackDataContext; -public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBlockContext, ServerBlockFaceContextRO { +public interface ServerTileStackContext extends TileStackDataContext, ServerBlockContext, ServerTileStackContextRO { - public interface Logic extends ServerBlockFaceContextRO.Logic, ServerBlockContext.Logic { + public interface Logic extends ServerTileStackContextRO.Logic, ServerBlockContext.Logic { @Override - ServerBlockFaceContext data(); + ServerTileStackContext data(); } @Override - ServerBlockFaceContext.Logic logic(); + ServerTileStackContext.Logic logic(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java similarity index 73% rename from src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java rename to src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java index b1a3f05..0b33933 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java @@ -17,23 +17,23 @@ */ package ru.windcorp.progressia.server.world.context; -import ru.windcorp.progressia.common.world.context.BlockFaceDataContextRO; +import ru.windcorp.progressia.common.world.context.TileStackDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; +import ru.windcorp.progressia.common.world.generic.context.TileStackGenericContextRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; -public interface ServerBlockFaceContextRO extends ServerBlockContextRO, BlockFaceDataContextRO { +public interface ServerTileStackContextRO extends ServerBlockContextRO, TileStackDataContextRO { public interface Logic - extends ServerBlockContextRO.Logic, BlockFaceGenericContextRO { + extends ServerBlockContextRO.Logic, TileStackGenericContextRO { @Override - ServerBlockFaceContextRO data(); + ServerTileStackContextRO data(); } @Override - ServerBlockFaceContextRO.Logic logic(); + ServerTileStackContextRO.Logic logic(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java index 6131776..345ff37 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java @@ -20,15 +20,7 @@ package ru.windcorp.progressia.server.world.context.impl; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.WorldLogicRO; -import ru.windcorp.progressia.server.world.context.ServerBlockContext; -import ru.windcorp.progressia.server.world.context.ServerBlockContextRO; -import ru.windcorp.progressia.server.world.context.ServerBlockFaceContext; -import ru.windcorp.progressia.server.world.context.ServerBlockFaceContextRO; -import ru.windcorp.progressia.server.world.context.ServerContext; -import ru.windcorp.progressia.server.world.context.ServerTileContext; -import ru.windcorp.progressia.server.world.context.ServerTileContextRO; -import ru.windcorp.progressia.server.world.context.ServerWorldContext; -import ru.windcorp.progressia.server.world.context.ServerWorldContextRO; +import ru.windcorp.progressia.server.world.context.*; /** * An implementation of the entire {@link ServerContext} tree. The objects of @@ -75,8 +67,8 @@ public abstract class ReusableServerContext implements ServerTileContext { */ LOCATION, /** - * This object conforms to {@link ServerBlockFaceContext} or - * {@link ServerBlockFaceContextRO}. + * This object conforms to {@link ServerTileStackContext} or + * {@link ServerTileStackContextRO}. */ TILE_STACK, /** From 15f741bc04bb4e3a792e61cae158f48c0a6a4db0 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 6 Aug 2021 10:49:40 +0300 Subject: [PATCH 43/63] Added subcontexting. Context#subcontexting. --- .../world/context/BlockDataContext.java | 32 ++- .../world/context/BlockDataContextRO.java | 32 ++- .../common/world/context/Context.java | 84 +++++--- .../common/world/context/TileDataContext.java | 14 +- .../world/context/TileDataContextRO.java | 14 +- .../world/context/TileStackDataContext.java | 21 +- .../world/context/TileStackDataContextRO.java | 21 +- .../world/context/WorldDataContext.java | 15 ++ .../world/context/WorldDataContextRO.java | 15 ++ .../generic/context/AbstractContextRO.java | 95 +++++++++ .../context/BlockGenericContextRO.java | 32 +++ .../context/BlockGenericContextWO.java | 32 +++ .../generic/context/TileGenericContextRO.java | 14 ++ .../generic/context/TileGenericContextWO.java | 14 ++ .../context/TileStackGenericContextRO.java | 21 +- .../context/TileStackGenericContextWO.java | 21 +- .../world/generic/context/WorldContexts.java | 197 ++++++++++++++++-- .../context/WorldGenericContextRO.java | 14 ++ .../context/WorldGenericContextWO.java | 14 ++ .../world/context/ServerBlockContext.java | 53 +++++ .../world/context/ServerBlockContextRO.java | 53 +++++ .../world/context/ServerTileContext.java | 20 ++ .../world/context/ServerTileContextRO.java | 20 ++ .../world/context/ServerTileStackContext.java | 30 +++ .../context/ServerTileStackContextRO.java | 30 +++ .../world/context/ServerWorldContext.java | 20 ++ .../world/context/ServerWorldContextRO.java | 20 ++ .../context/impl/ReusableServerContext.java | 31 ++- .../impl/ReusableServerContextImpl.java | 109 +++++----- 29 files changed, 978 insertions(+), 110 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java index 3462048..9667eac 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java @@ -17,9 +17,12 @@ */ package ru.windcorp.progressia.common.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO; +import ru.windcorp.progressia.common.world.rels.AbsRelation; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContext @@ -27,6 +30,33 @@ public interface BlockDataContext WorldDataContext, BlockDataContextRO { - // currently empty + /* + * Subcontexting + */ + + @Override + default BlockDataContext pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default BlockDataContext pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default BlockDataContext pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default TileStackDataContext push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default TileDataContext push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java index 70ad8f4..7d35ec3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java @@ -17,15 +17,45 @@ */ package ru.windcorp.progressia.common.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; +import ru.windcorp.progressia.common.world.rels.AbsRelation; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContextRO extends BlockGenericContextRO, WorldDataContextRO { - // currently empty + /* + * Subcontexting + */ + + @Override + default BlockDataContextRO pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default BlockDataContextRO pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default BlockDataContextRO pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default TileStackDataContextRO push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default TileDataContextRO push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/Context.java b/src/main/java/ru/windcorp/progressia/common/world/context/Context.java index bfbd164..73644ea 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/Context.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/Context.java @@ -17,11 +17,15 @@ */ package ru.windcorp.progressia.common.world.context; +import ru.windcorp.progressia.common.world.generic.context.AbstractContextRO; + /** * A cursor-like object for retrieving information about an in-game environment. * A context object typically holds a reference to some sort of data structure * and a cursor pointing to a location in that data structure. The exact meaning - * of "environment" and "location" is defined by extending interfaces. + * of "environment" and "location" is defined by extending interfaces. The terms + * relevant and implied should be understood to refer to the + * aforementioned location. *

      * Context objects are intended to be the primary way of interacting for in-game * content. Wherever possible, context objects should be preferred over other @@ -41,37 +45,48 @@ package ru.windcorp.progressia.common.world.context; * thread-safe and are often pooled and reused. *

      *

      Subcontexting

      - * Subcontexting is the invocation of user-provided code with a context - * object derived from an existing one. For example, block context provides a - * convenience method for referencing the block's neighbor: + * Context objects allow subcontexting. Subcontexting is the temporary + * modification of the context object. Contexts use a stack approach to + * modification: all modifications must be reverted in the reversed order they + * were applied. + *

      + * Modification methods are usually named {@code pushXXX}. To revert + * the most recent non-reverted modification, use {@link #pop()}. As a general + * rule, a method that is given a context must always {@link #pop()} every + * change it has pushed. Failure to abide by this contract results in bugs that + * is difficult to trace. + *

      + * Although various push methods declare differing result types, the same object + * is always returned: * *

      - * blockContextA.forNeighbor(RelFace.UP, blockContextB -> {
      - * 	foo(blockContextA); // undefined behavior!
      - * 	foo(blockContextB); // correct
      - * });
      + * someContext.pushXXX() == someContext
        * 
      * - * In this example, {@code forNeighbor} is a subcontexting method, - * {@code blockContextA} is the parent context, {@code blockContextB} is the - * subcontext, and the lambda is the context consumer. - *

      - * Parent contexts are invalid while the subcontexting method is - * running. Referencing {@code blockContextA} from inside the lambda - * creates undefined behavior. - *

      - * This restriction exists because some implementations of contexts may - * implement subcontexting by simply modifying the parent context for the - * duration of the call and presenting the temporarily modified parent context - * as the subcontext: + * Therefore invoking {@link #pop()} is valid using both the original reference + * and the obtained reference. + *

      Subcontexting example

      + * Given a {@link ru.windcorp.progressia.common.world.context.BlockDataContext + * BlockDataContext} {@code a} one can process the tile stack on the top of the + * relevant block by using * *
      - * public void forNeighbor(BlockFace face, Consumer<BlockContext> action) {
      - * 	this.position.add(face);
      - * 	action.accept(this);
      - * 	this.position.sub(face);
      - * }
      + * TileStackDataContext b = a.push(RelFace.TOP);
      + * processTileStack(b);
      + * b.pop();
        * 
      + * + * One can improve readability by eliminating the temporary variable: + * + *
      + * processTileStack(a.push(RelFace.TOP));
      + * a.pop();
      + * 
      + * + * Notice that {@code a.pop()} and {@code b.pop()} are interchangeable. + * + * @see AbstractContextRO + * @author javapony */ public interface Context { @@ -102,4 +117,23 @@ public interface Context { */ boolean isReal(); + /** + * Reverts the more recent modification to this object that has not been + * reverted yet. + *

      + * Context objects may be modified temporarily with various push methods + * (see subcontexting). To revert the most + * recent non-reverted modification, use {@link #pop()}. As a general rule, + * a method that is given a context must always {@link #pop()} every change + * it has pushed. Failure to abide by this contract results in bugs that is + * difficult to trace. + *

      + * This method may be invoked using either the original reference or the + * reference provided by push method. + *

      + * This method fails with an {@link IllegalStateException} when there are no + * modifications to revert. + */ + void pop(); + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java index 78538c4..b424b2f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java @@ -27,6 +27,18 @@ public interface TileDataContext TileStackDataContext, TileDataContextRO { - // currently empty + /* + * Subcontexting + */ + + @Override + default TileDataContext pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default TileDataContext pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java index e9f2d41..f6979e2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java @@ -26,6 +26,18 @@ public interface TileDataContextRO extends TileGenericContextRO, TileStackDataContextRO { - // currently empty + /* + * Subcontexting + */ + + @Override + default TileDataContextRO pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default TileDataContextRO pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java index 12ded3c..1751a50 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContext.java @@ -26,7 +26,24 @@ public interface TileStackDataContext extends TileStackGenericContextWO, BlockDataContext, TileStackDataContextRO { - - // currently empty + + /* + * Subcontexting + */ + + @Override + default TileDataContext push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default TileStackDataContext pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default TileStackDataContext pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java index 1e3a46d..bcdb948 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileStackDataContextRO.java @@ -24,8 +24,25 @@ import ru.windcorp.progressia.common.world.tile.TileData; public interface TileStackDataContextRO extends TileStackGenericContextRO, - BlockDataContext { + BlockDataContextRO { - // currently empty + /* + * Subcontexting + */ + + @Override + default TileDataContextRO push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default TileStackDataContextRO pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default TileStackDataContextRO pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java index 68965b5..9dcb0ae 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java @@ -17,9 +17,11 @@ */ package ru.windcorp.progressia.common.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextWO; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface WorldDataContext @@ -35,5 +37,18 @@ public interface WorldDataContext * @see #getTime() */ void advanceTime(float change); + + /* + * Subcontexting + */ + + @Override + BlockDataContext push(Vec3i location); + + @Override + TileStackDataContext push(Vec3i location, RelFace face); + + @Override + TileDataContext push(Vec3i location, RelFace face, int layer); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java index 8201738..be037bf 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java @@ -18,10 +18,12 @@ package ru.windcorp.progressia.common.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; public interface WorldDataContextRO extends WorldGenericContextRO { @@ -43,5 +45,18 @@ public interface WorldDataContextRO extends WorldGenericContextRO. + */ +package ru.windcorp.progressia.common.world.generic.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.StashingStack; +import ru.windcorp.progressia.common.world.generic.BlockGeneric; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.generic.TileGeneric; +import ru.windcorp.progressia.common.world.rels.RelFace; + +//@formatter:off +public abstract class AbstractContextRO< + B extends BlockGeneric, + T extends TileGeneric, + E extends EntityGeneric +> implements TileGenericContextRO { +//@formatter:on + + public static final int MAX_SUBCONTEXTS = 64; + + protected class Frame { + + public final Vec3i location = new Vec3i(); + public RelFace face; + public int layer; + + } + + protected Frame frame = null; + + private final StashingStack frameStack = new StashingStack<>(MAX_SUBCONTEXTS, Frame::new); + + @Override + public void pop() { + if (!isSubcontexting()) { + throw new IllegalStateException("Cannot pop(): already top frame"); + } + + frame = frameStack.pop(); + } + + @Override + public BlockGenericContextRO push(Vec3i location) { + frame = frameStack.push(); + + frame.location.set(location.x, location.y, location.z); + frame.face = null; + frame.layer = -1; + + return this; + } + + @Override + public TileStackGenericContextRO push(Vec3i location, RelFace face) { + frame = frameStack.push(); + + frame.location.set(location.x, location.y, location.z); + frame.face = face; + frame.layer = -1; + + return this; + } + + @Override + public TileGenericContextRO push(Vec3i location, RelFace face, int layer) { + frame = frameStack.push(); + + frame.location.set(location.x, location.y, location.z); + frame.face = face; + frame.layer = layer; + + return this; + } + + public boolean isSubcontexting() { + return frameStack.isEmpty(); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index 239a02e..842fd0a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -17,9 +17,12 @@ */ package ru.windcorp.progressia.common.world.generic.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; +import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; /** * A {@link Context} referencing a world with a block location specified. The @@ -129,5 +132,34 @@ public interface BlockGenericContextRO< default int getTileCount(BlockFace face) { return getTileCount(face); } + + /* + * Subcontexting + */ + + @Override + default BlockGenericContextRO pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default BlockGenericContextRO pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default BlockGenericContextRO pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default TileStackGenericContextRO push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default TileGenericContextRO push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index ffdb969..97ec62d 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -17,9 +17,12 @@ */ package ru.windcorp.progressia.common.world.generic.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; +import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; /** * A writable {@link Context} referencing a world with a block location @@ -72,5 +75,34 @@ public interface BlockGenericContextWO< default void removeTile(BlockFace face, int tag) { removeTile(getLocation(), face, tag); } + + /* + * Subcontexting + */ + + @Override + default BlockGenericContextWO pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default BlockGenericContextWO pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default BlockGenericContextWO pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default TileStackGenericContextWO push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default TileGenericContextWO push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java index bdc5b69..1088a16 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java @@ -56,5 +56,19 @@ public interface TileGenericContextRO< default T getTile() { return getTile(getLocation(), getFace(), getLayer()); } + + /* + * Subcontexting + */ + + @Override + default TileGenericContextRO pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default TileGenericContextRO pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java index ae8a2ff..1193f51 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java @@ -43,5 +43,19 @@ public interface TileGenericContextWO< default void removeTile() { removeTile(getLocation(), getFace(), getTag()); } + + /* + * Subcontexting + */ + + @Override + default TileGenericContextWO pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default TileGenericContextWO pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java index 082788b..2a5cd3c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextRO.java @@ -30,7 +30,7 @@ public interface TileStackGenericContextRO< B extends BlockGeneric, T extends TileGeneric, E extends EntityGeneric -> extends WorldContexts.BlockFace, BlockGenericContextRO { +> extends WorldContexts.TileStack, BlockGenericContextRO { //@formatter:on /** @@ -100,5 +100,24 @@ public interface TileStackGenericContextRO< default int getTileCount() { return getTileCount(getLocation(), getFace()); } + + /* + * Subcontexting + */ + + @Override + default TileGenericContextRO push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default TileStackGenericContextRO pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default TileStackGenericContextRO pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java index 28c87ee..7a618b9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileStackGenericContextWO.java @@ -32,7 +32,7 @@ public interface TileStackGenericContextWO< B extends BlockGeneric, T extends TileGeneric, E extends EntityGeneric -> extends WorldContexts.BlockFace, BlockGenericContextWO { +> extends WorldContexts.TileStack, BlockGenericContextWO { //@formatter:on /** @@ -59,5 +59,24 @@ public interface TileStackGenericContextWO< default void removeTile(int tag) { removeTile(getLocation(), getFace(), tag); } + + /* + * Subcontexting + */ + + @Override + default TileGenericContextWO push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default TileStackGenericContextWO pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default TileStackGenericContextWO pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java index 4dd8c19..bfc85bb 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -20,19 +20,20 @@ package ru.windcorp.progressia.common.world.generic.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.RelFace; /** * This class defines several {@link Context} subinterfaces that are further * extended by Generic contexts. These interfaces declare methods for - * determining which location is "relevant" to the context. Since they are not - * Java generics they can safely be extended more than once. + * determining which location is "relevant" to the context and the basic + * subcontexting methods. Since they are not Java generics they can safely be + * extended more than once. *

      * Do not reuse these interfaces outside the Generic contexts' package; consider * them to be an implementation detail. * * @author javapony - * */ class WorldContexts { @@ -42,48 +43,149 @@ class WorldContexts { * {@link WorldGenericContextWO}. * * @author javapony - * */ public static interface World extends Context { - // currently empty + /** + * Assigns the specified location to this context. Block face and tile + * layer information is discarded if it was present. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param location the new location to use + * @return this object + * @see #pop() + */ + Block push(Vec3i location); + + /** + * Assigns the specified location and block face to this context. Tile + * layer information is discarded if it was present. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param location the new location to use + * @param face the new block face to use + * @return this object + * @see #pop() + */ + TileStack push(Vec3i location, RelFace face); + + /** + * Assigns the specified position to this context. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param location the new location to use + * @param face the new block face to use + * @param layer the new tile layer to use + * @return this object + * @see #pop() + */ + Tile push(Vec3i location, RelFace face, int layer); } /** - * A {@link Context} with a world instance and a block location. This interface + * A {@link Context} with a world instance and a block location. This + * interface * should not be implemented directly; see {@link BlockGenericContextRO} or * {@link BlockGenericContextWO}. * * @author javapony - * */ public static interface Block extends World { /** * Returns the location of the block. *

      - * The coordinate system in use is not specified, but it is consistent across + * The coordinate system in use is not specified, but it is consistent + * across * all methods of this context. *

      - * The object returned by this method must not be modified. It is only valid + * The object returned by this method must not be modified. It is only + * valid * while the context is {@linkplain valid}. * * @return a vector describing the block's position */ Vec3i getLocation(); + /** + * Shifts the location in the specified direction. Block face and tile + * layer information is discarded if it was present. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param dx the change of the x component + * @param dy the change of the y component + * @param dz the change of the z component + * @return this object + * @see #pop() + */ + default Block pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + /** + * Shifts the location in the specified direction. Block face and tile + * layer information is discarded if it was present. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param direction the change added to the current location + * @return this object + * @see #pop() + */ + default Block pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + /** + * Shifts the location in the specified direction. Block face and tile + * layer information is discarded if it was present. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param direction the change added to the current location + * @return this object + * @see #pop() + */ + default Block pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + /** + * Assigns the specified block face to this context. Tile layer + * information is discarded if it was present. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param face the new block face to use + * @return this object + * @see #pop() + */ + default TileStack push(RelFace face) { + return push(getLocation(), face); + } + + /** + * Assigns the specified block face and tile layer to this context. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param face the new block face to use + * @param layer the new tile layer to use + * @return this object + * @see #pop() + */ + default Tile push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } + } /** - * A {@link Context} with a world instance, a block location and a block face + * A {@link Context} with a world instance, a block location and a block + * face * (block side). This interface should not be implemented directly; see * {@link TileStackGenericContextRO} or {@link TileStackGenericContextWO}. * * @author javapony - * */ - public static interface BlockFace extends Block { + public static interface TileStack extends Block { /** * Returns the face relevant to this context. @@ -92,17 +194,57 @@ class WorldContexts { */ RelFace getFace(); + /** + * Assigns the specified tile layer to this context. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @param layer the new tile layer to use + * @return this object + * @see #pop() + */ + default Tile push(int layer) { + return push(getLocation(), getFace(), layer); + } + + /** + * Assigns the counter face (the face on the opposite side of this + * block) to this context. Tile layer information is discarded if it was + * present. See {@linkplain Context#subcontexting subcontexting} for + * more details. + * + * @return this object + * @see #pop() + */ + default TileStack pushCounter() { + return push(getFace().getCounter()); + } + + /** + * Assigns the face opposite to the current face to this context. The + * current face and its opposite are the only two tile stacks occupying + * the gap between the two respective blocks. Tile layer information is + * discarded if it was present. See {@linkplain Context#subcontexting + * subcontexting} for + * more details. + * + * @return this object + * @see #pop() + */ + default TileStack pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } + } /** * A {@link Context} with a world instance, a block location, a block face * (block side) and a tile layer. This interface should not be implemented - * directly; see {@link TileGenericContextRO} or {@link TileGenericContextWO}. + * directly; see {@link TileGenericContextRO} or + * {@link TileGenericContextWO}. * * @author javapony - * */ - public static interface Tile extends BlockFace { + public static interface Tile extends TileStack { /** * Returns the tile layer relevant to this context. @@ -114,11 +256,34 @@ class WorldContexts { /** * Gets the tag of the tile at the relevant position. * - * @return the tag of the tile or {@code -1} if the location is not loaded + * @return the tag of the tile or {@code -1} if the location is not + * loaded * or the tile does not exist */ int getTag(); + /** + * Assigns the tile layer closer to the host block to this context. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @return this object + * @see #pop() + */ + default Tile pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + /** + * Assigns the tile layer farther to the host block to this context. See + * {@linkplain Context#subcontexting subcontexting} for more details. + * + * @return this object + * @see #pop() + */ + default Tile pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } + } WorldContexts() { diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java index d604d62..59707e9 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java @@ -25,6 +25,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; /** * A {@link Context} with a world instance. @@ -188,4 +189,17 @@ public interface WorldGenericContextRO< }); } + /* + * Subcontexting + */ + + @Override + BlockGenericContextRO push(Vec3i location); + + @Override + TileStackGenericContextRO push(Vec3i location, RelFace face); + + @Override + TileGenericContextRO push(Vec3i location, RelFace face, int layer); + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index ad1291e..0a465a0 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -23,6 +23,7 @@ import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; /** * A writable {@link Context} with a world instance. This context provides @@ -149,5 +150,18 @@ public interface WorldGenericContextWO< * @param change the change to apply */ void changeEntity(SE entity, StateChange change); + + /* + * Subcontexting + */ + + @Override + BlockGenericContextWO push(Vec3i location); + + @Override + TileStackGenericContextWO push(Vec3i location, RelFace face); + + @Override + TileGenericContextWO push(Vec3i location, RelFace face, int layer); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java index 4130b50..c8bdf0b 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java @@ -17,7 +17,10 @@ */ package ru.windcorp.progressia.server.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.BlockDataContext; +import ru.windcorp.progressia.common.world.rels.AbsRelation; +import ru.windcorp.progressia.common.world.rels.RelFace; public interface ServerBlockContext extends BlockDataContext, ServerWorldContext, ServerBlockContextRO { @@ -25,10 +28,60 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext @Override ServerBlockContext data(); + + @Override + default ServerBlockContext.Logic pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default ServerBlockContext.Logic pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default ServerBlockContext.Logic pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default ServerTileStackContext.Logic push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default ServerTileContext.Logic push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } @Override ServerBlockContext.Logic logic(); + + @Override + default ServerBlockContext pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default ServerBlockContext pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default ServerBlockContext pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default ServerTileStackContext push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default ServerTileContext push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java index ca2e09f..eefa195 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java @@ -17,9 +17,12 @@ */ package ru.windcorp.progressia.server.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.BlockDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; +import ru.windcorp.progressia.common.world.rels.AbsRelation; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; @@ -30,10 +33,60 @@ public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataCon @Override ServerBlockContextRO data(); + + @Override + default ServerBlockContextRO.Logic pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default ServerBlockContextRO.Logic pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default ServerBlockContextRO.Logic pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default ServerTileStackContextRO.Logic push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default ServerTileContextRO.Logic push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } @Override ServerBlockContextRO.Logic logic(); + + @Override + default ServerBlockContextRO pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default ServerBlockContextRO pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default ServerBlockContextRO pushRelative(AbsRelation direction) { + return push(direction.getVector()); + } + + @Override + default ServerTileStackContextRO push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default ServerTileContextRO push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java index bc5fe6c..6850f43 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java @@ -25,10 +25,30 @@ public interface ServerTileContext extends TileDataContext, ServerTileStackConte @Override ServerTileContext data(); + + @Override + default ServerTileContext.Logic pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default ServerTileContext.Logic pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } @Override ServerTileContext.Logic logic(); + + @Override + default ServerTileContext pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default ServerTileContext pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java index 87faf0c..18382bd 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java @@ -30,10 +30,30 @@ public interface ServerTileContextRO extends ServerTileStackContextRO, TileDataC @Override ServerTileContextRO data(); + + @Override + default ServerTileContextRO.Logic pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default ServerTileContextRO.Logic pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } @Override ServerTileContextRO.Logic logic(); + + @Override + default ServerTileContextRO pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default ServerTileContextRO pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java index 938271b..7454f26 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContext.java @@ -25,10 +25,40 @@ public interface ServerTileStackContext extends TileStackDataContext, ServerBloc @Override ServerTileStackContext data(); + + @Override + default ServerTileContext.Logic push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default ServerTileStackContext.Logic pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default ServerTileStackContext.Logic pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } @Override ServerTileStackContext.Logic logic(); + + @Override + default ServerTileContext push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default ServerTileStackContext pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default ServerTileStackContext pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java index 0b33933..ef2d476 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileStackContextRO.java @@ -30,10 +30,40 @@ public interface ServerTileStackContextRO extends ServerBlockContextRO, TileStac @Override ServerTileStackContextRO data(); + + @Override + default ServerTileContextRO.Logic push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default ServerTileStackContextRO.Logic pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default ServerTileStackContextRO.Logic pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } @Override ServerTileStackContextRO.Logic logic(); + + @Override + default ServerTileContextRO push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default ServerTileStackContextRO pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default ServerTileStackContextRO pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java index b8504c4..3de8038 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java @@ -17,7 +17,9 @@ */ package ru.windcorp.progressia.server.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.WorldDataContext; +import ru.windcorp.progressia.common.world.rels.RelFace; public interface ServerWorldContext extends WorldDataContext, ServerWorldContextRO { @@ -25,10 +27,28 @@ public interface ServerWorldContext extends WorldDataContext, ServerWorldContext @Override ServerWorldContext data(); + + @Override + ServerBlockContext.Logic push(Vec3i location); + + @Override + ServerTileStackContext.Logic push(Vec3i location, RelFace face); + + @Override + ServerTileContext.Logic push(Vec3i location, RelFace face, int layer); } @Override ServerWorldContext.Logic logic(); + + @Override + ServerBlockContext push(Vec3i location); + + @Override + ServerTileStackContext push(Vec3i location, RelFace face); + + @Override + ServerTileContext push(Vec3i location, RelFace face, int layer); } \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java index 0202024..ff849c1 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java @@ -1,8 +1,10 @@ package ru.windcorp.progressia.server.world.context; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.WorldDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; @@ -18,6 +20,15 @@ public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext * @return a view of this context that returns data objects */ ServerWorldContextRO data(); + + @Override + ServerBlockContextRO.Logic push(Vec3i location); + + @Override + ServerTileStackContextRO.Logic push(Vec3i location, RelFace face); + + @Override + ServerTileContextRO.Logic push(Vec3i location, RelFace face, int layer); } @@ -29,5 +40,14 @@ public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext * @return a view of this context that returns appropriate logic objects */ ServerWorldContextRO.Logic logic(); + + @Override + ServerBlockContextRO push(Vec3i location); + + @Override + ServerTileStackContextRO push(Vec3i location, RelFace face); + + @Override + ServerTileContextRO push(Vec3i location, RelFace face, int layer); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java index 345ff37..d32974c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java @@ -17,7 +17,13 @@ */ package ru.windcorp.progressia.server.world.context.impl; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.context.AbstractContextRO; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.world.WorldLogic; import ru.windcorp.progressia.server.world.WorldLogicRO; import ru.windcorp.progressia.server.world.context.*; @@ -45,7 +51,8 @@ import ru.windcorp.progressia.server.world.context.*; * * @author javapony */ -public abstract class ReusableServerContext implements ServerTileContext { +public abstract class ReusableServerContext extends AbstractContextRO + implements ServerTileContext { /** * An RSC can conform to a variety of different {@link Context} interfaces. @@ -92,9 +99,7 @@ public abstract class ReusableServerContext implements ServerTileContext { * * @return a {@link ReusableServerContextBuilders.Empty} instance that may * be used to reinitialize this object - * @throws IllegalStateException if active subcontexting is detected. - * Detection is done on a best-effort basis; - * do not rely this exception + * @throws IllegalStateException if active subcontexting is detected */ public abstract ReusableServerContextBuilders.Empty reuse() throws IllegalStateException; @@ -115,5 +120,23 @@ public abstract class ReusableServerContext implements ServerTileContext { public static ReusableServerContextBuilders.Empty empty() { return new ReusableServerContextImpl(); } + + @Override + public ReusableServerContext push(Vec3i location) { + super.push(location); + return this; + } + + @Override + public ReusableServerContext push(Vec3i location, RelFace face) { + super.push(location, face); + return this; + } + + @Override + public ReusableServerContext push(Vec3i location, RelFace face, int layer) { + super.push(location, face, layer); + return this; + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java index 7e4545d..2994205 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java @@ -69,30 +69,6 @@ class ReusableServerContextImpl extends ReusableServerContext */ protected WorldData worldData; - /** - * The relevant location. If this is {@code null}, the role is - * {@link Role#WORLD} or {@link Role#NONE}. - */ - protected Vec3i location; - - /** - * A {@code final} reference to the {@link Vec3i} instance used by - * {@link #location}. - */ - protected final Vec3i locationVectorContainer = new Vec3i(); - - /** - * The relevant {@link RelFace}. If the role is {@link Role#TILE_STACK} or - * {@link Role#TILE}, this is not {@code null}. - */ - protected RelFace blockFace; - - /** - * The index of the relevant tile. This value is {@code -1} unless the role - * is {@link Role#TILE}. - */ - protected int layer; - /** * The {@link Random} instance exposed with {@link #getRandom()}. */ @@ -124,11 +100,11 @@ class ReusableServerContextImpl extends ReusableServerContext public Role getRole() { if (server == null) return Role.NONE; - if (location == null) + if (frame == null) return Role.WORLD; - if (blockFace == null) + if (frame.face == null) return Role.LOCATION; - if (layer == -1) + if (frame.layer == -1) return Role.TILE_STACK; return Role.TILE; } @@ -186,19 +162,19 @@ class ReusableServerContextImpl extends ReusableServerContext case TILE: result = String.format( "ServerTileContext[x=%d, y=%d, z=%d, %s, index=%d]", - location.x, - location.y, - location.z, - blockFace, - layer + frame.location.x, + frame.location.y, + frame.location.z, + frame.face, + frame.layer ); break; case TILE_STACK: result = String - .format("ServerBlockFaceContext[x=%d, y=%d, z=%d, %s]", location.x, location.y, location.z, blockFace); + .format("ServerBlockFaceContext[x=%d, y=%d, z=%d, %s]", frame.location.x, frame.location.y, frame.location.z, frame.face); break; case LOCATION: - result = String.format("ServerBlockContext[x=%d, y=%d, z=%d]", location.x, location.y, location.z); + result = String.format("ServerBlockContext[x=%d, y=%d, z=%d]", frame.location.x, frame.location.y, frame.location.z); break; case WORLD: result = String.format("ServerWorldContext"); @@ -222,16 +198,13 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public Empty reuse() { - if (subcontextDepth != 0) { - throw new IllegalStateException("Resetting is not allowed when subcontexting"); - } - server = null; worldLogic = null; worldData = null; - location = null; - blockFace = null; - layer = -1; + + while (isSubcontexting()) { + pop(); + } isBuilder = true; @@ -270,8 +243,7 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public WithLocation at(Vec3i location) { requireBuilderRole(Role.WORLD); - this.location = this.locationVectorContainer; - this.location.set(location.x, location.y, location.z); + push(location); return this; } @@ -282,14 +254,14 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public WithTileStack on(RelFace side) { requireBuilderRole(Role.LOCATION); - this.blockFace = side; + frame.face = side; return this; } @Override public WithTileStack on(BlockFace side) { requireBuilderRole(Role.LOCATION); - this.blockFace = side.relativize(worldLogic.getData().getUp(location)); + frame.face = side.relativize(worldLogic.getData().getUp(frame.location)); return this; } @@ -300,7 +272,7 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public ReusableServerContext index(int index) { requireBuilderRole(Role.TILE_STACK); - this.layer = index; + frame.layer = index; return build(); } @@ -317,19 +289,19 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public Vec3i getLocation() { assert requireContextRole(Role.LOCATION); - return location; + return frame.location; } @Override public RelFace getFace() { assert requireContextRole(Role.TILE_STACK); - return blockFace; + return frame.face; } @Override public int getLayer() { assert requireContextRole(Role.TILE); - return layer; + return frame.layer; } /* @@ -402,16 +374,16 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public int getTag() { assert requireContextRole(Role.TILE); - TileDataStack stack = worldData.getTilesOrNull(location, blockFace); + TileDataStack stack = worldData.getTilesOrNull(frame.location, frame.face); if (stack == null) return -1; - return stack.getTagByIndex(layer); + return stack.getTagByIndex(frame.layer); } @Override public int getTileCount(Vec3i location, BlockFace face) { assert requireContextRole(Role.TILE_STACK); - TileDataStack stack = worldData.getTilesOrNull(location, blockFace); + TileDataStack stack = worldData.getTilesOrNull(frame.location, frame.face); if (stack == null) return 0; return stack.size(); @@ -516,17 +488,17 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public Vec3i getLocation() { - return location; + return frame.location; } @Override public RelFace getFace() { - return blockFace; + return frame.face; } @Override public int getLayer() { - return layer; + return frame.layer; } /* @@ -614,6 +586,33 @@ class ReusableServerContextImpl extends ReusableServerContext return worldLogic.getEntity(entityId); } + /* + * Subcontexting + */ + + @Override + public Logic push(Vec3i location) { + ReusableServerContextImpl.this.push(location); + return this; + } + + @Override + public Logic push(Vec3i location, RelFace face) { + ReusableServerContextImpl.this.push(location, face); + return this; + } + + @Override + public Logic push(Vec3i location, RelFace face, int layer) { + ReusableServerContextImpl.this.push(location, face, layer); + return this; + } + + @Override + public void pop() { + ReusableServerContextImpl.this.pop(); + } + /* * MISC */ From 0f909039fe4c8dd67104e8024651ed487784bbce Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 6 Aug 2021 11:02:43 +0300 Subject: [PATCH 44/63] Renamed ReusableServerContext to DefaultServerContext --- ...Context.java => DefaultServerContext.java} | 28 ++++++++-------- ...java => DefaultServerContextBuilders.java} | 18 +++++------ ...mpl.java => DefaultServerContextImpl.java} | 32 +++++++++---------- 3 files changed, 39 insertions(+), 39 deletions(-) rename src/main/java/ru/windcorp/progressia/server/world/context/impl/{ReusableServerContext.java => DefaultServerContext.java} (79%) rename src/main/java/ru/windcorp/progressia/server/world/context/impl/{ReusableServerContextBuilders.java => DefaultServerContextBuilders.java} (79%) rename src/main/java/ru/windcorp/progressia/server/world/context/impl/{ReusableServerContextImpl.java => DefaultServerContextImpl.java} (93%) diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContext.java similarity index 79% rename from src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java rename to src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContext.java index d32974c..afeadea 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContext.java @@ -44,14 +44,14 @@ import ru.windcorp.progressia.server.world.context.*; * Use wrappers to alter these properties. *

      * This class defines the outward-facing safe interface of the actual - * implementation located in {@link ReusableServerContextImpl}. The reasoning + * implementation located in {@link DefaultServerContextImpl}. The reasoning * for creating a subclass is to allow a single instance to implement both - * {@linkplain ReusableServerContextBuilders builder interfaces} and the context + * {@linkplain DefaultServerContextBuilders builder interfaces} and the context * interface without causing confusion around object states. * * @author javapony */ -public abstract class ReusableServerContext extends AbstractContextRO +public abstract class DefaultServerContext extends AbstractContextRO implements ServerTileContext { /** @@ -87,9 +87,9 @@ public abstract class ReusableServerContext extends AbstractContextRO reference) { + default DefaultServerContext at(TileGenericReferenceRO reference) { if (!reference.isValid()) { throw new IllegalArgumentException("Reference " + reference + " is invalid"); } @@ -54,12 +54,12 @@ public interface ReusableServerContextBuilders { } - public interface WithLocation extends ReusableServerContextBuilders { + public interface WithLocation extends DefaultServerContextBuilders { WithTileStack on(RelFace side); WithTileStack on(BlockFace side); - default ReusableServerContext on(TileGenericReferenceRO reference) { + default DefaultServerContext on(TileGenericReferenceRO reference) { if (!reference.isValid()) { throw new IllegalArgumentException("Reference " + reference + " is invalid"); } @@ -70,11 +70,11 @@ public interface ReusableServerContextBuilders { } - public interface WithTileStack extends ReusableServerContextBuilders { + public interface WithTileStack extends DefaultServerContextBuilders { - ReusableServerContext index(int index); + DefaultServerContext index(int index); - default ReusableServerContext index(TileGenericReferenceRO reference) { + default DefaultServerContext index(TileGenericReferenceRO reference) { if (!reference.isValid()) { throw new IllegalArgumentException("Reference " + reference + " is invalid"); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java similarity index 93% rename from src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java rename to src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index 2994205..a391dd0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -39,15 +39,15 @@ import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.context.ServerTileContext; import ru.windcorp.progressia.server.world.tile.TileLogic; -class ReusableServerContextImpl extends ReusableServerContext - implements ReusableServerContextBuilders.Empty, ReusableServerContextBuilders.WithWorld, - ReusableServerContextBuilders.WithLocation, ReusableServerContextBuilders.WithTileStack { +class DefaultServerContextImpl extends DefaultServerContext + implements DefaultServerContextBuilders.Empty, DefaultServerContextBuilders.WithWorld, + DefaultServerContextBuilders.WithLocation, DefaultServerContextBuilders.WithTileStack { /* * STATE MANAGEMENT & UTIL */ - public ReusableServerContextImpl() { + public DefaultServerContextImpl() { reuse(); } @@ -89,7 +89,7 @@ class ReusableServerContextImpl extends ReusableServerContext /** * The Logic view returned by {@link #logic()}. */ - protected final ReusableServerContextImpl.Logic logic = new Logic(); + protected final DefaultServerContextImpl.Logic logic = new Logic(); /** * Returns the Role currently assumed by this object. @@ -217,7 +217,7 @@ class ReusableServerContextImpl extends ReusableServerContext */ @Override - public ReusableServerContext build() { + public DefaultServerContext build() { assert requireBuilderRole(null); isBuilder = false; return this; @@ -270,7 +270,7 @@ class ReusableServerContextImpl extends ReusableServerContext */ @Override - public ReusableServerContext index(int index) { + public DefaultServerContext index(int index) { requireBuilderRole(Role.TILE_STACK); frame.layer = index; return build(); @@ -538,7 +538,7 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public boolean isTagValid(Vec3i location, BlockFace face, int tag) { - return ReusableServerContextImpl.this.isTagValid(location, face, tag); + return DefaultServerContextImpl.this.isTagValid(location, face, tag); } @Override @@ -573,7 +573,7 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public int getTag() { - return ReusableServerContextImpl.this.getTag(); + return DefaultServerContextImpl.this.getTag(); } @Override @@ -592,25 +592,25 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public Logic push(Vec3i location) { - ReusableServerContextImpl.this.push(location); + DefaultServerContextImpl.this.push(location); return this; } @Override public Logic push(Vec3i location, RelFace face) { - ReusableServerContextImpl.this.push(location, face); + DefaultServerContextImpl.this.push(location, face); return this; } @Override public Logic push(Vec3i location, RelFace face, int layer) { - ReusableServerContextImpl.this.push(location, face, layer); + DefaultServerContextImpl.this.push(location, face, layer); return this; } @Override public void pop() { - ReusableServerContextImpl.this.pop(); + DefaultServerContextImpl.this.pop(); } /* @@ -618,13 +618,13 @@ class ReusableServerContextImpl extends ReusableServerContext */ @Override - public ReusableServerContext data() { - return ReusableServerContextImpl.this; + public DefaultServerContext data() { + return DefaultServerContextImpl.this; } @Override public String toString() { - return ReusableServerContextImpl.this + ".Logic"; + return DefaultServerContextImpl.this + ".Logic"; } } From 020802a89c32c35f19d140f780dbc7adc0f1d935 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 8 Aug 2021 12:19:31 +0300 Subject: [PATCH 45/63] Added FilterServerContext and DefaultServerContextLogic - Added DefaultServerContextLogic - A standard implementation of ServerTileContext.Logic that delegates all methods to a ServerTileContext instance - Now used by DefaultServerContextImpl - Added FilterServerContext - A base for creating context wrappers --- .../impl/DefaultServerContextBuilders.java | 6 +- .../impl/DefaultServerContextImpl.java | 219 +++--------------- .../impl/DefaultServerContextLogic.java | 165 +++++++++++++ .../context/impl/FilterServerContext.java | 210 +++++++++++++++++ 4 files changed, 405 insertions(+), 195 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java index 6c10747..8069db8 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java @@ -18,12 +18,12 @@ package ru.windcorp.progressia.server.world.context.impl; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.WorldLogic; public interface DefaultServerContextBuilders { @@ -31,10 +31,10 @@ public interface DefaultServerContextBuilders { public interface Empty /* does not extend RSCB */ { - WithWorld in(Server server, WorldLogic world); + WithWorld in(Server server, WorldData world); default WithWorld inRealWorldOf(Server server) { - return in(server, server.getWorld()); + return in(server, server.getWorld().getData()); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index a391dd0..1fa1178 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -33,11 +33,6 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.TileLogicStack; -import ru.windcorp.progressia.server.world.WorldLogic; -import ru.windcorp.progressia.server.world.block.BlockLogic; -import ru.windcorp.progressia.server.world.context.ServerTileContext; -import ru.windcorp.progressia.server.world.tile.TileLogic; class DefaultServerContextImpl extends DefaultServerContext implements DefaultServerContextBuilders.Empty, DefaultServerContextBuilders.WithWorld, @@ -58,16 +53,10 @@ class DefaultServerContextImpl extends DefaultServerContext protected Server server; /** - * The relevant {@link WorldLogic} instance. If this is {@code null}, the + * The relevant {@link WorldData} instance. If this is {@code null}, the * role is {@link Role#NONE}. */ - protected WorldLogic worldLogic; - - /** - * The {@link WorldData} accessible through {@link #worldLogic}. This field - * is kept always in sync with {@link #worldLogic}. - */ - protected WorldData worldData; + protected WorldData world; /** * The {@link Random} instance exposed with {@link #getRandom()}. @@ -89,7 +78,7 @@ class DefaultServerContextImpl extends DefaultServerContext /** * The Logic view returned by {@link #logic()}. */ - protected final DefaultServerContextImpl.Logic logic = new Logic(); + protected final DefaultServerContextImpl.Logic logic = new DefaultServerContextLogic(this); /** * Returns the Role currently assumed by this object. @@ -199,8 +188,8 @@ class DefaultServerContextImpl extends DefaultServerContext public Empty reuse() { server = null; - worldLogic = null; - worldData = null; +// worldLogic = null; + world = null; while (isSubcontexting()) { pop(); @@ -228,11 +217,10 @@ class DefaultServerContextImpl extends DefaultServerContext */ @Override - public WithWorld in(Server server, WorldLogic world) { + public WithWorld in(Server server, WorldData world) { requireBuilderRole(Role.NONE); this.server = server; - this.worldLogic = world; - this.worldData = world.getData(); + this.world = world; return this; } @@ -261,7 +249,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public WithTileStack on(BlockFace side) { requireBuilderRole(Role.LOCATION); - frame.face = side.relativize(worldLogic.getData().getUp(frame.location)); + frame.face = side.relativize(world.getUp(frame.location)); return this; } @@ -329,31 +317,31 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public BlockData getBlock(Vec3i location) { assert requireContextRole(Role.WORLD); - return worldData.getBlock(location); + return world.getBlock(location); } @Override public boolean isLocationLoaded(Vec3i location) { assert requireContextRole(Role.WORLD); - return worldData.isLocationLoaded(location); + return world.isLocationLoaded(location); } @Override public TileData getTile(Vec3i location, BlockFace face, int layer) { assert requireContextRole(Role.WORLD); - return worldData.getTile(location, face, layer); + return world.getTile(location, face, layer); } @Override public boolean hasTile(Vec3i location, BlockFace face, int layer) { assert requireContextRole(Role.WORLD); - return worldData.hasTile(location, face, layer); + return world.hasTile(location, face, layer); } @Override public TileData getTileByTag(Vec3i location, BlockFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = worldData.getTilesOrNull(location, face); + TileDataStack stack = world.getTilesOrNull(location, face); if (stack == null) return null; int layer = stack.getIndexByTag(tag); @@ -365,7 +353,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public boolean isTagValid(Vec3i location, BlockFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = worldData.getTilesOrNull(location, face); + TileDataStack stack = world.getTilesOrNull(location, face); if (stack == null) return false; return stack.getIndexByTag(tag) != -1; @@ -374,7 +362,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public int getTag() { assert requireContextRole(Role.TILE); - TileDataStack stack = worldData.getTilesOrNull(frame.location, frame.face); + TileDataStack stack = world.getTilesOrNull(frame.location, frame.face); if (stack == null) return -1; return stack.getTagByIndex(frame.layer); @@ -383,7 +371,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public int getTileCount(Vec3i location, BlockFace face) { assert requireContextRole(Role.TILE_STACK); - TileDataStack stack = worldData.getTilesOrNull(frame.location, frame.face); + TileDataStack stack = world.getTilesOrNull(frame.location, frame.face); if (stack == null) return 0; return stack.size(); @@ -392,25 +380,25 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public Collection getEntities() { assert requireContextRole(Role.WORLD); - return worldData.getEntities(); + return world.getEntities(); } @Override public EntityData getEntity(long entityId) { assert requireContextRole(Role.WORLD); - return worldData.getEntity(entityId); + return world.getEntity(entityId); } @Override public GravityModel getGravityModel() { assert requireContextRole(Role.WORLD); - return worldData.getGravityModel(); + return world.getGravityModel(); } @Override public float getTime() { assert requireContextRole(Role.WORLD); - return worldData.getTime(); + return world.getTime(); } /* @@ -426,19 +414,19 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public void setBlock(Vec3i blockInWorld, BlockData block) { assert requireContextRole(Role.WORLD); - worldData.setBlock(blockInWorld, block, true); + world.setBlock(blockInWorld, block, true); } @Override public void addTile(Vec3i location, BlockFace face, TileData tile) { assert requireContextRole(Role.WORLD); - worldData.getTiles(location, face).addFarthest(tile); + world.getTiles(location, face).addFarthest(tile); } @Override public void removeTile(Vec3i location, BlockFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = worldData.getTilesOrNull(location, face); + TileDataStack stack = world.getTilesOrNull(location, face); if (stack == null) return; int layer = stack.getIndexByTag(tag); @@ -450,184 +438,31 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public void addEntity(EntityData entity) { assert requireContextRole(Role.WORLD); - worldData.addEntity(entity); + world.addEntity(entity); } @Override public void removeEntity(long entityId) { assert requireContextRole(Role.WORLD); - worldData.removeEntity(entityId); + world.removeEntity(entityId); } @Override public void changeEntity(SE entity, StateChange change) { assert requireContextRole(Role.WORLD); - worldData.changeEntity(entity, change); + world.changeEntity(entity, change); } @Override public void advanceTime(float change) { assert requireContextRole(Role.WORLD); - worldData.advanceTime(change); + world.advanceTime(change); } /* * ServerWorldContext.Logic STUFF */ - private class Logic implements ServerTileContext.Logic { - - /* - * LOCATION GETTERS - */ - - @Override - public Server getServer() { - return server; - } - - @Override - public Vec3i getLocation() { - return frame.location; - } - - @Override - public RelFace getFace() { - return frame.face; - } - - @Override - public int getLayer() { - return frame.layer; - } - - /* - * RO CONTEXT INTERFACE - */ - - @Override - public boolean isReal() { - return true; - } - - @Override - public Random getRandom() { - return random; - } - - @Override - public double getTickLength() { - return server.getTickLength(); - } - - @Override - public BlockLogic getBlock(Vec3i location) { - assert requireContextRole(Role.WORLD); - return worldLogic.getBlock(location); - } - - @Override - public boolean isLocationLoaded(Vec3i location) { - return worldData.isLocationLoaded(location); - } - - @Override - public boolean hasTile(Vec3i location, BlockFace face, int layer) { - return worldData.hasTile(location, face, layer); - } - - @Override - public boolean isTagValid(Vec3i location, BlockFace face, int tag) { - return DefaultServerContextImpl.this.isTagValid(location, face, tag); - } - - @Override - public TileLogic getTile(Vec3i location, BlockFace face, int layer) { - assert requireContextRole(Role.WORLD); - return worldLogic.getTile(location, face, layer); - } - - @Override - public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) { - assert requireContextRole(Role.WORLD); - TileLogicStack stack = worldLogic.getTilesOrNull(location, face); - if (stack == null) { - return null; - } - int layer = stack.getIndexByTag(tag); - if (layer == -1) { - return null; - } - return stack.get(layer); - } - - @Override - public int getTileCount(Vec3i location, BlockFace face) { - assert requireContextRole(Role.WORLD); - TileLogicStack stack = worldLogic.getTilesOrNull(location, face); - if (stack == null) { - return 0; - } - return stack.size(); - } - - @Override - public int getTag() { - return DefaultServerContextImpl.this.getTag(); - } - - @Override - public Collection getEntities() { - return worldLogic.getEntities(); - } - - @Override - public EntityData getEntity(long entityId) { - return worldLogic.getEntity(entityId); - } - - /* - * Subcontexting - */ - - @Override - public Logic push(Vec3i location) { - DefaultServerContextImpl.this.push(location); - return this; - } - - @Override - public Logic push(Vec3i location, RelFace face) { - DefaultServerContextImpl.this.push(location, face); - return this; - } - - @Override - public Logic push(Vec3i location, RelFace face, int layer) { - DefaultServerContextImpl.this.push(location, face, layer); - return this; - } - - @Override - public void pop() { - DefaultServerContextImpl.this.pop(); - } - - /* - * MISC - */ - - @Override - public DefaultServerContext data() { - return DefaultServerContextImpl.this; - } - - @Override - public String toString() { - return DefaultServerContextImpl.this + ".Logic"; - } - } - @Override public Logic logic() { assert requireContextRole(Role.WORLD); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java new file mode 100644 index 0000000..4461d23 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java @@ -0,0 +1,165 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import java.util.Collection; +import java.util.Random; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.tile.TileLogic; +import ru.windcorp.progressia.server.world.tile.TileLogicRegistry; + +public class DefaultServerContextLogic implements ServerTileContext.Logic { + + private final ServerTileContext parent; + + public DefaultServerContextLogic(ServerTileContext parent) { + this.parent = parent; + } + + @Override + public ServerTileContext data() { + return parent; + } + + @Override + public Server getServer() { + return parent.getServer(); + } + + @Override + public Random getRandom() { + return parent.getRandom(); + } + + @Override + public BlockLogic getBlock(Vec3i location) { + BlockData data = parent.getBlock(location); + return data == null ? null : BlockLogicRegistry.getInstance().get(data.getId()); + } + + @Override + public boolean isLocationLoaded(Vec3i location) { + return parent.isLocationLoaded(location); + } + + @Override + public ServerTileContext.Logic push(Vec3i location) { + parent.push(location); + return this; + } + + @Override + public ServerTileContext.Logic push(Vec3i location, RelFace face) { + parent.push(location, face); + return this; + } + + @Override + public ServerTileContext.Logic push(Vec3i location, RelFace face, int layer) { + parent.push(location, face, layer); + return this; + } + + @Override + public double getTickLength() { + return parent.getTickLength(); + } + + @Override + public TileLogic getTile(Vec3i location, BlockFace face, int layer) { + TileData data = parent.getTile(location, face, layer); + return data == null ? null : TileLogicRegistry.getInstance().get(data.getId()); + } + + @Override + public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) { + TileData data = parent.getTileByTag(location, face, tag); + return data == null ? null : TileLogicRegistry.getInstance().get(data.getId()); + } + + @Override + public Vec3i getLocation() { + return parent.getLocation(); + } + + @Override + public boolean hasTile(Vec3i location, BlockFace face, int layer) { + return parent.hasTile(location, face, layer); + } + + @Override + public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + return parent.isTagValid(location, face, tag); + } + + @Override + public boolean isReal() { + return parent.isReal(); + } + + @Override + public int getTileCount(Vec3i location, BlockFace face) { + return parent.getTileCount(location, face); + } + + @Override + public Collection getEntities() { + return parent.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return parent.getEntity(entityId); + } + + @Override + public void pop() { + parent.pop(); + } + + @Override + public RelFace getFace() { + return parent.getFace(); + } + + @Override + public int getLayer() { + return parent.getLayer(); + } + + @Override + public int getTag() { + return parent.getTag(); + } + + @Override + public String toString() { + return parent + ".Logic"; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java new file mode 100644 index 0000000..67e9a79 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java @@ -0,0 +1,210 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import java.util.Collection; +import java.util.Random; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.GravityModel; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileStackContext; + +/** + * This is an implementation of the server context tree that delegates all calls + * to a provided instance of {@link ServerTileContext}. + */ +public abstract class FilterServerContext implements ServerTileContext { + + protected final ServerTileContext parent; + protected final DefaultServerContextLogic logic = new DefaultServerContextLogic(this); + + public FilterServerContext(ServerTileContext parent) { + this.parent = parent; + } + + public ServerTileContext getParent() { + return parent; + } + + @Override + public int getLayer() { + return parent.getLayer(); + } + + @Override + public int getTag() { + return parent.getTag(); + } + + @Override + public RelFace getFace() { + return parent.getFace(); + } + + @Override + public Vec3i getLocation() { + return parent.getLocation(); + } + + @Override + public boolean isReal() { + return parent.isReal(); + } + + @Override + public void pop() { + parent.pop(); + } + + @Override + public boolean isImmediate() { + return parent.isImmediate(); + } + + @Override + public void addTile(Vec3i location, BlockFace face, TileData tile) { + parent.addTile(location, face, tile); + } + + @Override + public void removeTile(Vec3i location, BlockFace face, int tag) { + parent.removeTile(location, face, tag); + } + + @Override + public void addEntity(EntityData entity) { + parent.addEntity(entity); + } + + @Override + public void removeEntity(long entityId) { + parent.removeEntity(entityId); + } + + @Override + public void changeEntity(SE entity, StateChange change) { + parent.changeEntity(entity, change); + } + + @Override + public void advanceTime(float change) { + parent.advanceTime(change); + } + + @Override + public float getTime() { + return parent.getTime(); + } + + @Override + public GravityModel getGravityModel() { + return parent.getGravityModel(); + } + + @Override + public BlockData getBlock(Vec3i location) { + return parent.getBlock(location); + } + + @Override + public boolean isLocationLoaded(Vec3i location) { + return parent.isLocationLoaded(location); + } + + @Override + public TileData getTile(Vec3i location, BlockFace face, int layer) { + return parent.getTile(location, face, layer); + } + + @Override + public TileData getTileByTag(Vec3i location, BlockFace face, int tag) { + return parent.getTileByTag(location, face, tag); + } + + @Override + public boolean hasTile(Vec3i location, BlockFace face, int layer) { + return parent.hasTile(location, face, layer); + } + + @Override + public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + return parent.isTagValid(location, face, tag); + } + + @Override + public int getTileCount(Vec3i location, BlockFace face) { + return parent.getTileCount(location, face); + } + + @Override + public Collection getEntities() { + return parent.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return parent.getEntity(entityId); + } + + @Override + public ServerBlockContext push(Vec3i location) { + return parent.push(location); + } + + @Override + public ServerTileStackContext push(Vec3i location, RelFace face) { + return parent.push(location, face); + } + + @Override + public ServerTileContext push(Vec3i location, RelFace face, int layer) { + return parent.push(location, face, layer); + } + + @Override + public Server getServer() { + return parent.getServer(); + } + + @Override + public Random getRandom() { + return parent.getRandom(); + } + + @Override + public double getTickLength() { + return parent.getTickLength(); + } + + @Override + public ServerTileContext.Logic logic() { + return logic; + } + +} From 5fb4c601fffdc7c978a77202fcd3e0743f91f91e Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 8 Aug 2021 14:07:07 +0300 Subject: [PATCH 46/63] Added ReportingServerContext - Added ReportingServerContext to listen for write events in contexts - Fixed method WorldGenericContextWO.setBlock(Vec3i, B) --- .../context/WorldGenericContextWO.java | 4 +- .../context/impl/FilterServerContext.java | 5 + .../context/impl/ReportingServerContext.java | 145 ++++++++++++++++++ 3 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index 0a465a0..3f27b17 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -63,9 +63,7 @@ public interface WorldGenericContextWO< * @param block the new block * @see #isImmediate() */ - default void setBlock(Vec3i location, B block) { - setBlock(location, block); - } + void setBlock(Vec3i location, B block); /** * Requests that a tile is added to the top of the tile stack at the given diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java index 67e9a79..4896b84 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java @@ -86,6 +86,11 @@ public abstract class FilterServerContext implements ServerTileContext { public boolean isImmediate() { return parent.isImmediate(); } + + @Override + public void setBlock(Vec3i location, BlockData block) { + parent.setBlock(location, block); + } @Override public void addTile(Vec3i location, BlockFace face, TileData tile) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java new file mode 100644 index 0000000..302a47f --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java @@ -0,0 +1,145 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.world.context.ServerTileContext; + +public class ReportingServerContext extends FilterServerContext { + + public static interface ChangeListener { + + void onBlockSet(Vec3i location, BlockData block); + + void onTileAdded(Vec3i location, BlockFace face, TileData tile); + + void onTileRemoved(Vec3i location, BlockFace face, int tag); + + void onEntityAdded(EntityData entity); + + void onEntityRemoved(long entityId); + + void onEntityChanged(SE entity, StateChange change); + + void onTimeChanged(float change); + + } + + private ChangeListener listener = null; + private boolean passToParent = true; + + /** + * Creates a new {@link ReportingServerContext} instance that delegates + * method calls to the specified parent context. Write methods are always + * passed, disable with {@link #setPassToParent(boolean)}. No listener is + * set, set a listener with {@link #withListener(ChangeListener)}. + * + * @param parent the parent context + */ + public ReportingServerContext(ServerTileContext parent) { + super(parent); + } + + public ReportingServerContext withListener(ChangeListener listener) { + this.listener = listener; + return this; + } + + public ReportingServerContext setPassToParent(boolean pass) { + this.passToParent = pass; + return this; + } + + @Override + public void setBlock(Vec3i location, BlockData block) { + if (passToParent) { + super.setBlock(location, block); + } + if (listener != null) { + listener.onBlockSet(location, block); + } + } + + @Override + public void addTile(Vec3i location, BlockFace face, TileData tile) { + if (passToParent) { + super.addTile(location, face, tile); + } + if (listener != null) { + listener.onTileAdded(location, face, tile); + } + } + + @Override + public void removeTile(Vec3i location, BlockFace face, int tag) { + if (passToParent) { + super.removeTile(location, face, tag); + } + if (listener != null) { + listener.onTileRemoved(location, face, tag); + } + } + + @Override + public void addEntity(EntityData entity) { + if (passToParent) { + super.addEntity(entity); + } + if (listener != null) { + listener.onEntityAdded(entity); + } + } + + @Override + public void removeEntity(long entityId) { + if (passToParent) { + super.removeEntity(entityId); + } + if (listener != null) { + listener.onEntityRemoved(entityId); + } + } + + @Override + public void changeEntity(SE entity, StateChange change) { + if (passToParent) { + super.changeEntity(entity, change); + } + if (listener != null) { + listener.onEntityChanged(entity, change); + } + } + + @Override + public void advanceTime(float change) { + if (passToParent) { + super.advanceTime(change); + } + if (listener != null) { + listener.onTimeChanged(change); + } + } + +} From 0a45613e454debc137b7ac974de960a3ea946a9f Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 9 Aug 2021 20:32:15 +0300 Subject: [PATCH 47/63] Began work on integrating the new Contexts. Compiles but does not work - All TickContexts including TickContextMutable are deleted - Previous occurrences of TickContexts are replaced by appropriate ServerContexts - Added Context.popAndReturn methods for convenience Current known problems: - World does not generate properly on startup - No bulk methods in the new API (the likes of forEachTile, etc.) - AbsFace/RelFace ambiguity in the new API (see TestTileLogicGrass.java:68) - TestTileLogicGrass.java:53 is disabled for some reason --- .../common/world/context/Context.java | 20 + .../ru/windcorp/progressia/server/Server.java | 40 +- .../server/world/ChunkTickContext.java | 55 -- .../server/world/DefaultChunkLogic.java | 47 +- .../server/world/DefaultWorldLogic.java | 2 +- .../server/world/TickAndUpdateUtil.java | 132 +++-- .../progressia/server/world/TickContext.java | 49 -- .../server/world/TickContextMutable.java | 497 ------------------ .../server/world/UpdateTriggerer.java | 14 +- .../server/world/block/BlockLogic.java | 5 +- .../server/world/block/BlockTickContext.java | 114 ---- .../server/world/block/TickableBlock.java | 6 +- .../server/world/block/UpdateableBlock.java | 12 +- .../server/world/entity/EntityLogic.java | 4 +- .../world/tasks/BlockTriggeredUpdate.java | 9 +- .../server/world/tasks/ChangeEntity.java | 3 +- .../server/world/tasks/StateChange.java | 24 - .../server/world/tasks/TickChunk.java | 56 +- .../world/tasks/TileTriggeredUpdate.java | 19 +- .../server/world/tasks/WorldAccessor.java | 52 +- .../server/world/tile/HangingTileLogic.java | 21 +- .../server/world/tile/TSTickContext.java | 113 ---- .../server/world/tile/TickableTile.java | 6 +- .../server/world/tile/TileLogic.java | 5 +- .../server/world/tile/TileTickContext.java | 77 --- .../server/world/tile/UpdateableTile.java | 4 +- .../windcorp/progressia/test/TestContent.java | 6 +- .../test/TestEntityLogicStatie.java | 6 +- .../progressia/test/TestTileLogicGrass.java | 27 +- 29 files changed, 305 insertions(+), 1120 deletions(-) delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/TickContext.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java delete mode 100644 src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/Context.java b/src/main/java/ru/windcorp/progressia/common/world/context/Context.java index 73644ea..786e1eb 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/Context.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/Context.java @@ -135,5 +135,25 @@ public interface Context { * modifications to revert. */ void pop(); + + default T popAndReturn(T result) { + pop(); + return result; + } + + default boolean popAndReturn(boolean result) { + pop(); + return result; + } + + default int popAndReturn(int result) { + pop(); + return result; + } + + default float popAndReturn(float result) { + pop(); + return result; + } } diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 0896caa..a57ce2f 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -35,6 +35,9 @@ import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon; import ru.windcorp.progressia.server.management.load.EntityRequestDaemon; import ru.windcorp.progressia.server.management.load.LoadManager; import ru.windcorp.progressia.server.world.DefaultWorldLogic; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; +import ru.windcorp.progressia.server.world.context.impl.DefaultServerContext; +import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; @@ -97,6 +100,19 @@ public class Server { return world; } + /** + * Instantiates and returns an new {@link ServerWorldContext} instance + * suitable for read and write access to the server's world. This is the + * preferred way to query or change the world. + * + * @return the context + */ + public ServerWorldContext createContext() { + + return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build()).withListener(worldAccessor); + + } + /** * Returns this server's {@link ClientManager}. Use this to deal with * communications, e.g. send packets. @@ -219,16 +235,20 @@ public class Server { return this.serverThread.getTicker().getUptimeTicks(); } - /** - * Returns the {@link WorldAccessor} object for this server. Use the - * provided accessor to request common {@link Evaluation}s and - * {@link Change}s. - * - * @return a {@link WorldAccessor} - * @see #requestChange(Change) - * @see #requestEvaluation(Evaluation) - */ - public WorldAccessor getWorldAccessor() { +// /** +// * Returns the {@link WorldAccessor} object for this server. Use the +// * provided accessor to request common {@link Evaluation}s and +// * {@link Change}s. +// * +// * @return a {@link WorldAccessor} +// * @see #requestChange(Change) +// * @see #requestEvaluation(Evaluation) +// */ +// public WorldAccessor getWorldAccessor() { +// return worldAccessor; +// } + + public WorldAccessor getWorldAccessor___really_bad_dont_use() { return worldAccessor; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java deleted file mode 100644 index aec68fe..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/ChunkTickContext.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world; - -import java.util.function.Consumer; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.server.world.block.BlockTickContext; - -public interface ChunkTickContext extends TickContext { - - Vec3i getChunk(); - - default DefaultChunkLogic getChunkLogic() { - return getWorld().getChunk(getChunk()); - } - - default DefaultChunkData getChunkData() { - DefaultChunkLogic chunkLogic = getChunkLogic(); - return chunkLogic == null ? null : chunkLogic.getData(); - } - - default AbsFace getUp() { - return getChunkData().getUp(); - } - - default void forEachBlock(Consumer action) { - TickContextMutable context = TickContextMutable.uninitialized(); - - GenericChunks.forEachBiC(blockInChunk -> { - context.rebuild().withServer(getServer()).withChunk(getChunk()).withBlockInChunk(blockInChunk).build(); - action.accept(context); - }); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java index 69fed5e..0e2dbbe 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java @@ -34,9 +34,13 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.TileDataReference; +import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.server.world.block.TickableBlock; +import ru.windcorp.progressia.server.world.context.ServerBlockContextRO; +import ru.windcorp.progressia.server.world.context.ServerTileContextRO; +import ru.windcorp.progressia.server.world.context.ServerWorldContextRO; import ru.windcorp.progressia.server.world.tasks.TickChunk; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; import ru.windcorp.progressia.server.world.tile.TickableTile; @@ -221,28 +225,45 @@ public class DefaultChunkLogic implements ChunkLogic { } private void tmp_generateTickLists() { - ChunkTickContext context = TickContextMutable.start().withChunk(this).build(); - - context.forEachBlock(bctxt -> { - BlockLogic block = bctxt.getBlock(); + ServerWorldContextRO context = Server.getCurrentServer().createContext(); + Vec3i blockInChunk = new Vec3i(); + + forEachBiW(location -> { + + ServerBlockContextRO blockContext = context.push(location); + + BlockLogic block = blockContext.logic().getBlock(); + Coordinates.convertInWorldToInChunk(location, blockInChunk); if (!(block instanceof TickableBlock)) return; - if (((TickableBlock) block).getTickingPolicy(bctxt) == TickingPolicy.REGULAR) { - tickingBlocks.add(Coordinates.convertInWorldToInChunk(bctxt.getBlockInWorld(), null)); + if (((TickableBlock) block).getTickingPolicy(blockContext) == TickingPolicy.REGULAR) { + tickingBlocks.add(blockInChunk); } - bctxt.forEachFace(fctxt -> fctxt.forEachTile(tctxt -> { - TileLogic tile = tctxt.getTile(); + for (RelFace face : RelFace.getFaces()) { + TileLogicStack stack = getTilesOrNull(blockInChunk, face); + if (stack == null || stack.isEmpty()) continue; + + for (int i = 0; i < stack.size(); ++i) { + ServerTileContextRO tileContext = blockContext.push(face, i); + + TileLogic tile = stack.get(i); - if (!(tile instanceof TickableTile)) - return; + if (!(tile instanceof TickableTile)) + return; - if (((TickableTile) tile).getTickingPolicy(tctxt) == TickingPolicy.REGULAR) { - tickingTiles.add(tctxt.getReference()); + if (((TickableTile) tile).getTickingPolicy(tileContext) == TickingPolicy.REGULAR) { + tickingTiles.add(stack.getData().getReference(i)); + } + + tileContext.pop(); } - })); + } + + blockContext.pop(); + }); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java index d578fa7..f2b1883 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java @@ -65,7 +65,7 @@ public class DefaultWorldLogic implements WorldLogic { } }); - data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server))); + data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server.getWorldAccessor___really_bad_dont_use()))); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index 112d722..286a557 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; @@ -24,19 +24,26 @@ import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; -import ru.windcorp.progressia.server.world.block.BlockTickContext; import ru.windcorp.progressia.server.world.block.TickableBlock; import ru.windcorp.progressia.server.world.block.UpdateableBlock; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileStackContext; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; import ru.windcorp.progressia.server.world.entity.EntityLogic; import ru.windcorp.progressia.server.world.entity.EntityLogicRegistry; import ru.windcorp.progressia.server.world.tile.TickableTile; import ru.windcorp.progressia.server.world.tile.TileLogic; -import ru.windcorp.progressia.server.world.tile.TileTickContext; import ru.windcorp.progressia.server.world.tile.UpdateableTile; public class TickAndUpdateUtil { - public static void tickBlock(TickableBlock block, BlockTickContext context) { + public static void tickBlock(ServerBlockContext context) { + BlockLogic uncheckedBlock = context.logic().getBlock(); + if (!(uncheckedBlock instanceof BlockLogic)) { + return; + } + TickableBlock block = (TickableBlock) uncheckedBlock; try { block.tick(context); } catch (Exception e) { @@ -44,16 +51,21 @@ public class TickAndUpdateUtil { } } - public static void tickBlock(DefaultWorldLogic world, Vec3i blockInWorld) { - BlockLogic block = world.getBlock(blockInWorld); - if (!(block instanceof TickableBlock)) - return; // also checks nulls - - BlockTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).build(); - tickBlock((TickableBlock) block, tickContext); + public static void tickBlock(Server server, Vec3i blockInWorld) { + BlockLogic block = server.getWorld().getBlock(blockInWorld); + if (!(block instanceof TickableBlock)) { + return; + } + ServerBlockContext context = server.createContext().push(blockInWorld); + tickBlock(context); } - public static void tickTile(TickableTile tile, TileTickContext context) { + public static void tickTile(ServerTileContext context) { + TileLogic uncheckedTile = context.logic().getTile(); + if (!(uncheckedTile instanceof TickableTile)) { + return; + } + TickableTile tile = (TickableTile) uncheckedTile; try { tile.tick(context); } catch (Exception e) { @@ -61,82 +73,88 @@ public class TickAndUpdateUtil { } } - public static void tickTile(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { - TileLogic tile = world.getTile(blockInWorld, face, layer); + public static void tickTile(Server server, Vec3i blockInWorld, BlockFace face, int layer) { + TileLogic tile = server.getWorld().getTile(blockInWorld, face, layer); if (!(tile instanceof TickableTile)) { return; } - - TileTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face) - .withLayer(layer); - tickTile((TickableTile) tile, tickContext); + ServerTileContext context = server.createContext() + .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)), layer); + tickTile(context); } - public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { - if (!world.isLocationLoaded(blockInWorld)) { + public static void tickTiles(Server server, Vec3i blockInWorld, BlockFace face) { + if (!server.getWorld().hasTiles(blockInWorld, face)) { return; } - - TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() - .forEachTile(context -> { - TileLogic tile = context.getTile(); - if (tile instanceof TickableTile) { - tickTile((TickableTile) tile, context); - } - }); + + ServerTileStackContext context = server.createContext() + .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld))); + for (int i = 0; i < context.getTileCount(); ++i) { + tickTile(context.push(i)); + context.pop(); + } } - public static void updateBlock(UpdateableBlock block, BlockTickContext context) { + public static void updateBlock(ServerBlockContext context) { + BlockLogic uncheckedBlock = context.logic().getBlock(); + if (!(uncheckedBlock instanceof BlockLogic)) { + return; + } + UpdateableBlock block = (UpdateableBlock) uncheckedBlock; try { block.update(context); } catch (Exception e) { - throw CrashReports.report(e, "Could not update block {}", block); + throw CrashReports.report(e, "Could not update block %s", block); } } - public static void updateBlock(DefaultWorldLogic world, Vec3i blockInWorld) { - BlockLogic block = world.getBlock(blockInWorld); - if (!(block instanceof UpdateableBlock)) - return; // also checks nulls - - BlockTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).build(); - updateBlock((UpdateableBlock) block, tickContext); + public static void updateBlock(Server server, Vec3i blockInWorld) { + BlockLogic block = server.getWorld().getBlock(blockInWorld); + if (!(block instanceof UpdateableBlock)) { + return; + } + ServerBlockContext context = server.createContext().push(blockInWorld); + updateBlock(context); } - public static void updateTile(UpdateableTile tile, TileTickContext context) { + public static void updateTile(ServerTileContext context) { + TileLogic uncheckedTile = context.logic().getTile(); + if (!(uncheckedTile instanceof UpdateableTile)) { + return; + } + UpdateableTile tile = (UpdateableTile) uncheckedTile; try { tile.update(context); } catch (Exception e) { - throw CrashReports.report(e, "Could not update tile {}", tile); + throw CrashReports.report(e, "Could not tick tile %s", tile); } } - public static void updateTile(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face, int layer) { - TileLogic tile = world.getTile(blockInWorld, face, layer); + public static void updateTile(Server server, Vec3i blockInWorld, BlockFace face, int layer) { + TileLogic tile = server.getWorld().getTile(blockInWorld, face, layer); if (!(tile instanceof UpdateableTile)) { return; } - - TileTickContext tickContext = TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face) - .withLayer(layer); - updateTile((UpdateableTile) tile, tickContext); + ServerTileContext context = server.createContext() + .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)), layer); + updateTile(context); } - public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { - if (!world.isLocationLoaded(blockInWorld)) { + public static void updateTiles(Server server, Vec3i blockInWorld, BlockFace face) { + if (!server.getWorld().hasTiles(blockInWorld, face)) { return; } - - TickContextMutable.start().withWorld(world).withBlock(blockInWorld).withFace(face).build() - .forEachTile(context -> { - TileLogic tile = context.getTile(); - if (tile instanceof UpdateableTile) { - updateTile((UpdateableTile) tile, context); - } - }); + + ServerTileStackContext context = server.createContext() + .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld))); + for (int i = 0; i < context.getTileCount(); ++i) { + updateTile(context.push(i)); + context.pop(); + } } - public static void tickEntity(EntityLogic logic, EntityData data, TickContext context) { + public static void tickEntity(EntityLogic logic, EntityData data, ServerWorldContext context) { try { logic.tick(data, context); } catch (Exception e) { @@ -148,7 +166,7 @@ public class TickAndUpdateUtil { tickEntity( EntityLogicRegistry.getInstance().get(data.getId()), data, - TickContextMutable.start().withServer(server).build() + server.createContext() ); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java b/src/main/java/ru/windcorp/progressia/server/world/TickContext.java deleted file mode 100644 index 5d92f4a..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContext.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world; - -import java.util.Random; - -import ru.windcorp.progressia.common.world.DefaultWorldData; -import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.tasks.WorldAccessor; - -public interface TickContext { - - float getTickLength(); - - Server getServer(); - - default DefaultWorldLogic getWorld() { - return getServer().getWorld(); - } - - default WorldAccessor getAccessor() { - return getServer().getWorldAccessor(); - } - - default Random getRandom() { - return getServer().getAdHocRandom(); - } - - default DefaultWorldData getWorldData() { - return getWorld().getData(); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java b/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java deleted file mode 100644 index a5eb592..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/TickContextMutable.java +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world; - -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.generic.TileGenericStackRO; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.block.BlockTickContext; -import ru.windcorp.progressia.server.world.tile.TSTickContext; -import ru.windcorp.progressia.server.world.tile.TileTickContext; - -public abstract class TickContextMutable implements BlockTickContext, TSTickContext, TileTickContext { - - private static enum Role { - NONE, WORLD, CHUNK, BLOCK, TILE_STACK, TILE; - } - - /* - * TickContextMutable interface - */ - - // Only TickContextMutable.Impl can extend; extend Impl if need be - private TickContextMutable() { - } - - public abstract Builder.Empty rebuild(); - - /* - * Static methods - */ - - public static TickContextMutable uninitialized() { - return new Impl(); - } - - public static Builder.Empty start() { - return uninitialized().rebuild(); - } - - public static Builder.World copyWorld(TickContext context) { - return start().withServer(context.getServer()); - } - - public static Builder.Chunk copyChunk(ChunkTickContext context) { - return start().withChunk(context.getChunkLogic()); - } - - public static Builder.Block copyBlock(BlockTickContext context) { - return copyWorld(context).withBlock(context.getBlockInWorld()); - } - - public static Builder.TileStack copyTS(TSTickContext context) { - return copyBlock(context).withFace(context.getFace()); - } - - public static TileTickContext copyTile(TileTickContext context) { - return copyTS(context).withLayer(context.getLayer()); - } - - /* - * Builder interfaces - */ - - public static interface Builder { - TickContextMutable build(); - - public static interface Empty /* does not extend Builder */ { - World withServer(Server server); - - default Builder.World withWorld(DefaultWorldLogic world) { - Objects.requireNonNull(world, "world"); - return withServer(world.getServer()); - } - - default Builder.Chunk withChunk(DefaultChunkLogic chunk) { - Objects.requireNonNull(chunk, "chunk"); - return withWorld(chunk.getWorld()).withChunk(chunk.getPosition()); - } - } - - public static interface World extends Builder { - Chunk withChunk(Vec3i chunk); - - Block withBlock(Vec3i blockInWorld); - - TileStack withTS(TileGenericStackRO tileStack); - - default Builder.Chunk withChunk(DefaultChunkData chunk) { - Objects.requireNonNull(chunk, "chunk"); - return withChunk(chunk.getPosition()); - } - - default TileTickContext withTile(TileDataReference ref) { - Objects.requireNonNull(ref, "ref"); - return withTS(ref.getStack()).withLayer(ref.getIndex()); - } - } - - public static interface Chunk extends Builder { - Builder.Block withBlockInChunk(Vec3i blockInChunk); - } - - public static interface Block extends Builder { - Builder.TileStack withFace(BlockFace face); - } - - public static interface TileStack extends Builder { - TickContextMutable withLayer(int layer); - } - } - - /* - * Impl - */ - - public static class Impl - extends TickContextMutable - implements Builder.Empty, Builder.World, Builder.Chunk, Builder.Block, Builder.TileStack { - - protected Impl() { - } - - protected Server server; - protected final Vec3i chunk = new Vec3i(); - protected final Vec3i blockInWorld = new Vec3i(); - protected RelFace face; - protected int layer; - - protected Role role = Role.NONE; - protected boolean isBeingBuilt = false; - - /** - * Updated lazily - */ - protected final Vec3i blockInChunk = new Vec3i(); - - /* - * TickContextMutable - */ - - @Override - public Server getServer() { - checkContextState(Role.WORLD); - return this.server; - } - - @Override - public float getTickLength() { - checkContextState(Role.WORLD); - return (float) this.server.getTickLength(); - } - - @Override - public Vec3i getChunk() { - checkContextState(Role.CHUNK); - return this.chunk; - } - - @Override - public Vec3i getBlockInWorld() { - checkContextState(Role.BLOCK); - return this.blockInWorld; - } - - @Override - public RelFace getFace() { - checkContextState(Role.TILE_STACK); - return this.face; - } - - @Override - public int getLayer() { - checkContextState(Role.TILE); - return this.layer; - } - - @Override - public Builder.Empty rebuild() { - this.role = Role.NONE; - this.isBeingBuilt = true; - - this.server = null; - this.chunk.set(0); - this.blockInWorld.set(0); - this.face = null; - this.layer = -1; - - return this; - } - - /* - * Builder - * memo: do NOT use Context getters, they throw ISEs - */ - - @Override - public TickContextMutable build() { - checkBuilderState(null); - this.isBeingBuilt = false; - return this; - } - - @Override - public World withServer(Server server) { - Objects.requireNonNull(server, "server"); - checkBuilderState(Role.NONE); - this.server = server; - this.role = Role.WORLD; - return this; - } - - @Override - public Chunk withChunk(Vec3i chunk) { - Objects.requireNonNull(chunk, "chunk"); - checkBuilderState(Role.WORLD); - - this.chunk.set(chunk.x, chunk.y, chunk.z); - - this.role = Role.CHUNK; - return this; - } - - @Override - public Block withBlock(Vec3i blockInWorld) { - Objects.requireNonNull(blockInWorld, "blockInWorld"); - checkBuilderState(Role.WORLD); - - this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); - Coordinates.convertInWorldToChunk(blockInWorld, this.chunk); - - this.role = Role.BLOCK; - return this; - } - - @Override - public TileStack withTS(TileGenericStackRO tileStack) { - Objects.requireNonNull(tileStack, "tileStack"); - - return withBlock( - tileStack.getBlockInWorld(this.blockInWorld) // This is safe - ).withFace(tileStack.getFace()); - } - - @Override - public Block withBlockInChunk(Vec3i blockInChunk) { - Objects.requireNonNull(blockInChunk, "blockInChunk"); - checkBuilderState(Role.CHUNK); - - Coordinates.getInWorld(this.chunk, blockInChunk, this.blockInWorld); - - this.role = Role.BLOCK; - return this; - } - - @Override - public TileStack withFace(BlockFace face) { - Objects.requireNonNull(face, "face"); - checkBuilderState(Role.BLOCK); - - this.face = face.relativize(server.getWorld().getChunk(chunk).getUp()); - - this.role = Role.TILE_STACK; - return this; - } - - @Override - public TickContextMutable withLayer(int layer) { - checkBuilderState(Role.TILE); - - this.layer = layer; - - this.role = Role.TILE; - return build(); - } - - /* - * Optimization - */ - - @Override - public Vec3i getBlockInChunk() { - return Coordinates.convertInWorldToInChunk(getBlockInWorld(), this.blockInChunk); - } - - @Override - public void forEachBlock(Consumer action) { - checkContextState(Role.CHUNK); - - Vec3i v = this.blockInWorld; - - int previousX = v.x; - int previousY = v.y; - int previousZ = v.z; - Role previousRole = this.role; - - this.role = Role.BLOCK; - - final int minX = Coordinates.getInWorld(chunk.x, 0); - final int minY = Coordinates.getInWorld(chunk.y, 0); - final int minZ = Coordinates.getInWorld(chunk.z, 0); - final int size = DefaultChunkData.BLOCKS_PER_CHUNK; - - for (v.x = minX; v.x < minX + size; ++v.x) { - for (v.y = minY; v.y < minY + size; ++v.y) { - for (v.z = minZ; v.z < minZ + size; ++v.z) { - action.accept(this); - } - } - } - - this.role = previousRole; - blockInWorld.set(previousX, previousY, previousZ); - } - - @Override - public void forEachFace(Consumer action) { - checkContextState(Role.BLOCK); - RelFace previousFace = this.face; - Role previousRole = this.role; - - this.role = Role.TILE_STACK; - for (int i = 0; i < BlockFace.BLOCK_FACE_COUNT; ++i) { - this.face = RelFace.getFaces().get(i); - action.accept(this); - } - - this.role = previousRole; - this.face = previousFace; - } - - @Override - public R evalNeighbor(Vec3i direction, Function action) { - this.blockInWorld.add(direction); - R result = action.apply(this); - this.blockInWorld.sub(direction); - - return result; - } - - @Override - public void forNeighbor(Vec3i direction, Consumer action) { - this.blockInWorld.add(direction); - action.accept(this); - this.blockInWorld.sub(direction); - } - - @Override - public boolean forEachTile(Consumer action) { - checkContextState(Role.TILE_STACK); - int previousLayer = this.layer; - Role previousRole = this.role; - - this.role = Role.TILE; - TileDataStack stack = getTDSOrNull(); - if (stack == null || stack.isEmpty()) - return false; - - for (this.layer = 0; this.layer < stack.size(); ++this.layer) { - action.accept(this); - } - - this.role = previousRole; - this.layer = previousLayer; - return true; - } - - @Override - public R evalComplementary(Function action) { - Objects.requireNonNull(action, "action"); - checkContextState(Role.TILE_STACK); - - Vec3i vector = this.face.getVector(getUp()); - - this.blockInWorld.add(vector); - this.face = this.face.getCounter(); - R result = action.apply(this); - this.face = this.face.getCounter(); - this.blockInWorld.sub(vector); - - return result; - } - - @Override - public void forComplementary(Consumer action) { - Objects.requireNonNull(action, "action"); - checkContextState(Role.TILE_STACK); - - Vec3i vector = this.face.getVector(getUp()); - - this.blockInWorld.add(vector); - this.face = this.face.getCounter(); - action.accept(this); - this.face = this.face.getCounter(); - this.blockInWorld.sub(vector); - } - - /* - * Misc - */ - - protected void checkContextState(Role requiredRole) { - if (isBeingBuilt) { - throw new IllegalStateException("This context is still being built"); - } - - if ((role == null) || (requiredRole.compareTo(role) > 0)) { - throw new IllegalStateException( - "This context is currently initialized as " + role + "; requested " + requiredRole - ); - } - } - - protected void checkBuilderState(Role requiredRole) { - if (!isBeingBuilt) { - throw new IllegalStateException("This context is already built"); - } - - if (requiredRole == null) { - if (role == Role.NONE) { - throw new IllegalStateException("This context is currently not initialized"); - } - } else { - if (role != requiredRole) { - throw new IllegalStateException( - "This context is currently initialized as " + role + "; requested " + requiredRole - ); - } - } - } - - @Override - public String toString() { - final String format; - - switch (this.role) { - case WORLD: - format = "TickContext"; - break; - case CHUNK: - format = "(%2$d; %3$d; %4$d)"; - break; - case BLOCK: - format = "(%5$d; %6$d; %7$d)"; - break; - case TILE_STACK: - format = "((%5$d; %6$d; %7$d); %8$6s)"; - break; - case TILE: - format = "((%5$d; %6$d; %7$d); %8$6s; %9$d)"; - break; - case NONE: - default: - format = "Uninitialized TickContextMutable"; - break; - } - - return String.format( - format, - this.chunk.x, - this.chunk.y, - this.chunk.z, - this.blockInWorld.x, - this.blockInWorld.y, - this.blockInWorld.z, - this.face, - this.layer - ); - } - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java index fc22047..8175937 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/UpdateTriggerer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; @@ -25,14 +25,14 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.tasks.WorldAccessor; public class UpdateTriggerer implements ChunkDataListener { - private final Server server; + private final WorldAccessor worldAccessor; - public UpdateTriggerer(Server server) { - this.server = server; + public UpdateTriggerer(WorldAccessor worldAccessor) { + this.worldAccessor = worldAccessor; } @Override @@ -42,7 +42,7 @@ public class UpdateTriggerer implements ChunkDataListener { BlockData previous, BlockData current ) { - server.getWorldAccessor().triggerUpdates(Coordinates.getInWorld(chunk.getPosition(), blockInChunk, null)); + worldAccessor.triggerUpdates(Coordinates.getInWorld(chunk.getPosition(), blockInChunk, null)); } @Override @@ -53,7 +53,7 @@ public class UpdateTriggerer implements ChunkDataListener { TileData tile, boolean wasAdded ) { - server.getWorldAccessor().triggerUpdates(Coordinates.getInWorld(chunk.getPosition(), blockInChunk, null), face); + worldAccessor.triggerUpdates(Coordinates.getInWorld(chunk.getPosition(), blockInChunk, null), face); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java index 1d08194..7b2204f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/BlockLogic.java @@ -21,6 +21,7 @@ package ru.windcorp.progressia.server.world.block; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.generic.BlockGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.context.ServerBlockContextRO; public class BlockLogic extends Namespaced implements BlockGeneric { @@ -28,7 +29,7 @@ public class BlockLogic extends Namespaced implements BlockGeneric { super(id); } - public boolean isSolid(BlockTickContext context, RelFace face) { + public boolean isSolid(ServerBlockContextRO context, RelFace face) { return isSolid(face); } @@ -36,7 +37,7 @@ public class BlockLogic extends Namespaced implements BlockGeneric { return true; } - public boolean isTransparent(BlockTickContext context) { + public boolean isTransparent(ServerBlockContextRO context) { return isTransparent(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java deleted file mode 100644 index 7069aa9..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/block/BlockTickContext.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world.block; - -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.BlockRelation; -import ru.windcorp.progressia.server.world.ChunkTickContext; -import ru.windcorp.progressia.server.world.TickContextMutable; -import ru.windcorp.progressia.server.world.tile.TSTickContext; - -public interface BlockTickContext extends ChunkTickContext { - - /** - * Returns the current world coordinates. - * - * @return the world coordinates of the block being ticked - */ - Vec3i getBlockInWorld(); - - default Vec3i getBlockInChunk() { - return Coordinates.convertInWorldToInChunk(getBlockInWorld(), null); - } - - default BlockLogic getBlock() { - return getWorld().getBlock(getBlockInWorld()); - } - - default BlockData getBlockData() { - return getWorldData().getBlock(getBlockInWorld()); - } - - default void forEachFace(Consumer action) { - Objects.requireNonNull(action, "action"); - TickContextMutable context = TickContextMutable.uninitialized(); - - for (AbsFace face : AbsFace.getFaces()) { - context.rebuild().withServer(getServer()).withBlock(getBlockInWorld()).withFace(face).build(); - action.accept(context); - } - } - - default BlockTickContext getNeighbor(Vec3i direction) { - Objects.requireNonNull(direction, "direction"); - return TickContextMutable.copyWorld(this).withBlock(getBlockInWorld().add_(direction)).build(); - } - - default BlockTickContext getNeighbor(BlockRelation relation) { - Objects.requireNonNull(relation, "relation"); - return getNeighbor(relation.getVector(getChunkData().getUp())); - } - - default R evalNeighbor(Vec3i direction, Function action) { - Objects.requireNonNull(action, "action"); - Objects.requireNonNull(direction, "direction"); - return action.apply(getNeighbor(direction)); - } - - default R evalNeighbor(BlockRelation relation, Function action) { - Objects.requireNonNull(action, "action"); - Objects.requireNonNull(relation, "relation"); - return evalNeighbor(relation.getVector(getChunkData().getUp()), action); - } - - default void forNeighbor(Vec3i direction, Consumer action) { - Objects.requireNonNull(action, "action"); - Objects.requireNonNull(direction, "direction"); - evalNeighbor(direction, (Function) ctxt -> { - action.accept(ctxt); - return null; - }); - } - - default void forNeighbor(BlockRelation relation, Consumer action) { - Objects.requireNonNull(action, "action"); - Objects.requireNonNull(relation, "relation"); - forNeighbor(relation.getVector(getChunkData().getUp()), action); - } - - /* - * Convenience methods - changes - */ - - default void setThisBlock(BlockData block) { - getAccessor().setBlock(getBlockInWorld(), block); - } - - default void setThisBlock(String id) { - getAccessor().setBlock(getBlockInWorld(), id); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java b/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java index 56ba938..bc4569b 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/TickableBlock.java @@ -18,12 +18,14 @@ package ru.windcorp.progressia.server.world.block; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerBlockContextRO; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; public interface TickableBlock { - void tick(BlockTickContext context); + void tick(ServerBlockContext context); - TickingPolicy getTickingPolicy(BlockTickContext context); + TickingPolicy getTickingPolicy(ServerBlockContextRO context); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java b/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java index 1497c92..757e972 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java +++ b/src/main/java/ru/windcorp/progressia/server/world/block/UpdateableBlock.java @@ -18,18 +18,10 @@ package ru.windcorp.progressia.server.world.block; -import org.apache.logging.log4j.LogManager; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; public interface UpdateableBlock { - default void update(BlockTickContext context) { - LogManager.getLogger().info( - "Updating block {} @ ({}; {}; {})", - context.getBlock(), - context.getBlockInWorld().x, - context.getBlockInWorld().y, - context.getBlockInWorld().z - ); - } + void update(ServerBlockContext context); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java b/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java index 7725612..2ebd2d6 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/entity/EntityLogic.java @@ -20,7 +20,7 @@ package ru.windcorp.progressia.server.world.entity; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.server.world.TickContext; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; public class EntityLogic extends Namespaced { @@ -28,7 +28,7 @@ public class EntityLogic extends Namespaced { super(id); } - public void tick(EntityData entity, TickContext context) { + public void tick(EntityData entity, ServerWorldContext context) { entity.incrementAge(context.getTickLength()); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java index 120cd22..57d2c67 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/BlockTriggeredUpdate.java @@ -25,7 +25,6 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; -import ru.windcorp.progressia.server.world.DefaultWorldLogic; class BlockTriggeredUpdate extends CachedEvaluation { @@ -39,13 +38,11 @@ class BlockTriggeredUpdate extends CachedEvaluation { public void evaluate(Server server) { Vec3i cursor = new Vec3i(blockInWorld.x, blockInWorld.y, blockInWorld.z); - DefaultWorldLogic world = server.getWorld(); - for (AbsFace face : AbsFace.getFaces()) { - TickAndUpdateUtil.updateTiles(world, cursor, face); + TickAndUpdateUtil.updateTiles(server, cursor, face); cursor.add(face.getVector()); - TickAndUpdateUtil.updateBlock(world, cursor); - TickAndUpdateUtil.updateTiles(world, cursor, face.getCounter()); + TickAndUpdateUtil.updateBlock(server, cursor); + TickAndUpdateUtil.updateTiles(server, cursor, face.getCounter()); cursor.sub(face.getVector()); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java index 08f1212..8760460 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java @@ -21,6 +21,7 @@ package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.PacketChangeEntity; import ru.windcorp.progressia.server.Server; @@ -36,7 +37,7 @@ class ChangeEntity extends CachedChange { super(disposer); } - public void set(T entity, StateChange change) { + public void set(EntityData entity, StateChange change) { if (this.entity != null) throw new IllegalStateException("Entity is not null. Current: " + this.entity + "; requested: " + entity); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java deleted file mode 100644 index 93d5f08..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/StateChange.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world.tasks; - -@FunctionalInterface -public interface StateChange { - void change(T object); -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index 336f166..d7fabc1 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.server.world.tasks; import java.util.ArrayList; @@ -27,17 +27,22 @@ import com.google.common.collect.ImmutableList; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatMathUtil; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.DefaultChunkLogic; -import ru.windcorp.progressia.server.world.TickContextMutable; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.TickableBlock; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileStackContext; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; import ru.windcorp.progressia.server.world.ticking.Evaluation; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; -import ru.windcorp.progressia.server.world.tile.TSTickContext; import ru.windcorp.progressia.server.world.tile.TickableTile; import ru.windcorp.progressia.server.world.tile.TileLogic; import static ru.windcorp.progressia.common.world.DefaultChunkData.BLOCKS_PER_CHUNK; @@ -82,11 +87,11 @@ public class TickChunk extends Evaluation { if (!chunk.hasTickingBlocks()) return; - TickContextMutable context = TickContextMutable.uninitialized(); + ServerWorldContext context = server.createContext(); chunk.forEachTickingBlock((blockInChunk, block) -> { - context.rebuild().withChunk(chunk).withBlockInChunk(blockInChunk).build(); - ((TickableBlock) block).tick(context); + ((TickableBlock) block).tick(contextPushBiC(context, chunk, blockInChunk)); + context.pop(); }); } @@ -94,11 +99,14 @@ public class TickChunk extends Evaluation { if (!chunk.hasTickingTiles()) return; - TickContextMutable context = TickContextMutable.uninitialized(); + ServerWorldContext context = server.createContext(); + Vec3i blockInWorld = new Vec3i(); chunk.forEachTickingTile((ref, tile) -> { - context.rebuild().withServer(server).withTile(ref); - ((TickableTile) tile).tick(context); + ((TickableTile) tile).tick( + context.push(ref.getStack().getBlockInWorld(blockInWorld), ref.getStack().getFace(), ref.getIndex()) + ); + context.pop(); }); } @@ -144,7 +152,7 @@ public class TickChunk extends Evaluation { return; TickableBlock tickable = (TickableBlock) block; - TickContextMutable context = TickContextMutable.start().withChunk(chunk).withBlockInChunk(blockInChunk).build(); + ServerBlockContext context = contextPushBiC(server.createContext(), chunk, blockInChunk); if (tickable.getTickingPolicy(context) != TickingPolicy.RANDOM) return; @@ -164,18 +172,22 @@ public class TickChunk extends Evaluation { if (tiles == null || tiles.isEmpty()) return; - TSTickContext context = TickContextMutable.start().withServer(server).withTS(tiles).build(); + ServerTileStackContext context = contextPushBiC(server.createContext(), chunk, blockInChunk).push(face.relativize(chunk.getUp())); - context.forEachTile(tctxt -> { - TileLogic logic = tctxt.getTile(); + for (int i = 0; i < tiles.size(); ++i) { + ServerTileContext tileContext = context.push(i); + + TileLogic logic = tileContext.logic().getTile(); if (!(logic instanceof TickableTile)) return; TickableTile tickable = (TickableTile) logic; - if (tickable.getTickingPolicy(tctxt) != TickingPolicy.RANDOM) + if (tickable.getTickingPolicy(tileContext) != TickingPolicy.RANDOM) return; - tickable.tick(tctxt); - }); + tickable.tick(tileContext); + + tileContext.pop(); + } } private float computeRandomTicks(Server server) { @@ -184,6 +196,18 @@ public class TickChunk extends Evaluation { server.getTickLength()); } + private ServerBlockContext contextPushBiC( + ServerWorldContext context, + ChunkGenericRO chunk, + Vec3i blockInChunk + ) { + Vec3i blockInWorld = Vectors.grab3i(); + Coordinates.getInWorld(chunk.getPosition(), blockInChunk, blockInWorld); + ServerBlockContext blockContext = context.push(blockInWorld); + Vectors.release(blockInWorld); + return blockContext; + } + @Override public void getRelevantChunk(Vec3i output) { Vec3i p = chunk.getData().getPosition(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java index 66e95a1..c052108 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TileTriggeredUpdate.java @@ -25,7 +25,6 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.TickAndUpdateUtil; -import ru.windcorp.progressia.server.world.DefaultWorldLogic; class TileTriggeredUpdate extends CachedEvaluation { @@ -40,17 +39,15 @@ class TileTriggeredUpdate extends CachedEvaluation { public void evaluate(Server server) { Vec3i cursor = new Vec3i(blockInWorld.x, blockInWorld.y, blockInWorld.z); - DefaultWorldLogic world = server.getWorld(); - - TickAndUpdateUtil.updateTiles(world, cursor, face); // Update facemates - // (also self) - TickAndUpdateUtil.updateBlock(world, cursor); // Update block on one - // side + // Update facemates (also self) + TickAndUpdateUtil.updateTiles(server, cursor, face); + // Update block on one side + TickAndUpdateUtil.updateBlock(server, cursor); cursor.add(face.getVector()); - TickAndUpdateUtil.updateBlock(world, cursor); // Update block on the - // other side - TickAndUpdateUtil.updateTiles(world, cursor, face.getCounter()); // Update - // complement + // Update block on the other side + TickAndUpdateUtil.updateBlock(server, cursor); + // Update complement + TickAndUpdateUtil.updateTiles(server, cursor, face.getCounter()); } public void init(Vec3i blockInWorld, AbsFace face) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java index 15ab504..cb95063 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java @@ -21,17 +21,19 @@ package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.state.StateChange; +import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.util.MultiLOC; import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataRegistry; import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext; import ru.windcorp.progressia.server.world.ticking.TickerTask; -public class WorldAccessor { +public class WorldAccessor implements ReportingServerContext.ChangeListener { private final MultiLOC cache; { @@ -54,38 +56,52 @@ public class WorldAccessor { this.server = server; } - public void setBlock(Vec3i blockInWorld, BlockData block) { + @Override + public void onBlockSet(Vec3i blockInWorld, BlockData block) { SetBlock change = cache.grab(SetBlock.class); change.getPacket().set(block, blockInWorld); server.requestChange(change); } - public void setBlock(Vec3i blockInWorld, String id) { - setBlock(blockInWorld, BlockDataRegistry.getInstance().get(id)); - } - - public void addTile(Vec3i blockInWorld, BlockFace face, TileData tile) { + @Override + public void onTileAdded(Vec3i blockInWorld, BlockFace face, TileData tile) { AddTile change = cache.grab(AddTile.class); change.getPacket().set(tile, blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld))); server.requestChange(change); } - public void addTile(Vec3i blockInWorld, BlockFace face, String id) { - addTile(blockInWorld, face, TileDataRegistry.getInstance().get(id)); - } - - public void removeTile(Vec3i blockInWorld, BlockFace face, int tag) { + @Override + public void onTileRemoved(Vec3i blockInWorld, BlockFace face, int tag) { RemoveTile change = cache.grab(RemoveTile.class); change.getPacket().set(blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld)), tag); server.requestChange(change); } + + @Override + public void onEntityAdded(EntityData entity) { + // TODO Auto-generated method stub + + } + + @Override + public void onEntityRemoved(long entityId) { + // TODO Auto-generated method stub + + } + + @Override + public void onTimeChanged(float change) { + // TODO Auto-generated method stub + System.err.println("WorldAccessor.onTimeChanged() NYI!"); + } - public void changeEntity( - T entity, - StateChange stateChange + @Override + public void onEntityChanged( + SE entity, + StateChange stateChange ) { ChangeEntity change = cache.grab(ChangeEntity.class); - change.set(entity, stateChange); + change.set((EntityData) entity, stateChange); server.requestChange(change); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java index 745f289..f916a24 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java @@ -19,6 +19,8 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileContextRO; public class HangingTileLogic extends TileLogic implements UpdateableTile { @@ -27,15 +29,15 @@ public class HangingTileLogic extends TileLogic implements UpdateableTile { } @Override - public void update(TileTickContext context) { + public void update(ServerTileContext context) { if (!canOccupyFace(context)) { - context.removeThisTile(); + context.removeTile(); } } @Override - public boolean canOccupyFace(TileTickContext context) { - BlockLogic host = context.getBlock(); + public boolean canOccupyFace(ServerTileContextRO context) { + BlockLogic host = context.logic().getBlock(); if (host == null) return false; @@ -45,13 +47,14 @@ public class HangingTileLogic extends TileLogic implements UpdateableTile { if (canBeSquashed(context)) return true; - return context.evalComplementary(ctxt -> { - BlockLogic complHost = ctxt.getBlock(); - return complHost == null || !complHost.isSolid(ctxt, context.getFace()); - }); + context.pushOpposite(); + BlockLogic complHost = context.logic().getBlock(); + boolean result = complHost == null || !complHost.isSolid(context, context.getFace()); + context.pop(); + return result; } - public boolean canBeSquashed(TileTickContext context) { + public boolean canBeSquashed(ServerTileContextRO context) { return false; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java deleted file mode 100644 index d805607..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TSTickContext.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world.tile; - -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; - -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.server.world.DefaultChunkLogic; -import ru.windcorp.progressia.server.world.TickContextMutable; -import ru.windcorp.progressia.server.world.TileLogicStackRO; -import ru.windcorp.progressia.server.world.block.BlockTickContext; - -public interface TSTickContext extends BlockTickContext { - - /* - * Specifications - */ - - RelFace getFace(); - - /* - * Getters - */ - - default TileLogicStackRO getTLSOrNull() { - DefaultChunkLogic chunkLogic = getChunkLogic(); - if (chunkLogic == null) - return null; - - return chunkLogic.getTilesOrNull(getBlockInChunk(), getFace()); - } - - default TileLogicStackRO getTLS() { - return getChunkLogic().getTiles(getBlockInChunk(), getFace()); - } - - default TileDataStack getTDSOrNull() { - DefaultChunkData chunkData = getChunkData(); - if (chunkData == null) - return null; - - return chunkData.getTilesOrNull(getBlockInChunk(), getFace()); - } - - default TileDataStack getTDS() { - return getChunkData().getTiles(getBlockInChunk(), getFace()); - } - - /* - * Contexts - */ - - default TileTickContext forLayer(int layer) { - return TickContextMutable.start().withServer(getServer()).withBlock(getBlockInWorld()).withFace(getFace()) - .withLayer(layer); - } - - default boolean forEachTile(Consumer action) { - TickContextMutable context = TickContextMutable.uninitialized(); - - TileDataStack stack = getTDSOrNull(); - if (stack == null || stack.isEmpty()) - return false; - - for (int layer = 0; layer < stack.size(); ++layer) { - context.rebuild().withServer(getServer()).withBlock(getBlockInWorld()).withFace(getFace()).withLayer(layer); - action.accept(context); - } - - return true; - } - - default TSTickContext getComplementary() { - return TickContextMutable.copyWorld(this) - .withBlock(getBlockInWorld().add_(getFace().getVector(getUp()))) - .withFace(getFace().getCounter()) - .build(); - } - - default R evalComplementary(Function action) { - Objects.requireNonNull(action, "action"); - return action.apply(getComplementary()); - } - - default void forComplementary(Consumer action) { - Objects.requireNonNull(action, "action"); - evalComplementary((Function) ctxt -> { - action.accept(ctxt); - return null; - }); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java index 4def3b0..ce2487d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TickableTile.java @@ -18,12 +18,14 @@ package ru.windcorp.progressia.server.world.tile; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileContextRO; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; public interface TickableTile { - void tick(TileTickContext context); + void tick(ServerTileContext context); - TickingPolicy getTickingPolicy(TileTickContext context); + TickingPolicy getTickingPolicy(ServerTileContextRO context); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java index 67466b5..229d7e3 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/TileLogic.java @@ -21,6 +21,7 @@ package ru.windcorp.progressia.server.world.tile; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.generic.TileGeneric; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.context.ServerTileContextRO; public class TileLogic extends Namespaced implements TileGeneric { @@ -28,7 +29,7 @@ public class TileLogic extends Namespaced implements TileGeneric { super(id); } - public boolean canOccupyFace(TileTickContext context) { + public boolean canOccupyFace(ServerTileContextRO context) { return canOccupyFace(context.getFace()); } @@ -36,7 +37,7 @@ public class TileLogic extends Namespaced implements TileGeneric { return true; } - public boolean isSolid(TileTickContext context) { + public boolean isSolid(ServerTileContextRO context) { return isSolid(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java b/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java deleted file mode 100644 index 597291a..0000000 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/TileTickContext.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.server.world.tile; - -import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.server.world.TileLogicStackRO; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.TileDataReference; - -public interface TileTickContext extends TSTickContext { - - /* - * Specifications - */ - - /** - * Returns the current layer. - * - * @return the layer that the tile being ticked occupies in the tile stack - */ - int getLayer(); - - /* - * Getters - */ - - default TileLogic getTile() { - TileLogicStackRO stack = getTLSOrNull(); - if (stack == null) - return null; - return stack.get(getLayer()); - } - - default TileData getTileData() { - TileDataStack stack = getTDSOrNull(); - if (stack == null) - return null; - return stack.get(getLayer()); - } - - default TileDataReference getReference() { - return getTDS().getReference(getLayer()); - } - - default int getTag() { - return getTDS().getTagByIndex(getLayer()); - } - - /* - * Contexts - */ - - /* - * Convenience methods - changes - */ - - default void removeThisTile() { - getAccessor().removeTile(getBlockInWorld(), getFace(), getTag()); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java b/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java index bf114fa..3d63585 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/UpdateableTile.java @@ -18,8 +18,10 @@ package ru.windcorp.progressia.server.world.tile; +import ru.windcorp.progressia.server.world.context.ServerTileContext; + public interface UpdateableTile { - void update(TileTickContext context); + void update(ServerTileContext context); } diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 46bf460..0ddc3e5 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -383,7 +383,7 @@ public class TestContent { ru.windcorp.progressia.server.comms.Client client ) { Vec3i blockInWorld = ((ControlBreakBlockData) packet.getControl()).getBlockInWorld(); - server.getWorldAccessor().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air")); + server.createContext().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air")); } private static void onBlockPlaceTrigger(ControlData control) { @@ -403,7 +403,7 @@ public class TestContent { Vec3i blockInWorld = controlData.getBlockInWorld(); if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) return; - server.getWorldAccessor().setBlock(blockInWorld, block); + server.createContext().setBlock(blockInWorld, block); } private static void onTilePlaceTrigger(ControlData control) { @@ -428,7 +428,7 @@ public class TestContent { return; if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) return; - server.getWorldAccessor().addTile(blockInWorld, face, tile); + server.createContext().addTile(blockInWorld, face, tile); } private static void registerMisc() { diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java index 5fa66fb..ac49fc9 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicStatie.java @@ -19,7 +19,7 @@ package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.server.world.TickContext; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; import ru.windcorp.progressia.server.world.entity.EntityLogic; public class TestEntityLogicStatie extends EntityLogic { @@ -29,13 +29,13 @@ public class TestEntityLogicStatie extends EntityLogic { } @Override - public void tick(EntityData entity, TickContext context) { + public void tick(EntityData entity, ServerWorldContext context) { super.tick(entity, context); TestEntityDataStatie statie = (TestEntityDataStatie) entity; int size = (int) (18 + 6 * Math.sin(entity.getAge())); - context.getServer().getWorldAccessor().changeEntity(statie, e -> e.setSizeNow(size)); + context.changeEntity(statie, e -> e.setSizeNow(size)); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index 246c882..b41f5a7 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -20,11 +20,11 @@ package ru.windcorp.progressia.test; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; -import ru.windcorp.progressia.server.world.block.BlockTickContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileContextRO; import ru.windcorp.progressia.server.world.ticking.TickingPolicy; import ru.windcorp.progressia.server.world.tile.HangingTileLogic; import ru.windcorp.progressia.server.world.tile.TickableTile; -import ru.windcorp.progressia.server.world.tile.TileTickContext; public class TestTileLogicGrass extends HangingTileLogic implements TickableTile { @@ -33,7 +33,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile } @Override - public boolean canOccupyFace(TileTickContext context) { + public boolean canOccupyFace(ServerTileContextRO context) { return context.getFace() != RelFace.DOWN && super.canOccupyFace(context); } @@ -43,34 +43,31 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile } @Override - public TickingPolicy getTickingPolicy(TileTickContext context) { + public TickingPolicy getTickingPolicy(ServerTileContextRO context) { return TickingPolicy.RANDOM; } @Override - public void tick(TileTickContext context) { + public void tick(ServerTileContext context) { if (!isLocationSuitable(context)) { // context.removeThisTile(); } } @Override - public boolean canBeSquashed(TileTickContext context) { + public boolean canBeSquashed(ServerTileContextRO context) { return true; } - private boolean isLocationSuitable(TileTickContext context) { + private boolean isLocationSuitable(ServerTileContextRO context) { return canOccupyFace(context) && isBlockAboveTransparent(context); } - private boolean isBlockAboveTransparent(BlockTickContext context) { - return context.evalNeighbor(RelFace.UP, bctxt -> { - BlockLogic block = bctxt.getBlock(); - if (block == null) - return true; - - return block.isTransparent(bctxt); - }); + private boolean isBlockAboveTransparent(ServerTileContextRO context) { + // TODO rework + context.pushRelative(RelFace.UP.resolve(context.getServer().getWorld().getUp(context.getLocation()))); + BlockLogic block = context.logic().getBlock(); + return context.popAndReturn(block == null || block.isTransparent(context)); } } From a03c783fc9080b03c3dfbd6534b9a9d3ffd43453 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 11 Aug 2021 13:02:18 +0300 Subject: [PATCH 48/63] Fixing bugs introduced in previous commit - Fixed AbstractContextRO.isSubcontexting() - Fixed push(...) overrides in FilterServerContext - Fixed DefaultChunkLogic.tmp_generateTickLists() - Debug screen now also lists visible and loaded chunks - AbstractContextRO.Frame now has a toString() --- .../generic/context/AbstractContextRO.java | 44 +++++++++++-------- .../ru/windcorp/progressia/server/Server.java | 2 +- .../server/world/DefaultChunkLogic.java | 13 +++--- .../impl/DefaultServerContextImpl.java | 2 +- .../context/impl/FilterServerContext.java | 9 ++-- .../progressia/test/LayerTestGUI.java | 32 ++++++++++++-- .../resources/assets/languages/en-US.lang | 2 +- .../resources/assets/languages/ru-RU.lang | 2 +- 8 files changed, 71 insertions(+), 35 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java index db4770f..29e3127 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java @@ -31,65 +31,71 @@ public abstract class AbstractContextRO< E extends EntityGeneric > implements TileGenericContextRO { //@formatter:on - + public static final int MAX_SUBCONTEXTS = 64; - + protected class Frame { - + public final Vec3i location = new Vec3i(); public RelFace face; public int layer; - + + @Override + public String toString() { + return "Frame [x=" + location.x + ", y=" + location.y + ", z=" + location.z + ", face=" + face + ", layer=" + + layer + "]"; + } + } - + protected Frame frame = null; - + private final StashingStack frameStack = new StashingStack<>(MAX_SUBCONTEXTS, Frame::new); - + @Override public void pop() { if (!isSubcontexting()) { throw new IllegalStateException("Cannot pop(): already top frame"); } - + frame = frameStack.pop(); } - + @Override public BlockGenericContextRO push(Vec3i location) { frame = frameStack.push(); - + frame.location.set(location.x, location.y, location.z); frame.face = null; frame.layer = -1; - + return this; } - + @Override public TileStackGenericContextRO push(Vec3i location, RelFace face) { frame = frameStack.push(); - + frame.location.set(location.x, location.y, location.z); frame.face = face; frame.layer = -1; - + return this; } - + @Override public TileGenericContextRO push(Vec3i location, RelFace face, int layer) { frame = frameStack.push(); - + frame.location.set(location.x, location.y, location.z); frame.face = face; frame.layer = layer; - + return this; } - + public boolean isSubcontexting() { - return frameStack.isEmpty(); + return !frameStack.isEmpty(); } } diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index a57ce2f..0efc551 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -109,7 +109,7 @@ public class Server { */ public ServerWorldContext createContext() { - return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build()).withListener(worldAccessor); + return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build()).withListener(worldAccessor).setPassToParent(false); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java index 0e2dbbe..978fae3 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java @@ -235,8 +235,10 @@ public class DefaultChunkLogic implements ChunkLogic { BlockLogic block = blockContext.logic().getBlock(); Coordinates.convertInWorldToInChunk(location, blockInChunk); - if (!(block instanceof TickableBlock)) + if (!(block instanceof TickableBlock)) { + blockContext.pop(); return; + } if (((TickableBlock) block).getTickingPolicy(blockContext) == TickingPolicy.REGULAR) { tickingBlocks.add(blockInChunk); @@ -248,16 +250,17 @@ public class DefaultChunkLogic implements ChunkLogic { for (int i = 0; i < stack.size(); ++i) { ServerTileContextRO tileContext = blockContext.push(face, i); - TileLogic tile = stack.get(i); - if (!(tile instanceof TickableTile)) - return; + if (!(tile instanceof TickableTile)) { + tileContext.pop(); + continue; + } if (((TickableTile) tile).getTickingPolicy(tileContext) == TickingPolicy.REGULAR) { tickingTiles.add(stack.getData().getReference(i)); } - + tileContext.pop(); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index 1fa1178..77e5551 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -109,7 +109,7 @@ class DefaultServerContextImpl extends DefaultServerContext */ public boolean requireContextRole(Role role) throws IllegalStateException { - boolean ok = !isBuilder && getRole().compareTo(role) <= 0; + boolean ok = !isBuilder && getRole().compareTo(role) >= 0; if (!ok) { complainAboutIllegalState(role, false); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java index 4896b84..40927c3 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java @@ -179,17 +179,20 @@ public abstract class FilterServerContext implements ServerTileContext { @Override public ServerBlockContext push(Vec3i location) { - return parent.push(location); + parent.push(location); + return this; } @Override public ServerTileStackContext push(Vec3i location, RelFace face) { - return parent.push(location, face); + parent.push(location, face); + return this; } @Override public ServerTileContext push(Vec3i location, RelFace face, int layer) { - return parent.push(location, face, layer); + parent.push(location, face, layer); + return this; } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java index fcdc1ac..65913d2 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestGUI.java @@ -35,6 +35,7 @@ import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical; import ru.windcorp.progressia.client.localization.Localizer; import ru.windcorp.progressia.client.localization.MutableString; import ru.windcorp.progressia.client.localization.MutableStringLocalized; +import ru.windcorp.progressia.client.world.WorldRender; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.dynstr.DynamicStrings; import ru.windcorp.progressia.server.Server; @@ -128,14 +129,37 @@ public class LayerTestGUI extends GUILayer { 128 ) ); - + group.addChild( new DynamicLabel( - "ChunkUpdatesDisplay", + "ChunkStatsDisplay", font, DynamicStrings.builder() - .addDyn(new MutableStringLocalized("LayerTestGUI.ChunkUpdatesDisplay")) - .addDyn(ClientState.getInstance().getWorld()::getPendingChunkUpdates) + .addDyn(new MutableStringLocalized("LayerTestGUI.ChunkStatsDisplay")) + .addDyn(() -> { + if (ClientState.getInstance() == null) { + return -1; + } else { + WorldRender world = ClientState.getInstance().getWorld(); + return world.getChunks().size() - world.getPendingChunkUpdates(); + } + }, 4) + .add('/') + .addDyn(() -> { + if (ClientState.getInstance() == null) { + return -1; + } else { + return ClientState.getInstance().getWorld().getPendingChunkUpdates(); + } + }, 4) + .add('/') + .addDyn(() -> { + if (ServerState.getInstance() == null) { + return -1; + } else { + return ServerState.getInstance().getWorld().getChunks().size(); + } + }, 4) .buildSupplier(), 128 ) diff --git a/src/main/resources/assets/languages/en-US.lang b/src/main/resources/assets/languages/en-US.lang index e4b69de..e2ff70b 100644 --- a/src/main/resources/assets/languages/en-US.lang +++ b/src/main/resources/assets/languages/en-US.lang @@ -11,7 +11,7 @@ LayerTestGUI.LanguageDisplay = Language: %5s (L) LayerTestGUI.FPSDisplay = FPS: LayerTestGUI.TPSDisplay = TPS: LayerTestGUI.TPSDisplay.NA = TPS: n/a -LayerTestGUI.ChunkUpdatesDisplay = Pending updates: +LayerTestGUI.ChunkStatsDisplay = Chunks vis/pnd/load: LayerTestGUI.PosDisplay = Pos: LayerTestGUI.PosDisplay.NA.Client = Pos: client n/a LayerTestGUI.PosDisplay.NA.Entity = Pos: entity n/a diff --git a/src/main/resources/assets/languages/ru-RU.lang b/src/main/resources/assets/languages/ru-RU.lang index a01e6ad..97935d6 100644 --- a/src/main/resources/assets/languages/ru-RU.lang +++ b/src/main/resources/assets/languages/ru-RU.lang @@ -11,7 +11,7 @@ LayerTestGUI.LanguageDisplay = Язык: %5s (L) LayerTestGUI.FPSDisplay = FPS: LayerTestGUI.TPSDisplay = TPS: LayerTestGUI.TPSDisplay.NA = TPS: н/д -LayerTestGUI.ChunkUpdatesDisplay = Обновления в очереди: +LayerTestGUI.ChunkStatsDisplay = Чанки вид/очр/загр: LayerTestGUI.PosDisplay = Поз: LayerTestGUI.PosDisplay.NA.Client = Поз: клиент н/д LayerTestGUI.PosDisplay.NA.Entity = Поз: сущность н/д From 78a1c25554e033c999d611287c1614d39ebb807b Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 11 Aug 2021 13:45:47 +0300 Subject: [PATCH 49/63] Grass tiles have regained the ability to disappear under blocks - Test:Grass now (again) randomly disappears under opaque blocks - Fixed a truly egregious bug in AbstractContextRO.pop() - Fixed BlockContext.pushRelative(AbsRelation) - Some changes in toString methods in contexts --- .../common/world/context/BlockDataContext.java | 2 +- .../common/world/context/BlockDataContextRO.java | 2 +- .../world/generic/context/AbstractContextRO.java | 3 ++- .../world/generic/context/BlockGenericContextRO.java | 2 +- .../world/generic/context/BlockGenericContextWO.java | 2 +- .../common/world/generic/context/WorldContexts.java | 2 +- .../server/world/context/ServerBlockContext.java | 4 ++-- .../server/world/context/ServerBlockContextRO.java | 4 ++-- .../context/impl/DefaultServerContextBuilders.java | 2 +- .../world/context/impl/DefaultServerContextImpl.java | 11 +++++------ .../world/context/impl/FilterServerContext.java | 5 +++++ .../progressia/server/world/tasks/TickChunk.java | 12 ++++++++---- .../server/world/tile/HangingTileLogic.java | 4 +--- .../windcorp/progressia/test/TestTileLogicGrass.java | 2 +- 14 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java index 9667eac..36e7dbe 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java @@ -46,7 +46,7 @@ public interface BlockDataContext @Override default BlockDataContext pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java index 7d35ec3..8d75845 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java @@ -45,7 +45,7 @@ public interface BlockDataContextRO @Override default BlockDataContextRO pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java index 29e3127..0657a3e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/AbstractContextRO.java @@ -58,7 +58,8 @@ public abstract class AbstractContextRO< throw new IllegalStateException("Cannot pop(): already top frame"); } - frame = frameStack.pop(); + frameStack.pop(); + frame = frameStack.peek(); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index 842fd0a..cacbe45 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -149,7 +149,7 @@ public interface BlockGenericContextRO< @Override default BlockGenericContextRO pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index 97ec62d..c1fa216 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -92,7 +92,7 @@ public interface BlockGenericContextWO< @Override default BlockGenericContextWO pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java index bfc85bb..30b85ce 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -146,7 +146,7 @@ class WorldContexts { * @see #pop() */ default Block pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } /** diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java index c8bdf0b..6b66ba0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java @@ -41,7 +41,7 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext @Override default ServerBlockContext.Logic pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override @@ -71,7 +71,7 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext @Override default ServerBlockContext pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java index eefa195..8ef355e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java @@ -46,7 +46,7 @@ public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataCon @Override default ServerBlockContextRO.Logic pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override @@ -76,7 +76,7 @@ public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataCon @Override default ServerBlockContextRO pushRelative(AbsRelation direction) { - return push(direction.getVector()); + return push(getLocation().add_(direction.getVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java index 8069db8..cb182ce 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextBuilders.java @@ -29,7 +29,7 @@ public interface DefaultServerContextBuilders { DefaultServerContext build(); - public interface Empty /* does not extend RSCB */ { + public interface Empty /* does not extend DSCB */ { WithWorld in(Server server, WorldData world); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index 77e5551..ec89e47 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -150,7 +150,7 @@ class DefaultServerContextImpl extends DefaultServerContext switch (getRole()) { case TILE: result = String.format( - "ServerTileContext[x=%d, y=%d, z=%d, %s, index=%d]", + "ServerTileContext [x=%+4d, y=%+4d, z=%+4d, %s, index=%d]", frame.location.x, frame.location.y, frame.location.z, @@ -160,16 +160,16 @@ class DefaultServerContextImpl extends DefaultServerContext break; case TILE_STACK: result = String - .format("ServerBlockFaceContext[x=%d, y=%d, z=%d, %s]", frame.location.x, frame.location.y, frame.location.z, frame.face); + .format("ServerBlockFaceContext [x=%+4d, y=%+4d, z=%+4d, %s]", frame.location.x, frame.location.y, frame.location.z, frame.face); break; case LOCATION: - result = String.format("ServerBlockContext[x=%d, y=%d, z=%d]", frame.location.x, frame.location.y, frame.location.z); + result = String.format("ServerBlockContext [x=%+4d, y=%+4d, z=%+4d]", frame.location.x, frame.location.y, frame.location.z); break; case WORLD: - result = String.format("ServerWorldContext"); + result = "ServerWorldContext"; break; default: - result = "Uninitialized ReusableServerContext"; + result = "Uninitialized DefaultServerContext"; break; } @@ -188,7 +188,6 @@ class DefaultServerContextImpl extends DefaultServerContext public Empty reuse() { server = null; -// worldLogic = null; world = null; while (isSubcontexting()) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java index 40927c3..b7b5ff5 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java @@ -51,6 +51,11 @@ public abstract class FilterServerContext implements ServerTileContext { public ServerTileContext getParent() { return parent; } + + @Override + public String toString() { + return getClass().getSimpleName() + " [" + parent + "]"; + } @Override public int getLayer() { diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index d7fabc1..4ed21f1 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -178,12 +178,16 @@ public class TickChunk extends Evaluation { ServerTileContext tileContext = context.push(i); TileLogic logic = tileContext.logic().getTile(); - if (!(logic instanceof TickableTile)) - return; + if (!(logic instanceof TickableTile)) { + tileContext.pop(); + continue; + } TickableTile tickable = (TickableTile) logic; - if (tickable.getTickingPolicy(tileContext) != TickingPolicy.RANDOM) - return; + if (tickable.getTickingPolicy(tileContext) != TickingPolicy.RANDOM) { + tileContext.pop(); + continue; + } tickable.tick(tileContext); tileContext.pop(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java b/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java index f916a24..87a5c07 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tile/HangingTileLogic.java @@ -49,9 +49,7 @@ public class HangingTileLogic extends TileLogic implements UpdateableTile { context.pushOpposite(); BlockLogic complHost = context.logic().getBlock(); - boolean result = complHost == null || !complHost.isSolid(context, context.getFace()); - context.pop(); - return result; + return context.popAndReturn(complHost == null || !complHost.isSolid(context, context.getFace())); } public boolean canBeSquashed(ServerTileContextRO context) { diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index b41f5a7..bfe438f 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -50,7 +50,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile @Override public void tick(ServerTileContext context) { if (!isLocationSuitable(context)) { -// context.removeThisTile(); + context.removeTile(); } } From 54c66d28d6579bad0d4973a741a8b8c343908af4 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 13 Aug 2021 16:11:46 +0300 Subject: [PATCH 50/63] Added TransformingServerContext and RotatingServerContext. WIP There is a problem with faces in contexts when up != POS_Z, world crashes soon after startup - Added TransformingServerContext - a common basis for context wrappers that alter the coordinate space - Added RotatingServerContext - a context wrapper that rotates the coordinate space - Used to ensure positive Z is up - PacketAffectTile now checks the provided tile tag for validity - This causes a crash when the invalid action is requested, not executed - TickChunk task reuses contexts --- .../world/generic/context/WorldContexts.java | 76 +++++ .../common/world/tile/PacketAffectTile.java | 4 + .../ru/windcorp/progressia/server/Server.java | 57 +++- .../server/world/DefaultChunkLogic.java | 30 +- .../server/world/TickAndUpdateUtil.java | 31 +- .../server/world/context/ServerContexts.java | 141 +++++++++ .../impl/DefaultServerContextImpl.java | 36 +++ .../impl/DefaultServerContextLogic.java | 21 ++ .../context/impl/FilterServerContext.java | 21 ++ .../context/impl/RotatingServerContext.java | 54 ++++ .../impl/TransformingServerContext.java | 273 ++++++++++++++++++ .../server/world/tasks/TickChunk.java | 90 +++--- .../windcorp/progressia/test/TestContent.java | 6 +- .../progressia/test/TestTileLogicGrass.java | 3 +- 14 files changed, 749 insertions(+), 94 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java create mode 100644 src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java index 30b85ce..5cf9f44 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -20,7 +20,9 @@ package ru.windcorp.progressia.common.world.generic.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.AbsRelation; +import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; /** @@ -81,6 +83,80 @@ class WorldContexts { */ Tile push(Vec3i location, RelFace face, int layer); + /** + * Converts the provided location given in the context's coordinate + * space to the underlying absolute coordinate space. + *

      + * The definition of "absolute coordinate space" for contexts that are + * not {@linkplain #isReal() real} may be arbitrary, but methods + * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)}, + * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are + * guaranteed to be consistent for all contexts. + * + * @param contextLocation the location expressed in context coordinate + * system + * @param output the {@link Vec3i} object to output the result + * into, or {@code null} + * @return The location expressed in absolute coordinate system. If + * {@code output} is not {@code null}, {@code output} is + * returned; otherwise, a new {@link Vec3i} is instantiated and + * returned + */ + Vec3i toAbsolute(Vec3i contextLocation, Vec3i output); + + /** + * Converts the provided location given in the absolute coordinate + * space to the context coordinate space. + *

      + * The definition of "absolute coordinate space" for contexts that are + * not {@linkplain #isReal() real} may be arbitrary, but methods + * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)}, + * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are + * guaranteed to be consistent for all contexts. + * + * @param contextLocation the location expressed in absolute coordinate + * system + * @param output the {@link Vec3i} object to output the result + * into, or {@code null} + * @return The location expressed in context coordinate system. If + * {@code output} is not {@code null}, {@code output} is + * returned; otherwise, a new {@link Vec3i} is instantiated and + * returned + */ + Vec3i toContext(Vec3i absoluteLocation, Vec3i output); + + /** + * Converts the provided face given in the context's coordinate + * space to the underlying absolute coordinate space. + *

      + * The definition of "absolute coordinate space" for contexts that are + * not {@linkplain #isReal() real} may be arbitrary, but methods + * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)}, + * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are + * guaranteed to be consistent for all contexts. + * + * @param contextLocation the face expressed in context coordinate + * system + * @return the face expressed in absolute coordinate system + */ + AbsFace toAbsolute(BlockFace contextFace); + + /** + * Converts the provided face given in the absolute coordinate + * space to the context coordinate space. + *

      + * The definition of "absolute coordinate space" for contexts that are + * not {@linkplain #isReal() real} may be arbitrary, but methods + * {@link #toAbsolute(Vec3i, Vec3i)}, {@link #toAbsolute(BlockFace)}, + * {@link #toContext(Vec3i, Vec3i)} and {@link #toContext(AbsFace)} are + * guaranteed to be consistent for all contexts. + * + * @param contextLocation the face expressed in absolute coordinate + * system + * @return the face expressed in context coordinate system + */ + RelFace toContext(AbsFace absoluteFace); + } /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java index 9be01e2..41cffef 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java @@ -51,6 +51,10 @@ public abstract class PacketAffectTile extends PacketAffectChunk { } public void set(Vec3i blockInWorld, AbsFace face, int tag) { + if (tag < 0) { + throw new IllegalArgumentException("Cannot affect tile with tag -1"); + } + this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); this.face = face; this.tag = tag; diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 0efc551..915c262 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -24,20 +24,26 @@ import org.apache.logging.log4j.LogManager; import com.google.common.eventbus.EventBus; +import glm.vec._3.i.Vec3i; import ru.windcorp.jputil.functions.ThrowingRunnable; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.TaskQueue; import ru.windcorp.progressia.common.util.crash.ReportingEventBus; import ru.windcorp.progressia.common.world.DefaultWorldData; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.server.comms.ClientManager; import ru.windcorp.progressia.server.events.ServerEvent; import ru.windcorp.progressia.server.management.load.ChunkRequestDaemon; import ru.windcorp.progressia.server.management.load.EntityRequestDaemon; import ru.windcorp.progressia.server.management.load.LoadManager; import ru.windcorp.progressia.server.world.DefaultWorldLogic; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; import ru.windcorp.progressia.server.world.context.ServerWorldContext; import ru.windcorp.progressia.server.world.context.impl.DefaultServerContext; import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext; +import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; @@ -102,15 +108,54 @@ public class Server { /** * Instantiates and returns an new {@link ServerWorldContext} instance - * suitable for read and write access to the server's world. This is the - * preferred way to query or change the world. + * suitable for read and write access to the server's world. This context + * uses the absolute coordinate space (not rotated to match positive Z = + * up). * * @return the context + * @see #createContext(AbsFace) */ - public ServerWorldContext createContext() { + public ServerWorldContext createAbsoluteContext() { + return doCreateAbsoluteContext(); + } - return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build()).withListener(worldAccessor).setPassToParent(false); - + private ServerTileContext doCreateAbsoluteContext() { + return new ReportingServerContext(DefaultServerContext.empty().inRealWorldOf(this).build()) + .withListener(worldAccessor).setPassToParent(false); + } + + /** + * Instantiates and returns an new {@link ServerWorldContext} instance + * suitable for read and write access to the server's world. This is the + * preferred way to query or change the world. This context uses the + * coordinate space in which positive Z = {@code up}. + * + * @param up the desired up direction + * @return the context + * @see #createContext(Vec3i) + * @see #createAbsoluteContext() + */ + public ServerWorldContext createContext(AbsFace up) { + return new RotatingServerContext(doCreateAbsoluteContext(), up); + } + + /** + * Instantiates and returns an new {@link ServerBlockContext} instance + * suitable for read and write access to the server's world. The context is + * initialized to point to the provided block. This is the preferred way to + * query or change the world. This context uses the coordinate space in + * which positive Z matches the discrete up direction of the provided + * location. + * + * @param up the desired up direction + * @return the context + * @see #createContext(AbsFace) + * @see #createAbsoluteContext() + */ + public ServerBlockContext createContext(Vec3i blockInWorld) { + AbsFace up = getWorld().getUp(blockInWorld); + Vec3i relativeBlockInWorld = AxisRotations.relativize(blockInWorld, up, null); + return new RotatingServerContext(doCreateAbsoluteContext(), up).push(relativeBlockInWorld); } /** @@ -247,7 +292,7 @@ public class Server { // public WorldAccessor getWorldAccessor() { // return worldAccessor; // } - + public WorldAccessor getWorldAccessor___really_bad_dont_use() { return worldAccessor; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java index 978fae3..d18ff11 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultChunkLogic.java @@ -28,17 +28,18 @@ import java.util.function.BiConsumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.TileDataStack; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.TileDataReference; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.server.world.block.TickableBlock; import ru.windcorp.progressia.server.world.context.ServerBlockContextRO; +import ru.windcorp.progressia.server.world.context.ServerContexts; import ru.windcorp.progressia.server.world.context.ServerTileContextRO; import ru.windcorp.progressia.server.world.context.ServerWorldContextRO; import ru.windcorp.progressia.server.world.tasks.TickChunk; @@ -225,15 +226,12 @@ public class DefaultChunkLogic implements ChunkLogic { } private void tmp_generateTickLists() { - ServerWorldContextRO context = Server.getCurrentServer().createContext(); - Vec3i blockInChunk = new Vec3i(); + ServerWorldContextRO context = Server.getCurrentServer().createContext(getUp()); - forEachBiW(location -> { + GenericChunks.forEachBiC(blockInChunk -> { - ServerBlockContextRO blockContext = context.push(location); - - BlockLogic block = blockContext.logic().getBlock(); - Coordinates.convertInWorldToInChunk(location, blockInChunk); + ServerBlockContextRO blockContext = ServerContexts.pushAbs(context, this, blockInChunk); + BlockLogic block = getBlock(blockInChunk); if (!(block instanceof TickableBlock)) { blockContext.pop(); @@ -241,7 +239,7 @@ public class DefaultChunkLogic implements ChunkLogic { } if (((TickableBlock) block).getTickingPolicy(blockContext) == TickingPolicy.REGULAR) { - tickingBlocks.add(blockInChunk); + tickingBlocks.add(blockInChunk.add_(0)); } for (RelFace face : RelFace.getFaces()) { @@ -249,16 +247,14 @@ public class DefaultChunkLogic implements ChunkLogic { if (stack == null || stack.isEmpty()) continue; for (int i = 0; i < stack.size(); ++i) { - ServerTileContextRO tileContext = blockContext.push(face, i); + ServerTileContextRO tileContext = blockContext.push(context.toContext(face.resolve(getUp())), i); TileLogic tile = stack.get(i); - if (!(tile instanceof TickableTile)) { - tileContext.pop(); - continue; - } - - if (((TickableTile) tile).getTickingPolicy(tileContext) == TickingPolicy.REGULAR) { - tickingTiles.add(stack.getData().getReference(i)); + if (tile instanceof TickableTile) { + TickingPolicy policy = ((TickableTile) tile).getTickingPolicy(tileContext); + if (policy == TickingPolicy.REGULAR) { + tickingTiles.add(stack.getData().getReference(i)); + } } tileContext.pop(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index 286a557..9e21c63 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -21,12 +21,13 @@ package ru.windcorp.progressia.server.world; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.TickableBlock; import ru.windcorp.progressia.server.world.block.UpdateableBlock; import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerContexts; import ru.windcorp.progressia.server.world.context.ServerTileContext; import ru.windcorp.progressia.server.world.context.ServerTileStackContext; import ru.windcorp.progressia.server.world.context.ServerWorldContext; @@ -56,7 +57,7 @@ public class TickAndUpdateUtil { if (!(block instanceof TickableBlock)) { return; } - ServerBlockContext context = server.createContext().push(blockInWorld); + ServerBlockContext context = server.createContext(blockInWorld); tickBlock(context); } @@ -73,23 +74,22 @@ public class TickAndUpdateUtil { } } - public static void tickTile(Server server, Vec3i blockInWorld, BlockFace face, int layer) { + public static void tickTile(Server server, Vec3i blockInWorld, AbsFace face, int layer) { TileLogic tile = server.getWorld().getTile(blockInWorld, face, layer); if (!(tile instanceof TickableTile)) { return; } - ServerTileContext context = server.createContext() - .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)), layer); + ServerTileContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face) + .push(layer); tickTile(context); } - public static void tickTiles(Server server, Vec3i blockInWorld, BlockFace face) { + public static void tickTiles(Server server, Vec3i blockInWorld, AbsFace face) { if (!server.getWorld().hasTiles(blockInWorld, face)) { return; } - ServerTileStackContext context = server.createContext() - .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld))); + ServerTileStackContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face); for (int i = 0; i < context.getTileCount(); ++i) { tickTile(context.push(i)); context.pop(); @@ -114,7 +114,7 @@ public class TickAndUpdateUtil { if (!(block instanceof UpdateableBlock)) { return; } - ServerBlockContext context = server.createContext().push(blockInWorld); + ServerBlockContext context = server.createContext(blockInWorld); updateBlock(context); } @@ -131,23 +131,22 @@ public class TickAndUpdateUtil { } } - public static void updateTile(Server server, Vec3i blockInWorld, BlockFace face, int layer) { + public static void updateTile(Server server, Vec3i blockInWorld, AbsFace face, int layer) { TileLogic tile = server.getWorld().getTile(blockInWorld, face, layer); if (!(tile instanceof UpdateableTile)) { return; } - ServerTileContext context = server.createContext() - .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld)), layer); + ServerTileContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face) + .push(layer); updateTile(context); } - public static void updateTiles(Server server, Vec3i blockInWorld, BlockFace face) { + public static void updateTiles(Server server, Vec3i blockInWorld, AbsFace face) { if (!server.getWorld().hasTiles(blockInWorld, face)) { return; } - ServerTileStackContext context = server.createContext() - .push(blockInWorld, face.relativize(server.getWorld().getUp(blockInWorld))); + ServerTileStackContext context = ServerContexts.pushAbs(server.createContext(blockInWorld), blockInWorld, face); for (int i = 0; i < context.getTileCount(); ++i) { updateTile(context.push(i)); context.pop(); @@ -166,7 +165,7 @@ public class TickAndUpdateUtil { tickEntity( EntityLogicRegistry.getInstance().get(data.getId()), data, - server.createContext() + server.createContext(data.getUpFace()) ); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java new file mode 100644 index 0000000..b0cf996 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContexts.java @@ -0,0 +1,141 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; +import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; + +public class ServerContexts { + + /* + * RW + */ + + public static ServerBlockContext pushAbs(ServerWorldContext context, Vec3i blockInWorld) { + Vec3i contextLocation = Vectors.grab3i(); + context.toContext(blockInWorld, contextLocation); + ServerBlockContext blockContext = context.push(contextLocation); + Vectors.release(contextLocation); + return blockContext; + } + + public static ServerBlockContext pushAbs(ServerWorldContext context, ChunkGenericRO chunk, Vec3i blockInChunk) { + Vec3i contextLocation = Vectors.grab3i(); + Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation); + context.toContext(contextLocation, contextLocation); + ServerBlockContext blockContext = context.push(contextLocation); + Vectors.release(contextLocation); + return blockContext; + } + + public static ServerTileStackContext pushAbs(ServerWorldContext context, Vec3i blockInWorld, AbsFace face) { + Vec3i contextLocation = Vectors.grab3i(); + context.toContext(blockInWorld, contextLocation); + RelFace contextFace = context.toContext(face); + ServerTileStackContext tileStackContext = context.push(contextLocation, contextFace); + Vectors.release(contextLocation); + return tileStackContext; + } + + public static ServerTileStackContext pushAbs(ServerWorldContext context, ChunkGenericRO chunk, Vec3i blockInChunk, AbsFace face) { + Vec3i contextLocation = Vectors.grab3i(); + Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation); + context.toContext(contextLocation, contextLocation); + RelFace contextFace = context.toContext(face); + ServerTileStackContext tileStackContext = context.push(contextLocation, contextFace); + Vectors.release(contextLocation); + return tileStackContext; + } + + public static ServerTileStackContext pushAbs(ServerBlockContext context, AbsFace face) { + return context.push(context.toContext(face)); + } + + public static ServerTileContext pushAbs(ServerWorldContext context, AbsFace up, TileGenericReferenceRO ref) { + Vec3i contextLocation = Vectors.grab3i(); + ref.getStack().getBlockInWorld(contextLocation); + context.toContext(contextLocation, contextLocation); + RelFace contextFace = context.toContext(ref.getStack().getFace().resolve(up)); + ServerTileContext tileContext = context.push(contextLocation, contextFace, ref.getIndex()); + Vectors.release(contextLocation); + return tileContext; + } + + /* + * RO + */ + + public static ServerBlockContextRO pushAbs(ServerWorldContextRO context, Vec3i blockInWorld) { + Vec3i contextLocation = Vectors.grab3i(); + context.toContext(blockInWorld, contextLocation); + ServerBlockContextRO blockContextRO = context.push(contextLocation); + Vectors.release(contextLocation); + return blockContextRO; + } + + public static ServerBlockContextRO pushAbs(ServerWorldContextRO context, ChunkGenericRO chunk, Vec3i blockInChunk) { + Vec3i contextLocation = Vectors.grab3i(); + Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation); + context.toContext(contextLocation, contextLocation); + ServerBlockContextRO blockContextRO = context.push(contextLocation); + Vectors.release(contextLocation); + return blockContextRO; + } + + public static ServerTileStackContextRO pushAbs(ServerWorldContextRO context, Vec3i blockInWorld, AbsFace face) { + Vec3i contextLocation = Vectors.grab3i(); + context.toContext(blockInWorld, contextLocation); + RelFace contextFace = context.toContext(face); + ServerTileStackContextRO tileStackContextRO = context.push(contextLocation, contextFace); + Vectors.release(contextLocation); + return tileStackContextRO; + } + + public static ServerTileStackContextRO pushAbs(ServerWorldContextRO context, ChunkGenericRO chunk, Vec3i blockInChunk, AbsFace face) { + Vec3i contextLocation = Vectors.grab3i(); + Coordinates.getInWorld(chunk.getPosition(), blockInChunk, contextLocation); + context.toContext(contextLocation, contextLocation); + RelFace contextFace = context.toContext(face); + ServerTileStackContextRO tileStackContextRO = context.push(contextLocation, contextFace); + Vectors.release(contextLocation); + return tileStackContextRO; + } + + public static ServerTileStackContextRO pushAbs(ServerBlockContextRO context, AbsFace face) { + return context.push(context.toContext(face)); + } + + public static ServerTileContextRO pushAbs(ServerWorldContextRO context, AbsFace up, TileGenericReferenceRO ref) { + Vec3i contextLocation = Vectors.grab3i(); + ref.getStack().getBlockInWorld(contextLocation); + context.toContext(contextLocation, contextLocation); + RelFace contextFace = context.toContext(ref.getStack().getFace().resolve(up)); + ServerTileContextRO tileContextRO = context.push(contextLocation, contextFace, ref.getIndex()); + Vectors.release(contextLocation); + return tileContextRO; + } + + private ServerContexts() { + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index ec89e47..aeda6e8 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -29,6 +29,7 @@ import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; @@ -290,6 +291,41 @@ class DefaultServerContextImpl extends DefaultServerContext assert requireContextRole(Role.TILE); return frame.layer; } + + /* + * ABSOLUTE COORDINATE CONVERSIONS + * (or lack thereof) + */ + + @Override + public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + output.set(contextLocation.x, contextLocation.y, contextLocation.z); + return output; + } + + @Override + public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + output.set(absoluteLocation.x, absoluteLocation.y, absoluteLocation.z); + return output; + } + + @Override + public AbsFace toAbsolute(BlockFace contextFace) { + return contextFace.resolve(AbsFace.POS_Z); + } + + @Override + public RelFace toContext(AbsFace absoluteFace) { + return absoluteFace.relativize(AbsFace.POS_Z); + } /* * RO CONTEXT INTERFACE diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java index 4461d23..640a475 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java @@ -23,6 +23,7 @@ import java.util.Random; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; @@ -84,6 +85,26 @@ public class DefaultServerContextLogic implements ServerTileContext.Logic { parent.push(location, face, layer); return this; } + + @Override + public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) { + return parent.toAbsolute(contextLocation, output); + } + + @Override + public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) { + return parent.toContext(absoluteLocation, output); + } + + @Override + public AbsFace toAbsolute(BlockFace contextFace) { + return parent.toAbsolute(contextFace); + } + + @Override + public RelFace toContext(AbsFace absoluteFace) { + return parent.toContext(absoluteFace); + } @Override public double getTickLength() { diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java index b7b5ff5..677f9d3 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java @@ -27,6 +27,7 @@ import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; @@ -199,6 +200,26 @@ public abstract class FilterServerContext implements ServerTileContext { parent.push(location, face, layer); return this; } + + @Override + public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) { + return parent.toAbsolute(contextLocation, output); + } + + @Override + public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) { + return parent.toContext(absoluteLocation, output); + } + + @Override + public AbsFace toAbsolute(BlockFace contextFace) { + return parent.toAbsolute(contextFace); + } + + @Override + public RelFace toContext(AbsFace absoluteFace) { + return parent.toContext(absoluteFace); + } @Override public Server getServer() { diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java new file mode 100644 index 0000000..2ccc86c --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java @@ -0,0 +1,54 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.context.ServerTileContext; + +public class RotatingServerContext extends TransformingServerContext { + + private final AbsFace up; + + public RotatingServerContext(ServerTileContext parent, AbsFace up) { + super(parent); + this.up = up; + } + + @Override + protected void transform(Vec3i userLocation, Vec3i output) { + output.set(userLocation.x, userLocation.y, userLocation.z); + } + + @Override + protected void untransform(Vec3i parentLocation, Vec3i output) { + output.set(parentLocation.x, parentLocation.y, parentLocation.z); + } + + @Override + protected RelFace transform(RelFace userFace) { + return userFace.resolve(up).relativize(AbsFace.POS_Z); + } + + @Override + protected RelFace untransform(RelFace parentFace) { + return parentFace.resolve(AbsFace.POS_Z).relativize(up); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java new file mode 100644 index 0000000..7305876 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java @@ -0,0 +1,273 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.server.world.context.impl; + +import java.util.ArrayList; +import java.util.List; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.ServerTileStackContext; + +public abstract class TransformingServerContext extends FilterServerContext { + + private final Vec3i location = new Vec3i(); + private boolean isLocationValid = false; + + private RelFace face; + + private final List vectorCache = new ArrayList<>(1); + + public TransformingServerContext(ServerTileContext parent) { + super(parent); + } + + protected abstract void transform(Vec3i userLocation, Vec3i output); + + protected abstract void untransform(Vec3i parentLocation, Vec3i output); + + protected abstract RelFace transform(RelFace userFace); + + protected abstract RelFace untransform(RelFace parentFace); + + protected void invalidateCache() { + isLocationValid = false; + face = null; + } + + private Vec3i grabVector(Vec3i userVector) { + Vec3i parentVector; + + if (vectorCache.isEmpty()) { + parentVector = new Vec3i(); + } else { + parentVector = vectorCache.remove(vectorCache.size() - 1); + } + + transform(userVector, parentVector); + + return parentVector; + } + + private void releaseVector(Vec3i parentVector) { + vectorCache.add(parentVector); + } + + @Override + public Vec3i getLocation() { + // Always invoke parent method to allow parent to determine validity + Vec3i parentLocation = super.getLocation(); + + if (!isLocationValid) { + untransform(parentLocation, location); + isLocationValid = true; + } + + return location; + } + + @Override + public RelFace getFace() { + // Always invoke parent method to allow parent to determine validity + RelFace parentFace = super.getFace(); + + if (face == null) { + face = untransform(parentFace); + } + + return face; + } + + @Override + public void pop() { + super.pop(); + invalidateCache(); + } + + @Override + public ServerBlockContext push(Vec3i userLocation) { + transform(userLocation, location); + isLocationValid = true; + super.push(location); + face = null; + return this; + } + + @Override + public ServerTileStackContext push(Vec3i userLocation, RelFace userFace) { + transform(userLocation, location); + isLocationValid = true; + face = transform(userFace); + super.push(location, face); + return this; + } + + @Override + public ServerTileContext push(Vec3i userLocation, RelFace userFace, int layer) { + transform(userLocation, location); + isLocationValid = true; + face = transform(userFace); + super.push(location, face, layer); + return this; + } + + @Override + public Vec3i toAbsolute(Vec3i contextLocation, Vec3i output) { + if (output == null) { + output = new Vec3i(); + } + + transform(contextLocation, output); + + return super.toAbsolute(output, output); + } + + @Override + public Vec3i toContext(Vec3i absoluteLocation, Vec3i output) { + output = super.toContext(absoluteLocation, output); + untransform(output, output); + return output; + } + + @Override + public AbsFace toAbsolute(BlockFace contextFace) { + return super.toAbsolute(transform(contextFace.relativize(AbsFace.POS_Z))); + } + + @Override + public RelFace toContext(AbsFace absoluteFace) { + return untransform(super.toContext(absoluteFace)); + } + + @Override + public boolean isLocationLoaded(Vec3i userLocation) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.isLocationLoaded(parentLocation); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public BlockData getBlock(Vec3i userLocation) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.getBlock(parentLocation); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public void setBlock(Vec3i userLocation, BlockData block) { + Vec3i parentLocation = grabVector(userLocation); + + try { + super.setBlock(parentLocation, block); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public boolean hasTile(Vec3i userLocation, BlockFace userFace, int layer) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.hasTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), layer); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public TileData getTile(Vec3i userLocation, BlockFace userFace, int layer) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.getTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), layer); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public boolean isTagValid(Vec3i userLocation, BlockFace userFace, int tag) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.isTagValid(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public TileData getTileByTag(Vec3i userLocation, BlockFace userFace, int tag) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.getTileByTag(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public int getTileCount(Vec3i userLocation, BlockFace userFace) { + Vec3i parentLocation = grabVector(userLocation); + + try { + return super.getTileCount(parentLocation, transform(userFace.relativize(AbsFace.POS_Z))); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public void addTile(Vec3i userLocation, BlockFace userFace, TileData tile) { + Vec3i parentLocation = grabVector(userLocation); + + try { + super.addTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tile); + } finally { + releaseVector(parentLocation); + } + } + + @Override + public void removeTile(Vec3i userLocation, BlockFace userFace, int tag) { + Vec3i parentLocation = grabVector(userLocation); + + try { + super.removeTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag); + } finally { + releaseVector(parentLocation); + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java index 4ed21f1..a2a59f9 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/TickChunk.java @@ -27,17 +27,15 @@ import com.google.common.collect.ImmutableList; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatMathUtil; -import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.DefaultChunkLogic; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.block.TickableBlock; import ru.windcorp.progressia.server.world.context.ServerBlockContext; +import ru.windcorp.progressia.server.world.context.ServerContexts; import ru.windcorp.progressia.server.world.context.ServerTileContext; import ru.windcorp.progressia.server.world.context.ServerTileStackContext; import ru.windcorp.progressia.server.world.context.ServerWorldContext; @@ -53,20 +51,21 @@ public class TickChunk extends Evaluation { DefaultChunkData.BLOCKS_PER_CHUNK * DefaultChunkData.BLOCKS_PER_CHUNK; - private final List> randomTickMethods; + private final List> randomTickMethods; { - List> randomTickMethods = new ArrayList<>(); + List> randomTickMethods = new ArrayList<>(); randomTickMethods.add(this::tickRandomBlock); for (AbsFace face : AbsFace.getFaces()) { - randomTickMethods.add(s -> this.tickRandomTile(s, face)); + randomTickMethods.add(context -> this.tickRandomTile(face, context)); } this.randomTickMethods = ImmutableList.copyOf(randomTickMethods); } private final DefaultChunkLogic chunk; + private ServerWorldContext context; public TickChunk(DefaultChunkLogic chunk) { this.chunk = chunk; @@ -74,44 +73,41 @@ public class TickChunk extends Evaluation { @Override public void evaluate(Server server) { - tickRegulars(server); - tickRandom(server); + if (context == null || context.getServer() != server) { + context = server.createContext(chunk.getUp()); + } + + tickRegulars(context); + tickRandom(context); } - private void tickRegulars(Server server) { - tickRegularBlocks(server); - tickRegularTiles(server); + private void tickRegulars(ServerWorldContext context) { + tickRegularBlocks(context); + tickRegularTiles(context); } - private void tickRegularBlocks(Server server) { + private void tickRegularBlocks(ServerWorldContext context) { if (!chunk.hasTickingBlocks()) return; - ServerWorldContext context = server.createContext(); - chunk.forEachTickingBlock((blockInChunk, block) -> { - ((TickableBlock) block).tick(contextPushBiC(context, chunk, blockInChunk)); + ((TickableBlock) block).tick(ServerContexts.pushAbs(context, chunk, blockInChunk)); context.pop(); }); } - private void tickRegularTiles(Server server) { + private void tickRegularTiles(ServerWorldContext context) { if (!chunk.hasTickingTiles()) return; - ServerWorldContext context = server.createContext(); - Vec3i blockInWorld = new Vec3i(); - chunk.forEachTickingTile((ref, tile) -> { - ((TickableTile) tile).tick( - context.push(ref.getStack().getBlockInWorld(blockInWorld), ref.getStack().getFace(), ref.getIndex()) - ); + ((TickableTile) tile).tick(ServerContexts.pushAbs(context, chunk.getUp(), ref)); context.pop(); }); } - private void tickRandom(Server server) { - float ticks = computeRandomTicks(server); + private void tickRandom(ServerWorldContext context) { + float ticks = computeRandomTicks(context.getServer()); /* * If we are expected to run 3.25 random ticks per tick @@ -122,23 +118,23 @@ public class TickChunk extends Evaluation { float extraTickChance = ticks - unconditionalTicks; for (int i = 0; i < unconditionalTicks; ++i) { - tickRandomOnce(server); + tickRandomOnce(context); } - if (server.getAdHocRandom().nextFloat() < extraTickChance) { - tickRandomOnce(server); + if (context.getRandom().nextFloat() < extraTickChance) { + tickRandomOnce(context); } } - private void tickRandomOnce(Server server) { + private void tickRandomOnce(ServerWorldContext context) { // Pick a target at random: a block or one of 3 primary block faces randomTickMethods.get( - server.getAdHocRandom().nextInt(randomTickMethods.size()) - ).accept(server); + context.getRandom().nextInt(randomTickMethods.size()) + ).accept(context); } - private void tickRandomBlock(Server server) { - Random random = server.getAdHocRandom(); + private void tickRandomBlock(ServerWorldContext context) { + Random random = context.getRandom(); Vec3i blockInChunk = new Vec3i( random.nextInt(BLOCKS_PER_CHUNK), @@ -152,15 +148,17 @@ public class TickChunk extends Evaluation { return; TickableBlock tickable = (TickableBlock) block; - ServerBlockContext context = contextPushBiC(server.createContext(), chunk, blockInChunk); + ServerBlockContext blockContext = ServerContexts.pushAbs(context, chunk, blockInChunk); - if (tickable.getTickingPolicy(context) != TickingPolicy.RANDOM) + if (tickable.getTickingPolicy(blockContext) != TickingPolicy.RANDOM) return; - tickable.tick(context); + tickable.tick(blockContext); + + blockContext.pop(); } - private void tickRandomTile(Server server, AbsFace face) { - Random random = server.getAdHocRandom(); + private void tickRandomTile(AbsFace face, ServerWorldContext context) { + Random random = context.getRandom(); Vec3i blockInChunk = new Vec3i( random.nextInt(BLOCKS_PER_CHUNK), @@ -172,10 +170,10 @@ public class TickChunk extends Evaluation { if (tiles == null || tiles.isEmpty()) return; - ServerTileStackContext context = contextPushBiC(server.createContext(), chunk, blockInChunk).push(face.relativize(chunk.getUp())); + ServerTileStackContext tsContext = ServerContexts.pushAbs(context, chunk, blockInChunk, face); for (int i = 0; i < tiles.size(); ++i) { - ServerTileContext tileContext = context.push(i); + ServerTileContext tileContext = tsContext.push(i); TileLogic logic = tileContext.logic().getTile(); if (!(logic instanceof TickableTile)) { @@ -192,6 +190,8 @@ public class TickChunk extends Evaluation { tileContext.pop(); } + + tsContext.pop(); } private float computeRandomTicks(Server server) { @@ -200,18 +200,6 @@ public class TickChunk extends Evaluation { server.getTickLength()); } - private ServerBlockContext contextPushBiC( - ServerWorldContext context, - ChunkGenericRO chunk, - Vec3i blockInChunk - ) { - Vec3i blockInWorld = Vectors.grab3i(); - Coordinates.getInWorld(chunk.getPosition(), blockInChunk, blockInWorld); - ServerBlockContext blockContext = context.push(blockInWorld); - Vectors.release(blockInWorld); - return blockContext; - } - @Override public void getRelevantChunk(Vec3i output) { Vec3i p = chunk.getData().getPosition(); diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 0ddc3e5..7b9122f 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -383,7 +383,7 @@ public class TestContent { ru.windcorp.progressia.server.comms.Client client ) { Vec3i blockInWorld = ((ControlBreakBlockData) packet.getControl()).getBlockInWorld(); - server.createContext().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air")); + server.createAbsoluteContext().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Air")); } private static void onBlockPlaceTrigger(ControlData control) { @@ -403,7 +403,7 @@ public class TestContent { Vec3i blockInWorld = controlData.getBlockInWorld(); if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) return; - server.createContext().setBlock(blockInWorld, block); + server.createAbsoluteContext().setBlock(blockInWorld, block); } private static void onTilePlaceTrigger(ControlData control) { @@ -428,7 +428,7 @@ public class TestContent { return; if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) return; - server.createContext().addTile(blockInWorld, face, tile); + server.createAbsoluteContext().addTile(blockInWorld, face, tile); } private static void registerMisc() { diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index bfe438f..c197ce1 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -18,6 +18,7 @@ package ru.windcorp.progressia.test; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.context.ServerTileContext; @@ -65,7 +66,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile private boolean isBlockAboveTransparent(ServerTileContextRO context) { // TODO rework - context.pushRelative(RelFace.UP.resolve(context.getServer().getWorld().getUp(context.getLocation()))); + context.pushRelative(RelFace.UP.resolve(AbsFace.POS_Z)); BlockLogic block = context.logic().getBlock(); return context.popAndReturn(block == null || block.isTransparent(context)); } From 82872c7cf3e1f1a5730b083b26df8987700468fa Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 15 Aug 2021 23:54:25 +0300 Subject: [PATCH 51/63] Fixed RotatingServerContext - RotatingServerContext now rotates coordinates, too - Fixed a bug caused by the implementation of push methods by TransformingServerContext - Fixed unbounded recursion in WorldGenericRO.hasTile(Vec3i, BlockFace, int) --- .../common/world/generic/WorldGenericRO.java | 3 +- .../context/impl/RotatingServerContext.java | 9 ++++-- .../impl/TransformingServerContext.java | 30 +++++++++++++------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java index eac2a0c..826396f 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java @@ -137,7 +137,8 @@ public interface WorldGenericRO< * @return {@code true} iff the tile exists */ default boolean hasTile(Vec3i location, BlockFace face, int layer) { - return hasTile(location, face, layer); + TS stack = getTilesOrNull(location, face); + return stack != null && stack.size() > layer; } default boolean isChunkLoaded(Vec3i chunkPos) { diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java index 2ccc86c..c6459c4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java @@ -19,6 +19,7 @@ package ru.windcorp.progressia.server.world.context.impl; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.context.ServerTileContext; @@ -30,15 +31,19 @@ public class RotatingServerContext extends TransformingServerContext { super(parent); this.up = up; } + + public AbsFace getUp() { + return up; + } @Override protected void transform(Vec3i userLocation, Vec3i output) { - output.set(userLocation.x, userLocation.y, userLocation.z); + AxisRotations.resolve(userLocation, up, output); } @Override protected void untransform(Vec3i parentLocation, Vec3i output) { - output.set(parentLocation.x, parentLocation.y, parentLocation.z); + AxisRotations.relativize(parentLocation, up, output); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java index 7305876..1fb387e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java @@ -35,7 +35,7 @@ public abstract class TransformingServerContext extends FilterServerContext { private final Vec3i location = new Vec3i(); private boolean isLocationValid = false; - private RelFace face; + private RelFace face = null; private final List vectorCache = new ArrayList<>(1); @@ -107,28 +107,40 @@ public abstract class TransformingServerContext extends FilterServerContext { @Override public ServerBlockContext push(Vec3i userLocation) { - transform(userLocation, location); + Vec3i parentLocation = grabVector(userLocation); + super.push(parentLocation); + releaseVector(parentLocation); + + location.set(userLocation.x, userLocation.y, userLocation.z); isLocationValid = true; - super.push(location); face = null; + return this; } @Override public ServerTileStackContext push(Vec3i userLocation, RelFace userFace) { - transform(userLocation, location); + Vec3i parentLocation = grabVector(userLocation); + super.push(parentLocation, transform(userFace)); + releaseVector(parentLocation); + + location.set(userLocation.x, userLocation.y, userLocation.z); isLocationValid = true; - face = transform(userFace); - super.push(location, face); + face = userFace; + return this; } @Override public ServerTileContext push(Vec3i userLocation, RelFace userFace, int layer) { - transform(userLocation, location); + Vec3i parentLocation = grabVector(userLocation); + super.push(parentLocation, transform(userFace), layer); + releaseVector(parentLocation); + + location.set(userLocation.x, userLocation.y, userLocation.z); isLocationValid = true; - face = transform(userFace); - super.push(location, face, layer); + face = userFace; + return this; } From a6fd81ba1e81900bf424ab6e9592037f9830ee58 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Mon, 16 Aug 2021 13:05:57 +0300 Subject: [PATCH 52/63] Contexts now only accept RelFace; fixed tile placement crash --- .../world/context/BlockDataContext.java | 6 +- .../world/context/BlockDataContextRO.java | 6 +- .../context/BlockGenericContextRO.java | 17 +++--- .../context/BlockGenericContextWO.java | 11 ++-- .../world/generic/context/WorldContexts.java | 8 +-- .../context/WorldGenericContextRO.java | 58 ++----------------- .../context/WorldGenericContextWO.java | 5 +- .../common/world/tile/PacketAddTile.java | 2 +- .../common/world/tile/PacketAffectTile.java | 14 +++-- .../world/context/ServerBlockContext.java | 10 ++-- .../world/context/ServerBlockContextRO.java | 10 ++-- .../impl/DefaultServerContextImpl.java | 16 ++--- .../impl/DefaultServerContextLogic.java | 13 ++--- .../context/impl/FilterServerContext.java | 17 +++--- .../context/impl/ReportingServerContext.java | 5 +- .../impl/TransformingServerContext.java | 33 +++++------ .../windcorp/progressia/test/TestContent.java | 2 +- .../progressia/test/TestTileLogicGrass.java | 4 +- 18 files changed, 94 insertions(+), 143 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java index 36e7dbe..e535014 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java @@ -21,8 +21,8 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO; -import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContext @@ -45,8 +45,8 @@ public interface BlockDataContext } @Override - default BlockDataContext pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default BlockDataContext pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java index 8d75845..621cc9a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java @@ -21,8 +21,8 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; -import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContextRO @@ -44,8 +44,8 @@ public interface BlockDataContextRO } @Override - default BlockDataContextRO pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default BlockDataContextRO pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index cacbe45..8984ad3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -20,9 +20,8 @@ package ru.windcorp.progressia.common.world.generic.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; -import ru.windcorp.progressia.common.world.rels.AbsRelation; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; /** * A {@link Context} referencing a world with a block location specified. The @@ -68,7 +67,7 @@ public interface BlockGenericContextRO< * @param layer the layer of the tile * @return {@code true} iff the tile exists */ - default boolean hasTile(BlockFace face, int layer) { + default boolean hasTile(RelFace face, int layer) { return hasTile(getLocation(), face, layer); } @@ -80,7 +79,7 @@ public interface BlockGenericContextRO< * @param tag the tag of the tile * @return {@code true} iff the tile exists */ - default boolean isTagValid(BlockFace face, int tag) { + default boolean isTagValid(RelFace face, int tag) { return isTagValid(getLocation(), face, tag); } @@ -97,7 +96,7 @@ public interface BlockGenericContextRO< * @param layer the layer of the tile stack that the tile occupies * @return the tile or {@code null} if the position does not contain a tile */ - default T getTile(BlockFace face, int layer) { + default T getTile(RelFace face, int layer) { return getTile(getLocation(), face, layer); } @@ -115,7 +114,7 @@ public interface BlockGenericContextRO< * @param tag the tag of the tile * @return the tile or {@code null} if the position does not contain a tile */ - default T getTileByTag(BlockFace face, int tag) { + default T getTileByTag(RelFace face, int tag) { return getTileByTag(getLocation(), face, tag); } @@ -129,7 +128,7 @@ public interface BlockGenericContextRO< * @return the count of tiles in the tile stack or {@code -1} if the tile * stack could not exist */ - default int getTileCount(BlockFace face) { + default int getTileCount(RelFace face) { return getTileCount(face); } @@ -148,8 +147,8 @@ public interface BlockGenericContextRO< } @Override - default BlockGenericContextRO pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default BlockGenericContextRO pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index c1fa216..3555c09 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -20,9 +20,8 @@ package ru.windcorp.progressia.common.world.generic.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; -import ru.windcorp.progressia.common.world.rels.AbsRelation; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; /** * A writable {@link Context} referencing a world with a block location @@ -59,7 +58,7 @@ public interface BlockGenericContextWO< * @param face the face of the block to add the tile to * @param tile the tile to add */ - default void addTile(BlockFace face, T tile) { + default void addTile(RelFace face, T tile) { addTile(getLocation(), face, tile); } @@ -72,7 +71,7 @@ public interface BlockGenericContextWO< * @param face the of the block to remove the tile from * @param tag the tag of the tile to remove */ - default void removeTile(BlockFace face, int tag) { + default void removeTile(RelFace face, int tag) { removeTile(getLocation(), face, tag); } @@ -91,8 +90,8 @@ public interface BlockGenericContextWO< } @Override - default BlockGenericContextWO pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default BlockGenericContextWO pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java index 5cf9f44..f8953d3 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldContexts.java @@ -21,9 +21,9 @@ package ru.windcorp.progressia.common.world.generic.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; /** * This class defines several {@link Context} subinterfaces that are further @@ -139,7 +139,7 @@ class WorldContexts { * system * @return the face expressed in absolute coordinate system */ - AbsFace toAbsolute(BlockFace contextFace); + AbsFace toAbsolute(RelFace contextFace); /** * Converts the provided face given in the absolute coordinate @@ -221,8 +221,8 @@ class WorldContexts { * @return this object * @see #pop() */ - default Block pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default Block pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java index 59707e9..ec188d1 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java @@ -20,11 +20,9 @@ package ru.windcorp.progressia.common.world.generic.context; import java.util.Collection; import java.util.function.Consumer; -import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; /** @@ -76,7 +74,7 @@ public interface WorldGenericContextRO< * @param layer the layer of the tile stack that the tile occupies * @return the tile or {@code null} if the position does not contain a tile */ - T getTile(Vec3i location, BlockFace face, int layer); + T getTile(Vec3i location, RelFace face, int layer); /** * Retrieves the tile at the specified position and the tile's tag. This @@ -92,7 +90,7 @@ public interface WorldGenericContextRO< * @param tag the tag of the tile * @return the tile or {@code null} if the position does not contain a tile */ - T getTileByTag(Vec3i location, BlockFace face, int tag); + T getTileByTag(Vec3i location, RelFace face, int tag); /** * Determines whether the specified position has a tile. @@ -102,7 +100,7 @@ public interface WorldGenericContextRO< * @param layer the layer of the tile * @return {@code true} iff the tile exists */ - boolean hasTile(Vec3i location, BlockFace face, int layer); + boolean hasTile(Vec3i location, RelFace face, int layer); /** * Determines whether the specified position has a tile with the given tag. @@ -112,7 +110,7 @@ public interface WorldGenericContextRO< * @param tag the tag of the tile * @return {@code true} iff the tile exists */ - boolean isTagValid(Vec3i location, BlockFace face, int tag); + boolean isTagValid(Vec3i location, RelFace face, int tag); /** * Counts the amount of tiles in the specified tile stack. @@ -124,7 +122,7 @@ public interface WorldGenericContextRO< * @return the count of tiles in the tile stack or {@code -1} if the tile * stack could not exist */ - int getTileCount(Vec3i location, BlockFace face); + int getTileCount(Vec3i location, RelFace face); /** * Retrieves a listing of all entities. {@link #forEachEntity(Consumer)} @@ -143,52 +141,6 @@ public interface WorldGenericContextRO< */ E getEntity(long entityId); - /* - * Convenience methods - */ - - /** - * Iterates all entities safely - */ - default void forEachEntity(Consumer action) { - getEntities().forEach(action); - } - - /** - * Iterates all entities in cuboid safely - */ - default void forEachEntityIn(Vec3i min, Vec3i max, Consumer action) { - forEachEntity(e -> { - Vec3 pos = e.getPosition(); - if (pos.x < min.x || pos.y < min.y || pos.z < min.z || pos.x > max.x || pos.y > max.y || pos.z > max.z) { - action.accept(e); - } - }); - } - - /** - * Iterates all entities in cuboid safely - */ - default void forEachEntityIn(Vec3 min, Vec3 max, Consumer action) { - forEachEntity(e -> { - Vec3 pos = e.getPosition(); - if (pos.x < min.x || pos.y < min.y || pos.z < min.z || pos.x > max.x || pos.y > max.y || pos.z > max.z) { - action.accept(e); - } - }); - } - - /** - * Iterates all entities with ID safely - */ - default void forEachEntityWithId(String id, Consumer action) { - forEachEntity(e -> { - if (id.equals(e.getId())) { - action.accept(e); - } - }); - } - /* * Subcontexting */ diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index 3f27b17..d1dac01 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -22,7 +22,6 @@ import ru.windcorp.progressia.common.state.StateChange; import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; /** @@ -76,7 +75,7 @@ public interface WorldGenericContextWO< * @param face the face of the block to add the tile to * @param tile the tile to add */ - void addTile(Vec3i location, BlockFace face, T tile); + void addTile(Vec3i location, RelFace face, T tile); /** * Requests that a tile identified by its tag is removed from the specified @@ -88,7 +87,7 @@ public interface WorldGenericContextWO< * @param face the of the block to remove the tile from * @param tag the tag of the tile to remove */ - void removeTile(Vec3i location, BlockFace face, int tag); + void removeTile(Vec3i location, RelFace face, int tag); /** * Requests that the referenced tile is removed from its tile stack. If the diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java index 1655446..a2f805e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java @@ -44,7 +44,7 @@ public class PacketAddTile extends PacketAffectTile { } public void set(TileData tile, Vec3i blockInWorld, AbsFace face) { - super.set(blockInWorld, face, -1); + super.set(blockInWorld, face, TAG_NOT_APPLICABLE); this.tileId = tile.getId(); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java index 41cffef..747dfa6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world.tile; import java.io.DataInput; @@ -34,6 +34,12 @@ public abstract class PacketAffectTile extends PacketAffectChunk { private AbsFace face; private int tag; + /** + * Indicates to the safeguards in {@link #set(Vec3i, AbsFace, int)} that the + * concept of a tile tag is not applicable to this action. + */ + protected static final int TAG_NOT_APPLICABLE = -2; + public PacketAffectTile(String id) { super(id); } @@ -51,10 +57,10 @@ public abstract class PacketAffectTile extends PacketAffectChunk { } public void set(Vec3i blockInWorld, AbsFace face, int tag) { - if (tag < 0) { - throw new IllegalArgumentException("Cannot affect tile with tag -1"); + if (tag < 0 && tag != TAG_NOT_APPLICABLE) { + throw new IllegalArgumentException("Cannot affect tile with tag " + tag); } - + this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); this.face = face; this.tag = tag; diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java index 6b66ba0..e0b5c70 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java @@ -19,8 +19,8 @@ package ru.windcorp.progressia.server.world.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.BlockDataContext; -import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; public interface ServerBlockContext extends BlockDataContext, ServerWorldContext, ServerBlockContextRO { @@ -40,8 +40,8 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext } @Override - default ServerBlockContext.Logic pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default ServerBlockContext.Logic pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override @@ -70,8 +70,8 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext } @Override - default ServerBlockContext pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default ServerBlockContext pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java index 8ef355e..1fdb90e 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java @@ -21,8 +21,8 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.BlockDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; -import ru.windcorp.progressia.common.world.rels.AbsRelation; import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; @@ -45,8 +45,8 @@ public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataCon } @Override - default ServerBlockContextRO.Logic pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default ServerBlockContextRO.Logic pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override @@ -75,8 +75,8 @@ public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataCon } @Override - default ServerBlockContextRO pushRelative(AbsRelation direction) { - return push(getLocation().add_(direction.getVector())); + default ServerBlockContextRO pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index aeda6e8..7d4f6cf 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -318,7 +318,7 @@ class DefaultServerContextImpl extends DefaultServerContext } @Override - public AbsFace toAbsolute(BlockFace contextFace) { + public AbsFace toAbsolute(RelFace contextFace) { return contextFace.resolve(AbsFace.POS_Z); } @@ -362,19 +362,19 @@ class DefaultServerContextImpl extends DefaultServerContext } @Override - public TileData getTile(Vec3i location, BlockFace face, int layer) { + public TileData getTile(Vec3i location, RelFace face, int layer) { assert requireContextRole(Role.WORLD); return world.getTile(location, face, layer); } @Override - public boolean hasTile(Vec3i location, BlockFace face, int layer) { + public boolean hasTile(Vec3i location, RelFace face, int layer) { assert requireContextRole(Role.WORLD); return world.hasTile(location, face, layer); } @Override - public TileData getTileByTag(Vec3i location, BlockFace face, int tag) { + public TileData getTileByTag(Vec3i location, RelFace face, int tag) { assert requireContextRole(Role.WORLD); TileDataStack stack = world.getTilesOrNull(location, face); if (stack == null) @@ -386,7 +386,7 @@ class DefaultServerContextImpl extends DefaultServerContext } @Override - public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + public boolean isTagValid(Vec3i location, RelFace face, int tag) { assert requireContextRole(Role.WORLD); TileDataStack stack = world.getTilesOrNull(location, face); if (stack == null) @@ -404,7 +404,7 @@ class DefaultServerContextImpl extends DefaultServerContext } @Override - public int getTileCount(Vec3i location, BlockFace face) { + public int getTileCount(Vec3i location, RelFace face) { assert requireContextRole(Role.TILE_STACK); TileDataStack stack = world.getTilesOrNull(frame.location, frame.face); if (stack == null) @@ -453,13 +453,13 @@ class DefaultServerContextImpl extends DefaultServerContext } @Override - public void addTile(Vec3i location, BlockFace face, TileData tile) { + public void addTile(Vec3i location, RelFace face, TileData tile) { assert requireContextRole(Role.WORLD); world.getTiles(location, face).addFarthest(tile); } @Override - public void removeTile(Vec3i location, BlockFace face, int tag) { + public void removeTile(Vec3i location, RelFace face, int tag) { assert requireContextRole(Role.WORLD); TileDataStack stack = world.getTilesOrNull(location, face); if (stack == null) diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java index 640a475..d6bb661 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextLogic.java @@ -24,7 +24,6 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; @@ -97,7 +96,7 @@ public class DefaultServerContextLogic implements ServerTileContext.Logic { } @Override - public AbsFace toAbsolute(BlockFace contextFace) { + public AbsFace toAbsolute(RelFace contextFace) { return parent.toAbsolute(contextFace); } @@ -112,13 +111,13 @@ public class DefaultServerContextLogic implements ServerTileContext.Logic { } @Override - public TileLogic getTile(Vec3i location, BlockFace face, int layer) { + public TileLogic getTile(Vec3i location, RelFace face, int layer) { TileData data = parent.getTile(location, face, layer); return data == null ? null : TileLogicRegistry.getInstance().get(data.getId()); } @Override - public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) { + public TileLogic getTileByTag(Vec3i location, RelFace face, int tag) { TileData data = parent.getTileByTag(location, face, tag); return data == null ? null : TileLogicRegistry.getInstance().get(data.getId()); } @@ -129,12 +128,12 @@ public class DefaultServerContextLogic implements ServerTileContext.Logic { } @Override - public boolean hasTile(Vec3i location, BlockFace face, int layer) { + public boolean hasTile(Vec3i location, RelFace face, int layer) { return parent.hasTile(location, face, layer); } @Override - public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + public boolean isTagValid(Vec3i location, RelFace face, int tag) { return parent.isTagValid(location, face, tag); } @@ -144,7 +143,7 @@ public class DefaultServerContextLogic implements ServerTileContext.Logic { } @Override - public int getTileCount(Vec3i location, BlockFace face) { + public int getTileCount(Vec3i location, RelFace face) { return parent.getTileCount(location, face); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java index 677f9d3..80c5073 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/FilterServerContext.java @@ -28,7 +28,6 @@ import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; @@ -99,12 +98,12 @@ public abstract class FilterServerContext implements ServerTileContext { } @Override - public void addTile(Vec3i location, BlockFace face, TileData tile) { + public void addTile(Vec3i location, RelFace face, TileData tile) { parent.addTile(location, face, tile); } @Override - public void removeTile(Vec3i location, BlockFace face, int tag) { + public void removeTile(Vec3i location, RelFace face, int tag) { parent.removeTile(location, face, tag); } @@ -149,27 +148,27 @@ public abstract class FilterServerContext implements ServerTileContext { } @Override - public TileData getTile(Vec3i location, BlockFace face, int layer) { + public TileData getTile(Vec3i location, RelFace face, int layer) { return parent.getTile(location, face, layer); } @Override - public TileData getTileByTag(Vec3i location, BlockFace face, int tag) { + public TileData getTileByTag(Vec3i location, RelFace face, int tag) { return parent.getTileByTag(location, face, tag); } @Override - public boolean hasTile(Vec3i location, BlockFace face, int layer) { + public boolean hasTile(Vec3i location, RelFace face, int layer) { return parent.hasTile(location, face, layer); } @Override - public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + public boolean isTagValid(Vec3i location, RelFace face, int tag) { return parent.isTagValid(location, face, tag); } @Override - public int getTileCount(Vec3i location, BlockFace face) { + public int getTileCount(Vec3i location, RelFace face) { return parent.getTileCount(location, face); } @@ -212,7 +211,7 @@ public abstract class FilterServerContext implements ServerTileContext { } @Override - public AbsFace toAbsolute(BlockFace contextFace) { + public AbsFace toAbsolute(RelFace contextFace) { return parent.toAbsolute(contextFace); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java index 302a47f..732b2a0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java @@ -24,6 +24,7 @@ import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.EntityGeneric; import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.world.context.ServerTileContext; @@ -83,7 +84,7 @@ public class ReportingServerContext extends FilterServerContext { } @Override - public void addTile(Vec3i location, BlockFace face, TileData tile) { + public void addTile(Vec3i location, RelFace face, TileData tile) { if (passToParent) { super.addTile(location, face, tile); } @@ -93,7 +94,7 @@ public class ReportingServerContext extends FilterServerContext { } @Override - public void removeTile(Vec3i location, BlockFace face, int tag) { + public void removeTile(Vec3i location, RelFace face, int tag) { if (passToParent) { super.removeTile(location, face, tag); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java index 1fb387e..9c0be6c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/TransformingServerContext.java @@ -23,7 +23,6 @@ import java.util.List; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.world.context.ServerBlockContext; @@ -163,8 +162,8 @@ public abstract class TransformingServerContext extends FilterServerContext { } @Override - public AbsFace toAbsolute(BlockFace contextFace) { - return super.toAbsolute(transform(contextFace.relativize(AbsFace.POS_Z))); + public AbsFace toAbsolute(RelFace contextFace) { + return super.toAbsolute(transform(contextFace)); } @Override @@ -206,77 +205,77 @@ public abstract class TransformingServerContext extends FilterServerContext { } @Override - public boolean hasTile(Vec3i userLocation, BlockFace userFace, int layer) { + public boolean hasTile(Vec3i userLocation, RelFace userFace, int layer) { Vec3i parentLocation = grabVector(userLocation); try { - return super.hasTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), layer); + return super.hasTile(parentLocation, transform(userFace), layer); } finally { releaseVector(parentLocation); } } @Override - public TileData getTile(Vec3i userLocation, BlockFace userFace, int layer) { + public TileData getTile(Vec3i userLocation, RelFace userFace, int layer) { Vec3i parentLocation = grabVector(userLocation); try { - return super.getTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), layer); + return super.getTile(parentLocation, transform(userFace), layer); } finally { releaseVector(parentLocation); } } @Override - public boolean isTagValid(Vec3i userLocation, BlockFace userFace, int tag) { + public boolean isTagValid(Vec3i userLocation, RelFace userFace, int tag) { Vec3i parentLocation = grabVector(userLocation); try { - return super.isTagValid(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag); + return super.isTagValid(parentLocation, transform(userFace), tag); } finally { releaseVector(parentLocation); } } @Override - public TileData getTileByTag(Vec3i userLocation, BlockFace userFace, int tag) { + public TileData getTileByTag(Vec3i userLocation, RelFace userFace, int tag) { Vec3i parentLocation = grabVector(userLocation); try { - return super.getTileByTag(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag); + return super.getTileByTag(parentLocation, transform(userFace), tag); } finally { releaseVector(parentLocation); } } @Override - public int getTileCount(Vec3i userLocation, BlockFace userFace) { + public int getTileCount(Vec3i userLocation, RelFace userFace) { Vec3i parentLocation = grabVector(userLocation); try { - return super.getTileCount(parentLocation, transform(userFace.relativize(AbsFace.POS_Z))); + return super.getTileCount(parentLocation, transform(userFace)); } finally { releaseVector(parentLocation); } } @Override - public void addTile(Vec3i userLocation, BlockFace userFace, TileData tile) { + public void addTile(Vec3i userLocation, RelFace userFace, TileData tile) { Vec3i parentLocation = grabVector(userLocation); try { - super.addTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tile); + super.addTile(parentLocation, transform(userFace), tile); } finally { releaseVector(parentLocation); } } @Override - public void removeTile(Vec3i userLocation, BlockFace userFace, int tag) { + public void removeTile(Vec3i userLocation, RelFace userFace, int tag) { Vec3i parentLocation = grabVector(userLocation); try { - super.removeTile(parentLocation, transform(userFace.relativize(AbsFace.POS_Z)), tag); + super.removeTile(parentLocation, transform(userFace), tag); } finally { releaseVector(parentLocation); } diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 7b9122f..fe972a4 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -428,7 +428,7 @@ public class TestContent { return; if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) return; - server.createAbsoluteContext().addTile(blockInWorld, face, tile); + server.createAbsoluteContext().addTile(blockInWorld, face.relativize(AbsFace.POS_Z), tile); } private static void registerMisc() { diff --git a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java index c197ce1..8a42bee 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTileLogicGrass.java @@ -18,7 +18,6 @@ package ru.windcorp.progressia.test; -import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.context.ServerTileContext; @@ -65,8 +64,7 @@ public class TestTileLogicGrass extends HangingTileLogic implements TickableTile } private boolean isBlockAboveTransparent(ServerTileContextRO context) { - // TODO rework - context.pushRelative(RelFace.UP.resolve(AbsFace.POS_Z)); + context.pushRelative(RelFace.UP); BlockLogic block = context.logic().getBlock(); return context.popAndReturn(block == null || block.isTransparent(context)); } From d33b48578d7f41cee5e3e62769ce1f49f67ccc62 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Tue, 17 Aug 2021 16:05:44 +0300 Subject: [PATCH 53/63] Added SurfaceContexts to replace SurfaceWorld+Request. WIP There is a problem with features when up != POS_Z --- .../ru/windcorp/progressia/server/Server.java | 54 ++++--- .../world/ticking/TickerCoordinator.java | 32 +++-- .../progressia/test/TestBushFeature.java | 26 ++-- .../progressia/test/TestGrassFeature.java | 20 +-- .../progressia/test/TestTreeFeature.java | 69 ++++----- .../gen/planet/PlanetFeatureGenerator.java | 13 +- .../test/gen/planet/TestPlanetGenerator.java | 2 +- .../test/gen/surface/SurfaceFeature.java | 60 +------- .../gen/surface/SurfaceFeatureGenerator.java | 26 +++- .../gen/surface/SurfaceTopLayerFeature.java | 50 ++++--- .../surface/context/SurfaceBlockContext.java | 87 +++++++++++ .../gen/surface/context/SurfaceContext.java | 136 ++++++++++++++++++ .../surface/context/SurfaceContextImpl.java | 114 +++++++++++++++ .../context/SurfaceContextImplLogic.java | 72 ++++++++++ .../surface/context/SurfaceTileContext.java | 54 +++++++ .../context/SurfaceTileStackContext.java | 64 +++++++++ .../surface/context/SurfaceWorldContext.java | 54 +++++++ 17 files changed, 757 insertions(+), 176 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 915c262..132b5bf 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -47,6 +47,7 @@ import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; +import ru.windcorp.progressia.server.world.ticking.TickerCoordinator; import ru.windcorp.progressia.test.gen.planet.Planet; import ru.windcorp.progressia.test.gen.planet.TestPlanetGenerator; @@ -232,13 +233,41 @@ public class Server { schedule(() -> task.accept(this)); } - public void requestChange(Change change) { + /** + * Delayed + */ + public void scheduleChange(Change change) { serverThread.getTicker().requestChange(change); } - - public void requestEvaluation(Evaluation evaluation) { + + /** + * Delayed + */ + public void scheduleEvaluation(Evaluation evaluation) { serverThread.getTicker().requestEvaluation(evaluation); } + + /** + * Immediate if possible, otherwise delayed + */ + public void requestChange(Change change) { + if (serverThread.getTicker().getPhase() == TickerCoordinator.TickPhase.SYNCHRONOUS) { + change.affect(this); + } else { + serverThread.getTicker().requestChange(change); + } + } + + /** + * Immediate if possible, otherwise delayed + */ + public void requestEvaluation(Evaluation evaluation) { + if (serverThread.getTicker().getPhase() == TickerCoordinator.TickPhase.SYNCHRONOUS) { + evaluation.evaluate(this); + } else { + serverThread.getTicker().requestEvaluation(evaluation); + } + } public void subscribe(Object object) { eventBus.register(object); @@ -279,20 +308,7 @@ public class Server { public long getUptimeTicks() { return this.serverThread.getTicker().getUptimeTicks(); } - -// /** -// * Returns the {@link WorldAccessor} object for this server. Use the -// * provided accessor to request common {@link Evaluation}s and -// * {@link Change}s. -// * -// * @return a {@link WorldAccessor} -// * @see #requestChange(Change) -// * @see #requestEvaluation(Evaluation) -// */ -// public WorldAccessor getWorldAccessor() { -// return worldAccessor; -// } - + public WorldAccessor getWorldAccessor___really_bad_dont_use() { return worldAccessor; } @@ -338,8 +354,8 @@ public class Server { } private void scheduleWorldTicks(Server server) { - server.getWorld().getChunks().forEach(chunk -> requestEvaluation(chunk.getTickTask())); - requestEvaluation(server.getWorld().getTickEntitiesTask()); + server.getWorld().getChunks().forEach(chunk -> scheduleEvaluation(chunk.getTickTask())); + scheduleEvaluation(server.getWorld().getTickEntitiesTask()); } /** diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java index 25dc4db..08a0841 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java @@ -23,8 +23,8 @@ import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -47,6 +47,12 @@ import ru.windcorp.progressia.server.Server; * @author javapony */ public class TickerCoordinator { + + public enum TickPhase { + SYNCHRONOUS, + EVALUATION, + CHANGE + } static final int INITIAL_QUEUE_SIZE = 1024; @@ -77,7 +83,7 @@ public class TickerCoordinator { private final AtomicInteger workingTickers = new AtomicInteger(); - private final AtomicBoolean canChange = new AtomicBoolean(true); + private final AtomicReference phase = new AtomicReference<>(TickPhase.SYNCHRONOUS); private boolean isTickStartSet = false; private long tickStart = -1; @@ -96,17 +102,14 @@ public class TickerCoordinator { } this.tickers = ImmutableList.copyOf(tickerCollection); - this.threads = Collections2.transform(this.tickers, Ticker::getThread); // Immutable - // because - // it - // is - // a - // view + + // Immutable because it is a view + this.threads = Collections2.transform(this.tickers, Ticker::getThread); server.getWorld().getData().addListener(ChunkDataListeners.createAdder(new ChunkDataListener() { @Override public void onChunkChanged(DefaultChunkData chunk) { - if (!canChange.get()) { + if (phase.get() == TickPhase.EVALUATION) { throw CrashReports.report(null, "A change has been detected during evaluation phase"); } } @@ -156,8 +159,14 @@ public class TickerCoordinator { public long getUptimeTicks() { return ticks; } + + public TickPhase getPhase() { + return phase.get(); + } private void onTickStart() { + phase.set(TickPhase.EVALUATION); + long now = System.currentTimeMillis(); if (isTickStartSet) { @@ -171,6 +180,7 @@ public class TickerCoordinator { private void onTickEnd() { ticks++; + phase.set(TickPhase.SYNCHRONOUS); } /* @@ -212,9 +222,9 @@ public class TickerCoordinator { } private synchronized void runOnePass() throws InterruptedException { - canChange.set(false); + phase.set(TickPhase.EVALUATION); runPassStage(pendingEvaluations, "EVALUATION"); - canChange.set(true); + phase.set(TickPhase.CHANGE); runPassStage(pendingChanges, "CHANGE"); } diff --git a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java index 50a56aa..a7174f9 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java @@ -22,9 +22,9 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; -import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; public class TestBushFeature extends SurfaceTopLayerFeature { @@ -32,35 +32,35 @@ public class TestBushFeature extends SurfaceTopLayerFeature { super(id); } - private void tryToSetLeaves(SurfaceWorld world, Vec3i posSfc, BlockData leaves) { - if (world.getBlockSfc(posSfc).getId().equals("Test:Air")) { - world.setBlockSfc(posSfc, leaves, false); + private void tryToSetLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) { + if (context.getBlock(location).getId().equals("Test:Air")) { + context.setBlock(location, leaves); } } @Override - protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) { - if (request.getRandom().nextInt(10*10) > 0) return; + protected void processTopBlock(SurfaceBlockContext context) { + if (context.getRandom().nextInt(10*10) > 0) return; - Vec3i center = topBlock.add_(0, 0, 1); + Vec3i center = context.getLocation().add_(0, 0, 1); BlockData log = BlockDataRegistry.getInstance().get("Test:Log"); BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); - world.setBlockSfc(center, log, false); + context.setBlock(center, log); VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 3, 3, 3, p -> { - tryToSetLeaves(world, p, leaves); + tryToSetLeaves(context, p, leaves); }); VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 5, 5, 1, p -> { - tryToSetLeaves(world, p, leaves); + tryToSetLeaves(context, p, leaves); }); } @Override - protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) { - return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP); + protected boolean isSolid(SurfaceBlockContext context) { + return context.logic().getBlock().isSolid(RelFace.UP); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java b/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java index 3689998..cd18ebe 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java @@ -21,13 +21,11 @@ import java.util.Set; import com.google.common.collect.ImmutableSet; -import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; -import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; -import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; public class TestGrassFeature extends SurfaceTopLayerFeature { @@ -44,8 +42,8 @@ public class TestGrassFeature extends SurfaceTopLayerFeature { } @Override - protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) { - if (!WHITELIST.contains(world.getBlockSfc(topBlock).getId())) { + protected void processTopBlock(SurfaceBlockContext context) { + if (!WHITELIST.contains(context.getBlock().getId())) { return; } @@ -54,15 +52,19 @@ public class TestGrassFeature extends SurfaceTopLayerFeature { for (RelFace face : RelFace.getFaces()) { if (face == RelFace.DOWN) continue; - if (BlockLogicRegistry.getInstance().get(world.getBlockSfc(topBlock.add_(face.getRelVector())).getId()).isTransparent()) { - world.getTilesSfc(topBlock, face).addFarthest(grass); + if (context.pushRelative(face).logic().getBlock().isTransparent()) { + context.pop(); + context.addTile(face, grass); + } else { + context.pop(); } + } } @Override - protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) { - return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP); + protected boolean isSolid(SurfaceBlockContext context) { + return context.logic().getBlock().isSolid(RelFace.UP); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java index 5ca923a..2e91dc9 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java @@ -24,25 +24,27 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; -import ru.windcorp.progressia.test.gen.surface.SurfaceWorld; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; public class TestTreeFeature extends SurfaceTopLayerFeature { public TestTreeFeature(String id) { super(id); } - - private void tryToSetLeaves(SurfaceWorld world, Vec3i posSfc, BlockData leaves) { - if (world.getBlockSfc(posSfc).getId().equals("Test:Air")) { - world.setBlockSfc(posSfc, leaves, false); + + private void tryToSetLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) { + if (context.getBlock(location).getId().equals("Test:Air")) { + context.setBlock(location, leaves); } } - + private void iterateSpheroid(Vec3i center, double horDiameter, double vertDiameter, Consumer action) { VectorUtil.iterateCuboidAround( - center.x, center.y, center.z, + center.x, + center.y, + center.z, (int) Math.ceil(horDiameter) / 2 * 2 + 5, (int) Math.ceil(horDiameter) / 2 * 2 + 5, (int) Math.ceil(vertDiameter) / 2 * 2 + 5, @@ -50,54 +52,55 @@ public class TestTreeFeature extends SurfaceTopLayerFeature { double sx = (pos.x - center.x) / horDiameter; double sy = (pos.y - center.y) / horDiameter; double sz = (pos.z - center.z) / vertDiameter; - - if (sx*sx + sy*sy + sz*sz <= 1) { + + if (sx * sx + sy * sy + sz * sz <= 1) { action.accept(pos); } } ); } - + @Override - protected void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock) { - if (request.getRandom().nextInt(20*20) > 0) return; - - Vec3i start = topBlock.add_(0, 0, 1); + protected void processTopBlock(SurfaceBlockContext context) { + if (context.getRandom().nextInt(20 * 20) > 0) + return; + + Vec3i start = context.getLocation().add_(0, 0, 1); BlockData log = BlockDataRegistry.getInstance().get("Test:Log"); BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); - + Vec3i center = start.add_(0); - - int height = request.getRandom().nextInt(3) + 5; + + int height = context.getRandom().nextInt(3) + 5; for (; center.z < start.z + height; ++center.z) { - world.setBlockSfc(center, log, false); + context.setBlock(center, log); } - + double branchHorDistance = 0; - + do { - double branchSize = 0.5 + 1 * request.getRandom().nextDouble(); - double branchHorAngle = 2 * Math.PI * request.getRandom().nextDouble(); - int branchVertOffset = -2 + request.getRandom().nextInt(3); - + double branchSize = 0.5 + 1 * context.getRandom().nextDouble(); + double branchHorAngle = 2 * Math.PI * context.getRandom().nextDouble(); + int branchVertOffset = -2 + context.getRandom().nextInt(3); + Vec3i branchCenter = center.add_( (int) (Math.sin(branchHorAngle) * branchHorDistance), (int) (Math.cos(branchHorAngle) * branchHorDistance), branchVertOffset ); - + iterateSpheroid(branchCenter, 1.75 * branchSize, 2.5 * branchSize, p -> { - tryToSetLeaves(world, p, leaves); + tryToSetLeaves(context, p, leaves); }); - - branchHorDistance = 1 + 2 * request.getRandom().nextDouble(); - } while (request.getRandom().nextInt(8) > 1); + + branchHorDistance = 1 + 2 * context.getRandom().nextDouble(); + } while (context.getRandom().nextInt(8) > 1); } - + @Override - protected boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld) { - return BlockLogicRegistry.getInstance().get(world.getBlockSfc(surfaceBlockInWorld).getId()).isSolid(RelFace.UP); + protected boolean isSolid(SurfaceBlockContext context) { + return context.logic().getBlock().isSolid(RelFace.UP); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java index a33cb87..38ed248 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java @@ -25,6 +25,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.test.TestBushFeature; import ru.windcorp.progressia.test.TestGrassFeature; import ru.windcorp.progressia.test.TestTreeFeature; @@ -57,11 +58,11 @@ public class PlanetFeatureGenerator { return parent; } - public void generateFeatures(DefaultChunkData chunk) { + public void generateFeatures(Server server, DefaultChunkData chunk) { if (isOrdinaryChunk(chunk.getPosition())) { - generateOrdinaryFeatures(chunk); + generateOrdinaryFeatures(server, chunk); } else { - generateBorderFeatures(chunk); + generateBorderFeatures(server, chunk); } chunk.setGenerationHint(true); @@ -72,11 +73,11 @@ public class PlanetFeatureGenerator { return sorted.x != sorted.y; } - private void generateOrdinaryFeatures(DefaultChunkData chunk) { - surfaceGenerators.get(chunk.getUp()).generateFeatures(chunk); + private void generateOrdinaryFeatures(Server server, DefaultChunkData chunk) { + surfaceGenerators.get(chunk.getUp()).generateFeatures(server, chunk); } - private void generateBorderFeatures(DefaultChunkData chunk) { + private void generateBorderFeatures(Server server, DefaultChunkData chunk) { // Do nothing } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index 8b92470..f531282 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -81,7 +81,7 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { DefaultChunkData chunk = getWorldData().getChunk(chunkPos); if (!isChunkReady(chunk.getGenerationHint())) { - featureGenerator.generateFeatures(chunk); + featureGenerator.generateFeatures(getServer(), chunk); } return chunk; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index 0510d98..7bd1cc4 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -18,15 +18,13 @@ package ru.windcorp.progressia.test.gen.surface; import java.util.Random; -import java.util.function.Consumer; import glm.Glm; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.generic.GenericChunks; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; public abstract class SurfaceFeature extends Namespaced { @@ -107,60 +105,6 @@ public abstract class SurfaceFeature extends Namespaced { super(id); } - public abstract void process(SurfaceWorld world, Request request); - - /* - * Utility methods - */ - - public boolean contains(Request request, Vec3i surfaceBlockInWorld) { - Vec3i bic = Vectors.grab3i(); - bic.set(surfaceBlockInWorld.x, surfaceBlockInWorld.y, surfaceBlockInWorld.z); - bic.sub(request.minSfc); - boolean result = GenericChunks.containsBiC(bic); - Vectors.release(bic); - return result; - } - - public void forEach(Request request, Consumer action) { - VectorUtil.iterateCuboid( - request.minSfc.x, - request.minSfc.y, - request.minSfc.z, - request.maxSfc.x + 1, - request.maxSfc.y + 1, - request.maxSfc.z + 1, - action - ); - } - - /** - * Provided vectors have z set to {@link #getMinZ()}. - */ - public void forEachOnFloor(Request request, Consumer action) { - forEachOnLayer(request, action, request.getMinZ()); - } - - /** - * Provided vectors have z set to {@link #getMaxZ()}. - */ - public void forEachOnCeiling(Request request, Consumer action) { - forEachOnLayer(request, action, request.getMaxZ()); - } - - /** - * Provided vectors have z set to layer. - */ - public void forEachOnLayer(Request request, Consumer action, int layer) { - VectorUtil.iterateCuboid( - request.minSfc.x, - request.minSfc.y, - layer, - request.maxSfc.x + 1, - request.maxSfc.y + 1, - layer + 1, - action - ); - } + public abstract void process(SurfaceWorldContext context); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java index 54b582e..aafd0ea 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java @@ -21,8 +21,13 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Random; +import glm.Glm; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceContextImpl; public class SurfaceFeatureGenerator { @@ -42,14 +47,27 @@ public class SurfaceFeatureGenerator { return surface; } - public void generateFeatures(DefaultChunkData chunk) { - SurfaceWorld world = new SurfaceWorld(surface, chunk.getWorld()); + public void generateFeatures(Server server, DefaultChunkData chunk) { Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); - SurfaceFeature.Request request = new SurfaceFeature.Request(world, chunk, random); + + SurfaceContextImpl context = new SurfaceContextImpl((ServerTileContext) server.createAbsoluteContext(), surface); + context.setRandom(random); + + Vec3i tmpA = new Vec3i(); + Vec3i tmpB = new Vec3i(); + + chunk.getMinBIW(tmpA); + chunk.getMaxBIW(tmpB); + + context.toContext(tmpA, tmpA); + context.toContext(tmpB, tmpB); + + Glm.min(tmpA, tmpB, context.getMin()); + Glm.max(tmpA, tmpB, context.getMax()); for (SurfaceFeature feature : features) { - feature.process(world, request); + feature.process(context); } chunk.setGenerationHint(true); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java index 5947950..4981dff 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java @@ -18,41 +18,47 @@ package ru.windcorp.progressia.test.gen.surface; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.Vectors; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; public abstract class SurfaceTopLayerFeature extends SurfaceFeature { - + public SurfaceTopLayerFeature(String id) { super(id); } - protected abstract void processTopBlock(SurfaceWorld world, Request request, Vec3i topBlock); - - protected abstract boolean isSolid(SurfaceWorld world, Vec3i surfaceBlockInWorld); - + protected abstract void processTopBlock(SurfaceBlockContext context); + + protected abstract boolean isSolid(SurfaceBlockContext context); + @Override - public void process(SurfaceWorld world, Request request) { - Vec3i cursor = Vectors.grab3i(); - - forEachOnLayer(request, pos -> { - + public void process(SurfaceWorldContext context) { + Vec3i cursor = new Vec3i(); + + context.forEachOnFloor(pos -> { + cursor.set(pos.x, pos.y, pos.z); - - if (!isSolid(world, cursor)) { + + if (!isSolid(context.push(cursor))) { + context.pop(); return; } - - for (cursor.z += 1; cursor.z <= request.getMaxZ() + 1; ++cursor.z) { - if (!isSolid(world, cursor)) { - cursor.z -= 1; - processTopBlock(world, request, cursor); + context.pop(); + + for (cursor.z += 1; cursor.z <= context.getMaxZ() + 1; ++cursor.z) { + SurfaceBlockContext blockContext = context.push(cursor); + + if (!isSolid(blockContext)) { + processTopBlock(blockContext.pushRelative(0, 0, -1)); + context.pop(); + context.pop(); return; } + + context.pop(); } - - }, request.getMinZ()); - - Vectors.release(cursor); + + }); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java new file mode 100644 index 0000000..be3c285 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java @@ -0,0 +1,87 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.rels.RelRelation; +import ru.windcorp.progressia.server.world.context.ServerBlockContext; + +public interface SurfaceBlockContext extends ServerBlockContext, SurfaceWorldContext { + + public interface Logic extends ServerBlockContext.Logic, SurfaceWorldContext.Logic { + + @Override + SurfaceBlockContext data(); + + @Override + default SurfaceBlockContext.Logic pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default SurfaceBlockContext.Logic pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default SurfaceBlockContext.Logic pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); + } + + @Override + default SurfaceTileStackContext.Logic push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default SurfaceTileContext.Logic push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } + + } + + @Override + SurfaceBlockContext.Logic logic(); + + @Override + default SurfaceBlockContext pushRelative(int dx, int dy, int dz) { + return push(getLocation().add_(dx, dy, dz)); + } + + @Override + default SurfaceBlockContext pushRelative(Vec3i direction) { + return push(getLocation().add_(direction)); + } + + @Override + default SurfaceBlockContext pushRelative(RelRelation direction) { + return push(getLocation().add_(direction.getRelVector())); + } + + @Override + default SurfaceTileStackContext push(RelFace face) { + return push(getLocation(), face); + } + + @Override + default SurfaceTileContext push(RelFace face, int layer) { + return push(getLocation(), face, layer); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java new file mode 100644 index 0000000..b0b1aca --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java @@ -0,0 +1,136 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.test.gen.surface.Surface; + +public interface SurfaceContext { + + /** + * Returns the {@link Surface} object relevant to this context. + * + * @return the surface details + */ + Surface getSurface(); + + /** + * Returns lower bounds (inclusive) on the coordinates of the requested + * region. + * + * @return the coordinates of the minimum corner of the region that + * should be processed + */ + Vec3i getMin(); + + /** + * Returns upper bounds (inclusive) on the coordinates of the requested + * region. + * + * @return the coordinates of the maximum corner of the region that + * should be processed + */ + Vec3i getMax(); + + /* + * Convenience methods + */ + + default int getMinX() { + return getMin().x; + } + + default int getMinY() { + return getMin().y; + } + + default int getMinZ() { + return getMin().z; + } + + default int getMaxX() { + return getMax().x; + } + + default int getMaxY() { + return getMax().y; + } + + default int getMaxZ() { + return getMax().z; + } + + default boolean isRequested(int x, int y, int z) { + Vec3i min = getMin(); + Vec3i max = getMax(); + return (min.x <= x && x <= max.x) && (min.y <= y && y <= max.y) && (min.z <= z && z <= max.z); + } + + default boolean isRequested(Vec3i location) { + return isRequested(location.x, location.y, location.z); + } + + default void forEachRequested(Consumer action) { + Vec3i min = getMin(); + Vec3i max = getMax(); + VectorUtil.iterateCuboid( + min.x, + min.y, + min.z, + max.x + 1, + max.y + 1, + max.z + 1, + action + ); + } + + /** + * Provided vectors have z set to {@link #getMinZ()}. + */ + default void forEachOnFloor(Consumer action) { + forEachOnLayer(action, getMinZ()); + } + + /** + * Provided vectors have z set to {@link #getMaxZ()}. + */ + default void forEachOnCeiling(Consumer action) { + forEachOnLayer(action, getMaxZ()); + } + + /** + * Provided vectors have z set to layer. + */ + default void forEachOnLayer(Consumer action, int layer) { + Vec3i min = getMin(); + Vec3i max = getMax(); + VectorUtil.iterateCuboid( + min.x, + min.y, + layer, + max.x + 1, + max.y + 1, + layer + 1, + action + ); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java new file mode 100644 index 0000000..307330e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java @@ -0,0 +1,114 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import java.util.Random; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext; +import ru.windcorp.progressia.test.gen.surface.Surface; + +public class SurfaceContextImpl extends RotatingServerContext implements SurfaceTileContext { + + final Surface surface; + final Vec3i min = new Vec3i(); + final Vec3i max = new Vec3i(); + private Random random; + + private final SurfaceContextImplLogic logic; + + public SurfaceContextImpl(ServerTileContext parent, Surface surface) { + super(parent, surface.getUp()); + this.logic = new SurfaceContextImplLogic(this); + + this.surface = surface; + } + + @Override + protected void transform(Vec3i userLocation, Vec3i output) { + output.set(userLocation.x, userLocation.y, userLocation.z); + output.z += surface.getSeaLevel(); + super.transform(output, output); + } + + @Override + protected void untransform(Vec3i parentLocation, Vec3i output) { + super.untransform(parentLocation, output); + output.z -= surface.getSeaLevel(); + } + + @Override + public Surface getSurface() { + return surface; + } + + /** + * {@inheritDoc} + * + * @implNote can rw + */ + @Override + public Vec3i getMin() { + return min; + } + + /** + * {@inheritDoc} + * + * @implNote can rw + */ + @Override + public Vec3i getMax() { + return max; + } + + @Override + public Random getRandom() { + return random; + } + + public void setRandom(Random random) { + this.random = random; + } + + @Override + public SurfaceContextImplLogic logic() { + return logic; + } + + @Override + public SurfaceTileContext push(Vec3i location) { + super.push(location); + return this; + } + + @Override + public SurfaceTileContext push(Vec3i location, RelFace face) { + super.push(location, face); + return this; + } + + @Override + public SurfaceTileContext push(Vec3i location, RelFace face, int layer) { + super.push(location, face, layer); + return this; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java new file mode 100644 index 0000000..b8f45df --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java @@ -0,0 +1,72 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.context.impl.DefaultServerContextLogic; +import ru.windcorp.progressia.test.gen.surface.Surface; + +public class SurfaceContextImplLogic extends DefaultServerContextLogic implements SurfaceTileContext.Logic { + + private final SurfaceContextImpl surfaceParent; + + public SurfaceContextImplLogic(SurfaceContextImpl surfaceParent) { + super(surfaceParent); + this.surfaceParent = surfaceParent; + } + + @Override + public Surface getSurface() { + return this.surfaceParent.surface; + } + + @Override + public Vec3i getMin() { + return this.surfaceParent.min; + } + + @Override + public Vec3i getMax() { + return this.surfaceParent.max; + } + + @Override + public SurfaceContextImpl data() { + return this.surfaceParent; + } + + @Override + public SurfaceTileContext.Logic push(Vec3i location) { + super.push(location); + return this; + } + + @Override + public SurfaceTileContext.Logic push(Vec3i location, RelFace face) { + super.push(location, face); + return this; + } + + @Override + public SurfaceTileContext.Logic push(Vec3i location, RelFace face, int layer) { + super.push(location, face, layer); + return this; + } + +} \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java new file mode 100644 index 0000000..13f2211 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java @@ -0,0 +1,54 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import ru.windcorp.progressia.server.world.context.ServerTileContext; + +public interface SurfaceTileContext extends ServerTileContext, SurfaceTileStackContext { + + public interface Logic extends ServerTileContext.Logic, SurfaceTileStackContext.Logic { + + @Override + SurfaceTileContext data(); + + @Override + default SurfaceTileContext.Logic pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default SurfaceTileContext.Logic pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } + + } + + @Override + SurfaceTileContext.Logic logic(); + + @Override + default SurfaceTileContext pushCloser() { + return push(getLocation(), getFace(), getLayer() - 1); + } + + @Override + default SurfaceTileContext pushFarther() { + return push(getLocation(), getFace(), getLayer() + 1); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java new file mode 100644 index 0000000..54f65bc --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java @@ -0,0 +1,64 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import ru.windcorp.progressia.server.world.context.ServerTileStackContext; + +public interface SurfaceTileStackContext extends ServerTileStackContext, SurfaceBlockContext { + + public interface Logic extends ServerTileStackContext.Logic, SurfaceBlockContext.Logic { + + @Override + SurfaceTileStackContext data(); + + @Override + default SurfaceTileContext.Logic push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default SurfaceTileStackContext.Logic pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default SurfaceTileStackContext.Logic pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } + + } + + @Override + SurfaceTileStackContext.Logic logic(); + + @Override + default SurfaceTileContext push(int layer) { + return push(getLocation(), getFace(), layer); + } + + @Override + default SurfaceTileStackContext pushCounter() { + return push(getFace().getCounter()); + } + + @Override + default SurfaceTileStackContext pushOpposite() { + return push(getLocation().add_(getFace().getRelVector()), getFace().getCounter()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java new file mode 100644 index 0000000..76510cf --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java @@ -0,0 +1,54 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen.surface.context; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; + +public interface SurfaceWorldContext extends ServerWorldContext, SurfaceContext { + + public interface Logic extends ServerWorldContext.Logic, SurfaceContext { + + @Override + SurfaceWorldContext data(); + + @Override + SurfaceBlockContext.Logic push(Vec3i location); + + @Override + SurfaceTileStackContext.Logic push(Vec3i location, RelFace face); + + @Override + SurfaceTileContext.Logic push(Vec3i location, RelFace face, int layer); + + } + + @Override + SurfaceWorldContext.Logic logic(); + + @Override + SurfaceBlockContext push(Vec3i location); + + @Override + SurfaceTileStackContext push(Vec3i location, RelFace face); + + @Override + SurfaceTileContext push(Vec3i location, RelFace face, int layer); + +} From a3760d742561ecffeae67e2e4a4a8c51e57455d0 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Tue, 17 Aug 2021 19:21:57 +0300 Subject: [PATCH 54/63] Removed erroneous RelFace resolution by WorldAccessor --- .../context/impl/DefaultServerContextImpl.java | 16 ++++++++-------- .../context/impl/ReportingServerContext.java | 5 ++--- .../server/world/tasks/WorldAccessor.java | 12 +++++++----- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java index 7d4f6cf..b4dfedc 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/DefaultServerContextImpl.java @@ -364,19 +364,19 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public TileData getTile(Vec3i location, RelFace face, int layer) { assert requireContextRole(Role.WORLD); - return world.getTile(location, face, layer); + return world.getTile(location, face.resolve(AbsFace.POS_Z), layer); } @Override public boolean hasTile(Vec3i location, RelFace face, int layer) { assert requireContextRole(Role.WORLD); - return world.hasTile(location, face, layer); + return world.hasTile(location, face.resolve(AbsFace.POS_Z), layer); } @Override public TileData getTileByTag(Vec3i location, RelFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = world.getTilesOrNull(location, face); + TileDataStack stack = world.getTilesOrNull(location, face.resolve(AbsFace.POS_Z)); if (stack == null) return null; int layer = stack.getIndexByTag(tag); @@ -388,7 +388,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public boolean isTagValid(Vec3i location, RelFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = world.getTilesOrNull(location, face); + TileDataStack stack = world.getTilesOrNull(location, face.resolve(AbsFace.POS_Z)); if (stack == null) return false; return stack.getIndexByTag(tag) != -1; @@ -397,7 +397,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public int getTag() { assert requireContextRole(Role.TILE); - TileDataStack stack = world.getTilesOrNull(frame.location, frame.face); + TileDataStack stack = world.getTilesOrNull(frame.location, frame.face.resolve(AbsFace.POS_Z)); if (stack == null) return -1; return stack.getTagByIndex(frame.layer); @@ -406,7 +406,7 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public int getTileCount(Vec3i location, RelFace face) { assert requireContextRole(Role.TILE_STACK); - TileDataStack stack = world.getTilesOrNull(frame.location, frame.face); + TileDataStack stack = world.getTilesOrNull(location, face.resolve(AbsFace.POS_Z)); if (stack == null) return 0; return stack.size(); @@ -455,13 +455,13 @@ class DefaultServerContextImpl extends DefaultServerContext @Override public void addTile(Vec3i location, RelFace face, TileData tile) { assert requireContextRole(Role.WORLD); - world.getTiles(location, face).addFarthest(tile); + world.getTiles(location, face.resolve(AbsFace.POS_Z)).addFarthest(tile); } @Override public void removeTile(Vec3i location, RelFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = world.getTilesOrNull(location, face); + TileDataStack stack = world.getTilesOrNull(location, face.resolve(AbsFace.POS_Z)); if (stack == null) return; int layer = stack.getIndexByTag(tag); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java index 732b2a0..57ff66c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReportingServerContext.java @@ -23,7 +23,6 @@ import ru.windcorp.progressia.common.state.StatefulObject; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.EntityGeneric; -import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.world.context.ServerTileContext; @@ -34,9 +33,9 @@ public class ReportingServerContext extends FilterServerContext { void onBlockSet(Vec3i location, BlockData block); - void onTileAdded(Vec3i location, BlockFace face, TileData tile); + void onTileAdded(Vec3i location, RelFace face, TileData tile); - void onTileRemoved(Vec3i location, BlockFace face, int tag); + void onTileRemoved(Vec3i location, RelFace face, int tag); void onEntityAdded(EntityData entity); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java index cb95063..76ab835 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/WorldAccessor.java @@ -27,7 +27,9 @@ import ru.windcorp.progressia.common.util.MultiLOC; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.EntityGeneric; +import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.BlockFace; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext; @@ -64,16 +66,16 @@ public class WorldAccessor implements ReportingServerContext.ChangeListener { } @Override - public void onTileAdded(Vec3i blockInWorld, BlockFace face, TileData tile) { + public void onTileAdded(Vec3i blockInWorld, RelFace face, TileData tile) { AddTile change = cache.grab(AddTile.class); - change.getPacket().set(tile, blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld))); + change.getPacket().set(tile, blockInWorld, face.resolve(AbsFace.POS_Z)); server.requestChange(change); } @Override - public void onTileRemoved(Vec3i blockInWorld, BlockFace face, int tag) { + public void onTileRemoved(Vec3i blockInWorld, RelFace face, int tag) { RemoveTile change = cache.grab(RemoveTile.class); - change.getPacket().set(blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld)), tag); + change.getPacket().set(blockInWorld, face.resolve(AbsFace.POS_Z), tag); server.requestChange(change); } @@ -131,7 +133,7 @@ public class WorldAccessor implements ReportingServerContext.ChangeListener { // TODO rename to something meaningful public void triggerUpdates(Vec3i blockInWorld, BlockFace face) { TileTriggeredUpdate evaluation = cache.grab(TileTriggeredUpdate.class); - evaluation.init(blockInWorld, face.resolve(server.getWorld().getUp(blockInWorld))); + evaluation.init(blockInWorld, face.resolve(AbsFace.POS_Z)); server.requestEvaluation(evaluation); } From 539a61e85475d798a585af6fe89e24e38f1ef11a Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 18 Aug 2021 00:26:45 +0300 Subject: [PATCH 55/63] Almost resolved feature generation issue, removed dead code - SurfaceFeatures that change neighboring chunks no longer suffer from tearing if world saving is enabled - World saving is still disabled by default - wontfix until we get a new, more optimized world IO system - See GitHub issue #13 for details - Removed WorldAccessor getter from Server. This is an implementation detail. - Removed SurfaceWorld, SurfaceFeature.Request (see previous commit) --- .../ru/windcorp/progressia/server/Server.java | 7 +- .../server/world/DefaultWorldLogic.java | 5 +- .../test/gen/planet/TestPlanetGenerator.java | 5 +- .../test/gen/surface/SurfaceFeature.java | 79 ------- .../test/gen/surface/SurfaceWorld.java | 205 ------------------ 5 files changed, 6 insertions(+), 295 deletions(-) delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 132b5bf..2ad6171 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -82,7 +82,8 @@ public class Server { this.world = new DefaultWorldLogic( world, this, - new TestPlanetGenerator("Test:PlanetGenerator", this, new Planet(4, 9.8f, 16f, 16f)) + new TestPlanetGenerator("Test:PlanetGenerator", this, new Planet(4, 9.8f, 16f, 16f)), + worldAccessor ); this.serverThread = new ServerThread(this); @@ -308,10 +309,6 @@ public class Server { public long getUptimeTicks() { return this.serverThread.getTicker().getUptimeTicks(); } - - public WorldAccessor getWorldAccessor___really_bad_dont_use() { - return worldAccessor; - } /** * Returns the ticking settings for this server. diff --git a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java index f2b1883..3e654b6 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/DefaultWorldLogic.java @@ -33,6 +33,7 @@ import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.generation.WorldGenerator; import ru.windcorp.progressia.server.world.tasks.TickEntitiesTask; +import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Evaluation; public class DefaultWorldLogic implements WorldLogic { @@ -46,7 +47,7 @@ public class DefaultWorldLogic implements WorldLogic { private final Evaluation tickEntitiesTask = new TickEntitiesTask(); - public DefaultWorldLogic(DefaultWorldData data, Server server, WorldGenerator generator) { + public DefaultWorldLogic(DefaultWorldData data, Server server, WorldGenerator generator, WorldAccessor accessor) { this.data = data; this.server = server; @@ -65,7 +66,7 @@ public class DefaultWorldLogic implements WorldLogic { } }); - data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(server.getWorldAccessor___really_bad_dont_use()))); + data.addListener(ChunkDataListeners.createAdder(new UpdateTriggerer(accessor))); } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java index f531282..0846be7 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java @@ -88,11 +88,8 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { } private void conjureTerrain(Vec3i chunkPos) { + getServer().getLoadManager().getChunkManager().loadChunk(chunkPos); DefaultChunkData chunk = getWorldData().getChunk(chunkPos); - - if (chunk == null) { - chunk = getWorldData().getChunk(chunkPos); - } if (chunk == null) { chunk = terrainGenerator.generateTerrain(chunkPos); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java index 7bd1cc4..e4bb250 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java @@ -17,90 +17,11 @@ */ package ru.windcorp.progressia.test.gen.surface; -import java.util.Random; - -import glm.Glm; -import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; public abstract class SurfaceFeature extends Namespaced { - public static class Request { - - private final SurfaceWorld world; - private final DefaultChunkData chunk; - private final Vec3i minSfc = new Vec3i(); - private final Vec3i maxSfc = new Vec3i(); - - private final Random random; - - public Request(SurfaceWorld world, DefaultChunkData chunk, Random random) { - this.world = world; - this.chunk = chunk; - this.random = random; - - Vec3i tmpMin = chunk.getMinBIW(null); - Vec3i tmpMax = chunk.getMaxBIW(null); - - GenericChunks.relativize(tmpMin, chunk.getUp(), tmpMin); - GenericChunks.relativize(tmpMax, chunk.getUp(), tmpMax); - - Glm.min(tmpMin, tmpMax, minSfc); - Glm.max(tmpMin, tmpMax, maxSfc); - - minSfc.z -= world.getSurface().getSeaLevel(); - maxSfc.z -= world.getSurface().getSeaLevel(); - } - - public DefaultChunkData getChunk() { - return chunk; - } - - public SurfaceWorld getWorld() { - return world; - } - - public Random getRandom() { - return random; - } - - public int getMinX() { - return minSfc.x; - } - - public int getMaxX() { - return maxSfc.x; - } - - public int getMinY() { - return minSfc.y; - } - - public int getMaxY() { - return maxSfc.y; - } - - public int getMinZ() { - return minSfc.z; - } - - public int getMaxZ() { - return maxSfc.z; - } - - public Vec3i getMin() { - return minSfc; - } - - public Vec3i getMax() { - return maxSfc; - } - - } - public SurfaceFeature(String id) { super(id); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java deleted file mode 100644 index 43a218e..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test.gen.surface; - -import java.util.Collection; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.state.StateChange; -import ru.windcorp.progressia.common.state.StatefulObject; -import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.GravityModel; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.generic.EntityGeneric; -import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.WorldData; - -public class SurfaceWorld - implements WorldData { - - private final Surface surface; - private final WorldData parent; - - public SurfaceWorld( - Surface surface, - WorldData parent - ) { - this.surface = surface; - this.parent = parent; - } - - /** - * @return the surface - */ - public Surface getSurface() { - return surface; - } - - /** - * @return the parent - */ - public WorldData getParent() { - return parent; - } - - /* - * Delegate methods - */ - - @Override - public Collection getChunks() { - return parent.getChunks(); - } - - @Override - public ChunkData getChunk(Vec3i pos) { - return parent.getChunk(pos); - } - - @Override - public Collection getEntities() { - return parent.getEntities(); - } - - @Override - public EntityData getEntity(long entityId) { - return parent.getEntity(entityId); - } - - @Override - public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { - parent.setBlock(blockInWorld, block, notify); - } - - @Override - public void addEntity(EntityData entity) { - parent.addEntity(entity); - } - - @Override - public void removeEntity(long entityId) { - parent.removeEntity(entityId); - } - - public Vec3i resolve(Vec3i surfacePosition, Vec3i output) { - if (output == null) { - output = new Vec3i(); - } - - output.set(surfacePosition.x, surfacePosition.y, surfacePosition.z); - output.z += getSurface().getSeaLevel(); - - GenericChunks.resolve(output, getSurface().getUp(), output); - - return output; - } - - public Vec3i relativize(Vec3i absolutePosition, Vec3i output) { - if (output == null) { - output = new Vec3i(); - } - - output.set(absolutePosition.x, absolutePosition.y, absolutePosition.z); - - GenericChunks.relativize(output, getSurface().getUp(), output); - output.z -= getSurface().getSeaLevel(); - - return output; - } - - public BlockData getBlockSfc(Vec3i surfaceBlockInWorld) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - BlockData result = parent.getBlock(blockInWorld); - Vectors.release(blockInWorld); - return result; - } - - public void setBlockSfc(Vec3i surfaceBlockInWorld, BlockData block, boolean notify) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - parent.setBlock(blockInWorld, block, notify); - Vectors.release(blockInWorld); - } - - public TileDataStack getTilesSfc(Vec3i surfaceBlockInWorld, BlockFace face) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - TileDataStack result = parent.getTiles(blockInWorld, face); - Vectors.release(blockInWorld); - return result; - } - - public TileDataStack getTilesOrNullSfc(Vec3i surfaceBlockInWorld, BlockFace face) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - TileDataStack result = parent.getTilesOrNull(blockInWorld, face); - Vectors.release(blockInWorld); - return result; - } - - public boolean hasTilesSfc(Vec3i surfaceBlockInWorld, BlockFace face) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - boolean result = parent.hasTiles(blockInWorld, face); - Vectors.release(blockInWorld); - return result; - } - - public TileData getTileSfc(Vec3i surfaceBlockInWorld, BlockFace face, int layer) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - TileData result = parent.getTile(blockInWorld, face, layer); - Vectors.release(blockInWorld); - return result; - } - - public boolean isBlockLoadedSfc(Vec3i surfaceBlockInWorld) { - Vec3i blockInWorld = Vectors.grab3i(); - resolve(surfaceBlockInWorld, blockInWorld); - boolean result = parent.isLocationLoaded(blockInWorld); - Vectors.release(blockInWorld); - return result; - } - - @Override - public float getTime() { - return parent.getTime(); - } - - @Override - public GravityModel getGravityModel() { - return parent.getGravityModel(); - } - - @Override - public void changeEntity(SE entity, StateChange change) { - parent.changeEntity(entity, change); - } - - @Override - public void advanceTime(float change) { - parent.advanceTime(change); - } - -} From ca2014802a9925917355b6448e8881293fbb0f80 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 18 Aug 2021 09:30:29 +0300 Subject: [PATCH 56/63] Resolved a random deadlock that became way too frequent to ignore There was a deadlock that sometimes occurred when passing PacketSetBlock to client: PacketSetBlock first acquired monitor of the chunk it modified, than attempted to lock the visible chunks set. In parallel, a chunk update first acquires the visible chunks, than the individual chunk. Turns out, markForUpdate() doesn't need to be synchronized, so PacketSetBlock can now acquire the locks sequentially, avoiding the deadlock. --- .../java/ru/windcorp/progressia/client/world/ChunkRender.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index e96166d..41aa933 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -97,7 +97,7 @@ public class ChunkRender return data; } - public synchronized void markForUpdate() { + public void markForUpdate() { getWorld().markChunkForUpdate(getPosition()); } From 15b5d367b4f87c2774c8c9047c1492950795ad35 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Wed, 18 Aug 2021 10:58:18 +0300 Subject: [PATCH 57/63] Chunk loading region around the player is now compressed vertically --- .../ru/windcorp/progressia/server/Player.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/windcorp/progressia/server/Player.java b/src/main/java/ru/windcorp/progressia/server/Player.java index 008c000..e0a9db7 100644 --- a/src/main/java/ru/windcorp/progressia/server/Player.java +++ b/src/main/java/ru/windcorp/progressia/server/Player.java @@ -20,8 +20,12 @@ package ru.windcorp.progressia.server; import java.util.function.Consumer; +import glm.mat._3.Mat3; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.util.Matrices; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.PlayerData; @@ -60,10 +64,35 @@ public class Player extends PlayerData implements ChunkLoader { float radiusSq = radius * radius; int iRadius = (int) Math.ceil(radius); + // The sphere around the player is stretched by this factor vertically + // (along the player's up vector) + final float verticalStretching = 0.4f; + + float factor = (1/verticalStretching - 1); + Vec3 up = getServer().getWorld().getData().getGravityModel().getUp(getEntity().getPosition(), null); + + Mat3 transform = Matrices.grab3(); + + //@formatter:off + transform.set( + 1 + factor * up.x * up.x, 0 + factor * up.x * up.y, 0 + factor * up.x * up.z, + 0 + factor * up.y * up.x, 1 + factor * up.y * up.y, 0 + factor * up.y * up.z, + 0 + factor * up.z * up.x, 0 + factor * up.z * up.y, 1 + factor * up.z * up.z + ); + //@formatter:on + + Vec3 transformedCursor = Vectors.grab3(); + for (cursor.x = -iRadius; cursor.x <= +iRadius; ++cursor.x) { for (cursor.y = -iRadius; cursor.y <= +iRadius; ++cursor.y) { for (cursor.z = -iRadius; cursor.z <= +iRadius; ++cursor.z) { - if (cursor.x * cursor.x + cursor.y * cursor.y + (cursor.z/* * 2*/) * (cursor.z/* * 2*/) <= radiusSq) { + + transformedCursor.set(cursor.x, cursor.y, cursor.z); + + // .mul(Vec3) is cursed + transform.mul(transformedCursor, transformedCursor); + + if (transformedCursor.dot(transformedCursor) <= radiusSq) { cursor.add(start); chunkConsumer.accept(cursor); @@ -73,6 +102,9 @@ public class Player extends PlayerData implements ChunkLoader { } } } + + Matrices.release(transform); + Vectors.release(transformedCursor); } public String getLogin() { From 2328f2ae3a557df88daf52f88582a04cca3b481e Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 20 Aug 2021 18:07:41 +0300 Subject: [PATCH 58/63] Replaced placeholder worldgen with a passable one - Removed old (pre-planet) worldgen - TestGravityModel remains - Moved surface generator to .logic.world.generation.surface - Split planet generator into generator logic and config - Logic moved to .logic.world.generation.planet - Config extracted into TestGenerationConfig & others in .test.gen - GravityModel renamed to Test:PlanetGravityModel - TestTerrainGenerator utilities moved and made public thru Fields - Reconfigured planet generator to be a passable - Increased planet size to R=0.5 km - Added noise-based heightmaps (fabulous cliffs included) - Added noise-based forest density map - Reworked all SurfaceFeatures - TestGrassFeature now also places scatter and flowers - TestTreeFeature and TestBushFeature: - Common code exctracted to MultiblockVegetationFeature - Made prettier - gud muscle flex yeeeeeeeeeeee - Fixed a bug in the gravity model - A lot of other changes that I already forgot about --- .../ru/windcorp/progressia/server/Server.java | 8 +- .../progressia/server/ServerState.java | 3 +- .../context/impl/RotatingServerContext.java | 6 +- .../world/generation}/planet/Planet.java | 8 +- .../planet/PlanetFeatureGenerator.java | 25 +- .../generation/planet/PlanetGenerator.java} | 46 +- .../planet/PlanetGravityModel.java} | 15 +- .../planet/PlanetTerrainGenerator.java | 48 +-- .../world/generation}/surface/Surface.java | 2 +- .../generation}/surface/SurfaceFeature.java | 19 +- .../surface/SurfaceFeatureGenerator.java | 10 +- .../surface/SurfaceFloatField.java | 11 +- .../surface/SurfaceTerrainGenerator.java | 7 +- .../surface/SurfaceTopLayerFeature.java | 6 +- .../generation/surface}/TerrainLayer.java | 6 +- .../surface/context/SurfaceBlockContext.java | 2 +- .../surface/context/SurfaceContext.java | 4 +- .../surface/context/SurfaceContextImpl.java | 4 +- .../context/SurfaceContextImplLogic.java | 4 +- .../surface/context/SurfaceTileContext.java | 2 +- .../context/SurfaceTileStackContext.java | 2 +- .../surface/context/SurfaceWorldContext.java | 2 +- .../progressia/test/TestBushFeature.java | 66 --- .../windcorp/progressia/test/TestContent.java | 5 +- .../progressia/test/TestGrassFeature.java | 70 --- .../progressia/test/TestTreeFeature.java | 106 ----- .../windcorp/progressia/test/gen/Fields.java | 321 ++++++++++++++ .../test/gen/MultiblockVegetationFeature.java | 148 +++++++ .../progressia/test/gen/TestBushFeature.java | 49 +++ .../test/gen/TestGenerationConfig.java | 118 ++++++ .../progressia/test/gen/TestGrassFeature.java | 122 ++++++ .../progressia/test/gen/TestHeightMap.java | 79 ++++ .../test/gen/TestTerrainGenerator.java | 152 ------- .../progressia/test/gen/TestTreeFeature.java | 69 +++ .../test/gen/TestWorldGenerator.java | 400 ------------------ .../test/gen/planet/TestHeightMap.java | 70 --- .../gen/surface/SurfaceCachingFloatField.java | 77 ---- .../gen/surface/SurfaceFieldRegistry.java | 29 -- .../test/gen/surface/SurfaceNodeStorage.java | 57 --- 39 files changed, 1032 insertions(+), 1146 deletions(-) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/planet/Planet.java (88%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/planet/PlanetFeatureGenerator.java (70%) rename src/main/java/ru/windcorp/progressia/{test/gen/planet/TestPlanetGenerator.java => server/world/generation/planet/PlanetGenerator.java} (74%) rename src/main/java/ru/windcorp/progressia/{test/gen/planet/TestPlanetGravityModel.java => server/world/generation/planet/PlanetGravityModel.java} (94%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/planet/PlanetTerrainGenerator.java (67%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/Surface.java (94%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/SurfaceFeature.java (60%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/SurfaceFeatureGenerator.java (86%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/SurfaceFloatField.java (68%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/SurfaceTerrainGenerator.java (91%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/SurfaceTopLayerFeature.java (86%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation/surface}/TerrainLayer.java (81%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceBlockContext.java (97%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceContext.java (95%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceContextImpl.java (94%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceContextImplLogic.java (92%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceTileContext.java (95%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceTileStackContext.java (96%) rename src/main/java/ru/windcorp/progressia/{test/gen => server/world/generation}/surface/context/SurfaceWorldContext.java (95%) delete mode 100644 src/main/java/ru/windcorp/progressia/test/TestBushFeature.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/Fields.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestHeightMap.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java delete mode 100644 src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 2ad6171..e975b90 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -19,6 +19,7 @@ package ru.windcorp.progressia.server; import java.util.function.Consumer; +import java.util.function.Function; import org.apache.logging.log4j.LogManager; @@ -44,12 +45,11 @@ import ru.windcorp.progressia.server.world.context.ServerWorldContext; import ru.windcorp.progressia.server.world.context.impl.DefaultServerContext; import ru.windcorp.progressia.server.world.context.impl.ReportingServerContext; import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext; +import ru.windcorp.progressia.server.world.generation.WorldGenerator; import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; import ru.windcorp.progressia.server.world.ticking.TickerCoordinator; -import ru.windcorp.progressia.test.gen.planet.Planet; -import ru.windcorp.progressia.test.gen.planet.TestPlanetGenerator; public class Server { @@ -78,11 +78,11 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); - public Server(DefaultWorldData world) { + public Server(DefaultWorldData world, Function generatorCreator) { this.world = new DefaultWorldLogic( world, this, - new TestPlanetGenerator("Test:PlanetGenerator", this, new Planet(4, 9.8f, 16f, 16f)), + generatorCreator.apply(this), worldAccessor ); this.serverThread = new ServerThread(this); diff --git a/src/main/java/ru/windcorp/progressia/server/ServerState.java b/src/main/java/ru/windcorp/progressia/server/ServerState.java index de505f5..00aa901 100644 --- a/src/main/java/ru/windcorp/progressia/server/ServerState.java +++ b/src/main/java/ru/windcorp/progressia/server/ServerState.java @@ -19,6 +19,7 @@ package ru.windcorp.progressia.server; import ru.windcorp.progressia.common.world.DefaultWorldData; +import ru.windcorp.progressia.test.gen.TestGenerationConfig; public class ServerState { @@ -33,7 +34,7 @@ public class ServerState { } public static void startServer() { - Server server = new Server(new DefaultWorldData()); + Server server = new Server(new DefaultWorldData(), TestGenerationConfig.createGenerator()); setInstance(server); server.start(); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java index c6459c4..a73d2b0 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/RotatingServerContext.java @@ -18,8 +18,8 @@ package ru.windcorp.progressia.server.world.context.impl; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.context.ServerTileContext; @@ -38,12 +38,12 @@ public class RotatingServerContext extends TransformingServerContext { @Override protected void transform(Vec3i userLocation, Vec3i output) { - AxisRotations.resolve(userLocation, up, output); + GenericChunks.resolve(userLocation, up, output); } @Override protected void untransform(Vec3i parentLocation, Vec3i output) { - AxisRotations.relativize(parentLocation, up, output); + GenericChunks.relativize(parentLocation, up, output); } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/Planet.java similarity index 88% rename from src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/planet/Planet.java index 3637078..161e2c0 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/Planet.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/Planet.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.planet; +package ru.windcorp.progressia.server.world.generation.planet; import ru.windcorp.progressia.common.world.DefaultChunkData; @@ -23,7 +23,7 @@ public class Planet { private final int radiusInChunks; - private final TestPlanetGravityModel.Settings gravityModelSettings; + private final PlanetGravityModel.Settings gravityModelSettings; public Planet( int radiusInChunks, @@ -32,7 +32,7 @@ public class Planet { float innerGravityRadius ) { this.radiusInChunks = radiusInChunks; - this.gravityModelSettings = new TestPlanetGravityModel.Settings( + this.gravityModelSettings = new PlanetGravityModel.Settings( surfaceGravitationalAcceleration, curvature, innerGravityRadius @@ -82,7 +82,7 @@ public class Planet { /** * @return the gravityModelSettings */ - public TestPlanetGravityModel.Settings getGravityModelSettings() { + public PlanetGravityModel.Settings getGravityModelSettings() { return gravityModelSettings; } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetFeatureGenerator.java similarity index 70% rename from src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetFeatureGenerator.java index 38ed248..97e2424 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetFeatureGenerator.java @@ -15,10 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.planet; +package ru.windcorp.progressia.server.world.generation.planet; -import java.util.ArrayList; -import java.util.Collection; +import java.util.List; import java.util.Map; import glm.vec._3.i.Vec3i; @@ -26,26 +25,18 @@ import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.test.TestBushFeature; -import ru.windcorp.progressia.test.TestGrassFeature; -import ru.windcorp.progressia.test.TestTreeFeature; -import ru.windcorp.progressia.test.gen.surface.Surface; -import ru.windcorp.progressia.test.gen.surface.SurfaceFeature; -import ru.windcorp.progressia.test.gen.surface.SurfaceFeatureGenerator; +import ru.windcorp.progressia.server.world.generation.surface.Surface; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeature; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeatureGenerator; public class PlanetFeatureGenerator { - private final TestPlanetGenerator parent; + private final PlanetGenerator parent; private final Map surfaceGenerators; - public PlanetFeatureGenerator(TestPlanetGenerator generator) { + public PlanetFeatureGenerator(PlanetGenerator generator, List features) { this.parent = generator; - - Collection features = new ArrayList<>(); - features.add(new TestBushFeature("Test:BushFeature")); - features.add(new TestTreeFeature("Test:TreeFeature")); - features.add(new TestGrassFeature("Test:GrassFeature")); int seaLevel = (int) parent.getPlanet().getRadius(); this.surfaceGenerators = AbsFace.mapToFaces(face -> new SurfaceFeatureGenerator( @@ -54,7 +45,7 @@ public class PlanetFeatureGenerator { )); } - public TestPlanetGenerator getGenerator() { + public PlanetGenerator getGenerator() { return parent; } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java similarity index 74% rename from src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java index 0846be7..1d31417 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java @@ -15,49 +15,61 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.planet; +package ru.windcorp.progressia.server.world.generation.planet; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.List; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.FloatRangeMap; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeature; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; + +public class PlanetGenerator extends AbstractWorldGenerator { -public class TestPlanetGenerator extends AbstractWorldGenerator { - private final Planet planet; - + private final PlanetTerrainGenerator terrainGenerator; private final PlanetFeatureGenerator featureGenerator; - public TestPlanetGenerator(String id, Server server, Planet planet) { + public PlanetGenerator( + String id, + Server server, + Planet planet, + SurfaceFloatField heightMap, + FloatRangeMap layers, + List features + ) { super(id, server, Boolean.class, "Test:PlanetGravityModel"); - + this.planet = planet; - - TestPlanetGravityModel model = (TestPlanetGravityModel) this.getGravityModel(); + + PlanetGravityModel model = (PlanetGravityModel) this.getGravityModel(); model.configure(planet.getGravityModelSettings()); - - this.terrainGenerator = new PlanetTerrainGenerator(this); - this.featureGenerator = new PlanetFeatureGenerator(this); + + this.terrainGenerator = new PlanetTerrainGenerator(this, heightMap, layers); + this.featureGenerator = new PlanetFeatureGenerator(this, features); } - + /** * @return the planet */ public Planet getPlanet() { return planet; } - + @Override public Vec3 suggestSpawnLocation() { - return new Vec3(7f, 7f, getPlanet().getRadius() + 10); + return new Vec3(407f, 1f, getPlanet().getRadius() + 10); } @Override @@ -79,14 +91,14 @@ public class TestPlanetGenerator extends AbstractWorldGenerator { public DefaultChunkData generate(Vec3i chunkPos) { VectorUtil.iterateCuboidAround(chunkPos, 3, r -> conjureTerrain(r)); DefaultChunkData chunk = getWorldData().getChunk(chunkPos); - + if (!isChunkReady(chunk.getGenerationHint())) { featureGenerator.generateFeatures(getServer(), chunk); } - + return chunk; } - + private void conjureTerrain(Vec3i chunkPos) { getServer().getLoadManager().getChunkManager().loadChunk(chunkPos); DefaultChunkData chunk = getWorldData().getChunk(chunkPos); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGravityModel.java similarity index 94% rename from src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGravityModel.java index a7fb334..e2545b5 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestPlanetGravityModel.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGravityModel.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.planet; +package ru.windcorp.progressia.server.world.generation.planet; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; @@ -30,7 +30,7 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -public class TestPlanetGravityModel extends GravityModel { +public class PlanetGravityModel extends GravityModel { public static class Settings { public float surfaceGravitationalAcceleration; @@ -66,7 +66,7 @@ public class TestPlanetGravityModel extends GravityModel { private Settings settings = new Settings(); - public TestPlanetGravityModel(String id) { + public PlanetGravityModel(String id) { super(id); } @@ -90,7 +90,6 @@ public class TestPlanetGravityModel extends GravityModel { protected void doGetGravity(Vec3 pos, Vec3 output) { float r = getInnerRadius(); float c = getCurvature(); - float g = getSurfaceGravitationalAcceleration(); // Change to a CS where (0;0;0) is the center of the center chunk float px = pos.x - DefaultChunkData.CHUNK_RADIUS + 0.5f; @@ -142,14 +141,14 @@ public class TestPlanetGravityModel extends GravityModel { assert output.dot(output) == 1 : "maxAbs - midAbs = " + maxAbs + " - " + midAbs + " > " + c + " yet l*l != 1"; } - output.mul(-g); + output.mul(-getSurfaceGravitationalAcceleration()); } private void computeEdgeGravity(float lx, float ly, float lz, float rx, float ry, float rz, Vec3 output) { // da math is gud, no worry // - Javapony - float r = getInnerRadius(); + float c = getCurvature(); if (lx == 0) rx = 0; if (ly == 0) ry = 0; @@ -159,10 +158,10 @@ public class TestPlanetGravityModel extends GravityModel { float rSquared = rx*rx + ry*ry + rz*rz; float distanceAlongEdge = scalarProduct - (float) sqrt( - scalarProduct*scalarProduct - rSquared + r*r + scalarProduct*scalarProduct - rSquared + c*c ); - output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(r); + output.set(lx, ly, lz).mul(-distanceAlongEdge).add(rx, ry, rz).div(c); final float f = (float) sqrt(3.0/2); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java similarity index 67% rename from src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java index 227187d..ab081db 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java @@ -15,11 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.planet; +package ru.windcorp.progressia.server.world.generation.planet; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; import ru.windcorp.progressia.common.util.FloatRangeMap; import ru.windcorp.progressia.common.util.VectorUtil; import ru.windcorp.progressia.common.world.DefaultChunkData; @@ -27,37 +26,22 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.generic.GenericChunks; -import ru.windcorp.progressia.test.gen.TerrainLayer; -import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField; -import ru.windcorp.progressia.test.gen.surface.SurfaceTerrainGenerator; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceTerrainGenerator; +import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; class PlanetTerrainGenerator { - private final TestPlanetGenerator parent; + private final PlanetGenerator parent; private final SurfaceTerrainGenerator surfaceGenerator; - public PlanetTerrainGenerator(TestPlanetGenerator generator) { + public PlanetTerrainGenerator(PlanetGenerator generator, SurfaceFloatField heightMap, FloatRangeMap layers) { this.parent = generator; - - SurfaceFloatField heightMap = new TestHeightMap( - generator.getPlanet().getRadius() - DefaultChunkData.BLOCKS_PER_CHUNK, - generator.getPlanet().getRadius() / 4, - 5, - 6 - ); - - FloatRangeMap layers = new ArrayFloatRangeMap<>(); - BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - layers.put(Float.NEGATIVE_INFINITY, 0, (n, w, d, r, c) -> air); - layers.put(0, 4, (n, w, d, r, c) -> dirt); - layers.put(4, Float.POSITIVE_INFINITY, (n, w, d, r, c) -> granite); - - this.surfaceGenerator = new SurfaceTerrainGenerator((f, n, w) -> heightMap.get(f, n, w) + generator.getPlanet().getRadius(), layers); + SurfaceFloatField adjustedHeightMap = (f, n, w) -> heightMap.get(f, n, w) + generator.getPlanet().getRadius(); + this.surfaceGenerator = new SurfaceTerrainGenerator(adjustedHeightMap, layers); } - public TestPlanetGenerator getGenerator() { + public PlanetGenerator getGenerator() { return parent; } @@ -69,7 +53,7 @@ class PlanetTerrainGenerator { } else { generateBorderTerrain(chunk); } - + chunk.setGenerationHint(false); return chunk; @@ -87,24 +71,24 @@ class PlanetTerrainGenerator { private void generateBorderTerrain(DefaultChunkData chunk) { BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - + float radius = parent.getPlanet().getRadius(); Vec3 biw = new Vec3(); - + GenericChunks.forEachBiC(bic -> { - + biw.set( Coordinates.getInWorld(chunk.getX(), bic.x), Coordinates.getInWorld(chunk.getY(), bic.y), Coordinates.getInWorld(chunk.getZ(), bic.z) ); - + biw.sub(DefaultChunkData.CHUNK_RADIUS - 0.5f); VectorUtil.sortAfterAbs(biw, biw); - + chunk.setBlock(bic, biw.x <= radius ? stone : air, false); - + }); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java similarity index 94% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java index 0baa6f0..296e3eb 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/Surface.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface; +package ru.windcorp.progressia.server.world.generation.surface; import ru.windcorp.progressia.common.world.rels.AbsFace; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeature.java similarity index 60% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeature.java index e4bb250..8430168 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeature.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeature.java @@ -15,10 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface; +package ru.windcorp.progressia.server.world.generation.surface; + +import java.util.List; import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; +import ru.windcorp.progressia.server.world.context.ServerContext; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceWorldContext; public abstract class SurfaceFeature extends Namespaced { @@ -27,5 +30,17 @@ public abstract class SurfaceFeature extends Namespaced { } public abstract void process(SurfaceWorldContext context); + + protected static double randomDouble(ServerContext context, double from, double to) { + return from + (to - from) * context.getRandom().nextDouble(); + } + + protected static double stretch(double t, double from, double to) { + return from + (to - from) * t; + } + + protected static T pickRandom(ServerContext context, List from) { + return from.get(context.getRandom().nextInt(from.size())); + } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java similarity index 86% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java index aafd0ea..abfbcb3 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java @@ -15,10 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface; +package ru.windcorp.progressia.server.world.generation.surface; import java.util.ArrayList; -import java.util.Collection; +import java.util.List; import java.util.Random; import glm.Glm; @@ -27,15 +27,15 @@ import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.world.context.ServerTileContext; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceContextImpl; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceContextImpl; public class SurfaceFeatureGenerator { private final Surface surface; - private final Collection features; // TODO make ordered + private final List features; - public SurfaceFeatureGenerator(Surface surface, Collection features) { + public SurfaceFeatureGenerator(Surface surface, List features) { this.surface = surface; this.features = new ArrayList<>(features); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFloatField.java similarity index 68% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFloatField.java index 4b368d4..81506f1 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFloatField.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFloatField.java @@ -15,13 +15,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface; +package ru.windcorp.progressia.server.world.generation.surface; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; @FunctionalInterface public interface SurfaceFloatField { - float get(AbsFace face, float north, float west); + float get(AbsFace face, float x, float y); + + default float get(SurfaceBlockContext context) { + Vec3i location = context.getLocation(); + return get(context.getSurface().getUp(), location.x, location.y); + } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java similarity index 91% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java index ec93d58..a3511bd 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface; +package ru.windcorp.progressia.server.world.generation.surface; import java.util.Random; @@ -26,7 +26,6 @@ import ru.windcorp.progressia.common.util.FloatRangeMap; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AxisRotations; -import ru.windcorp.progressia.test.gen.TerrainLayer; public class SurfaceTerrainGenerator { @@ -44,7 +43,7 @@ public class SurfaceTerrainGenerator { Vec3 offset = new Vec3(chunk.getMinX(), chunk.getMinY(), chunk.getMinZ()); AxisRotations.relativize(offset, chunk.getUp(), offset); - offset.sub(DefaultChunkData.CHUNK_RADIUS - 0.5f); + offset.z -= DefaultChunkData.CHUNK_RADIUS - 0.5f; Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); @@ -65,7 +64,7 @@ public class SurfaceTerrainGenerator { for (relBIC.z = 0; relBIC.z < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { float depth = relSurface - relBIC.z; - BlockData block = layers.get(depth).get(north, west, depth, random, chunk); + BlockData block = layers.get(depth).get(chunk.getUp(), north, west, depth, random); chunk.resolve(relBIC, relBIC); chunk.setBlock(relBIC, block, false); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTopLayerFeature.java similarity index 86% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTopLayerFeature.java index 4981dff..d96d68b 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceTopLayerFeature.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTopLayerFeature.java @@ -15,11 +15,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface; +package ru.windcorp.progressia.server.world.generation.surface; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceWorldContext; public abstract class SurfaceTopLayerFeature extends SurfaceFeature { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java similarity index 81% rename from src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java index 21c1809..7af46fa 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TerrainLayer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java @@ -15,16 +15,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen; +package ru.windcorp.progressia.server.world.generation.surface; import java.util.Random; -import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.rels.AbsFace; @FunctionalInterface public interface TerrainLayer { - BlockData get(float north, float west, float depth, Random random, DefaultChunkData chunk); + BlockData get(AbsFace face, float north, float west, float depth, Random random); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceBlockContext.java similarity index 97% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceBlockContext.java index be3c285..64531fb 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceBlockContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.RelFace; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContext.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContext.java index b0b1aca..a69d60b 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContext.java @@ -15,13 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.test.gen.surface.Surface; +import ru.windcorp.progressia.server.world.generation.surface.Surface; public interface SurfaceContext { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContextImpl.java similarity index 94% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContextImpl.java index 307330e..6050c49 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContextImpl.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import java.util.Random; @@ -23,7 +23,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.context.ServerTileContext; import ru.windcorp.progressia.server.world.context.impl.RotatingServerContext; -import ru.windcorp.progressia.test.gen.surface.Surface; +import ru.windcorp.progressia.server.world.generation.surface.Surface; public class SurfaceContextImpl extends RotatingServerContext implements SurfaceTileContext { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContextImplLogic.java similarity index 92% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContextImplLogic.java index b8f45df..cbf9b88 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceContextImplLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceContextImplLogic.java @@ -15,12 +15,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.server.world.context.impl.DefaultServerContextLogic; -import ru.windcorp.progressia.test.gen.surface.Surface; +import ru.windcorp.progressia.server.world.generation.surface.Surface; public class SurfaceContextImplLogic extends DefaultServerContextLogic implements SurfaceTileContext.Logic { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceTileContext.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceTileContext.java index 13f2211..ce28c6e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceTileContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import ru.windcorp.progressia.server.world.context.ServerTileContext; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceTileStackContext.java similarity index 96% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceTileStackContext.java index 54f65bc..d090e94 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceTileStackContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceTileStackContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import ru.windcorp.progressia.server.world.context.ServerTileStackContext; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceWorldContext.java similarity index 95% rename from src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceWorldContext.java index 76510cf..96a0922 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/context/SurfaceWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/context/SurfaceWorldContext.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package ru.windcorp.progressia.test.gen.surface.context; +package ru.windcorp.progressia.server.world.generation.surface.context; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.rels.RelFace; diff --git a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java deleted file mode 100644 index a7174f9..0000000 --- a/src/main/java/ru/windcorp/progressia/test/TestBushFeature.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; - -public class TestBushFeature extends SurfaceTopLayerFeature { - - public TestBushFeature(String id) { - super(id); - } - - private void tryToSetLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) { - if (context.getBlock(location).getId().equals("Test:Air")) { - context.setBlock(location, leaves); - } - } - - @Override - protected void processTopBlock(SurfaceBlockContext context) { - if (context.getRandom().nextInt(10*10) > 0) return; - - Vec3i center = context.getLocation().add_(0, 0, 1); - - BlockData log = BlockDataRegistry.getInstance().get("Test:Log"); - BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); - - context.setBlock(center, log); - - VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 3, 3, 3, p -> { - tryToSetLeaves(context, p, leaves); - }); - - VectorUtil.iterateCuboidAround(center.x, center.y, center.z, 5, 5, 1, p -> { - tryToSetLeaves(context, p, leaves); - }); - } - - @Override - protected boolean isSolid(SurfaceBlockContext context) { - return context.logic().getBlock().isSolid(RelFace.UP); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index fe972a4..b8a5b33 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -27,7 +27,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Consumer; - import org.lwjgl.glfw.GLFW; import glm.vec._3.i.Vec3i; @@ -56,9 +55,9 @@ import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.comms.controls.*; import ru.windcorp.progressia.server.world.block.*; import ru.windcorp.progressia.server.world.entity.*; +import ru.windcorp.progressia.server.world.generation.planet.PlanetGravityModel; import ru.windcorp.progressia.server.world.tile.*; import ru.windcorp.progressia.test.gen.TestGravityModel; -import ru.windcorp.progressia.test.gen.planet.TestPlanetGravityModel; public class TestContent { @@ -435,7 +434,7 @@ public class TestContent { ChunkIO.registerCodec(new TestChunkCodec()); ChunkRenderOptimizerRegistry.getInstance().register("Core:SurfaceOptimizer", ChunkRenderOptimizerSurface::new); GravityModelRegistry.getInstance().register("Test:TheGravityModel", TestGravityModel::new); - GravityModelRegistry.getInstance().register("Test:PlanetGravityModel", TestPlanetGravityModel::new); + GravityModelRegistry.getInstance().register("Test:PlanetGravityModel", PlanetGravityModel::new); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java b/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java deleted file mode 100644 index cd18ebe..0000000 --- a/src/main/java/ru/windcorp/progressia/test/TestGrassFeature.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test; - -import java.util.Set; - -import com.google.common.collect.ImmutableSet; - -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataRegistry; -import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; - -public class TestGrassFeature extends SurfaceTopLayerFeature { - - private static final Set WHITELIST = ImmutableSet.of( - "Test:Dirt", - "Test:Stone", - "Test:GraniteMonolith", - "Test:GraniteCracked", - "Test:GraniteGravel" - ); - - public TestGrassFeature(String id) { - super(id); - } - - @Override - protected void processTopBlock(SurfaceBlockContext context) { - if (!WHITELIST.contains(context.getBlock().getId())) { - return; - } - - TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); - - for (RelFace face : RelFace.getFaces()) { - if (face == RelFace.DOWN) continue; - - if (context.pushRelative(face).logic().getBlock().isTransparent()) { - context.pop(); - context.addTile(face, grass); - } else { - context.pop(); - } - - } - } - - @Override - protected boolean isSolid(SurfaceBlockContext context) { - return context.logic().getBlock().isSolid(RelFace.UP); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java deleted file mode 100644 index 2e91dc9..0000000 --- a/src/main/java/ru/windcorp/progressia/test/TestTreeFeature.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test; - -import java.util.function.Consumer; - -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.rels.RelFace; -import ru.windcorp.progressia.test.gen.surface.SurfaceTopLayerFeature; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceBlockContext; -import ru.windcorp.progressia.test.gen.surface.context.SurfaceWorldContext; - -public class TestTreeFeature extends SurfaceTopLayerFeature { - - public TestTreeFeature(String id) { - super(id); - } - - private void tryToSetLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) { - if (context.getBlock(location).getId().equals("Test:Air")) { - context.setBlock(location, leaves); - } - } - - private void iterateSpheroid(Vec3i center, double horDiameter, double vertDiameter, Consumer action) { - VectorUtil.iterateCuboidAround( - center.x, - center.y, - center.z, - (int) Math.ceil(horDiameter) / 2 * 2 + 5, - (int) Math.ceil(horDiameter) / 2 * 2 + 5, - (int) Math.ceil(vertDiameter) / 2 * 2 + 5, - pos -> { - double sx = (pos.x - center.x) / horDiameter; - double sy = (pos.y - center.y) / horDiameter; - double sz = (pos.z - center.z) / vertDiameter; - - if (sx * sx + sy * sy + sz * sz <= 1) { - action.accept(pos); - } - } - ); - } - - @Override - protected void processTopBlock(SurfaceBlockContext context) { - if (context.getRandom().nextInt(20 * 20) > 0) - return; - - Vec3i start = context.getLocation().add_(0, 0, 1); - - BlockData log = BlockDataRegistry.getInstance().get("Test:Log"); - BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); - - Vec3i center = start.add_(0); - - int height = context.getRandom().nextInt(3) + 5; - for (; center.z < start.z + height; ++center.z) { - context.setBlock(center, log); - } - - double branchHorDistance = 0; - - do { - double branchSize = 0.5 + 1 * context.getRandom().nextDouble(); - double branchHorAngle = 2 * Math.PI * context.getRandom().nextDouble(); - int branchVertOffset = -2 + context.getRandom().nextInt(3); - - Vec3i branchCenter = center.add_( - (int) (Math.sin(branchHorAngle) * branchHorDistance), - (int) (Math.cos(branchHorAngle) * branchHorDistance), - branchVertOffset - ); - - iterateSpheroid(branchCenter, 1.75 * branchSize, 2.5 * branchSize, p -> { - tryToSetLeaves(context, p, leaves); - }); - - branchHorDistance = 1 + 2 * context.getRandom().nextDouble(); - } while (context.getRandom().nextInt(8) > 1); - } - - @Override - protected boolean isSolid(SurfaceBlockContext context) { - return context.logic().getBlock().isSolid(RelFace.UP); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/Fields.java b/src/main/java/ru/windcorp/progressia/test/gen/Fields.java new file mode 100644 index 0000000..86741df --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/Fields.java @@ -0,0 +1,321 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import kdotjpg.opensimplex2.areagen.OpenSimplex2S; +import ru.windcorp.progressia.common.util.namespaces.Namespaced; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.DefaultChunkData; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.world.generation.planet.Planet; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; + +public class Fields { + + @FunctionalInterface + public interface Field { + double compute(double x, double y); + } + + public static class FieldSet extends Namespaced implements SurfaceFloatField { + + private final Field[] fields = new Field[AbsFace.getFaces().size()]; + + public FieldSet(String id) { + super(id); + } + + public void put(AbsFace face, Field field) { + fields[face.getId()] = field; + } + + public Field get(AbsFace face) { + return fields[face.getId()]; + } + + @Override + public float get(AbsFace face, float x, float y) { + float offset = DefaultChunkData.CHUNK_RADIUS - 0.5f; + return (float) fields[face.getId()].compute(x - offset, y - offset); + } + + } + + private final Random primitiveRandomizer; + + private final OpenSimplex2S noise; + + private final Map registeredFields = Collections.synchronizedMap(new HashMap<>()); + + private final Logger logger = LogManager.getLogger(getClass()); + + public Fields(long seed) { + this.primitiveRandomizer = new Random(seed); + this.noise = new OpenSimplex2S(seed); + } + + public Field register(String id, AbsFace face, Field f) { + Objects.requireNonNull(f, "f"); + Objects.requireNonNull(face, "face"); + + synchronized (registeredFields) { + FieldSet fieldSet = registeredFields.computeIfAbsent(id, FieldSet::new); + + Field previous = fieldSet.get(face); + if (previous != null) { + throw new IllegalArgumentException( + "Duplicate field definition " + id + ":" + face + " for fields " + f + " and " + previous + ); + } + fieldSet.put(face, f); + + logger.debug("Registering {}:{} in {}", id, face, getClass().getSimpleName()); + } + + return f; + } + + public SurfaceFloatField register(String id, Function fieldGenerator) { + for (AbsFace face : AbsFace.getFaces()) { + register(id, face, fieldGenerator.apply(face)); + } + return get(id); + } + + public SurfaceFloatField register(String id, Supplier fieldGenerator) { + for (AbsFace face : AbsFace.getFaces()) { + register(id, face, fieldGenerator.get()); + } + return get(id); + } + + public SurfaceFloatField get(String id) { + return registeredFields.get(id); + } + + public Field get(String id, AbsFace face) { + return registeredFields.get(id).get(face); + } + + public static Field cutoff(Field f, double outerRadius, double thickness) { + return (x, y) -> { + + double cutoffCoefficient = 1; + cutoffCoefficient *= cutoffFunction(outerRadius - x, thickness); + cutoffCoefficient *= cutoffFunction(outerRadius + x, thickness); + cutoffCoefficient *= cutoffFunction(outerRadius - y, thickness); + cutoffCoefficient *= cutoffFunction(outerRadius + y, thickness); + + if (cutoffCoefficient == 0) { + return 0; + } + + return cutoffCoefficient * f.compute(x, y); + + }; + } + + public static Field cutoff(Field f, Planet planet, double thickness) { + return cutoff(f, planet.getRadius() - Coordinates.CHUNK_SIZE, thickness); + } + + private static double cutoffFunction(double distanceToCutoffPoint, double thickness) { + if (distanceToCutoffPoint < 0) { + return 0; + } else if (distanceToCutoffPoint < thickness) { + double t = distanceToCutoffPoint / thickness; + return (1 - Math.cos(Math.PI * t)) / 2; + } else { + return 1; + } + } + + public Field primitive() { + double xOffset = primitiveRandomizer.nextDouble() * 200 - 100; + double yOffset = primitiveRandomizer.nextDouble() * 200 - 100; + double rotation = primitiveRandomizer.nextDouble() * 2 * Math.PI; + + double sin = Math.sin(rotation); + double cos = Math.cos(rotation); + + return (x, y) -> noise.noise2(x * cos - y * sin + xOffset, x * sin + y * cos + yOffset); + } + + public static Field add(Field a, Field b) { + return (x, y) -> a.compute(x, y) + b.compute(x, y); + } + + public static Field multiply(Field a, Field b) { + return (x, y) -> a.compute(x, y) * b.compute(x, y); + } + + public static Field add(Field... functions) { + return (x, y) -> { + double sum = 0; + for (Field function : functions) { + sum += function.compute(x, y); + } + return sum; + }; + } + + public static Field multiply(Field... functions) { + return (x, y) -> { + double product = 1; + for (Field function : functions) { + product *= function.compute(x, y); + } + return product; + }; + } + + public static Field tweak(Field f, double scale, double amplitude, double bias) { + return (x, y) -> f.compute(x / scale, y / scale) * amplitude + bias; + } + + public static Field tweak(Field f, double scale, double amplitude) { + return tweak(f, scale, amplitude, 0); + } + + public static Field scale(Field f, double scale) { + return tweak(f, scale, 1, 0); + } + + public static Field amplify(Field f, double amplitude) { + return tweak(f, 1, amplitude, 0); + } + + public static Field bias(Field f, double bias) { + return tweak(f, 1, 1, bias); + } + + public static Field octaves(Field f, double scaleFactor, double amplitudeFactor, int octaves) { + return (x, y) -> { + double result = 0; + + double scale = 1; + double amplitude = 1; + + for (int i = 0; i < octaves; ++i) { + result += f.compute(x * scale, y * scale) * amplitude; + scale *= scaleFactor; + amplitude /= amplitudeFactor; + } + + return result; + }; + } + + public static Field octaves(Field f, double factor, int octaves) { + return octaves(f, factor, factor, octaves); + } + + public static Field squash(Field f, double slope) { + return (x, y) -> 1 / (1 + Math.exp(-slope * f.compute(x, y))); + } + + public static Field ridge(Field f) { + return (x, y) -> 1 - Math.abs(f.compute(x, y)); + } + + public static Field clamp(Field f, double min, double max) { + return (x, y) -> Math.min(Math.max(f.compute(x, y), min), max); + } + + public static Field withMin(Field f, double min) { + return (x, y) -> Math.max(f.compute(x, y), min); + } + + public static Field withMax(Field f, double max) { + return (x, y) -> Math.min(f.compute(x, y), max); + } + + public static Field select(Field f, double target, double width) { + return (x, y) -> { + double value = f.compute(x, y); + if (value < target - width) { + return 0; + } else if (value < target) { + return (width - (target - value)) / width; + } else if (value < target + width) { + return (width - (value - target)) / width; + } else { + return 0; + } + }; + } + + public static Field selectPositive(Field f, double target, double width) { + return (x, y) -> { + double value = f.compute(x, y); + if (value < target - width) { + return 0; + } else if (value < target + width) { + return (width - (target - value)) / (2*width); + } else { + return 1; + } + }; + } + + public static Field selectNegative(Field f, double target, double width) { + return (x, y) -> { + double value = target - f.compute(x, y); + if (value < target - width) { + return 0; + } else if (value < target + width) { + return (width - (target - value)) / (2*width); + } else { + return 1; + } + }; + } + + public static Field cliff(Field f, double target, double featureWidth, double slopeWidth) { + return (x, y) -> { + double value = f.compute(x, y); + + if (value < target - featureWidth) { + return 0; + } else if (value < target - slopeWidth) { + double t = (value - (target - featureWidth)) / (featureWidth - slopeWidth); + return -0.5 + Math.cos(t * Math.PI) / 2; + } else if (value < target + slopeWidth) { + double t = (value - (target - slopeWidth)) / (2 * slopeWidth); + return -Math.cos(t * Math.PI); + } else if (value < target + featureWidth) { + double t = (value - (target + slopeWidth)) / (featureWidth - slopeWidth); + return +0.5 + Math.cos(t * Math.PI) / 2; + } else { + return 0; + } + }; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java new file mode 100644 index 0000000..5cfcc43 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java @@ -0,0 +1,148 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import java.util.Set; +import java.util.function.Consumer; + +import com.google.common.collect.ImmutableSet; + +import glm.vec._3.i.Vec3i; +import kdotjpg.opensimplex2.areagen.OpenSimplex2S; +import ru.windcorp.progressia.common.util.VectorUtil; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceTopLayerFeature; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceWorldContext; + +public abstract class MultiblockVegetationFeature extends SurfaceTopLayerFeature { + + private final SurfaceFloatField selector; + private final OpenSimplex2S wavinessGenerator = new OpenSimplex2S(0); + + private final double maximumDensity; + + private final Set soilWhitelist; + + public MultiblockVegetationFeature(String id, SurfaceFloatField selector, double minimumPeriod) { + super(id); + this.selector = selector; + this.maximumDensity = 1 / minimumPeriod; + + ImmutableSet.Builder soilWhitelistBuilder = ImmutableSet.builder(); + createSoilWhitelist(soilWhitelistBuilder::add); + this.soilWhitelist = soilWhitelistBuilder.build(); + } + + protected void createSoilWhitelist(Consumer output) { + output.accept("Test:Dirt"); + } + + @Override + protected void processTopBlock(SurfaceBlockContext context) { + Vec3i location = context.getLocation(); + + if (location.z < 0) { + return; + } + + if (!soilWhitelist.isEmpty() && !soilWhitelist.contains(context.getBlock().getId())) { + return; + } + + double selectorValue = selector.get(context); + double chance = selectorValue * maximumDensity; + if (context.getRandom().nextDouble() >= chance) { + return; + } + + grow(context, selectorValue); + } + + protected abstract void grow(SurfaceBlockContext context, double selectorValue); + + @Override + protected boolean isSolid(SurfaceBlockContext context) { + return context.logic().getBlock().isSolid(RelFace.UP); + } + + /* + * Utilities + */ + + protected void setLeaves(SurfaceWorldContext context, Vec3i location, BlockData leaves) { + if (context.getBlock(location).getId().equals("Test:Air")) { + context.setBlock(location, leaves); + } + } + + protected void iterateBlob( + Vec3i center, + double horDiameter, + double vertDiameter, + double wavinessAmplitude, + double wavinessScale, + Consumer action + ) { + VectorUtil.iterateCuboidAround( + center.x, + center.y, + center.z, + (int) Math.ceil(horDiameter) / 2 * 2 + 5, + (int) Math.ceil(horDiameter) / 2 * 2 + 5, + (int) Math.ceil(vertDiameter) / 2 * 2 + 5, + pos -> { + + double sx = (pos.x - center.x) / horDiameter; + double sy = (pos.y - center.y) / horDiameter; + double sz = (pos.z - center.z) / vertDiameter; + + double radius = 1; + + if (wavinessAmplitude > 0) { + radius += wavinessAmplitude * wavinessGenerator.noise3_Classic( + sx / wavinessScale, + sy / wavinessScale, + sz / wavinessScale + ); + } + + if (sx * sx + sy * sy + sz * sz <= radius * radius) { + action.accept(pos); + } + + } + ); + } + + protected void iterateSpheroid( + Vec3i center, + double horDiameter, + double vertDiameter, + Consumer action + ) { + iterateBlob(center, horDiameter, vertDiameter, 0, 0, action); + } + + protected void iterateSphere(Vec3i center, double diameter, Consumer action) { + iterateBlob(center, diameter, diameter, 0, 0, action); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java new file mode 100644 index 0000000..ca2765c --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java @@ -0,0 +1,49 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class TestBushFeature extends MultiblockVegetationFeature { + + private final BlockData trunk = BlockDataRegistry.getInstance().get("Test:Log"); + private final BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); + + public TestBushFeature(String id, SurfaceFloatField selector) { + super(id, selector, 7 * 7); + } + + @Override + protected void grow(SurfaceBlockContext context, double selectorValue) { + double size = selectorValue * randomDouble(context, 0.8, 1.2); + + Vec3i center = context.getLocation().add_(0, 0, 1); + + context.setBlock(center, trunk); + context.setBlock(center.add_(0, 0, 1), leaves); + + iterateBlob(center, stretch(size, 1.3, 2.5), stretch(size, 0.6, 1.5), 0.7, 2, p -> { + setLeaves(context, p, leaves); + }); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java new file mode 100644 index 0000000..b4ed652 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java @@ -0,0 +1,118 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import static ru.windcorp.progressia.test.gen.Fields.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; +import ru.windcorp.progressia.common.util.FloatRangeMap; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.generation.WorldGenerator; +import ru.windcorp.progressia.server.world.generation.planet.Planet; +import ru.windcorp.progressia.server.world.generation.planet.PlanetGenerator; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeature; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; + +public class TestGenerationConfig { + + private static final float PLANET_RADIUS = Units.get("0.5 km"); + private static final float SURFACE_GRAVITY = Units.get("9.8 m/s^2"); + private static final float CURVATURE = Units.get("100 m"); + private static final float INNER_RADIUS = Units.get("200 m"); + + private static final Fields FIELDS = new Fields("No bugs please".hashCode()); + + public static Function createGenerator() { + + Planet planet = new Planet( + ((int) PLANET_RADIUS) / Coordinates.CHUNK_SIZE, + SURFACE_GRAVITY, + CURVATURE, + INNER_RADIUS + ); + + TestHeightMap heightMap = new TestHeightMap(planet, planet.getRadius() / 4, FIELDS); + + FloatRangeMap layers = new ArrayFloatRangeMap<>(); + registerTerrainLayers(layers); + + List features = new ArrayList<>(); + registerFeatures(features); + + return server -> new PlanetGenerator("Test:PlanetGenerator", server, planet, heightMap, layers, features); + + } + + private static void registerTerrainLayers(FloatRangeMap layers) { + BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); + BlockData graniteCracked = BlockDataRegistry.getInstance().get("Test:GraniteCracked"); + BlockData graniteGravel = BlockDataRegistry.getInstance().get("Test:GraniteGravel"); + + BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); + BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); + + SurfaceFloatField cliffs = FIELDS.get("Test:CliffSelector"); + + layers.put(Float.NEGATIVE_INFINITY, 0, (f, n, w, d, r) -> air); + layers.put(0, 4, (f, n, w, d, r) -> { + if (cliffs.get(f, n, w) > 0) { + switch (r.nextInt(4)) { + case 0: + return granite; + case 1: + return graniteCracked; + default: + return graniteGravel; + } + } else { + return dirt; + } + }); + layers.put(4, Float.POSITIVE_INFINITY, (f, n, w, d, r) -> granite); + } + + private static void registerFeatures(List features) { + + SurfaceFloatField forestiness = FIELDS.register( + "Test:Forestiness", + () -> squash(scale(FIELDS.primitive(), 200), 5) + ); + + SurfaceFloatField floweriness = FIELDS.register( + "Test:Floweriness", + f -> multiply( + scale(octaves(FIELDS.primitive(), 2, 2), 40), + tweak(FIELDS.get("Test:Forestiness", f), 1, -1, 1.1) + ) + ); + + features.add(new TestBushFeature("Test:BushFeature", forestiness)); + features.add(new TestTreeFeature("Test:TreeFeature", forestiness)); + features.add(new TestGrassFeature("Test:GrassFeature", FIELDS.get("Test:CliffSelector"), floweriness)); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java new file mode 100644 index 0000000..d1d73e5 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java @@ -0,0 +1,122 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import java.util.List; +import java.util.Set; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +import ru.windcorp.progressia.common.world.rels.RelFace; +import ru.windcorp.progressia.common.world.tile.TileData; +import ru.windcorp.progressia.common.world.tile.TileDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceTopLayerFeature; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class TestGrassFeature extends SurfaceTopLayerFeature { + + private static final Set WHITELIST = ImmutableSet.of( + "Test:Dirt", + "Test:Stone", + "Test:GraniteMonolith", + "Test:GraniteCracked", + "Test:GraniteGravel" + ); + + private final SurfaceFloatField grassiness; + private final SurfaceFloatField floweriness; + private final double scatterDensity = 1.0 / (3*3); + + private final TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); + private final List flowers = ImmutableList.of( + TileDataRegistry.getInstance().get("Test:YellowFlowers") + ); + private final List scatter = ImmutableList.of( + TileDataRegistry.getInstance().get("Test:Stones"), + TileDataRegistry.getInstance().get("Test:Sand") + ); + + public TestGrassFeature(String id, SurfaceFloatField grassiness, SurfaceFloatField floweriness) { + super(id); + this.grassiness = grassiness; + this.floweriness = floweriness; + } + + @Override + protected void processTopBlock(SurfaceBlockContext context) { + if (context.getLocation().z < 0) { + return; + } + if (!WHITELIST.contains(context.getBlock().getId())) { + return; + } + + if (!context.pushRelative(RelFace.UP).logic().getBlock().isTransparent()) { + context.pop(); + return; + } + context.pop(); + + double grassiness = this.grassiness.get(context); + if (grassiness < 0.2) { + growGrass(context); + } + + placeScatter(context); + + if (grassiness < 0.2) { + growFlowers(context); + } + } + + private void placeScatter(SurfaceBlockContext context) { + if (context.getRandom().nextDouble() < scatterDensity) { + TileData tile = pickRandom(context, scatter); + context.addTile(RelFace.UP, tile); + } + } + + private void growGrass(SurfaceBlockContext context) { + for (RelFace face : RelFace.getFaces()) { + if (face == RelFace.DOWN) continue; + + if (context.pushRelative(face).logic().getBlock().isTransparent()) { + context.pop(); + context.addTile(face, grass); + } else { + context.pop(); + } + + } + } + + private void growFlowers(SurfaceBlockContext context) { + if (context.getRandom().nextDouble() < floweriness.get(context)) { + TileData tile = pickRandom(context, flowers); + context.addTile(RelFace.UP, tile); + } + } + + @Override + protected boolean isSolid(SurfaceBlockContext context) { + return context.logic().getBlock().isSolid(RelFace.UP); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestHeightMap.java b/src/main/java/ru/windcorp/progressia/test/gen/TestHeightMap.java new file mode 100644 index 0000000..c09aec1 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestHeightMap.java @@ -0,0 +1,79 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import static ru.windcorp.progressia.test.gen.Fields.*; + +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.world.generation.planet.Planet; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; + +public class TestHeightMap implements SurfaceFloatField { + + private final SurfaceFloatField shape; + + public TestHeightMap( + Planet planet, + float cutoffThickness, + Fields fields + ) { + + for (AbsFace face : AbsFace.getFaces()) { + + Field landmassDistribution = scale(octaves(fields.primitive(), 2, 5), 400); + Field landmasses = tweak(squash(landmassDistribution, 4), 1, 20, -20); + + Field plainsSelector = squash(withMin(landmassDistribution, 0), 10); + Field plains = tweak(octaves(fields.primitive(), 2, 3), 100, 3); + + Field randomCliffSelector = scale(fields.primitive(), 200); + randomCliffSelector = add( + select(randomCliffSelector, +0.7, 0.3), + amplify(select(randomCliffSelector, -0.7, 0.3), -1) + ); + Field randomCliffs = octaves(scale(fields.primitive(), 300), 3, 5); + + Field shoreCliffSelector = withMin(scale(fields.primitive(), 200), 0); + Field shoreCliffs = add( + landmassDistribution, + tweak(octaves(fields.primitive(), 2, 3), 50, 0.2) + ); + + fields.register("Test:CliffSelector", face, multiply( + shoreCliffSelector, + bias(select(shoreCliffs, 0, 0.07), 0) + )); + + fields.register("Test:Height", face, cutoff(add( + landmasses, + multiply(plains, plainsSelector), + multiply(amplify(cliff(randomCliffs, 0, 0.5, 0.03), 10), randomCliffSelector), + multiply(tweak(cliff(shoreCliffs, 0, 0.5, 0.03), 1, 15, 15), shoreCliffSelector) + ), planet, cutoffThickness)); + + } + + this.shape = fields.get("Test:Height"); + } + + @Override + public float get(AbsFace face, float x, float y) { + return (float) shape.get(face, x, y); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java deleted file mode 100644 index 8112105..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestTerrainGenerator.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.test.gen; - -import kdotjpg.opensimplex2.areagen.OpenSimplex2S; -import ru.windcorp.progressia.server.world.DefaultWorldLogic; - -class TestTerrainGenerator { - - @FunctionalInterface - private interface Func2D { - double compute(double x, double y); - } - - private final OpenSimplex2S noise; - private final Func2D shape; - - public TestTerrainGenerator(TestWorldGenerator testWorldGenerator, DefaultWorldLogic world) { - this.noise = new OpenSimplex2S("We're getting somewhere".hashCode()); - - Func2D plainsHeight = tweak( - octaves( - tweak(primitive(), 0.01, 0.5), - 2, - 3 - ), - 1, - 0.2, - 0.2 - ); - - Func2D mountainsHeight = tweak( - octaves( - ridge(tweak(primitive(), 0.01, 1)), - 2, - 1.5, - 12 - ), - 1, - 3 - ); - - Func2D mountainousity = tweak( - octaves( - tweak(primitive(), 0.007, 1), - 2, - 3 - ), - 1, - 1, - -0.25 - ); - - shape = tweak( - add(multiply(squash(mountainousity, 10), mountainsHeight), plainsHeight), - 0.001, - 1000, - 0 - ); - } - - public void compute(int startX, int startY, double[][] heightMap, double[][] slopeMap) { - for (int x = 0; x < heightMap.length; ++x) { - for (int y = 0; y < heightMap.length; ++y) { - heightMap[x][y] = shape.compute(x + startX, y + startY); - slopeMap[x][y] = computeSlope(shape, x + startX, y + startY, heightMap[x][y]); - } - } - } - - private double computeSlope(Func2D f, double x0, double y0, double f0) { - double di = 0.5; - - double dfdx = (f.compute(x0 + di, y0) - f0) / di; - double dfdy = (f.compute(x0, y0 + di) - f0) / di; - - return Math.hypot(dfdx, dfdy); - } - - /* - * Utility functions - */ - - private Func2D primitive() { - return noise::noise2; - } - - private Func2D add(Func2D a, Func2D b) { - return (x, y) -> a.compute(x, y) + b.compute(x, y); - } - - private Func2D multiply(Func2D a, Func2D b) { - return (x, y) -> a.compute(x, y) * b.compute(x, y); - } - - private Func2D tweak(Func2D f, double scale, double amplitude, double bias) { - return (x, y) -> f.compute(x * scale, y * scale) * amplitude + bias; - } - - private Func2D tweak(Func2D f, double scale, double amplitude) { - return tweak(f, scale, amplitude, 0); - } - - private Func2D octaves(Func2D f, double scaleFactor, double amplitudeFactor, int octaves) { - return (x, y) -> { - double result = 0; - - double scale = 1; - double amplitude = 1; - - for (int i = 0; i < octaves; ++i) { - result += f.compute(x * scale, y * scale) * amplitude; - scale *= scaleFactor; - amplitude /= amplitudeFactor; - } - - return result; - }; - } - - private Func2D octaves(Func2D f, double factor, int octaves) { - return octaves(f, factor, factor, octaves); - } - - private Func2D squash(Func2D f, double slope) { - return (x, y) -> 1 / (1 + Math.exp(-slope * f.compute(x, y))); - } - - private Func2D ridge(Func2D f) { - return (x, y) -> { - double result = 1 - Math.abs(f.compute(x, y)); - return result * result; - }; - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java new file mode 100644 index 0000000..d08862e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java @@ -0,0 +1,69 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class TestTreeFeature extends MultiblockVegetationFeature { + + private final BlockData trunk = BlockDataRegistry.getInstance().get("Test:Log"); + private final BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); + + public TestTreeFeature(String id, SurfaceFloatField selector) { + super(id, selector, 10 * 10); + } + + @Override + protected void grow(SurfaceBlockContext context, double selectorValue) { + + Vec3i start = context.getLocation().add_(0, 0, 1); + Vec3i center = start.add_(0); + + double size = selectorValue * randomDouble(context, 0.8, 1.2); + + int height = (int) stretch(size, 3, 7); + for (; center.z < start.z + height; ++center.z) { + context.setBlock(center, trunk); + } + + double branchHorDistance = 0; + + do { + double branchSize = 0.5 + randomDouble(context, 1, 2) * size; + double branchHorAngle = randomDouble(context, 0, 2 * Math.PI); + int branchVertOffset = (int) randomDouble(context, -2, 0); + + Vec3i branchCenter = center.add_( + (int) (Math.sin(branchHorAngle) * branchHorDistance), + (int) (Math.cos(branchHorAngle) * branchHorDistance), + branchVertOffset + ); + + iterateBlob(branchCenter, 1 * branchSize, 2.3 * branchSize, 0.5, 3, p -> { + setLeaves(context, p, leaves); + }); + + branchHorDistance = randomDouble(context, 0.7, 1.5); + } while (context.getRandom().nextInt(8) > 1); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java deleted file mode 100644 index 75d4eb0..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package ru.windcorp.progressia.test.gen; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Random; - -import glm.vec._3.Vec3; -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.VectorUtil; -import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.DefaultChunkData; -import ru.windcorp.progressia.common.world.Coordinates; -import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.DefaultWorldData; -import ru.windcorp.progressia.common.world.WorldDataListener; -import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.common.world.tile.TileData; -import ru.windcorp.progressia.common.world.tile.TileDataRegistry; -import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.generation.AbstractWorldGenerator; - -public class TestWorldGenerator extends AbstractWorldGenerator { - - private final TestTerrainGenerator terrainGen; - - public TestWorldGenerator(Server server) { - super("Test:WorldGenerator", server, Boolean.class, "Test:TheGravityModel"); - this.terrainGen = new TestTerrainGenerator(this, server.getWorld()); - - getWorldData().addListener(new WorldDataListener() { - @Override - public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { - findAndPopulate(chunk.getPosition(), world); - } - }); - } - - @Override - public Vec3 suggestSpawnLocation() { - return new Vec3(8, 8, 880); - } - - @Override - protected Boolean doReadGenerationHint(DataInputStream input) throws IOException, DecodingException { - return input.readBoolean(); - } - - @Override - protected void doWriteGenerationHint(DataOutputStream output, Boolean hint) throws IOException { - output.writeBoolean(hint); - } - - @Override - protected boolean checkIsChunkReady(Boolean hint) { - return hint; - } - - @Override - public DefaultChunkData generate(Vec3i chunkPos) { - DefaultChunkData chunk = generateUnpopulated(chunkPos, getWorldData()); - getWorldData().addChunk(chunk); - return chunk; - } - - private DefaultChunkData generateUnpopulated(Vec3i chunkPos, DefaultWorldData world) { - DefaultChunkData chunk = new DefaultChunkData(chunkPos, world); - chunk.setGenerationHint(false); - - final int bpc = DefaultChunkData.BLOCKS_PER_CHUNK; - Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z); - - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); - BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - - BlockData[] granites = new BlockData[] { - BlockDataRegistry.getInstance().get("Test:GraniteGravel"), - BlockDataRegistry.getInstance().get("Test:GraniteGravel"), - BlockDataRegistry.getInstance().get("Test:GraniteCracked"), - BlockDataRegistry.getInstance().get("Test:GraniteMonolith") - }; - - double[][] heightMap = new double[bpc][bpc]; - double[][] gradMap = new double[bpc][bpc]; - - int startX = Coordinates.getInWorld(chunk.getX(), 0); - int startY = Coordinates.getInWorld(chunk.getY(), 0); - int startZ = Coordinates.getInWorld(chunk.getZ(), 0); - - terrainGen.compute(startX, startY, heightMap, gradMap); - - VectorUtil.iterateCuboid(0, 0, 0, bpc, bpc, bpc, pos -> { - double layer = pos.z - heightMap[pos.x][pos.y] + startZ; - - if (layer < -4) { - chunk.setBlock(pos, stone, false); - } else if (layer < 0) { - if (gradMap[pos.x][pos.y] > 0.5) { - BlockData granite = granites[random.nextInt(4)]; - chunk.setBlock(pos, granite, false); - } else { - chunk.setBlock(pos, dirt, false); - } - } else { - chunk.setBlock(pos, air, false); - } - }); - - return chunk; - } - - private void findAndPopulate(Vec3i changePos, DefaultWorldData world) { - VectorUtil.iterateCuboidAround(changePos, 3, candidatePos -> { - if (canBePopulated(candidatePos, world)) { - populate(candidatePos, world); - } - }); - } - - private boolean canBePopulated(Vec3i candidatePos, DefaultWorldData world) { - Vec3i cursor = Vectors.grab3i(); - - DefaultChunkData candidate = world.getChunk(candidatePos); - if (candidate == null || isChunkReady(candidate.getGenerationHint())) - return false; - - for (int dx = -1; dx <= 1; ++dx) { - cursor.x = candidatePos.x + dx; - for (int dy = -1; dy <= 1; ++dy) { - cursor.y = candidatePos.y + dy; - for (int dz = -1; dz <= 1; ++dz) { - - if ((dx | dy | dz) == 0) - continue; - - cursor.z = candidatePos.z + dz; - - DefaultChunkData chunk = world.getChunk(cursor); - if (chunk == null) { - return false; - } - - } - } - } - - Vectors.release(cursor); - return true; - } - - private void populate(Vec3i chunkPos, DefaultWorldData world) { - Random random = new Random(chunkPos.x + chunkPos.y + chunkPos.z); - - DefaultChunkData chunk = world.getChunk(chunkPos); - assert chunk != null : "Something went wrong when populating chunk at (" + chunkPos.x + "; " + chunkPos.y + "; " - + chunkPos.z + ")"; - - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); - - Vec3i biw = new Vec3i(); - - int minX = chunk.getMinX(); - int maxX = chunk.getMaxX() + 1; - int minY = chunk.getMinY(); - int maxY = chunk.getMaxY() + 1; - int minZ = chunk.getMinZ(); - int maxZ = chunk.getMaxZ() + 1; - - final int bpc = DefaultChunkData.BLOCKS_PER_CHUNK; - double[][] heightMap = new double[bpc][bpc]; - double[][] gradMap = new double[bpc][bpc]; - - terrainGen.compute(minX, minY, heightMap, gradMap); - - for (biw.x = minX; biw.x < maxX; ++biw.x) { - for (biw.y = minY; biw.y < maxY; ++biw.y) { - - for (biw.z = minZ; biw.z < maxZ + 1 && world.getBlock(biw) != air; ++biw.z) - ; - biw.z -= 1; - - if (biw.z == maxZ) - continue; - if (biw.z < minZ) - continue; - - int xic = Coordinates.convertInWorldToInChunk(biw.x); - int yic = Coordinates.convertInWorldToInChunk(biw.y); - - addTiles( - chunk, - biw, - world, - random, - world.getBlock(biw) == dirt, - heightMap[xic][yic], - gradMap[xic][yic] - ); - - } - } - - chunk.setGenerationHint(true); - } - - private void addTiles( - DefaultChunkData chunk, - Vec3i biw, - DefaultWorldData world, - Random random, - boolean isDirt, - double height, - double grad - ) { - if (isDirt) - addGrass(chunk, biw, world, random); - addDecor(chunk, biw, world, random, isDirt); - addSnow(chunk, biw, world, random, isDirt, height, grad); - } - - private void addGrass(DefaultChunkData chunk, Vec3i biw, DefaultWorldData world, Random random) { - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - TileData grass = TileDataRegistry.getInstance().get("Test:Grass"); - - world.getTiles(biw, AbsFace.POS_Z).add(grass); - - for (AbsFace face : AbsFace.getFaces()) { - if (face.getVector().z != 0) - continue; - biw.add(face.getVector()); - - if (world.getBlock(biw) == air) { - biw.sub(face.getVector()); - world.getTiles(biw, face).add(grass); - } else { - biw.sub(face.getVector()); - } - } - } - - private void addDecor(DefaultChunkData chunk, Vec3i biw, DefaultWorldData world, Random random, boolean isDirt) { - if (isDirt) { - if (random.nextInt(8) == 0) { - world.getTiles(biw, AbsFace.POS_Z).addFarthest( - TileDataRegistry.getInstance().get("Test:Sand") - ); - } - - if (random.nextInt(8) == 0) { - world.getTiles(biw, AbsFace.POS_Z).addFarthest( - TileDataRegistry.getInstance().get("Test:Stones") - ); - } - - if (random.nextInt(8) == 0) { - world.getTiles(biw, AbsFace.POS_Z).addFarthest( - TileDataRegistry.getInstance().get("Test:YellowFlowers") - ); - } - } else { - if (random.nextInt(2) == 0) { - world.getTiles(biw, AbsFace.POS_Z).addFarthest( - TileDataRegistry.getInstance().get("Test:Stones") - ); - } - } - } - - private void addSnow( - DefaultChunkData chunk, - Vec3i biw, - DefaultWorldData world, - Random random, - boolean isDirt, - double height, - double grad - ) { - if (height < 1500) - return; - - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - - double quarterChance = computeSnowQuarterChance(height, grad); - double halfChance = computeSnowHalfChance(height, grad); - double opaqueChance = computeSnowOpaqueChance(height, grad); - - for (AbsFace face : AbsFace.getFaces()) { - if (face == AbsFace.NEG_Z) - continue; - - if (face.getVector().z == 0) { - biw.add(face.getVector()); - BlockData neighbour = world.getBlock(biw); - biw.sub(face.getVector()); - - if (neighbour != air) - continue; - } - - TileData tile; - - double maxValue = height > 3000 ? 3 : (1 + 2 * ((height - 1500) / 1500)); - double value = random.nextDouble() * maxValue; - if (value < quarterChance) { - tile = TileDataRegistry.getInstance().get("Test:SnowQuarter"); - } else if ((value -= quarterChance) < halfChance) { - tile = TileDataRegistry.getInstance().get("Test:SnowHalf"); - } else if ((value -= halfChance) < opaqueChance) { - tile = TileDataRegistry.getInstance().get("Test:SnowOpaque"); - } else { - tile = null; - } - - if (tile != null) { - world.getTiles(biw, face).addFarthest(tile); - } - } - } - - private double computeSnowQuarterChance(double height, double grad) { - double heightCoeff; - - if (height < 1500) - heightCoeff = 0; - else if (height < 2000) - heightCoeff = (height - 1500) / 500; - else - heightCoeff = 1; - - if (heightCoeff < 1e-4) - return 0; - - double gradCoeff = computeSnowGradCoeff(height, grad); - return heightCoeff * gradCoeff; - } - - private double computeSnowHalfChance(double height, double grad) { - double heightCoeff; - - if (height < 2000) - heightCoeff = 0; - else if (height < 2500) - heightCoeff = (height - 2000) / 500; - else - heightCoeff = 1; - - if (heightCoeff < 1e-4) - return 0; - - double gradCoeff = computeSnowGradCoeff(height, grad); - return heightCoeff * gradCoeff; - } - - private double computeSnowOpaqueChance(double height, double grad) { - double heightCoeff; - - if (height < 2500) - heightCoeff = 0; - else if (height < 3000) - heightCoeff = (height - 2500) / 500; - else - heightCoeff = 1; - - if (heightCoeff < 1e-4) - return 0; - - double gradCoeff = computeSnowGradCoeff(height, grad); - return heightCoeff * gradCoeff; - } - - private double computeSnowGradCoeff(double height, double grad) { - final double a = -0.00466666666666667; - final double b = 12.66666666666667; - double characteristicGrad = 1 / (a * height + b); - return Math.exp(-grad / characteristicGrad); - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java b/src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java deleted file mode 100644 index 2141c63..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/planet/TestHeightMap.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test.gen.planet; - -import ru.windcorp.progressia.common.world.rels.AbsFace; -import ru.windcorp.progressia.test.gen.surface.SurfaceFloatField; - -public class TestHeightMap implements SurfaceFloatField { - - private final float cutoffPoint; - private final float cutoffDistance; - private final float amplitude; - private final float characteristicSize; - - public TestHeightMap( - float cutoffPoint, - float cutoffDistance, - float amplitude, - float characteristicSize - ) { - this.cutoffPoint = cutoffPoint; - this.cutoffDistance = cutoffDistance; - this.amplitude = amplitude; - this.characteristicSize = characteristicSize; - } - - @Override - public float get(AbsFace face, float north, float west) { - double cutoffCoefficient = 1; - cutoffCoefficient *= cutoffFunction(cutoffPoint - north); - cutoffCoefficient *= cutoffFunction(cutoffPoint + north); - cutoffCoefficient *= cutoffFunction(cutoffPoint - west); - cutoffCoefficient *= cutoffFunction(cutoffPoint + west); - - if (cutoffCoefficient == 0) { - return 0; - } - - double base = Math.sin(north / characteristicSize) * Math.sin(west / characteristicSize); - base *= amplitude; - - return (float) (base * cutoffCoefficient); - } - - private double cutoffFunction(float distanceToCutoffPoint) { - if (distanceToCutoffPoint < 0) { - return 0; - } else if (distanceToCutoffPoint < cutoffDistance) { - return (1 - Math.cos(Math.PI * distanceToCutoffPoint / cutoffDistance)) / 2; - } else { - return 1; - } - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java deleted file mode 100644 index 01a98f0..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceCachingFloatField.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test.gen.surface; - -import ru.windcorp.progressia.common.util.namespaces.Namespaced; -import ru.windcorp.progressia.common.world.rels.AbsFace; - -/** - * A scalar field defined on a plane. For each pair of {@code float}s (north; west) a single {@code float} is defined by this object. - */ -public abstract class SurfaceCachingFloatField extends Namespaced implements SurfaceFloatField { - - private final int levels; - - private SurfaceFieldRegistry registry = null; - private int index; - - public SurfaceCachingFloatField(String id, int levels) { - super(id); - this.levels = levels; - } - - int getIndex() { - if (getRegistry() == null) { - throw new IllegalStateException("No registry assigned to field " + this); - } - return index; - } - - void setIndex(int index) { - if (getRegistry() == null) { - throw new IllegalStateException("No registry assigned to field " + this); - } - this.index = index; - } - - SurfaceFieldRegistry getRegistry() { - return registry; - } - - void setRegistry(SurfaceFieldRegistry registry) { - this.registry = registry; - } - - public int getLevels() { - return levels; - } - - protected abstract float computeDetailAt(AbsFace surface, int level, float north, float west); - - @Override - public float get(AbsFace surface, float north, float west) { - float result = 0; - - for (int level = 0; level < getLevels(); ++level) { - result += computeDetailAt(surface, level, north, west); - } - - return result; - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java deleted file mode 100644 index f1decd4..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceFieldRegistry.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test.gen.surface; - -public class SurfaceFieldRegistry { - - private int nextIndex = 0; - - public void register(SurfaceCachingFloatField field) { - field.setIndex(nextIndex); - nextIndex++; - } - -} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java deleted file mode 100644 index ad1ec39..0000000 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceNodeStorage.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Progressia - * Copyright (C) 2020-2021 Wind Corporation and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package ru.windcorp.progressia.test.gen.surface; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -import gnu.trove.map.TLongObjectMap; -import gnu.trove.map.hash.TLongObjectHashMap; -import ru.windcorp.progressia.common.util.CoordinatePacker; -import ru.windcorp.progressia.common.world.DecodingException; - -public class SurfaceNodeStorage { - - public static class Node { -// private float[] floats; - } - - private final TLongObjectMap map = new TLongObjectHashMap<>(); - - public Node getNode(int north, int west) { - return map.get(CoordinatePacker.pack2IntsIntoLong(north, west)); - } - - public boolean hasNode(int north, int west) { - return map.containsKey(CoordinatePacker.pack2IntsIntoLong(north, west)); - } - - public void put(int north, int west, Node node) { - map.put(CoordinatePacker.pack2IntsIntoLong(north, west), node); - } - - public void read(DataInput input) throws IOException, DecodingException { - System.err.println("PlaneNodeMap.read did nothing because nobody implemented it yet"); - } - - public void write(DataOutput output) throws IOException { - System.err.println("PlaneNodeMap.write did nothing because nobody implemented it yet"); - } - -} From 6f90bf345b13f093d3298d6dec2bde9f80818f37 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 20 Aug 2021 21:37:49 +0300 Subject: [PATCH 59/63] Incremented version and made some small changes - Version is now pre-alpha 2. Yay? - Removed compass display in the lower-left - The cross can now be hidden by pressing F1 - Does not hide LayerAbout though - Generator spawns the player in the middle of a surface rather than at its edge --- .../generation/planet/PlanetGenerator.java | 2 +- .../windcorp/progressia/test/LayerAbout.java | 2 +- .../windcorp/progressia/test/LayerTestUI.java | 62 +++---------------- 3 files changed, 10 insertions(+), 56 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java index 1d31417..b568639 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java @@ -69,7 +69,7 @@ public class PlanetGenerator extends AbstractWorldGenerator { @Override public Vec3 suggestSpawnLocation() { - return new Vec3(407f, 1f, getPlanet().getRadius() + 10); + return new Vec3(7f, 1f, getPlanet().getRadius() + 10); } @Override diff --git a/src/main/java/ru/windcorp/progressia/test/LayerAbout.java b/src/main/java/ru/windcorp/progressia/test/LayerAbout.java index 7b45fd4..334b462 100644 --- a/src/main/java/ru/windcorp/progressia/test/LayerAbout.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerAbout.java @@ -50,7 +50,7 @@ public class LayerAbout extends GUILayer { new Label( "Version", font, - new MutableStringLocalized("LayerAbout.Version").format("pre-alpha 1") + new MutableStringLocalized("LayerAbout.Version").format("pre-alpha 2") ) ); diff --git a/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java b/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java index 7962ca1..19c10aa 100755 --- a/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java +++ b/src/main/java/ru/windcorp/progressia/test/LayerTestUI.java @@ -15,14 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import org.lwjgl.glfw.GLFW; import com.google.common.eventbus.Subscribe; -import glm.mat._4.Mat4; import glm.vec._4.Vec4; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; @@ -30,9 +29,6 @@ import ru.windcorp.progressia.client.graphics.flat.AssembledFlatLayer; import ru.windcorp.progressia.client.graphics.flat.RenderTarget; import ru.windcorp.progressia.client.graphics.input.KeyEvent; import ru.windcorp.progressia.client.graphics.input.bus.Input; -import ru.windcorp.progressia.client.graphics.model.LambdaModel; -import ru.windcorp.progressia.client.graphics.texture.SimpleTextures; -import ru.windcorp.progressia.client.graphics.texture.Texture; public class LayerTestUI extends AssembledFlatLayer { @@ -42,55 +38,13 @@ public class LayerTestUI extends AssembledFlatLayer { GraphicsInterface.subscribeToInputEvents(this); } - private boolean flag = false; - - private static final int SCALE = 4; - private static final int TEX_SIZE = 16 * SCALE; - private static final int TEX_SHADOW = SCALE / 2; - private static final int BORDER = 5; - private static final int HEIGHT = TEX_SIZE + 4 * BORDER; - private static final int WIDTH = HEIGHT; + private boolean drawUI = true; @Override protected void assemble(RenderTarget target) { - final int boxColor = flag ? 0xFFEE8888 : 0xFFEEEE88; - final int borderColor = flag ? 0xFFAA4444 : 0xFFAAAA44; - final int boxShadowColor = flag ? 0xFF440000 : 0xFF444400; - - int x = 2 * BORDER; - int y = 2 * BORDER; - - target.fill(x + BORDER, y - BORDER, WIDTH, HEIGHT, boxShadowColor); - target.fill(x - 1, y - 1, WIDTH + 2, HEIGHT + 2, boxShadowColor); - target.fill(x, y, WIDTH, HEIGHT, borderColor); - target.fill(x + BORDER, y + BORDER, WIDTH - 2 * BORDER, HEIGHT - 2 * BORDER, boxColor); - - target.pushTransform(new Mat4().identity().translate(x + 2 * BORDER, y + 2 * BORDER, 0)); - - final Texture compassBg = SimpleTextures.get("compass_icon"); - final Texture compassFg = SimpleTextures.get("compass_icon_arrow"); - - target.drawTexture(TEX_SHADOW, -TEX_SHADOW, TEX_SIZE, TEX_SIZE, Colors.BLACK, compassBg); - target.drawTexture(0, 0, TEX_SIZE, TEX_SIZE, compassBg); - - target.addCustomRenderer( - new LambdaModel( - LambdaModel.lambdaBuilder() - .addDynamicPart( - target.createRectagle(0, 0, TEX_SIZE, TEX_SIZE, Colors.WHITE, compassFg), - mat -> mat.translate(TEX_SIZE / 2, TEX_SIZE / 2, 0) - .rotateZ(getCompassRotation()) - .translate(-TEX_SIZE / 2, -TEX_SIZE / 2, 0) - ) - ) - ); - target.popTransform(); - - drawCross(target); - } - - private double getCompassRotation() { - return 0; + if (drawUI) { + drawCross(target); + } } private void drawCross(RenderTarget target) { @@ -138,16 +92,16 @@ public class LayerTestUI extends AssembledFlatLayer { @Override protected void handleInput(Input input) { - + // Do nothing } @Subscribe public void onKeyEvent(KeyEvent event) { - if (event.isRepeat() || event.getKey() != GLFW.GLFW_KEY_LEFT_CONTROL) { + if (!event.isPress() || event.getKey() != GLFW.GLFW_KEY_F1) { return; } - flag = event.isPress(); + drawUI = !drawUI; invalidate(); } From 4f620b72619db8d6d0fbc43ebefe9bcd105176ed Mon Sep 17 00:00:00 2001 From: IvanZ Date: Sat, 21 Aug 2021 17:44:01 +0300 Subject: [PATCH 60/63] Added 6 more types of rocks - Added black granite, dolomite, eclogite, gabbro, limestone and marble - Monolith, cracked, gravel and sand variants - Renamed Test:Granite to Test:RedGranite - Added red granite sand --- .../windcorp/progressia/test/TestContent.java | 40 +++++++++++++++--- .../test/gen/TestGenerationConfig.java | 6 +-- .../textures/blocks/BlackGraniteCracked.png | Bin 0 -> 2051 bytes .../textures/blocks/BlackGraniteGravel.png | Bin 0 -> 2078 bytes .../textures/blocks/BlackGraniteMonolith.png | Bin 0 -> 1962 bytes .../textures/blocks/BlackGraniteSand.png | Bin 0 -> 2211 bytes .../textures/blocks/DolomiteCracked.png | Bin 0 -> 2156 bytes .../assets/textures/blocks/DolomiteGravel.png | Bin 0 -> 2229 bytes .../textures/blocks/DolomiteMonolith.png | Bin 0 -> 2026 bytes .../assets/textures/blocks/DolomiteSand.png | Bin 0 -> 2261 bytes .../textures/blocks/EclogiteCracked.png | Bin 0 -> 2235 bytes .../assets/textures/blocks/EclogiteGravel.png | Bin 0 -> 2235 bytes .../textures/blocks/EclogiteMonolith.png | Bin 0 -> 2132 bytes .../assets/textures/blocks/EclogiteSand.png | Bin 0 -> 2298 bytes .../assets/textures/blocks/GabbroCracked.png | Bin 0 -> 2291 bytes .../assets/textures/blocks/GabbroGravel.png | Bin 0 -> 2311 bytes .../assets/textures/blocks/GabbroMonolith.png | Bin 0 -> 2254 bytes .../assets/textures/blocks/GabbroSand.png | Bin 0 -> 2167 bytes .../assets/textures/blocks/GraniteCracked.png | Bin 7700 -> 0 bytes .../assets/textures/blocks/GraniteGravel.png | Bin 8882 -> 0 bytes .../textures/blocks/LimestoneCracked.png | Bin 0 -> 1919 bytes .../textures/blocks/LimestoneGravel.png | Bin 0 -> 1998 bytes .../textures/blocks/LimestoneMonolith.png | Bin 0 -> 1602 bytes .../assets/textures/blocks/LimestoneSand.png | Bin 0 -> 2017 bytes .../assets/textures/blocks/MarbleCracked.png | Bin 0 -> 1877 bytes .../assets/textures/blocks/MarbleGravel.png | Bin 0 -> 2098 bytes .../assets/textures/blocks/MarbleMonolith.png | Bin 0 -> 1844 bytes .../assets/textures/blocks/MarbleSand.png | Bin 0 -> 2202 bytes .../textures/blocks/RedGraniteCracked.png | Bin 0 -> 8017 bytes .../textures/blocks/RedGraniteGravel.png | Bin 0 -> 9110 bytes ...iteMonolith.png => RedGraniteMonolith.png} | Bin .../assets/textures/blocks/RedGraniteSand.png | Bin 0 -> 10019 bytes 32 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/assets/textures/blocks/BlackGraniteCracked.png create mode 100644 src/main/resources/assets/textures/blocks/BlackGraniteGravel.png create mode 100644 src/main/resources/assets/textures/blocks/BlackGraniteMonolith.png create mode 100644 src/main/resources/assets/textures/blocks/BlackGraniteSand.png create mode 100644 src/main/resources/assets/textures/blocks/DolomiteCracked.png create mode 100644 src/main/resources/assets/textures/blocks/DolomiteGravel.png create mode 100644 src/main/resources/assets/textures/blocks/DolomiteMonolith.png create mode 100644 src/main/resources/assets/textures/blocks/DolomiteSand.png create mode 100644 src/main/resources/assets/textures/blocks/EclogiteCracked.png create mode 100644 src/main/resources/assets/textures/blocks/EclogiteGravel.png create mode 100644 src/main/resources/assets/textures/blocks/EclogiteMonolith.png create mode 100644 src/main/resources/assets/textures/blocks/EclogiteSand.png create mode 100644 src/main/resources/assets/textures/blocks/GabbroCracked.png create mode 100644 src/main/resources/assets/textures/blocks/GabbroGravel.png create mode 100644 src/main/resources/assets/textures/blocks/GabbroMonolith.png create mode 100644 src/main/resources/assets/textures/blocks/GabbroSand.png delete mode 100644 src/main/resources/assets/textures/blocks/GraniteCracked.png delete mode 100644 src/main/resources/assets/textures/blocks/GraniteGravel.png create mode 100644 src/main/resources/assets/textures/blocks/LimestoneCracked.png create mode 100644 src/main/resources/assets/textures/blocks/LimestoneGravel.png create mode 100644 src/main/resources/assets/textures/blocks/LimestoneMonolith.png create mode 100644 src/main/resources/assets/textures/blocks/LimestoneSand.png create mode 100644 src/main/resources/assets/textures/blocks/MarbleCracked.png create mode 100644 src/main/resources/assets/textures/blocks/MarbleGravel.png create mode 100644 src/main/resources/assets/textures/blocks/MarbleMonolith.png create mode 100644 src/main/resources/assets/textures/blocks/MarbleSand.png create mode 100644 src/main/resources/assets/textures/blocks/RedGraniteCracked.png create mode 100644 src/main/resources/assets/textures/blocks/RedGraniteGravel.png rename src/main/resources/assets/textures/blocks/{GraniteMonolith.png => RedGraniteMonolith.png} (100%) create mode 100644 src/main/resources/assets/textures/blocks/RedGraniteSand.png diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index b8a5b33..9e868b4 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -29,6 +29,8 @@ import java.util.Set; import java.util.function.Consumer; import org.lwjgl.glfw.GLFW; +import com.google.common.collect.ImmutableList; + import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.audio.Sound; @@ -101,13 +103,7 @@ public class TestContent { register(new BlockRenderOpaqueCube("Test:Stone", getBlockTexture("Stone"))); register(new BlockLogic("Test:Stone")); - for (String type : new String[] { "Monolith", "Cracked", "Gravel" }) { - String id = "Test:Granite" + type; - - register(new BlockData(id)); - register(new BlockRenderOpaqueCube(id, getBlockTexture("Granite" + type))); - register(new BlockLogic(id)); - } + registerRocks(); register(new BlockData("Test:Brick")); register(new BlockRenderOpaqueCube("Test:Brick", getBlockTexture("Brick"))); @@ -153,6 +149,36 @@ public class TestContent { } + private static void registerRocks() { + List rockNames = ImmutableList.of( + "BlackGranite", + "Dolomite", + "Eclogite", + "Gabbro", + "Limestone", + "Marble", + "RedGranite" + ); + + List rockVariants = ImmutableList.of( + "Monolith", + "Cracked", + "Gravel", + "Sand" + ); + + for (String name : rockNames) { + for (String variant : rockVariants) { + String fullName = name + variant; + String id = "Test:" + fullName; + + register(new BlockData(id)); + register(new BlockRenderOpaqueCube(id, getBlockTexture(fullName))); + register(new BlockLogic(id)); + } + } + } + private static void registerTiles() { Set placeableBlacklist = new HashSet<>(); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java index b4ed652..22a66d7 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java @@ -68,9 +68,9 @@ public class TestGenerationConfig { } private static void registerTerrainLayers(FloatRangeMap layers) { - BlockData granite = BlockDataRegistry.getInstance().get("Test:GraniteMonolith"); - BlockData graniteCracked = BlockDataRegistry.getInstance().get("Test:GraniteCracked"); - BlockData graniteGravel = BlockDataRegistry.getInstance().get("Test:GraniteGravel"); + BlockData granite = BlockDataRegistry.getInstance().get("Test:RedGraniteMonolith"); + BlockData graniteCracked = BlockDataRegistry.getInstance().get("Test:RedGraniteCracked"); + BlockData graniteGravel = BlockDataRegistry.getInstance().get("Test:RedGraniteGravel"); BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); diff --git a/src/main/resources/assets/textures/blocks/BlackGraniteCracked.png b/src/main/resources/assets/textures/blocks/BlackGraniteCracked.png new file mode 100644 index 0000000000000000000000000000000000000000..5d3afa4706d14489547053b72d0ad9c78b72256b GIT binary patch literal 2051 zcmV+e2>kbnP)EX>4Tx04R}tkv&MmKpe$iQ>7v;9oj*}AwzX)K~%(1s#pXIrLEAagUO{|(8Q3W zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi;))n}g@7<3h$AF1Q%~m>^6(sA_we!cF2S?B&;2<Nu%s>LxK48fDJ&w53`EFipoTguBxu!0F_ESHq=$dl@n^^-ldA?s zj(KcAh2;3b|KNAGW_fbLO$sJ~{ukT+7zF~mK)Y$%-^aGyJ^}pCz?IhZZ?u4!Ptu!R zEp`Niw}Ff6t|spRmpj1FlP(#OBl&3xkM>^7x z&N-j>{U81~CP_lJ-STO<qVIc(vf}c^IWJyZ;0FO(E8;lj z-*5hf(h_Y9QfbC<Dh?SDc=mBlA3G^R!`b z7ULTj9kZi3Z{L2;z9@0yNWR~5_wgfb-*bF&!Z287vpHHDtQ*O)4Ph985I8qd)eYNh z%P!B+%jJ^YE+-6p!Zg8JM_t!|%R82IqvmZ$ZK z#o~lX9FylcWm#}&4rr~>QYzAEN}433Ny6jfBVD&)7zUJ*9O|0O>nlzcr>xg&+NNO= zMU?x3Z~yjJwARdKb3ET;GMSL3F>TXwcXy9xJhbO~bVW;+W%PZ|6AE~5{3cRT84h$^8AAOaG+(^IrIG);q2lD=(dn*&|jBBbEIKm5Sv z>4_kWP*;~%--Kbv=U;q=8%N5r{JCVo@zLV>bd02F%K7OTWmS;xa*Xd0Mj=rcV6-9# zL!?yC%NhoRRE*A|{UG4gFJ9yO0a{fkB{9a}8I9HgU-<;y5k*n3-DOl|O*&0!n+BXi z2#`{swLxnSfJqdwTs|-i7Oj-R4wkAaDT;!oX)&IM9|YuCMifPKeNUe6Dfb0J3Z#_y zK|t3w*kQo;ecHA~Yr{B>^g|Cq&<{P@TF3jF8$91fYRxb>1Op#$Z+UJ3j4||Ghv)gv znpB*goRaTzs&bD2n!^D^OWXAv>KZ=?kV2xuTxxBi@ z7>~{7iKaP_PG>Yti=ImC(4&nZ-{tJGjM0r$Wy$rcmuRHq`qfL8clQ+goVIC5r&E$N z<8I8o9#3FjHjvV8Yv}3 zQ813MI62|f>(^|ao><=B)3y!H`G6zv0(2Ngv~7bi9#Z)%@9$Wz*L?BiujslS1PsG~ zb(Yh`Db_i(F?fDJRaX>6fgLQ_c7yMGXsvNLq!a{!j|_qUr8Nk_`fYs5G??NrJxU1Pzki3|nL$DbnnQ!p1~-n>^#Lga`7XouJ)ZA# hyg1=$y{4*a{s#=NI-)Rwc&PvY002ovPDHLkV1mEi)xZD% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/BlackGraniteGravel.png b/src/main/resources/assets/textures/blocks/BlackGraniteGravel.png new file mode 100644 index 0000000000000000000000000000000000000000..bd49f48603a62c4724dd4a92d67a846b3c1ec138 GIT binary patch literal 2078 zcmV+(2;ujMP)EX>4Tx04R}tkv&MmKpe$iQ>7v;9oj*}AwzX)K~%(1s#pXIrLEAagUO{|(8Q3W zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi;))n}g@7<3h$AF1Q%~m>^6(sA_we!cF2S?B&;2<Nu%s>LxK48fDJ&w53`EFipoTguBxu!0F_ESHq=$dl@n^^-ldA?s zj(KcAh2;3b|KNAGW_fbLO$sJ~{ukT+7zF~mK)Y$%-^aGyJ^}pCz?IhZZ?u4!Ptu!R zEp`Niw}Ff6t|spRmpj1FlP(#OBl&3x8HPSmDV(EOHkD30m%`-DLVKv9$kArY=XYfW1>Tz~V5+2s{wSt7G6Bg+odb%nK-B0phl zhqYik5JIq6Eb%>$UYar;k8vD9nhrUgPPE1l2N6l!qtqqBb;%3OcDJRfYUGFa?^!Na zOwZ3L@)OI&65+bkRm&ke;5gt4K@bG=l7zA>Ns^d2i7B;4DaC%jB@7~l!y%O}IUX~b zw!xSdk?k|CUR`rBoAHP5f4~?+mSt?W8``GET8r&E-hTT#I@?icO=mlFsrk>p|3z7r zSYuJ1q~Gt;>m_u?;&dHKD&)oG3}Xzt-Ht_7A;inky3Qhmhg6cXC|Ix8;5fulOw%;{ z^B;dl>xy2lPcj}5h5^PHCX)$)=QIEMl~=D{BYodzyGDH)O{n&kv8t5AWVl6vYc*JOKxm zizQ(aBU~5H4{?M`nV$ggltL;+nht5(mZoWFDov$JmWu^-U88kHQ`dMwfNbgpAp}4E z_*ZuOjMZ|5)*3p8Q98odmecXTpx@(sJmG$R&vLnh<7~l#ADII**C-6obk4GM!9yuJ2G);p&9a%jKl3q+z z)trsTL{SVt97U{F8?r1zMsdvJ!y`>q(X<9@JEAzom6B|?BZ?yGrXkA?qXS8jN@&o)JAj=LkP0L{L!mvCq zkYO0{FrOoY;NpD7?CO%iAmw;C(6lYa8cbyf!;tNEgX_BZLBMb{LTgQ)=U8j;e2>X= z%66A=JRYfZNfIZ>&mTT8NQVT0&w8`s?YD1vetclF+hL5sT8l0V@>32D+k1rxD;{utc}@JAMoeqaS|jDlMDs8A^!q)0Pa=fCT0;={$RG%4 zO$(00VV{BH;Q1b(K7GO(iz_9L(;*zeX1gU#Q-muB!-(hS1#R1MfA^XGphp<^v~`U& z2FG!@m|Y>7w#D}Yz~TA%nK(&srQ*%aTY7^5mDYIb#kTW2r!@x05hx{@PA3Q<=nn=c z*X8l?iO+X;2-ihPkL7ZO%ugqDRdLwwdG*aVxUOKo&uH5QhmPrVg6m3x&}X~Zve|52 zp89Zz?|b;3qG=jhBiL;=2q6dppVKizDi^t0ZRk3KQVKutNaBS1yF0eq4N6MlBq2=$ zjJ2H4F8Dg1Q{*|7u4v6m)B%U4X;4ZM#W82&33s19u~~2UKaa&wYV>6a8UO$Q07*qo IM6N<$fEX>4Tx04R}tkv&MmKpe$iQ>7v;9oj*}AwzX)K~%(1s#pXIrLEAagUO{|(8Q3W zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi;))n}g@7<3h$AF1Q%~m>^6(sA_we!cF2S?B&;2<Nu%s>LxK48fDJ&w53`EFipoTguBxu!0F_ESHq=$dl@n^^-ldA?s zj(KcAh2;3b|KNAGW_fbLO$sJ~{ukT+7zF~mK)Y$%-^aGyJ^}pCz?IhZZ?u4!Ptu!R zEp`Niw}Ff6t|spRmpj1FlP(#OBl&3xKTAF2Qp zx~fO2DN&Rb{vPDL?GxEPi0|p}LQ;GUBzvf?2{XK)Zjh0Y@1^+Xzy4h|n+-8We*5hY z%=1hs1xn`kZ$F7Ku*@_2!vP`S@xvq6OOGI9Ov5xSyqqrNoLS}xr8QmGaXMXCnFe`x zIAEP47nr66=R8#f)>@8td!C+NFsl_xNsKZ4`2Le_-BO8~#u!Qw=wYHD$T_2wk-Iksob$+U-@b9Z_HY!Y~YY7g^?oMk}%~VxBEZ)})kZ z8pD2f$Mf?u&RV**#V!_SEipzwFi#_0*RkEMan^CZTqy;lZZv*yTrL-KE)-z9-4S9$ zNr{v-<2bU+mXtGH+aZMDa(SV@-k2AQ(haM&C8b0Rkq-}#IPXCSWKM|?10h7DoX9z& zwMJ=;_a5sUX2*ay!29

      uJxybf^+a7)D5cO!BBh|I8;rhV7zSMM04&QwE(LN%2&gK7lnN;|0D?lv1#2Br zDMgBjX&M=Z0c#yfYZ_x1ZZ}NRP}Mc_yl}l<@!nC@HA+gnv!oblng-__QYuO*gcv{w zG9c@!=6pV5t)-IkSGSoTKYk)*jZz9qVHyXT#$cBPsWkV;BmJ#s8gB@|E(-{U^8x1^ zo6UyJW{aHXk=rm5V`8(}AnS@0BlpK6(>zmhCIrX3hxaI@(OR==TOJ=juxdMAo-0xe zNTuknJ=eGSiJEzNqloB~->@rhV zHMX|wwmXb5jN`yO&rH)o%8`$UJO20WzwGu09v<>HzPs#~nH1j-DRTaZ9PzoIH@7e8kq?9N{kaEHM0A!3dRI61> z$**EFtCmU#re(oH@Cz5^)uc_O3A!?`xd1n^SmGsg!HO~Tr!PmkWzAY zx95E6i7AnCCZvR}DpCsEZZq<9zG94K8YjH>?DspyX=1odTyHm2U9&6`-Umu47}L;o wYhsAxQkdt3N(ii75T&qgSFgtt6XQ7Xf14Gl&qBV~^Z)<=07*qoM6N<$g8r(GJOBUy literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/BlackGraniteSand.png b/src/main/resources/assets/textures/blocks/BlackGraniteSand.png new file mode 100644 index 0000000000000000000000000000000000000000..71b867e90c96497803e9c0ed996f700dcd62b4cc GIT binary patch literal 2211 zcmV;U2weAxP)EX>4Tx04R}tkv&MmKpe$iQ>7v;9oj*}AwzX)K~%(1s#pXIrLEAagUO{|(8Q3W zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi;))n}g@7<3h$AF1Q%~m>^6(sA_we!cF2S?B&;2<Nu%s>LxK48fDJ&w53`EFipoTguBxu!0F_ESHq=$dl@n^^-ldA?s zj(KcAh2;3b|KNAGW_fbLO$sJ~{ukT+7zF~mK)Y$%-^aGyJ^}pCz?IhZZ?u4!Ptu!R zEp`Niw}Ff6t|spRmpj1FlP(#OBl&3xCRT&S* zoR&_R&*um~{`dpgY!+)}QLA3?@~8g+@Wtn!69{2Ub4fa#qSxtS+A9DAA%d>=X*OF} z)(S;Y$fdKaRx1tyM50HO&dMay8H8HB#%y7*+xgtx-E#HhF?a1d2Ez%X!2l(lX7BrC zG8q75Ri%A<%OMCjubxvpJ;U+VINlmbmN@JKGT9V2*Da2sVT7Azi|b~SPcAP2`2M@^ z@z!g?p%Cuc;r{L|0OoSZMg0>1a`_yUN|j2b%6K@$_kCnpW;oEvWV6_|jcG2iZHLg; zU;pbM#$p(&CHYK-SFc`CES}Ko_t3NohOt0OB+#@9mgAtPD)ZTtp|0aNYtA%{AQa-F zUS~2Iv34v@iYK(1Es~iG5m`~NtQA9DCmaePNzzA^dHVexi9`a^`~Z2qcCc0{jK!Q} zDv9H)nU2Tg3Izb#Z*R$FGrYTNqoh=3(+NT}4A;#j+NR!bApSP%pO_nr4>`nQ8tuL7`IT1+Qn#^WiC%S+BG8vptBTduAiv)}JAjU`&C%-g#*gP~47pCf*=t7^2@(G@ArEQ^Z|;ZqW5)FRV5Kmp!a)dS{c{%m`o;& z$75FZibO&rdUQkxFiewdHbbj*jU>tBiv|4MmXHuej7x+|XJ^kXYsF@>#q~V2N`>ik zMz9Y^$TGvhkjlq@+ISlTLEvxz(=>?1V)(v~=WWOp@JzB zhw)XabsWb=QWWYRIrjAd(a15=*@W|26+u>2-1QpI^?3B)5m%3%aDU$+e^SKVZYUHB zbh{n?_@_U!Fy>6A6U2C&#>0oW?wY|sM^@wyC0W^w1|z}<_}d+e*&LyJ-$9mScDo%f zU%eom%TOtoX*ST(LkhndIpop3=U(MHEFUS_RK_*?2D9ZU;@P5KF{qx7(CTC0x&A zF`to2sYnT#zz;~LlQ>(K*=&Yk8myf)f@#hPf&fWYKG?KuWLd&>918h7aZyB!$7wd- zFd7XJMUnA%jO#emYc(u;&8JVFQm$069fzbMGaHRKEtRQN>xBRD)jywGt0moT7YJc4 z790)-#^W)Xrm@{^*=#nXk|{P@mrtL3ieZ}Ajzg!{ClrE#u5%m{@!U0@>ry@|BOV>o zAL4Z+F%TeqYIU#X*d5NsZ*lQbo(C6;mdt#zUI-NmPlZ+>0l1Y`o_j&g087pgr zD8`shMp%|bK9{3?*QR~f#`8SFilRQxWHL-AQ%u z(P)&-b_0N#N}(z$yX}Uf<0FFLK)qJwmsh{=@Zkeimc`|RM+g^}7X*g`iFktD&Zp66 zZ~&G|6W{kyk_uuhMm!d$QmGIQM;ML9EX^gJ=P{ejSeeU@HMJ-dPkHm^4UOMDW;z}q z^g23$|{fU{mxyQrgS8mg+&YP}(s$EX>4Tx04R}tkv&MmKpe$iQ>CI6hgK1B$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi`@g@6Hs(2pL8nR+6}v_(bAarW+RVI`Q*kx9)Fhl#~v8_R9XN`^{2MI2F7jq-)8 z%L?Z$&T6^Jn)l={4Cb}vG}mbkBaTHRkc0>sRcxRP3sG7%QcR?1Kjz^da{Nhh$>iDq zBgZ@{P$4;f@IUz7ty!3yaFc>Dp!3DHKSqGSF3_mi_V=-EH%pV2qvfY2?_z3TSX+{ftykfE-YZh(VB zV6;ftYaZ|JYVYmeGtK^f07zhRmJ&y_%K!iX24YJ`L;&Cb%>cZLH-;1d000SaNLh0L z01m_e01m_fl`9S#00007bV*G`2jv156Co{9&o2!C00wADL_t(Y$0gE9ZXD+UK;c(^ z{WVwhSk2}nQIu#gF%T=Q zc?E9gfZgaL0tLe`d6+E;!Vodu<^1@=4}{^CMA69=L8)8hMTsm@vek%XkWlIl9luGd zStHIXrn4E##S%p+!ElKc4Xw7%WD}uDSS{zMN{MKDCJkHiFxwKP5vFZo$r4i(WO>fz zyN`H=!XICLhizNz@B6fUpW(xjcFjU9GFIaO4O^kR*WwS~{gp6I5sE?-M#%27=hQka z{`=+@QRWCrT-Rk&N*;Ox@;Ib>{)8f!pzA8pcFUu>ib$Hgem~&Jkx$dLNXMTjgdpi% z^6OQPdZWhq`E!)sPyea1X^(KXBM4%K_Y=}AClNM|uJZiQLw8-Is*>;4R8>imRR~ow zp3F&-l#bt}QYti2aMQoX(gY`GXQ)Mr42L&VNq~|jIHKaq(*v?F;Md^_q1q^(Ptd!h zwckP-IzgDDIW{^u^@hh}y5@d1Bd;pbG~@T@Clmz)Nsc2WLd`?+Btf@r;>`|JjY`w- zbir@BHcmK3dUfX8k_d}TT8#QbcB;)ZgiR20^ymQ3vG8n@JTIsK)3&GpVH5$LXQE3% z`>2bqOAN~)EedY#9!N_C-E(LjA7MA^AOtnn)t2CIbmVgqGGu-u|n1-aDGOr0Ya7HNfU z=%`iBQK!Ll9dX+qq1PK|ZUglnfB(zBC<9}Z`21O1iBnT8r9v^iGb|ItTm@v+e!{PXIXt{XJCVsnx?RQx%XJ9&H z^EsYlqbdsb_Y>-lMa{K98fd0PvYwJfVA>|=28HGG;$?^1i?@_Xj5L~iXrdyHLdX(w z&1D;;I9Wor-H>ECwq?<=4Q$tCFc@=qxQA}qWV;obX@C$+mpeQsr;P7d%O=umv5m(_ zr*p)f8bIkWoNvk3W9()JEsfE1fpc^~5pKvTjq&Ug(lF4yJ&N4~Mb%JD54-yqVcju$ zn4x$L_RNxx{XT}FA)4iqDh(03!IP5%c0oj4gt&W0NJGca6l}*OsRZFJM582Ljmb(u zfnZTc#`7&z5^{R}0?SmHJ=Z+co(nAV-kqB|rXr!?V+bX3e6ABjP0G z>UzL_yG~Il-1UY$Iyu2Kbi8zdmMs9t@(@{;eCQ2$`RA`$&ZfxKazloS*iD&CW}JWX zEm>M|{mUEX8=J*!hHDvg>n=r6;`=Q|qmb=lf~-5F(jkijwoyU4xT4n|@w+ch$f6M6 zZy^W$9;Iet6e&-iKEZD8lLcFZZctSfLI~O&A0ZT?ToObvPR(O{|3H5KL)Q&jx=x%| zT)qFm*|R6irwcU4!H^23q0y+jyuIvERu$KG_f!aEG#R1M6*1yEFmv)C<;FI@40w;#Wu`v>K>nl6ONC&)I1x@)M<70k%r0p z4|ix%U>To5SsbDOqeYCWS;#WWc>U7_n_bAB-{kD<6pEZMjG%(6>mCi)qSLCQ877M1 zuv#priVY_xM@(jGe*Wc#Zl{5+3f56UWjNH_2D(}x?}jr9MR440({9)4eVSnVdvs0? zIDC9cyj}42)hl#OMe)ywl88n}M@d%n`XeUu&F2X$i-xV^w-pq-$*b3w2<-r=>XOcW zmu9n$lEid<7op}jN=z9{P_qzeNOo~bdi@ioZ88sH2ICp^c84#&JfzGLk}OB+8f8^b irCW}UJG^~&#s2|5EX>4Tx04R}tkv&MmKpe$iQ>CI6hgK1B$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi`@g@6Hs(2pL8nR+6}v_(bAarW+RVI`Q*kx9)Fhl#~v8_R9XN`^{2MI2F7jq-)8 z%L?Z$&T6^Jn)l={4Cb}vG}mbkBaTHRkc0>sRcxRP3sG7%QcR?1Kjz^da{Nhh$>iDq zBgZ@{P$4;f@IUz7ty!3yaFc>Dp!3DHKSqGSF3_mi_V=-EH%pV2qvfY2?_z3TSX+{ftykfE-YZh(VB zV6;ftYaZ|JYVYmeGtK^f07zhRmJ&y_%K!iX24YJ`L;&Cb%>cZLH-;1d000SaNLh0L z01m_e01m_fl`9S#00007bV*G`2jv156C?_XvTh>)00yy1L_t(Y#|6R3a@&RhfZ-oI z2!cB(QX(x=Qe;VXVkb`0Ow+WT9(wAnPt*34OWvc?$7m0o>14(kx3Lp>kz%csL~-8$ z0>qAfpYZx0f6a{M9-<=g`uqQ|Sh?uBj;3qGNyfpKUopMGg=(dUA7_jw6Xvryf{-$tIXI5P(bMPjXEurqi}@5uND*rVow6a*8_YofSyL$) z5>->7y;Wzm^2kXkUw-p@3?oOgX_3#H^oDcFrpD!Em*sfC*MIn${rwKV|I?rG{18zP zSbJ;a#@-`}^(z1T*9#0YPZanpmn+ti#;|*bDnhHhN#c%B6p8!Z08@%Esuf5_C^FIqOm=ntXC}h>T`%adwTEMm*Wwq}Lzu=IsXrqeMa1dG@f*b@!I@ zUoNQRRgxrOvr$8oWE4dt2trgz#b1XgV#4KZpISl1_CxNwS4e;Sc=OwC_mf8^fNUDSv3xu;VPxqUYOD4VH65CJMs+Y(F0e2l?yB-VIV>EMkdazBoR3?*D zPCr~B`mRk*Q&>eQzP$oTAyX7eIfc3|aA-;F?``AwB8gI<(Q4tXR;(n0u?M#6(|WK; zA)ljQ=)`eC2532*#|OKJhpi&5MwRhoPIaq+s>*1&Jd!NoxjqRJY9UXh-NLAp$eRYc z?Ki9 zQsU(Rqf#exSN#0ujIY1>io~;tGKJZ4fLSb}7B)y$BQ~2GG#=!+yq_W{bKF=Y)hssj zl!Xu?iXc`?2L8&XVpZup++?v_k=P^Np7;6e(?c{xz{r~fnTTUMB!Q2=7!ai*2_j2W zv_h3Ej_5r4gq$uh8BVw#O!@rz$B0Kyj=1hkux*#|#3qbWPA~iHY+2}%K(Jh}oK1Ou ze2k$fh?303>2CDl5Y2oZ+`up$a9gSFvhG@`RS)OSOuLY zUwlOrW}Lq}W@;OZhC@O>q+yjXat2ka%KOtZ=A%CKT9H>Lw?7)rt6eUoh`EX7Y1q4Be^xb!V`!-Ee#-kyIA|S;9-eSt-^)34k8`R1LmW~UV z$o5tpNzHM0)8p__2O&wZ8g=qHjcPGRsc0~sE=iJvmFqK_+Q{os55b*NE0_4?ddSnF z#r5?qA9dQ4EDLFA^Qchd^7;;YGUUT`k3z9P7zJ!?)er>%fa8-(WJP1=!3Lrr;`#}S zrXsEZ*?(yTRV;sjt7E-b}MpY%UC?E=b#QWVDX z6^Jr>+YPKriL2W_5K%6fh_a?ptX5ER1uo9d$pA4+x#-^W)A27jUW8)gNRpH=%P1BM za=OaF;Q@XEKm6|<{o#~nM;)>_Ch|Q5;C|*KDLI6ffB#GN{``*l(&j;{iK6GQ7YkHH z!Cm_x2$annwTg-31uRzq58Dm0B%)$!j3!I2?}k(>1yo7Ii(u}B7-pHrof`6WZ$c2q zbXrX|HY)u5?gF!F(cJB@wY`Jy%y|3qC7L2pefArM!#?*nmpu8XN%!WS(bPs$6}%wE zC*@#g6TztP^7SdAvWe`40T1@~s8mV_flp4CG3AuJ;FG!|q{u_oWLADic>W_rLuZi$ z{QLXYboO?6{CJBr3UJ&t_q{$rk|BoEX>4Tx04R}tkv&MmKpe$iQ>CI6hgK1B$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi`@g@6Hs(2pL8nR+6}v_(bAarW+RVI`Q*kx9)Fhl#~v8_R9XN`^{2MI2F7jq-)8 z%L?Z$&T6^Jn)l={4Cb}vG}mbkBaTHRkc0>sRcxRP3sG7%QcR?1Kjz^da{Nhh$>iDq zBgZ@{P$4;f@IUz7ty!3yaFc>Dp!3DHKSqGSF3_mi_V=-EH%pV2qvfY2?_z3TSX+{ftykfE-YZh(VB zV6;ftYaZ|JYVYmeGtK^f07zhRmJ&y_%K!iX24YJ`L;&Cb%>cZLH-;1d000SaNLh0L z01m_e01m_fl`9S#00007bV*G`2jv156C5|iMV`q300rhrL_t(Y$0gNCk{nk7fZ_km zIn~(J-BL>y*q9+$Km;6s9hc%d>^TU*!fbFjuyIQ&bz4Vc>qR1%nlytqtcMa#$86jqH1zs4; z@)e)U4x{1I$M=lBMux6tWh2cX=!T9YOGx!hA}7WW`0CGKRMlvH9%NJtb;f!RMB2fywADE|zRTke3#L#0D6ed7~p**77{rAMaK@2^1 zj%aHchn}$ij%tFzTMdyBD-Y*DaYX3WEYmJ(|X zNtO};?WP8^$U#bO-rN(VMu;3@&C}C~+uId(kx?u*Xlv*XXI4c*^Z6&DTam9eboCWY z1PRRmr)x=~VY5ikr%qsl#}5IQShSL~-H1sFHgA_)>IN4FY#wRO6)H}w?rv$j9&y=o zN;a&VMfe7yL=`JE8Ht@p@&q|x7>1dbI`H`6NZST%x@7hBpRmP>GVQD75Sb>`-8b6_Z(=ckq`u>4jM}&}!Hs^9a646{wSGLQ7 ztXMLIKo~~i99S-LOp?-H4~!ioSpwEEr8}e%$o`3`Ezx3iN0ul=9GSi6!V)nK zGkeT%C9{GzZ(g%ZBvL1QK9yA6fL+`%^({gfWU;0A@(;=lEgW34gT`XI7=oZr%ChtQW5)>FMs<-(nL|7 zFZ}m$&m=V3=1aQjN+=tuF3|Q9r=;!}<}`iRu-k2siJH(>GX}`lw`7}FC~atl8KX4T8kXBF(K1v5$CUJ)Ks^ENWu|}boxzq!?etOUOX^$TU3^VIY zV1!_iT5O&Xg+ggVk|vz?d#=}#S8raErw(UskU{`Iv+aF?Rp7K>hz^@-WOv+?CWhE| zsBFzJ&Q!H$>>B2A#9GDBHZ<20QVPC!_kd*PR5rZq_b6lV!-RA>z3;H*=T7^sA;uZ4 zog-bY0FBL3;ymG-j@k!QlH>9MsWhj2`5GJhEOeQDW14Yq-=N z-u|AvyCCOr5ud!lA%ShaPP1kp< zZ!My~FnZ5R*^wBih8ZO1HjfK39Y*&p#T5?07*qo IM6N<$g6hoF;{X5v literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/DolomiteSand.png b/src/main/resources/assets/textures/blocks/DolomiteSand.png new file mode 100644 index 0000000000000000000000000000000000000000..b419bcf4c3623acd3d8eea850685b113c530a315 GIT binary patch literal 2261 zcmV;`2rBo9P)EX>4Tx04R}tkv&MmKpe$iQ>CI6hgK1B$WWauh>AE$6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi`@g@6Hs(2pL8nR+6}v_(bAarW+RVI`Q*kx9)Fhl#~v8_R9XN`^{2MI2F7jq-)8 z%L?Z$&T6^Jn)l={4Cb}vG}mbkBaTHRkc0>sRcxRP3sG7%QcR?1Kjz^da{Nhh$>iDq zBgZ@{P$4;f@IUz7ty!3yaFc>Dp!3DHKSqGSF3_mi_V=-EH%pV2qvfY2?_z3TSX+{ftykfE-YZh(VB zV6;ftYaZ|JYVYmeGtK^f07zhRmJ&y_%K!iX24YJ`L;&Cb%>cZLH-;1d000SaNLh0L z01m_e01m_fl`9S#00007bV*G`2jv156cH%+to!r;00z-XL_t(Y#|6RZlG=s=!0|si z03jhRAp{F}PqU71*PbNfbf)c>%=C5owIBQveS^M7XOd2vG>M&Euf1OO;=aTo4heDh z_Y3^%AAj5RyZ2=B1&mahW@mt^MrhP7F|!BQjS8oaONgNeuIm$6``lmOar(5x4?mZA zQrhSI{3B1FJt38fGqi{FS~XsO{WU-R??=SHeslaTWmq_Nhl%fUc~v763=ot9sF5gU z#zIxX%-l6U{^vcSw8Pp<69~ZR$sy(P?|k>&w}fT5xOh)8nMIArq*4jC8xY@qRe1NH zm}9%!U}g8P%s7kLgu}xpOx+3fMjLnH&}-E=I6gs(Mllj8EL@bfOuq=iHoB4DG z>jkF|A2D%VZtG3vJA>Qy3?Zm+vY$oKvlwOuJ#8XLvPRDyQNDUlI+vzeui<$<>9kI> zUSmERQ?1{isu~$n$8lQpMswbOtN=TLnnj~g}Q_0=6xD72&2 zs-lXJGc6*D!D2CIx7kr`&4}qsHam@8e}JwjXqry1d&8qci+!jVdFDu*AbRuj8uYrv4AMbELR(f`v(Zc{ig(j0*%`` zt!9UimP8Ed)Ne0%P)sv)x>z}j``ar9c8`!4;M+GZvF$E)&t~jy7_UVX&7jw=BgxR| z4LSc(MGk8Sx~9?VPskmd5>}(6(^1x|6`8$b+T9+#c7<3pOg3MjQLCT^xBPzgUqYII z8kbqkdz6kcOvV#TbB{0A9k%Nw$NPD1zkEde%cJOnPCs6q~mEu{Wg*)psFg1nZt6kqwt`Jlr*#0-8O1C zz^hlUn0sSJ-5QFjBMNJVtt$$dJe69Fk>m3HpIl_ z;Fb zA+RC0SD;*NqikKImnQ~VG|XhspjEGvOlAp%0+@R_ZYpK^_LM)pK0?x?^!iN>jt;r{ z{F#;Su-nY(cN;7`pW@M11VakVc8x+|hpC4kRz&I#nrwF_)n<)EGRGQ$Uw-*F{sNvo ze@o9kW4VpsjXe_a1eIEa;mBv~i7eJS?LNe08Q=9;thP*-F|P0XG+IL*JuDFT`JaE^ z34rfUQB)mg?6a7=NOF+rc#dJFh-(o>!x}N8$mMMnGZAO$yGTKuf!$}XkVBRPDtEu~ z@bnMNXHx<@s5Q$7+vSvn@AJ!t8@lZ-io9jLoG`F&C_UUK9ap)#z96C+IGrY66-*LZ zkcm@63=A<70%}OacYUH-7P~uQ>TbBJH_^2u!hO|74u&uiQ8F2eR`m|gb4VKnCX*o_ z&Oeee64Y+L5Y!Bo>jk&>w;UB7;0$JL0wTYE`ivA3SRVx;8?JCsY=` z&5LIx=KhvgI)@U8vG&I(VHsJLS#Jf*+#Yc~%+OiU>`vLZBhuMJ67dv@5~E!HLR8-3 zc^>-`jHOtkEvx`eg`4nTv;r#NRWZIzBzCe^#M2*L6))J+o j0`_3QZ|64%ioyQ@6YNa@_mwB(00000NkvXXu0mjf=rBB+ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/EclogiteCracked.png b/src/main/resources/assets/textures/blocks/EclogiteCracked.png new file mode 100644 index 0000000000000000000000000000000000000000..585efcfcbc6719a9a9042fe3a7a50766300c6716 GIT binary patch literal 2235 zcmV;s2t@aZP)EX>4Tx04R}tkv&MmKpe$iQ$>-AqE$p3GE^rEq9Tq`#UfZJZG~1HOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLxj8AiNQwVT3N2zhIPS;0dyl(!fKV$j)ohypRLwFH z(TJGNtco445HNr~^kPtArXEW!rrU6^NipZjxkD_N5PK9P8i>4rtTK|Hf* z>74h8gRCGa#OK8023?T&k?XR{Z=CZE3p_Juq!RPQL1HoA!g336_Voz|AXJ%nz^Y-Hz^PS+Fxw@V-)Dv1?pAX{yw(t`U&8F2ClTGzgz=mKS{4P zwa^jJvkhEaH#K<=xZDATo^;8O9LY~p$mM|dGy0|s(0>bbt+~B5_Hp_Eq^PUq8{ps& z7|T=ky2raaTYLNWOryUaQb2N=_TNs@00006VoOIv0N?=40KAGfh7@)uiT8IDvDpjkZii`HTQeS~r@VoR4KvjE#get*BMMy&eG1Ob^@p#5_ zX3m-A>{~B*hfn&1&p!LKxEVVvZD!L6 zcRM|*?KV@_=jnGp^624R)KE0%QJ>-0_#LzSXd%}9%fUsaX9dpoc@a<0{#5-$sK6-qJ zWob<2D|E}CVn~E;gf3f5oQRq2BIiIZvWimd#S+t0P<4|=-Qvb}7_EG6{g7vaTf9Wz zhrt|G*N{H=`0%J_iquV=fxAGIBt~N&*(~w&WI&oAXAu4rnFi$B)wTaYL_e`KSUM^MzaO)-@C){&6GtD@aV|_ch);N zj?2x+rrR`WuXkB*)o@31YV{KRojysH@}S>lI$JSyX2^=b;r?KJeV6T?AOOGg%a26TPWX3!UkyMqnJ2jT` z06Cg0&^PN;}~A&Tbg_5^~$BAvP{CNo3{cFSv&*4J<{7_Ab9wo4TIY^?Y2!-(Z# zN*X6T*y~~^F-a2h(e@_t$XzgST+CJ#&t9;<->226kop-?smt(mLZ@qy=Lywz15L~@ z#|vz!#N{mE8$SQ)8PehJ`$zYy zO=2(O?fo8?;}Lqjj-u$STN;DuoG?jw_Ue+*_sGH(|2cOEqL??|++w=4kyV9~Ch(`< zyv6x+&g=1vPP;^s$B1>a%6R5rRaGh*4SxIXTWE1g%`_P;5*pPOW?e^BWL}S!sGTjc z0{;BTJ3QH}@MM3Jjkd+Z2L~iVN`Jdfo~7K5XLP&kNFTm;_oxt6u56c32(b#0jk3vw zGbfE=?(ZLP72ML%bf%8SeC1QCSs${ZgLY1S;3tB5cNDX9u)Q;#%Qkwh_JnqgH8e!8|9 z-ngu{4ID2+eEjYk93CFfZr3Pscz!&jYn6#rox}Tk^m}WZo(`}bA61jtz0)R1bIykg zGD*UdOHAD*o82z5WO98qLlJXacZJjtkag9du~wn3L)a*DJ$CrVH{avuDRBbxX~1me z^Tys9{kBQXFnDyZ#rGFOE(bP(qA;`*UVZgn!Xm>g%SgG-{&t(od4kw$S&T>5+%6V~ zy2yJEcBr*19LHyNGeMRL8qEszvd%`iOi5F@8Vr!K6mJ>u`pPC3G71%%YdYixi$%;} zIHhkX$m(*+uXlEEhu2t!ilivq+uLF0rpQ8$D(7g3JU-k*Cc$;)1ms-XGfIX=y`obf zu+^*KN)kpXCia#@QHEF)i1u{B&o5rGwR?{og@qS!aXsU5FhydbAyDl~g_IyHlKyUwe@6-f}W-L>eJ%KZF#j6V<1^MHEEBFS^EXZ|mb zT;I;w>1&LGkVPtR(6^X6KCgd1B^OePLLn{+!g;{uWW|krPOa5pVFbjX!rhG)?QWZY ze)EEpWlpOm(rDKyH#4Na{_T?^Rg*Y>eM1)dWO>Tz*@RZz6*_I7L(7b{?Q<22mE$>{OB7|M2nAR?EUrG)^uiL}ASC)*2n9 zVEb3=497lsCLEX>4Tx04R}tkv&MmKpe$iQ$>-AqE$p3GE^rEq9Tq`#UfZJZG~1HOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLxj8AiNQwVT3N2zhIPS;0dyl(!fKV$j)ohypRLwFH z(TJGNtco445HNr~^kPtArXEW!rrU6^NipZjxkD_N5PK9P8i>4rtTK|Hf* z>74h8gRCGa#OK8023?T&k?XR{Z=CZE3p_Juq!RPQL1HoA!g336_Voz|AXJ%nz^Y-Hz^PS+Fxw@V-)Dv1?pAX{yw(t`U&8F2ClTGzgz=mKS{4P zwa^jJvkhEaH#K<=xZDATo^;8O9LY~p$mM|dGy0|s(0>bbt+~B5_Hp_Eq^PUq8{ps& z7|T=ky2raaTYLNWOryUaQb2N=_TNs@00006VoOIv0N?=40KAGfh7mo1_gS5&?=pv?@~J17AQwyg^^V@4_P>BqUBDC?dQ zdw6$_J!W=h=i>JhKK}S;d2it2`5{GB!73HW$(e@>npTm$b_G8XdH$k{Qjpl*U&pbB z>@`;?HyYSpz-OQTkGJ32BbfwTyy?(r*15SEP^;<)KmF*PoD9+=XQx#~SHTMtrhZ7X zs?l6BIqT05B#C;{Ku$%Rp~GU4v1G|yb*5;lil&JKVMJ9^DVhbWVu4Rz^bt3ft9<|A zF@~Ws9M32k8iyM-q#QJ*#C30qGx8{k5@aH?C}A|2QYtAFiY01QgWkx6f=Joa&?_o_ zEbvWdOubP-`rdoTClx8BY3X#l326p{+kj@h##v{8Qqsw?gkT;aN)kyJQ85(irb$tj zF^nRXC1TrC2E%}YZZc05oS{v7eF;fhGEYb{9B)QJ6tE`&PY>F>>^u0;f(PHd%ldL1 z+jbcYY+6et8mlc<>lM8Im`YV=b7zw{O*qidF|sIQ-;7vkFA>EdlUYRX#wE`sMzbm2)F(RM|P$!K#`p77Lb5fmpN1vy7QDM#&SlOF9RY8cCQTiW1$Chcok0bdw;Am`-fm zFyd&xMZI2RV*Bh^8gk#8&~ZIV^)miw!ks&tEY~cOAVtz!bT5XiHg&GLx14ny?(VN( zNiw5Z#2Y8()y20|%p!rmz%VovRi#xEsVOBcM`OgMWnt+hMwhpw^Oz)0=(r9S_G{EE z;9BNvrU@A z&)3-Gx{DD_wTSKdjAsFriUD#$JA?Di1W}TBdD)|Hj~Uog6j>oBXJk*1R9!n6x>FD! z&!D|r;oklls+f}`DOa5yd&?`Fopo8N7))mo;XFhyD17>QNZ*^GDI&`all`3*BR{}# z1C}h6MJ6CVd~%QD;{zIv3gqzW&4`v^vM3b!;JtU*-(KVS^K;zEoPsK|yU`#{GA=qE z2?F)9Nz0IUc(6^`C}WRiC}Kvk2x)DVk&6Y5+OkEp2ts0s)Ik^)f%-N6Li(2&ST#T=um;E!eeiBDOV zAQzFhYDFm28QU(aHIu5Ta@X9!@e;CRL8&AoiwZw{a?ETp=Fgv;;*S?({PVwObbGhtl7Q{`D8&-L`~5%o z?EHoWIq!b&h&y|m%;qU;s|KO(6NDL-p|U9?7)nl>#$0w?B%^7apeWcApH{g7$sA`o zC&_Y-A0Hx$8H+@KG{y6Le(>xr+uN(0cD^N^M{KnWTDr;0>jA-dPBEKP)eYh-5s4|<*vE2zftE>F-qYn|p66YP4-tCBy8#A9LO#CTp8yi#`JIGSt zk!2#Eo?deF)-I-2RpiXypcvA3p+QkTlj;>x{fPhe!Lg)|EX>4Tx04R}tkv&MmKpe$iQ$>-AqE$p3GE^rEq9Tq`#UfZJZG~1HOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4RLxj8AiNQwVT3N2zhIPS;0dyl(!fKV$j)ohypRLwFH z(TJGNtco445HNr~^kPtArXEW!rrU6^NipZjxkD_N5PK9P8i>4rtTK|Hf* z>74h8gRCGa#OK8023?T&k?XR{Z=CZE3p_Juq!RPQL1HoA!g336_Voz|AXJ%nz^Y-Hz^PS+Fxw@V-)Dv1?pAX{yw(t`U&8F2ClTGzgz=mKS{4P zwa^jJvkhEaH#K<=xZDATo^;8O9LY~p$mM|dGy0|s(0>bbt+~B5_Hp_Eq^PUq8{ps& z7|T=ky2raaTYLNWOryUaQb2N=_TNs@00006VoOIv0N?=40KAGfh7FP?ZfO)gq{JY#v$PLU!h?(Fv|KmYvq?zgWm zECQb|-`*H{J%mtrcQa>w*ix4jf!E{9>k(<0IIfMTE3$LJ-TNh*&4Dzpuw+M9#@OR) zzO7a)g8@aFB7VPrLMkfRX~Wo5k(Ufxg_qriURyz3^On@Knu*i|uBvl=HKlD@&d)23 zyAyYwgHqNs=&Uy@RJB7i71pqiP`j49!2r_<_;feJbS!*B!lh&v)eKCV<7UlrG(;eY z^ODuup1ew#IyP6X#eW{|X>G~Kb+~bThK9$tsN!iIqgrkcOBQ6sg@3NLEd2>_T5&U5 z5H}^~qQ!PxoI#&XQ|Qhq`y?SS9oAt^LxQi&h_=2r*Drut{&;j7H{aWxVfTf!09{u@W(%4*$#crVt1*~ z9g8dtnfWgAhrfROsi#0CCHp+X@H`4*Nc#K?x<*m7h&0D=4NR$XzuO}lfhkR-Y`A~f zQ8bbyZBR%Vx;Fc?Vi_1*;uIm`9M!YYdp5(tfFwF_>lGxr!y$~BdOBHjV$@0k6h2O8 zNV`u|);L!qZg1x3ItWAIoK&EIp_gpZ1XndsCnJZaFsARf)LF%NI%jvT@l*x<;}lUA zTn}{OONL?FIF3rYi8&wki4WY02?)#?uuX-Ju`22wI7y8NBWz#PAP^hDEmWJagJ(Ah;}RoHeK7Y>l!|ddf*CbLvsJ`d+b)nR(gbK&Rc#! z+?N|Z4;+%Bp{i^2BBc>3?qEXDGx=?Qg?OVOecwba8s1Ml>ZT?42!wq-6FgRp3^DfdSatg3c4uKbd}ZazgDCqzYoNRDd`rvnI$OWClF zVur5ADoc6F3TBH5vTErKe7?$(jEV~_`{;zCX!Kl_v!bE9Hr`@Pbll>~oW8KRv=`*x z{&M@1kIIMJ8}zQhF?CcwplwQQ+u|iW(enfT_w@yPUaZG-F{6^3AXtE2Z^%|+0`13Kts{w~7!tVFbH4WV~pv>78 z8J$*QN(lNc$JH86C211l*(M(cE~|5l_&6J3XeO;?@vrEGs8;Y@$%o|?;cm-*ccjiT zhPuXjb)de~yu60^&J=`2TbqPM#UDO@hgR35WrtK1c1?}%>WIp8Na7k|CIw_GtfxM&*6DIzY?Wy1p#k?FtOwHo=RKqdg!)#7qs`UGFYE|Q$#Oy99 zO{H@<9l3k|4mB^4&h6wU%~1IgZt&*;j~{tY`AvrP+Dhc%92u^7)dM>$txht)R3 zQEIfN;JkZ9Q=l;=LC@pTsl-W!CNv5~L0k{Ja9Q*BK{9%r8R&}c>!7g0000< KMNUMnLSTY?68VAv literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/EclogiteSand.png b/src/main/resources/assets/textures/blocks/EclogiteSand.png new file mode 100644 index 0000000000000000000000000000000000000000..d00b06de5dc2f40c3711e6386a5fafe4413585ef GIT binary patch literal 2298 zcmVEX>4Tx04R}tkv&MmKpe$iQ>7vmk#;EJkfAzR5EXHhDi*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RRe3JS*_Mt`=0!T!GgAu;X2I`B(Q`eQV=1djtZ)<5TjKi#YCF+;~xHD$DbmXOs)zT zITlcZ3d!+<|H1EW&EnLgn-q)#y)U-?F$x5BfmXw|zmILZbprUGfh(=!uQh?$PtqG5 zEqVkDZUYzB9ZlW?E_Z;)lP(#OBl&3x#Uk*2M&FbNLbpKwn%i4@AEysMmbzNL0S*p< zu@Yskd%U}^ySIPOwEO!3IXH5VI2XZR00006VoOIv0N?=40KAGfh7Hq%Zo?V*=Ei?4l*zCe3w4{4`uoMw;gI94RtqE<>= z1TG*65ClLFJ@k8tPx#Z*Kl(>EJyz0jN~JVseUnbJNh+-(s0oVVlzMASab=NbpMJ+$ zF~;woJm#p;r1AQKSLZkEK7L3t5aRoT1D018snp6G9bB=uUL~-!v-osk&H3%)hy3|3 z|01T$>5W}*O(JuVk>S!Xrr3tTPOX9!3NbJyoSdB_$I@)ARIogkcB4To8b*pH`TEm+ z41LTjBq9nj1ZFmW|LfoQU}uSVGQm6VY@oz4oL*`OkswR?94XV}@!nk~gE2=}4bN-+g-XK|fEE=RFcMKc_xhKt~fs8NO8jWUzo z2st!IN@w`u@R*$FvY@Ic!i@csH@rE%Bp}6DTwS2iAF{YrBcMvO-yCw)>msgZRoYsE z?|wL@KkU=$k64K(5rP62oj%!On%epza!Nr^6e6~R8;qfMZwcuJyASV@4u|>tlh4U! zA{eI4RF-LYGM8r^0*^k}dP*onv6P^^x=z2R^XB>nr`MxxP0{-XDK&%?Rfxu-{QKJz z7Ly*2?%l_nSah^5%lFo~z3q|Aq%o&1t7}UH%`v`bBMv4L+}RAJvcNx{eMdOxk&HwL zmI^E@aVCb1D@Y7)#=QCVM}GET8Btbw-5GM$>>$Yjw977~Vu3=rNb9o6;q!eEf;@is zfZ*7LdS}Skbolx921am>7z(1FU6M=|`9)sk$I~X&S{2(3l9pu-HJ#mZ1gnuYIjvym`_QM-A?UqzNjiQA4rfnikTYT~C8Qty>Uz9M0 z9%??vTnM7~hbV%}uRnaBaL~gy4KleD`p6SG+$`PIPj@yeIN>DvY|45f%Fq)rMh=>$;R|zenK=1W1|)%7?G}6iHJRY+ zgCin=AhHrBTgcOFw79pqf+&f!XC{s@L#(&EGL)C%EO5}BAciFHY~I>lMU_Re zOBIY@0R2XzP+mX|CrBr=lof^hyKfUuBzaN4;PrKvZ(klD%uLe0M6cOFT-mI0TEC*S zSmNgNl1eep%jbuv`5dC>GO#QT_YZL`6F(wj*)FzaF}i6HmSbq0Hs=>@{K=5}8|z5v zJnOYJ-rK#;U^qnh_~ZBd+ER}3XohP~aApF+YVZH#M^tDy!@eo9P$w@ zgW1?67!M*i5Re6CVHsyIWW7|RZQAI4jbJ>9=*(QaNq}5BPc)fkGBUs(vbwy&!>u)l z#E9mLeEOen$VEfk-fH~jgP&l|Jn(%Y#We2N!JAlkbBV8xkC{zOjH!z~858*EqX$pJ zB8=u!@|6N}(I+VS-1H56XO3u%8EP$R)kWqZkEN9&pM7;mDlAahC=*j;hOR|NH(0Ob zalJ5-@3XK{qSNgmc66H`&)bv}DYT0lE-ubFYxPJb6<#%(9G;$2$R;UNGT5d?!jnm4 z6o!(>)p?i8*VlAfW7f(GG_PCy^wA??S%stH3yRqiVp)yzyFWZZ45^s9$@=CtNi{=2 zQkjqYlopEE-kkG`EB3#yGalViODL405k|cp*3?GyMP_rGh@$ZPzn`$CM)7C<|3@R@ zF={rcU)O2&4c^~eCMXJ^_ep1pY~S4>o5`@fvBASTTTHw#j_G0zCUkoPLQ#eHcUBqq z#%O(qTTkL-3Z~_9a@|B!Vk%!AUNP#ANahP%cY6dRf!?i-h0XPKi&nRXF_|!(S=?Kx zFckwBjzwj$MlGFSV{Hjt0DEe(S;^6B->|t^LAR#_9(=g_G$_Xi+mMV08RBASI2hEsbe=fG0~Nm~zqT;!G{-jVt1cisM@xUk-5k2HW>HamOarYJmws(y<`_1CNw% UI(sds3IG5A07*qoM6N<$g4zl}Jpcdz literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/GabbroCracked.png b/src/main/resources/assets/textures/blocks/GabbroCracked.png new file mode 100644 index 0000000000000000000000000000000000000000..5388eb30da0faf8d6f7715b1a5d4391ba4a0c44f GIT binary patch literal 2291 zcmVEX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wTIZtkV;Oe;sNv?9C9M}Y!xaM5<{TC1{}#) zn`I;+YZi@W)AZgw-JJt@ga14H!iOLJAuvsY)_Irb&kwoz$}Mcy;_&b}g~BY3ZKK3u z^e!&Aw$z|ruhG98GF!;9zkAGNG^TUeAruO+erKJdqaz&0;r{&%ip3J5Wf^o@7j(Mk z++APi-raS?0DkwI-*Wf%ZPwOq;o3HqWr8P?OV6R}CMPH77^cDMttRQr47OttmZNx6 zA5~R3esRoXGD6B_=C&NiCaOe;Dltam5vw;>`R6AebAMw4RiCiCw~ssZxVF4Py-~(; zO?1OV*Hm;vM^#lcP2=drbE?%cmT94CI<{>irBdmw(ba&E6e63=piK;1Kfnj}_6~?f z6YT9i!*N`qkuYC9dc=Hb4nsFMJ~<^43885k@pz0}E>Edc{xp`TX-QkR*wGE{lLjB9X+l9SZpp zi;ZP^-2ti841-}0xm>O@Q8i`@^YnUc{`!}{A)3qo!S8wbLzh<@VO*}njRRBDDuB+O-hjA`1qwnMdA;j-VS zR;^%JI@9SCK@ho`Xvm!oPqv>B4n^49d;?V-BCo78QDQMdvdrVhPdGa}rg>wPcp`y1 znb2u>Fin%q%}r*KY4-N_2!+C2^m?3~od8fO&NCigarEMdd@jfP@Bf;eoo%wYEYjxY zgDu-~v2B}n=Nu)LWT9Ti&`e&vcMo0Duq}&ryG7vpB$5fn;~}H*2yZ%NW8*&g*))MC z;7vVB#S%aKa7?3K!8BAPNepj|$0JO`#Bm&6X|B?0oufp;ghFA$kto-1tnlLKh>MFJ zLExe3I&O|wB+r>03f*@crQ88_kAP_0f&vVv( zNh+B{jw>;W`2vU{-qhv4JKys5TR%g!4DQ^!ix32Op2ykg8MFC3nM{UQEJi#QBcGk+ z^z4L}XXhA(hV3{!HJ%~}0?A~O+CmLk*G($b3e{-^L(@4tI^dIspArZGwMLb}<%pG~ zCW;beGSPVQWSf5fl6X9hqC^lxnQFDla4^L4JTzS+o6C|;rx{$1k=}m$7hC)L`$&Ss z%kwi9stuG_3?-`Y;^=z_0%EZ!t@AdU8=I8!c?`?KbzDr#VSVim<#L6nq9BPs4!F0s z$Nc;pQ`bUtZH?unCEDFKsniUPVaWppQcH3B{jcJ+`=L#g^aWa`CuRnM|CX=OD zEU|X)Hlb*k;bg?ko40UW2Y2c+nOvdjS5#{i9zTABWtvP~mvC6%qSr_I>6>qEg(DHv zs|mN)ZWD=wXf*2hzC)+erc$YJaB#?U>S34`x~cQ<(}#$nh^ng8s%3oNMG^%r&Nqjzg`s@PD>~D2P~= zP5-jbvuAr0N=178KGkXkKkzXO8{4rteEu9kghH`MtuoKdOooUO;eQ(Jh{vgs%EEX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wTzeM|bFDLpD3a^wTIF7TC*ba%e z*s)~KXtXb*(MU5r^!Fux!r%Y)56^X7{`t)}n5IcCn(`MbNut;96N|+O27}b= zb-LXio(r8$7Y~a{wa z=OO&%&wuqQl`@85kjZ8Nk8CDOr`sW*s*Ic=jYbpK1yPi#RLcD7laG1$@FCrP7uWTe zotfdS*;#VA9FF5)+crPmxyQ`(B$6zLR;#9g?brx{0Ejf2O-f6PNTS5l)D($Cf?B{15pq_4fy%!+Ev1#Fx_qkQI^ql1JkTA8jUeclR_~^zu)EH-~dq&kR*v8@7zUE z{5*PmpGLFBv**vL*J~KM&Z%Cd)oLKkOux07N~S0j3%KJkg1i6x1{1{zPEK_q zT9o0?!RM3F!W!vxhD0L4FE3tl?%X@nYgInH@&SIuk9c%+M4^x)5{dF)eFHquA`$j> z_mCtRMNtTaLM$&Y6AFbW6!ToZdRI)1-G zNDZ>_@G;3`8q;iGnkLiJ6C57ylSm{u`_3|{RDy`6@%?w-W7`&TuirzKLV z@xldEHOORffIR8ql1L;xx{l|0938!(QLkfE4ZisNb3&mIp6AhSw{e^iuXc6_C;|M6 zkKNr@#NtV|w_XqmsSGR&Q53m#>lV`d{Nn2F?jEUB3VS$23u~-zY)~}}Tz5n!lfmcn zlS-$s1{Rv8(P}s8TSGeS4xzA0G#W+3!y0t)`xFxK1Zq%ae{UaYa&l_bvijt5IV{WK z-`{;lu~_8X`DNPe7L{^^fImc`ki#eY*xGtQwc6mx(?@*p!TV_8Fn!CS*Xt7qsC@Co zADNq*BNzCn4ib&pu;i7GP)EX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wTp4s;t%?uYbJa{gWfs{u?Ekw^-GVG7g^f+6kJf|Pr zM~vX_fBhTPN`;e?V-DWiW7Hp#N@U1qD>#lzv)N|pF8T1I2S{-UBA@AahP!l`O=i4p zzGXh2AhzE05fGS8=lH>f^OqOgKfTX?|MwsEZtbvK*<4&*V3bQpib5)*Qmz&eBoTxV zB!PUfKvGxv_Pg&mJ~?1#caL6w$i>A=q{^0gRyTKe_`!YNwOTA@4(l)?1TKGkjjmOkY1V5WYi!Z!beK<+}QnB#bKdls6Oq|uOgcK!?^I5|1Nb3*b)ftBx*&7>&i4VJEtrln}UX|Y_c$QfyV z^V`R~ZFXqBxh5h&(c(0(-r#vIv2|Lqa5ay*{ESkh%WJz#<4D4v!9yWQm>K27{r6=dCc!I){hHbUIzs zgodhWEEY?yuA01h^^*DArrqlDuGPk@Z4(3m2{nQA=+Vb#p6jz(t&rj}k|YxmGMmh} zwYy8+$Wbnqu*MdIu>amZDP0Ev=8HMowJPbfN*KV>USgWt2!v=!8GA8BeDUHHL9jvB z)A;TRBdybEw~>U1@n}r9*C&>UGqEPTYjtp(IUy0&WJJADXR(+O1QCi7L)VgIb%k%A ze$C70*L?T=E2KaD<2^A}u16F_L?L|i=n>!l@QkFcQ86oIGbyBpr$0Xv1p$8@Ac-OiXU6+S$H=OJ zk;{|PHI%r*mtTB=9FGx2P%4*Lc`IsF6KCnLS%*}s+jKi!Y{w>u0<7Tx1Oe&f;Z$qkGdQp(Yp%dxTNM!R-Tv!y&WTj9!0$ zEXx>1j$wao-(uRn9NYF^mi=&m*a-h?D7(>2yrL*Cz}k z%9RqjrePQv$|2kGrS$kP~sn^9hGXM}$#?xAK_JXDpl+wA(jGu^8?44RTy%vk8dH3d`k^ z#?B6JnoUGeLRA$elL>`Fo?+iY5=0jEgzEM-^TiA!lSS8c+MOP;jUN)16S$&>q!{ssYo zTrNwe(`LO6IXFB*ipBWq>u(4G0RaK&qYr;^X71ji-R&?O^yzmkA|ftdU4R%8Mn0z5 zpwqcQRTUh^!C5RZaz$#j8mW|yAc?4Il0n}h9+wfMh@myYG%Lg!dlg*Q!?ibL(s@j? zPWR>p*YlZ9r}!(MAc)B2ay);2L20YZz_KvS8etUDZg&`s2h3&;rw{IN`|tqQwaKJ1 cD5}E$0V?=!3Qy+C_5c6?07*qoM6N<$f;K}w0ssI2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/GabbroSand.png b/src/main/resources/assets/textures/blocks/GabbroSand.png new file mode 100644 index 0000000000000000000000000000000000000000..b562d38fb015279612d9da56c65601609b8f105f GIT binary patch literal 2167 zcmV--2#EKIP)EX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wT4T(i;wS60on#6Z1p|Shlwu3p=)AjHtyZf&_9B@) z!}t57@4x?Rt?N3gRYo+Mv%9y)^>vRye?+6vptIFsI2=>tDF+8fq^p$E2Pgdd#W~3$ z!EtR=Rbv*07>3DO+e1+ldc6xAr-7mcLVEt6;#QIrLno3{``VKf@y`x6=sk5;RV5JKQOE{3k7=_+5o+z>@E^Ek#^ zYcr2#)Dp;=Lf}UziiD7%D0418eZp-t0OpezfP%M{D9v1}7n(|Gjg0bw}f^5POn zf^3zsy|azTvW!lri=ms8Wr?clWLd_19z$KD>l(Ul&}y}K^V4hUs>1gJ9zJ}8ZfKZ> zMY4$b@yCA=h5@Rg;5aUlkO+Jq;ZFlVqOL*L4P4j7Ff4RUqpm9s4h~Qhg)od*EMkVE zA&z6x>-8w|oXK>8EGyi*cY>;F_`wvLZ;szQkE5Yo{^?2Y{w=D0_wUV&vP_QW4TO_s1ZU&7=}Srm27U_ zLe~xM?BC()x`!kQc6WCfkH^@y&HnyAWl^GO8qsWqEDP2*)}gL(-3Doz62~z@NEo_- zX=1%Ox8d>)4J%zu#xEh%rrz z$z%l7G+dX%!+UJpx`mJ-ie|{$-R@bI=VYrK$FUeqCIGyD{~wZMiQ`zPn!)`C_bG~; zmgiBHC5~eQ629*vNdRD(7F*qIuC6{~=oX5qA%FLm@6KGe!7^QP`tUKmiymp3BFhTR zW&__3ff^wsnk|pvaDeYmfEwSQqN*x;dv_>`oG6Ou_rIVhGKWWZk!2aBEK3H1F_I+l z{Mj>hcD9gZnJAiL+cvJ_VmmfTlJN24f6+7*)3neuoj6{gC>mv%BS{jTx5ks-{*LF* zp0kJ-Twh%wE-!o3b&aA(7=}Wx*Tc3g9LHij9${K0TU(n0V_ z|DN@A58HNVHa&FRAXzL}ty13n^qR6N5l2V&a9xWhPagmJ!g9GH3_~o-psp+4zkg3v z)%@e{e`7T2MOjuH9UXJ$&HG$@LKAPBg*xgm~Yiaa9- zCg{3Or_&+Ja*Cp0u}J84yR_HV*xlX5pHA_8A8~PUi6jZKtibcy^m;v>K7EQL)hyEl z)71I)+duq5Qeo;(X*OHjzP-cKr{AFKDzXsBvdnliLe&&hRig&Bwz|m2$0uiBef14x zS>U=3MUm6*k4e)ML)WRQ3g4fyv$Kn3IShvbilSr|Mhu1{f*=B^!f_nJS@835NK7YF zOw&X@IXO8S4hCqNj_0*FJ$-~_nV6y=Kl7uWPESD*& zs?lnBbUNF3-Ws0Q;_&c*vaC>54a>BUg+{yG=JxI`ZllS&ckhq{7>3PY&_|IZXf&FH zVMq}8B*_9%J|PTdgtLG=FKISgxUPe$Dr{`rBFi!+;~{}RrPXS( zv2jEghRCvv&~=@ zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3-Bkt92Ih5y3}ngA`#fsCLBG@su=W>xphE;p7z zPQTZpL?&>>5f^3lfBok%|G~dhqct&=np@76f3d~pJHJ%>{Ok9-v+;g^{`frS{(Rhg zpYS{s_!*u*YknW!JnnhDe;=RkbvloyUl(foePaCiM1L>j>wAOu@z0Hddv0Lg3!DC4 zDERlz@%ei^+p@XU@_P&Oef@c#zhU5iqi-=3pHp@v@;!Q6N^bmKy^V#qEiLp+-}JsT z-V6QpxB0x(vnIcT3zqLyD-8PIh0f3CJGbDs!0#y(zQ^F7m69!QY~lCziR-`q_perN zK1+X7{zpo`zq$Y6@n4xXH=v&M7?Ita@ z>~hsmJ&ubx-tvF?GXKtt&QU`-XX`gstjnt$S%os^oUx9Vkr8*^pr#w(&)47ol-EE8 z(+zWFgWV2Yf%K2$eu^vHL}>Jg6z2$JB|)8~ zdm3tx7MGG=EYimiGRdI}xHs=9?!MF~|2zy3l86+tq5Ucu>Le@1ME#UlsiB@iiYcX> zN~)=)o&f zPB`(TlTSJIG;{hlYj0Zr;p=~qHTP!C-%RO+<(oAgE#-3wCpbyU85#5RE*Vn>Trl1% zXSTW+y)vhq+2-krsSOoW8|c32dfoAib!y6F2XrhkoVClDlMAFslhhgeHhM~T@T1uiBYjeq z?$w8j$K~E!o7Hon6~-Ltq!6bqDIQ)o!%4js$5NXSD(dcVIZv%}xB^f2mV9EvGlPD1 zkCa$K*eil#zK_E4cAsbEZdVO!cSA9T%sRr#pp9qEE7j9iN_}ju;?L|eR<}y+?9s8I zwey*~0++KVw|oORiy4b;#=cyrDG{7HPl%06juLwY1HkGL^^U`hN|-6FKdwhT2HU&g z_Io!iVV}+8<&3GIwyN*8hdq<)1vb{-0gDuUyEtB*&R(_=f!LjfXB!3gg2AiL~V>Qdn8&sI#x1Ebv3A~ zNL?L(!RK4U@Pu6y{f&v^jd6j$NR&9;yX$1f8a>vHkg6sh76xj8eG6F4Pbt7QwD-1W zXOh)Z^{l@F4s=OLthv%i{0u2g`q3k6^tQeF$h?o05rA791|x{Sa;KAgn#5OXOvxr~?cLNpeJS4iJcH zLms~=%4>jX^MYgI?NlNd-Kd?tD7s3xX9>flT?42-T27Qg9|553b((4^n={gEy!JGu z%fUkQHl4#IeI5C>3IW|qP3qL7qt}paW!=2f(~c(B6WUm`i4{KOIv#k63D%(&#sIES zL}4yZ=4_0VeuFn@s0?ZX%sBu{qU^a&Th@ov8{`OO9T@IJP-N|sW6aa0xZ8qKY)$}z z(#fp?RlNr2MZtD6_L$({3tx~V9J&)l(ECkHg7LzF{%g(h8Z^K}z_B8(baoJ5aKCM8 z9w9@4UDYu%#p*kR;sfSe)f`BBIw4AMj;C5 zfLXL0J(i|g(+LKF`(#u-WT!@?r-P0qq*zTsUXg>`CjbD1heI{dH(Zez<~(Yhq)+BB z06GoIrZOl*gu|^G0nt`3P1W0ucBiXMLp^X6T2LS? z^et@(4*i80QA(z4ARUJY7T%=elNQHT7CjMRCED2(9vyS80S#8&i`;`j@car7ThQXm z)4Fsg_@s-1qfi*Fs+0ZAunWpsFK>F z0&}{$dM!g2Mzn$TnFfOUCd7rpMqFoZ>5*d_K~0Zk+!#1S>0`zb_P6K34|G_dhs?OT za_=PRfGd+=1F}TEVw1gL6ZF)MpoAZ3ZKx=s@;6L7&lJ3FBttPsUjaSMu1OIfvFP!9 z{Ed5ns!&S}XsJ|3(p@SJfUAQ|AOZ{xS|Po*Np8SeJK&s>L$g#ET;6cJw9V3S~3gll%&swHgFPG1QFk@cKG zm}-!>RK|n<2!5|Rx>4y$^IVE&DA{i`=+!cES|6BW_qAO{?gn*SyDe&4Pe#D=_uUC? zH9V4lDgt=@PY0(-(N(VaNFwT<)ETrT6~#W@p2t@Ewx{mq>3q{JoY(=-FAC`otT~x6{i6OH;kFM(CXu*=6xQ<_U<)}R-!4)^ z)fg@?jRJKqJm9ijn1#a4yFS}`KoOrsXCGR&jkzVMfd3f^stxW!rb*0!KQjg)Ne#vZ zaWI56_uUf>C}sfT2>K&%}O&C0ENp+ ze7A4KMhvWni~&!W4ZNUrM!kG#-X|w^!%LVyV!}~>x&oPyJR+qm4|TB`;2NXHvmu#* z*(B>lf|KdcTMfPe>{0-$rE6mFZ&vU`nKb%_9XwLx|-yfK}XwDOuSt9%j{g4ZvCmmX@1d1Lyir9fjom5R|C zLS^oQc*5K{gY1SeU}9zF#rE2KewUH4c_;;bSoV(R(vO zh^mYQmDEINsZ}k3h2Mj(APPO{%r!38$)UZIrV_SkrUqtb2(}?-R%I;>EikH}o_@NG zgolx*(m8`<&C*=czfM(J9~jvkAduIkz44vo4P%YE0@JAY2j%2%G}V-3E+~$xYQwOI z7@8Zw5a1>isFPAqZ)5r0oQQpxL~ceSnasHK40) zs@MBLe#DGZMY!D-Nl`A4&=1*Uv1qdh@&m487BL)(0!mBhvk|*xNKI~wFhYnGw8Cx% z%D*ZiFO4D6IlqSx0^fxR(QqNX<`8x)6RAf{MOlePm$(AB`W0@1??XF^mYD@Bv zE`%(r=~OaVJemAsdEG~D3EB``wMsfeBhWM|{>IanS7EnRBS}CJYK~^CG=&8Et2Gn> z1ONuD<&RUeFxza!iv6Fdf%c3SXOmo(pFNv8tV^9>+I7!`E@lr96v_M<+ad<29L&Wt zsamsp4fM&9hF%AAf1;7z<;I$gPQ3RnBAZ^O#!T!*_6`IZ8VPFWP7}!4pbj`HBN6d) zEz&ZkL25FL-}yI?AjD;Zi^98NJlsNSD|`_DK&|19E7sGUs~ZhquX`heU>F(#5_Q;t zVWql=NBJd(z?g_357Kp!-q@ERp*W%0fZ9ejzkh#Y;v(^#QjGYV9Kq3Hk+-ce$g-DL{OUI^`STFtnqFVYEhgv;o!YH1l`vPGI4j z^AH<%Od7)rS$o3A0Z*5}sX(b@eBfodwEvjKgV`FFDP8n}dsPHwIpb%t|I+x;FcUOD z(aeY!KSk2cR%E+$sX_fqxp;Iweq)j0_??x&(9e`$aEGotU;w;kks9F?<)G8a0&8y& zZjc8>UZ(|ww9Y%y2Nh03(PK@(+b90S(4)X5Yt)nHjhq)5DHZ~jjcZvE7tSK8~OmT2VYHP4|#hE6bY0+dGi zm@T7`J63%y%+f+f0qo`K*{N$FjDH(+%|$6D)>Pjylnr>A24Na98|WLIPDFKuzsDmd ztn1j4j)FEzYffWaeA>AOiaJF8J=kc=Oq2rjSdk%aq3Y|^H5#+C0nmIxMu7H3_Wm5v zXhwFxx!!s4JySqq7#AJ~2eE@8z!=Iv^UtLuajC7LOZK9lMGxwr*J^6CWE&?74PXpX z&pe%9zMUVwoxeaf4+-jwD2ugqmV1u^kxPQ=qQoGQupl8CmaZ#&=W^@Zy0LQ+|4;oq zQ%-P4obBwU`@uF!^*sx*d7Bn>lsO%3{A?05pr;6dNLHWek&A$MaT+<{es%nJ`;awN z??2Nk!@ZjZ^_w_#i^1WI517K^i0(O_%Dt>j$-tylgEk$P>60QQ?xR>4yx8MP6OJAz zXjb=@3HDi38-J(^xE=8x$3=`=yKc4l`b_Z6bDUD7pQCf#R>@hxu^hscIg;f%z)5l! zC^bN`94{H+F|I^r@EhE}Eg2j?Ltl2Jsa8Wp0eTvrmiwuy-Nc-=+3%>{0T&1_$ZzIg zXpfkuCNDJ>AS|nRq+V5oGdOYLJ;u}sf~F!zP4mDcc*6sJJg$*X)u&poLOvLnSnizw7{MEHrsTfSjzOpVoUe?E1zlUvf_Xv%i@fy2n5&o}3 zpFk}}$uyIOLp!Nw>X8-vC?uT>NYTH7o(rX?K-n&(7Fto%J%r54@45O0)Icrd0_xO$s#&c%&IWog0qIl`f zS%V}4oe`v(TT9gn`T=A!#O6&OTU38vuUQdhBh3qGGtVni?|G3^WtKp>!$cSgv@)2d z5t3}yijQj1jH>*`JPndjkzQxm`iuXq8H3_o{l=dA}St&HW)|H88ZC8+IKb(skf`WhA&4bTl$I8iF+bCI7S=O*XtB zceU1lr$|>*@x~^XZJtFZ)h|*bsch25ct>pdpv=05tW6`D1UgdJF2Fv0vW22Kf-B}7 zB&_=}2}%kbzI2{fgS;KPEwl?l83%fY02EGYJm@w0l`3^2k1)-+;3(4cKWD1}lGo!J z%5HlLleSqpjf9M*KBI(796Cr#IvST>L-IU6NwetsoENHKtfm5p3s1$*pNYnxkx6CI z=c6=e&?vfT#&3|cw~zHv1|23Jeah&^;fy*Hz~=77($S%2j^~A< z7$X8xAA)KY*^L(M$hM_v;~1#gXV|O>yEx*$Wn(s5-oUvE_yoeKVq2esy$%}U1u0w% zh`RjwYyeFP%qP;XnJwk3qwn%_=!pDoe?k{QRx#pIH8{@tL@aEn0}s`=(I)~nJ@b1u ztE~Xc-Hyt2kvn7szNfg*njpWsmk$(Qeh=;7wGo~P@yEKJ;xf1{qR& z!Ty{D4^000SaNLh0L04^f{04^f|c%?sf00007bV*G`2ju|- z3OOp^_g~Ba000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000HwNklSqHvObXpK7sP_eV?LkC{8EVSM(RV#sYlP?X^!i3O_E>Al z^PIceJ5Yi!PB`1%kY-Cp>xd#BB^2W@ptqM>+-&K_fqHiYrJ356^?E_qwS0GfkDW&T z^Z5%>N*oGLYO*ZhSQHpxh$Dlw7NZOZMc;HJNy4E#p{ue+0!qIVt(aNm5$p3c(kX-x z9J+?>W`nVort8^Up3}B1aS$bE14WwWyd94CTC!NK0nl2pz1Sdxpr0qY zp(e|7{{7=WF~%^OiNN#ml)_kxOwx#9w1ifFgp>j^ z4hRX4504CePaOJKYtdQ~#32$%TQ!_tUDC~ly6XYBxxPUMfx^v>BuyCmjxdf$)0AnN zaKb~o4ZFjUvT9f_GD4+^;{z+hUo*Vi12BX%@IVTyI`eS_zhH|lZVuzREH z8s45BY1<0RgdHtb8k+jV#}8lQ`-*9vY3d3oC7$-NcA~0U+%(fx4Q+kG%wVvbiV}T1 zmNZR=Glt9UIT%BKs)+IooM0N^`udXURIxcf0|SE@>Dq=w`B-C60>1q6i8M>eHWz@Q zX(qhbM+123-HdSQUt^6S z3R0TBMotEu=Q-EsXS^PEXsPkEW`Eq{P#nu6Km6_o@C5VVA!b8a97(ek+7J2s>nDa` zz|EG(*W_6Sz%vOts#`j}_G+~$xVVa}U zh#*V3xxXjyeLM+TYXHn_kWw*C|NEBhcFWj}RCSG1ig9ub^UT%t6;dgNsi&wa{2*bu z+0Z*!UEHyIeWsfyZtuTBM-f2~&<-6aP+E|$^7k;Ov1KqL>wHDk55!5#{deDUDh>z? zN zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;ek|euvMgOr1Edlee9E@h#ftIgx5s_KdO^QaD z)WugrW@H2acfW%JH2c5)^O*nOUoIt@m`cqpXUo6XV)LC}s(t?T``y`izdwI`-gAGx zZoY4LUJCpS&!08FuWw%WT<_o4=X;;d>*?2x+J4^{f4+NSnK$pEtr^5z616|MYd2eqJ}fLwe)(>&ZEPpZv$`wtW`k zCvxT!zH?SRXFs#+F*D`-PU+%uf|uUBqn*ZNV37#bj^9f zcwBVLb$8spKc|}vG5YNbKfRv>cN$)-1f%(R!yNVHjxV8w6)FiZNr%9z{yP?TAKUKZ zCMCA)a@CMMj+;3?@_+g=|IS6{sGyv)^}AM#%d65Dg(Byiv5w1#h&%71rn|tOufP8( zu7L=qyUdjdb~|(j!atJxNv?1M9k?*@^C@6g)_Vh%h!G?P;{p+|*@fh?v&DN;oMRy? z0qP9hQ&5AjxRm^2kUoZx2@X}jv-wPM_fnty^D;n4AX3PN@~cFs6Ra2$`BP#ghk6Pr zrj&9jsiu~C4p|kJbIC%~UP6f_6;QU+(n>cq)L2u^wbWW$?aj9U;-*GDw%S_joriYr z-1&6pg5HN8VZ@O}9%awgh7_eRa%Na@1zjT*0(^0|c*oFv7Ji23LUcu@pg zFy1R>wz?R-BBz+y=BbM08Dvs$mQ%!tVBF59Pg&Y>nwtGQa*F{RQt?O zkB@_wPI7U^M9@ZLSbKXeMFj-kh-I54q{N7j1DVOX*-jY;(m$=QO;qi0nQ+G0h-4^> zQ6)mt7lrS^=dj02zOaU2CDW^OeZ-YFvnqQPU%Ed##hJ%wAuLypM^V&8kPde$XRSV( z5`ue&*$T^BlQ~>YM7k%IrJdY~VNiIa_n`ar{ zCrJo;*O)hJ!n&3a*9mDX%EXg@%M)-$<7XKwkZ-U8i)PziEPHO}l-$iugrP8=xQHmK z1!`H5q0RPAi@IHu3Zq_!s*mIBZO_iR&%y{3fA+FX%tK{0dLcm>kw040IUzSy=r}xP z>kL7(uVSADMeb}}451_~;1C#DsN zLvYSY_4Jh>W@HWN9uoyWRvEU}F;_lOvW=XE|5_(09r;7p+_H^yDsxYz+#Eh|quO^3 zdjbB3LG6_0+AV2ZEW={nj%Dy8`_}v^!52r0j8!-Pn-sl|hiY*o=v<45m{lmY!7!ty zn_Any=+XBFbQ%9s#j2cRC`U)K;{+<__{z79ceQ*^n}4 zt`j5mlMaSDg)B$}t_Hjt;mANHyao>lxAplw+@1bbrrzIN>W%`jLL|=vqk(y~k z9!5xIhFSAmGolf0MU0)#0U}hO+$0ZAu;R{Dnv(VBDITV)iwZDn1nP86ZV0RG5V_^_ zi$Dc9gW6maU;W}Cg?r|Z-gGJSU79TBY9rvXNj!k2`HW~9*JS5{%>W3Vh3u@8%RmL} z+67ZA%L4y0rQ}JvdJU#|ph%Xs4S_m==2_mI&?Gcq^DtTAJ*6C&WJF-3(M2AsdKeHb zp>#0hCu;;}xPeC+CC)=tPTLPEffDck^c#-Mv!bq~f zMzwWU#fiRmg2yBqVR=f6!QJAb+#*nZ&@uVGS_IsJ5!ksxgMIUSB!tAvb`CkhLiNuh zTrP83nUY-jToCvI@}5-*(AO{-`9R(Uj56sJD|ih_lA|pZidZBS+s&6|!BSlY?jnF@ zi5q`)=awcy>setw&#bOqwGI5ky4@+}Sq%5Mu5rrnv#3a#B=%X`^ zqYjJeuyrqF+83Ev4nD<@J;=nU@>9%&>;P?HkdnEz7&@_qAdwymUtu?RilFE9u9LoNjEtJk!6E>h6GFx<Suin~>1l>Wc06G2hI_BV!`QV7~>Ofe-fUZb8)cF`; zC%nk!0>py%Z3*r3)pC@5ex*LTqN108`g#}_tB92J@LJe&3Tn`{tTFoDCaRPP&I=1( z9_|NGa861dAl6E8LlE#FzN#CnE#jM+RB3=IqJTrGP&rz?jXXQ;(xbbmPCAd8Z^sF` zApjNuQ-fe+k*M8A;dn{8vjJlu5lFaWKpQSgf*MMa{DIQ;&5m@{{~3r2kPy-Yc88=% zQOfTvq;N3EQy2#ECRcD>V16+8;vz(Yu!TMK)KIOG-`_&PAAn5(hy?RIBNSd_(`R@K zCwB`-pc^tzhOJ3x+_{npvBokMCPM|0<%6k3iEjuSl=!W-{oxX(vLRtX9(vD!$Z{ktuhgKD{b3C#A8K#j$w9 zj1I>YTv8TgIK1f!PK4rlOh=9&N9s+u?-FiG}U~Xqh~Xh^JFTc z6Ae{iKk0b@4xou5TvzIKk{gstPV&A3L8wEE6^H5TL7%i?{+w@cRdyPyhrFqnNhbvt z@wp*6xeJ*+5|gNtd6-ve|E@wZ*`6dL0wKc0r-;#*I`t76poLl%7awRwSWZ35v0H+M z3Q4s>mnkx=V7Nab1BzNp6=h4t@S^qO)yF{Q*A+dftG+k1A^FvjZ!)F$-CoV+-b;EE zvPXs`EFyg1twY!pr3PkFlj553D2PO&4Y^zUW9yQag<$nipHXdd4Bb+jp^((UWeceU z>dvZiB?d6SR3N47u%d8{DC*dkbz($VPPk|o1 z9Z|=W!j)@}Si?v3VLF98iaa=Lhf~B)V~wr}rwqKpdswR`rtVoO*wFCt0UR}VL`R5g zQ*_~YFRVSv$q?7FqhzeiOC5+QwY^nds6EuhL=#~(2nedCQ7;Xqm9#v}oauLHz+->Z zFo0^V-u137b+aG2Yn|_E{Q#*bhl&Wss}fHLQoNx4yeEIy5_+L0cpD%@rYNIva54a#g6UZHCl``VT-fx&bZJV%bY9U6K@DhGu3&xu*26 z%eh(G@vs}4frdrb$6%Nq;_q5=o>VlyU4VWjpl~kGVa}z-y+qHsDqu@3-(JqHQqJmB znxhmh0C?;q$67Z}Q{h6b#GnSZI6cn*8p~XeE{DNv^`IhdQ$UK^FftGmjfN^~4)cUb zq@4HV8I{9^e&M@Pu7!2Aa&0=TJjqHGAJ&cKLDpc8)P2Z|Q9=w|Nc!dsKLNJX=h^Gi zt-?yQmZNt1v{K}mFn7Q~$#@hcUJbAg_I4dl^J2&LX_PWXhzp9vFK_991?e+REN8OH zO!Y>fBNj}WH9YM9G{;~;H9e5rND2fY>YpT*)!tGOh+G2wGBdEZ@`aJ~wq%gj4J|@M zFcTfi0qu>DAJI9VCK4J7_YlEBEKl3&A|fWW=9N6k>ZHu>o_?*zE<%N1cUA>gz#Ey0 ztGXLFRBb~`fn*!O*B1h9L#%i(gLRLE{O`Ib`(|M!v}FOdQ6tzG7jj}EvhpYWkwsK@ zqf$y9l(wN-bOYuvVK&k>O8Tt<*d1w4_iec#+T7FWzWu`WXoAP3lSk#J9S-ZAKDEEs zmCe8g^h#0Hy>tHMKcLgqCfNfC3{XepmrZ_QCr$aL@k!{^(>}jRAUf3q7huHDH?e9ZzdF83z#53G7!v z3018A`>x8UqKu;WmhOkcIvypj24T2M{j=moYc9}>IX@k45OPYFYC9|!biDQmuUnuX zvSvkTOceBjZ3jL%IR`A7k3&El+ap@fCGX}xjs0=&;6aV?be5T}grG#RwoyisxODIu z(j5iJrw|wADETq-*FP|Y+orh&wn=6@&4IeQxM?XvNEN764LuVab_c)bhg1Zfbv@;~ zuQ>1O=-`#ICKShNOI;(Byj9TzsSR*foiKA-Ba~{qD!lAFLA5U|(uc}fKb}U7X*`dk zO5r4QnC7~$X7^eg`kiGgC1GDWYRTg>tkD7DByk$U-1*l>Dz5jUv%qo8$J z*$%CRRhFQ2)sEctc18a!WdH4L2V#NYBJ16)T4L}G60DVZ-U1l_0mcYpRcxn z25)l^8Iqr9If3L39v*{QTqf0W`=Ly>XQs-)DZ{;Di$6Dn|#$Xmiuk+&hlHl$M7|#i&?KjM1kJ_f= zb|`p1k5XfxMv$+_Q8c%LJk^{=vOJxxS=4D;YH*$3ro5XPg)m{1TT_-TKwL;Ee=W&62;X(Y{$9tuDv?(!*Y||plnuRuKm)d2lsAOGHYsF{-#ph?g zXpZvjIrQrV0{(nj3CHp@VsPk4xomlYxkgoeQSC-Y0(QBSI#c3#XR$Kc7Lb=YToeRg#|kt!4+#h6!$MG^tSWg#7|3?*ZWT#;*8!7B#4Ckig|Hys zQZ{XM@(X;@wwKI#b~{n*NXPbQ$n23I+9$F|E*+Rb=3f8bVD9qh^zo}@07YSVSZ7vO zy))Q3Zj`^8V(LDs7mT;gIyazA8$!t}M<@4U){d$3o{@AIUKqMsS|F2cIs?YkD2Lmk z&`0~zK81$MXu=t4f2bRbZV&TZ5P?oV&K;ORehcGK4Qh;oZ_PgKIBtm2ULzJ6SD*G+ z^`bc3(4%zoH5K?~(X8xJpROe9i5jVHYo0(MCPYo_x!=A+w5&8Njh;=?oAWC-5%ikm zHGnz=K@J*H^Si@DveyZ}60NPBHHv|#eYZK@H5GkN6!vJKh2hyiT!~JA+or z%85Nq#~+FJ$eMgNoRRY7o|_b85iU$y{7Af5yJwMbmS`Jo+k%TpB6tK@mf*}xso_ha zjyh;}rB_i5dd&TD8r%qk0UWpmFLgC99b<~oi8nIqW7ND9;G^ht%mf&)z>&POR1_cH zTG2*YK4v|WQbWfy=AK>Rb^+@UjKQoPfRH7D4%B)Lct)LF86OYdmyYysJINkbaqYMy zow@t;0g$Ds7(@xI0!xOat;JY{j5fY)Y8^xAp*b}DMr31?Tn^eD!4=(Yj{Ml<-pwT6 zG8%aTd(9_wvOIMeTU{jN=RIBlJN%>kyhjAkcm3)+=m=Z{@*k+xUV+7%vu=@Ca3S6* z-cuutW|9gik9X59fou+~$~fb624O~->x}5{+!+ZIt79$N9osrAJG9kLjkKW_QIBuq zo;e4r;xKP@XpG^r6G#8dg-5~5oV`N8)d|YbO-W1Pra1C^TI;qnrF~r|V-n_5y zv{l2`6G8SZR`nD%2AT!|fvpds>@!k$qU>SpfAbN$_Z#&n90 z{jg5@_OCMz+WG@W4MM<1e;X~_&ZgVVkg!a*LzzjemNWU?Z4I|R!p#iK*dGll1I7!% z^6^VDE--0u_mUKvMO;tqQfk?6^*qRh@^%=;W97At!>eZD$wC+yNO45=QYP3f@)IG$ z3>{-gjyhld*#`XXQMruaEcho(pc|&an79QhrF}X}xExX<-BV@~Zh1;8=XyyG3Ovfh z-7hs$nku;i_$zEH-;NUUxFNbI=BZN{&f|{4a|%Z7px@#W+uhzXPN1(%%jlqu`sWD4 zju?)9xB70Hh_Oe{kER~s%h@)sicdr?;1vM9rLA8RbRZ#Xzw_$hr(+Ga-A+f9m*E-sL_#_nOJ8Pq>ec}$Fq>nXn0Q+0&JOd))6Z{M3tc+o;`J>$+b5+ zenSyVa{@oMOgLm!!*5~bbTA1mxzuv`9;Ub*8nwb1lFd^G$K}M0b`9tGZk(W?;OP6u z*jGG4vH%uinD;TuR4=Qw~}-i=Qek;89_QU!>zN+c@`E3NQnv3hDYX4{<3Oh2J_a2 zB`Qjr18Rq9Ti+dSbQ{=K9YzG|y2f7HGu{Pkr0Bl5tuw8qsM!mPr@_kG-EliA%2VH$M01A6^F=cljOCJDiM&5O@paKD@* zUEjybGkQ;sStl8Fx6bWkLaH?wl2*fKzF1JE8D6u2<#_nr0nuhj&90GW8H?!zou>qw zkZlyvZnwFe+)nn93x}Vw&9^ z-EIfBRzs&TS6A=(?Bpq<(TH^t5v~J@qCf(mAzm%G`EZMrih85Ta<(MZ1==u>DkF*3 zq;Z5%f$2BNk~Nd-3BBDej@zfqHE&+OW*x=UT?ef-QcC1{agTBxZZB_ma`c!Y)0BD2 zG~FU(4ac!5;)t8s6wh@zcyh$$`Fny@fFTT`DCFVp04WXDVN9p#(;fC%&6dJK3@=T)|3b=$7b|!2S*7?45YI7^!aDZr(-&eI+o)iq~gWTz9L8x#C1SFxnx@H9`nn3qJk&8=9>yX|9>B zH@v&}Kweff8Xid$lOzejW=W=VqyhawpJba+VtmYa8z($`^pK-3o@1DjWw@cz6^`Su z33JZ>`yJO;*Bn3pgnp+9K&R!iUaj#wk7Sz@h9TrRQ52D+Iku%p)0C&rj*uo57jMs~ zs*1h65oK9oR1u}lSuU3V^!t6ze|*beFd)h2h%jb%{}Iy<*GS_djA@!^T~KVd0JyeA zg+%6M#o_*tjB&W_Mg&UeVcofLk+AQh?T2j*DfP zoPGC_^=yL9GHlPM-QB^IHCCID@pw!e#(1uW0Ql*LQ~vgszfx8uX%bU!b?9~4R8__G z`8!<4!?tW3$ALnVW*K>&vwM7u<<>BzNv?CGFmP%PMV1o9F^7kH2un#$jz2+E0z)Zm z&*MM;`j%$D%kJ(jy=EKXxHQ`x0FWkjz0N$0`2O$zAcmLPajq7+MVNA_&N%Jk^%L~Rg*E~M?gofi`6q;vWykPY3fZgGc zZIU9SBCkp;+oDnT80|ga^vyZOpML+_3L)?uk8QTa_F4#OFqzy@=?d2pWLZYO%}I-b zs;qE5i~eB9;P8aYA78RwuSt>w+x4jO97>I{9IC2BMqvUblw}DTnmv!AC^$TMPJ1xo z{j2W~n~>%F1DGbJ3FsR4_X{vi(HMB1M{j3HvI)446O?I?rd#^MA<}UzhKGmz@bB*d z5at!ab{LPZanIhM4Vd2E;@0cLQH&5KNwTG`Ear zce8t5zkEfOW?0fB3M0yGf~72SonzM&zUL4}G0&epW&hwIhLnU!grjO0LSmSb%lBsp zVe<6z&rptyZ7aINosXFoMMb~crqG(QENS=KbUGc%vLp;cgfOveo4e_h`69r!6^>J< z(Q320UvRX)$Eeq)X4N=5ea)cX!>-xvAAgGR=Rf?e%CeI4s|ySyQW+F^Mbq~P!ib&W z19VZ46&bCD&vY{7=-G3E#T`|i69fTKmZC6t^yCrBRCEU;-v024%{oNBKD%P4-^RA< z6h)2@5@lDc)*+3$i!KV3V?hFo#fmS!{y9~pnBCn{Qwj_dRT&skGQF8nmYOgOS%(R_ zG7zroQWhmyk#R5@&}_IETI1C{GzNkS+qO}%MrY7vn`F$!S0qVFRS6DGo>6Z$QA)AR z3%>l-*91X;QUYBR$eotY&2&NCwwW&jy1PBP!vh-K23K$1Atm&8_jq;lPsFNZy|||` z1eTKctqzXY;K7q4&QDM2wtY^&eMuap|6jf4f3uo9;_F?P_5c6?07*qoM6N<$g4lWm Al>h($ diff --git a/src/main/resources/assets/textures/blocks/LimestoneCracked.png b/src/main/resources/assets/textures/blocks/LimestoneCracked.png new file mode 100644 index 0000000000000000000000000000000000000000..588f8361bc68478471bd411335aa5c30ff0d2f01 GIT binary patch literal 1919 zcmV-_2Y~pAP)EX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wTz1-Q@18+r2%;y?fXSH9gAo*o~lsuBRD zH9`o2_jn&DijuF--WZqgAO!2WV+%`4iNoPQQ&;#9kU}C54E;ci5h>t#zH$07B8A{M3}|aD zQYxydB812=41^HawjCc9hC|1`?`-=ADu9HAXA6QiKpG zY{B_@W!+bD&U9@@*By9ze1lSg)9VkWdExu_7xsN8#>n&c7xcPr?9LH?w;1 zB_&b{5a7awwTA07@$tiZLQ13<*>*=xk+;7*@%;QkT~$Uak{bE1IU^ za5!*iTZ}d=>jnsvlo+L%mzkz%a3Nr|BISgV5^D>L(HLXconz=*ilX4#^NE-;dfz=t z?RdY?_bnhWMpG1qAL9>%6j)=4G2L~p1erurm&BB~UM4aMV=XynrrS)65v>(vS)kjd z!g-G|n)$X+*A>qH7z*vcNeH2topx5+Nk4wWOSpQu6NITh8Yz$K!xj5-BA) z!?Jl|OdJj^^Rja2TC@}bTNF6w@ZOViMkz%M9>~NXu+|`z#u@`cAcP?0#O*dS^c~K7 zQcR=-+qQDO-jGsaw7xr82>}S4kN5o08s|ORG*Oln<9MO03UY?7ZSFHlG0zKq-=U=B zdYy^gAtZL^3Ep9iK?p%k87UO|?#L-Iju)ho%(t1gtvS7p7-RVI z^_i3sAw*Kj1RtoHiicr9X@yqu-ldmqV_8-XhnBu;`SSHUF((RZ+4h}({^NIijEv)j zd09F32kNHca=l@Up)BtgYONXio}44zd$e<&>2@Qg#P6Rz0I=_#=BGc}w&7vu`SbJt z82XNfW6!pi%(wYowPi)hk;gX=eEIr}0HlO{5A559cHR?XWZymBIh0ZuEvc*OuAC5X zDbjTnr`M6&yr7gMr;L)4rl~2cCWMG{4r}dCCu_#d@qeLLF*?Dh`l$c_002ovPDHLk FV1j>8dR71c literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/LimestoneGravel.png b/src/main/resources/assets/textures/blocks/LimestoneGravel.png new file mode 100644 index 0000000000000000000000000000000000000000..d5229d7e57817d75d3a5509927bdae331b24601f GIT binary patch literal 1998 zcmV;<2Qm1GP)EX>4Tx04R}tkv&MmKpe$iQ>7vmK|6>zM5s;{L`57+6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UmP&La) z#baVNw<-o+As~POj6#%{sVCBl8F-Gbd-(Wz7vWjn=l&dhO5S9EPb7{q-LQx^h-Wt~ zo%23%h?OLT_?&pcpbHW|a$R=$jdRgqfoFz{OlqDuL@X9NSngm}GF0Lj;;^D>lrLmm zRyc2QRx35ux+i~OFt4qoxlVHgaV#N$Bt*!lp^OSFL}=AWF_EJEn1_GZ@h8b8ldB9y zjs;YqLUR1zfAG6ovoJm7CIw?a_ls?Ri~)gNpjo%=?_=9;o&f%5;7V)zs|{f8lk|F9 z3m*af+rY(jTa)*I%N=0oNtX=Ck^D4;LIHR`qi@OqgSSBMn%i4zAEysMhPqn50S*p< z@gilfd%U}+v$ucGwEFu2a%XaRzkDc_ zlB!g%u6DN>@XUBY*a1Nh@VDU)z{=9z@zWRHynD~0EV$qAFu5V6 zNLekI=D>e``iXHI5D4nJrtb$%rz6ue(+?who+r9%BF{2bbn%b+ zRhF16!?}^Jy|AbXw2}qh!O3RzK?=i;U+{C+gANc+|%e5bfA=399uU~&lijltW2_dlC-Jzt!=7zi7 z7VYPm<#LJf4(}(5!t(yz2LOZ+tX4J0;}IbhuU@?*CLkvEcRLOzL3_C{x{>F@fyc)O zx~@m0MBfi6rO>M=M2)ffysskLc&ak#)U9DMglLIPYoOmfYqbBB0o9ceHI!rZwJAJUu0S_ z#DFadhG9f&MYdic5WM)+*UWQZ4iPCN^Bho0qeBb~!!1nL>wuJsaU2m+ac<7U7DP!^n)Wr*sPbFnk(}hcs?A7VJ6Ql?>{`DyRHWkQc0GJ zilVffju$rTH7O;gIWW2rTUv^u#O8(=6XQ5?K3~X9hRrqm-4;L1rZYwXZQHV3E>TL8n~W^W=&l3S8tP@q zGzXlUNF=oP9wjV73Lx>}=Z`!-JdlVSn3z$vk_8VStnfAt1%= zsL6X$N?fl4T|aQSoH3bZQI+VT$eHJxLx?cCk)NMFVy)%z;el}&m}A1`hTP_yPZzxR zD5Yq-j!&PS*=*KWn_~;hUhP2M7*-S(xn8f??RLZv=!b!8KX7U;gcu3)jMSP;D?$iN z-cwdL7KIoQQlXS&935p@P?aUNusG*|#5@P|^?Jp7hcTA!+S7F%MNtqVv~5RKm4p!S zZlo-4bG=-E5Io%9v)^tILU3vtKoMi4s!F~bPSncy1J-091@jyba^l<^Da#TmiqJot8@BiMi-EGlYVvNQ4 ziD5WnOim1u%xFT4EEfyft|QYm-uH~7pk6E}3QI~*|H8Ed*xaD!`DU?twPG9xwALso zQBu-%3FkagNQO%XLLd>eZA%Chk@gEX>4Tx04R}tkv&MmKpe$iQ>7vmK|6>zM5s;{L`57+6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UmP&La) z#baVNw<-o+As~POj6#%{sVCBl8F-Gbd-(Wz7vWjn=l&dhO5S9EPb7{q-LQx^h-Wt~ zo%23%h?OLT_?&pcpbHW|a$R=$jdRgqfoFz{OlqDuL@X9NSngm}GF0Lj;;^D>lrLmm zRyc2QRx35ux+i~OFt4qoxlVHgaV#N$Bt*!lp^OSFL}=AWF_EJEn1_GZ@h8b8ldB9y zjs;YqLUR1zfAG6ovoJm7CIw?a_ls?Ri~)gNpjo%=?_=9;o&f%5;7V)zs|{f8lk|F9 z3m*af+rY(jTa)*I%N=0oNtX=Ck^D4;LIHR`qi@OqgSSBMn%i4zAEysMhPqn50S*p< z@gilfd%U}+v$ucGwEFu2a%Xazs#&E zpqqRO*Ka^h7ors2sc~u(7KJa`>l||NiISRe-4y5dc_ghzLF>b2{6$ zW7as&6M%icQ5Br$iJI{|PAZf4w|C5x<6LhwrMWxqjv?j{$)KSs6pDz@j^kjua}%Mp#+;L?A|nx?C?1awwtc4xs-T%+x^WyQ z+qPk?bH6E7#rME!#;}f#F}UAu?EB8w*B1cW7(^9?P+5#^AR?$hZ%SqG^?YKsibe!g ziKwvOc3SUi5}@_o`TjhD&&PxJ_jmSfkP)~iy$_~4k%6kxdVBHp4X690fH@tZ5CJG! zAA@kGs@TRrbzv6~%o+67ux9Ir-Y6DCX~yT{!Tq)aAOe|1W;4^R22*Hh0mWq|H7=TMiIDA+?~^% z(Tr^ys0ed95y3fw){OgYEP|_0Rn*K-RmL_hy9vEFwykr{Cs6cD|5de|OajU6K4{He z5}$Kkt}f&WwQn z+uPe4b51}|HQb%!I2dCr$7XW7H8PW9PSS(QTsuUNRqWfwzO6W^g4Pr>TQEf?YPRk{ z<|`^ZR^B7RoRi}?n8$Gm7^Vk^LKPp6gNP)eDBzEue_gUxw5piriHBnjJs6dM=^UoQ}y_Nj>%R3^%$LEuxc%H#+U(-LI&vo^(K;XUiSBmz&B>Oy^ zx7%0{nJUc$5nJWGrm6tk_l~v3 zj~{Ow$3z9TVV7x&<2Y9Qw#L3~P=%;*&Y)i$smLpt&%+6Knp`sc^XCV@{CLC6=xt4# znM62QLFBi_4KpFUppq(H2P-1@`24)M>hv-AKe^%?urW0Nwg3PC07*qoM6N<$f;YeV A*#H0l literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/LimestoneSand.png b/src/main/resources/assets/textures/blocks/LimestoneSand.png new file mode 100644 index 0000000000000000000000000000000000000000..2dec5bdf6298b2b25fba4d21628e5caaca5ebcf1 GIT binary patch literal 2017 zcmV<72Oju|P)EX>4Tx04R}tkv&MmKpe$iQ>8^Jf_4xQ%ut;yh>AK&6^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi`@g@7P>F@$M}nR+6jGx_(bAarW+RVI`Pz| zrE}gV4zrS^5T6r|8gxP8N3P2*zi}=)Ebz>*kx9)Fhl#~v8_R9XN`^{2NgPpBjq-)8 z%L?Z$&T6^Jn)l={4CS@uG}mbkB928Qkc0>sRcxRP3sG7%QcR?1Kjz^daQsPf$>iDq zBgZ@{P$4;f@IUz7ty!2DcauUfp!3DHKZb$8F3_mi_V=-EH%pV2qvfWBLxYt`+oxsTHaAVXa(-2exN zz(|p@*F4@GZ13&gGtK^f0I4T(z1{}VQ~&?~24YJ`L;(K){{a7>y{D4^000SaNLh0L z01m_e01m_fl`9S#00007bV*G`2jv0?6A%Pu=8%5?00rGiL_t(Y$0gKPawFFPK+*eB z=SCm^azt_{$+jGp?*;hFUVwh=vTACi@dO4CAaaKn{h>XaI^tjd_z7YBXNfUleZpiJci-L9Oy_t6kFQ&_G8tJGIG>M{VxXGN z*&cU1e*1z)uv%Rc-AHZ}?Q+RzM_h=MQW0XH?>e+G9F99~R@c0|z9OT;Mz~%r(Z(pG zD2OTI`ZLj6n#qiz@2QKDsxWw8VTuy(93lxalM#YLXEoXwvMl3jamDUWijmIxsz zv_P)cYceHyd|s2~1#aj$cRg8IlN-h81J*}Ae*A=U0q-39*JrE?)J=mF5TfV#=?Nt@ z4|jLyte`APHv1FeKR^F7xxPawO$0{gQA#7FWV8c$UNZC}QVK{A{6O>`T{J+%7>QDv zrkxN&B+m@LeE5~sYRPi7LTYX3tV5WBzUy$-(_JoD=XiR0<*?n7kPM?ksSI6A>4V_u z<%O)MnA9y&X@=1ge4y_wv#SN?&appUkV+dCixpA|x^X0o7p!$iAy_PzWO)t=hQ6oo zPNd{WDN&XcVeA>Kr>JVI3nUcB(w1g^hu z>U+wnq@GL(-Z7ockijzy9YPu&*Pr>@Pk+K%OIFp~G!5fu5xz$rj(g6hBQKvnQIsX~ z>5TjPdwfikMiZpu?QKT_QiQG_c-w5r@{-APhCr}dE_hzQFuH-Zsi>+363nlb=yB+Y zAt99{#=z_AhSl{AqaFD4^%-q4zPtMY{6MlD^VyX54-W)4;Jn9%p6D#YFffiiZ8=g@ z4Kg|U{(_7lB1p7X3q(rHmMfa7AX^9E&`hR0 zKfjQbB}z%8)X1zRD{}HIgQiB#=5rQ{B`HP@hdsyLD{tEkulobm4pi-or_Bx*!Fx|; zB$uuuB{+6H=kCn$utzIFicn-3hKPy-Dme7%tsF^bFZ`%9g*Eao$s(xA2BcskQmC3#-ZcL(nkp%o;Pp_C#? z#cZ`iAkf-ybu~xtb~{$nk{CVBd`?l6>~?#s9msRTyLUH~S%LSSq;i^8(+>lF=rKy* z$DZZQ4W_85>V^bl^9kMM%=vsmi(m;U5qv=E#BaZSrfn*wlL>ybSUZAHoXKb^A!m=oz8e~NhD5hJ0_C}S)TEKPzOV}y*L8&00000NkvXXu0mjfcE`lD literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/MarbleCracked.png b/src/main/resources/assets/textures/blocks/MarbleCracked.png new file mode 100644 index 0000000000000000000000000000000000000000..b1bd018fe9a5920d82d4ce7aa7194376a2e66cc1 GIT binary patch literal 1877 zcmV-b2demqP)EX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wTSX5OIFwVKt*q_G{xI$9@-X9B&T>;~7s#{Lic2jutP|KUHp z|9}Y$aUA2lM?`pfnqec$C>vsffWN+eWiW`DPNxWh!-I!!cXw1(MPLG&rs4d2jB}2z z>o^<^$mh?0cxx>pf-#1oEZOh(j7B4p!2lZsD5a>Xiuruba5Us>JjQhn5fBkxjz>QK z`!hE;H%xD*xX#fu4bC~_`}hC)yeJ5*rD=0F)?{)_CuE{PD=&Zg24( zL<#fR0`Od2UA>`quETjxUDX&t&`Pu2?f}o=@)E5>wCalr;JoiIQo`A2#NFLJ#soBV z&G>vw6i0vuJYDAi5PC+8Qo>*mqm*zs9MD=5oKS!VrBHo+wwo=>^_tCQL)Ug>S&A1= z+GeClf=J)22xx6kN@0vKc<-^+QWPZuv~5dZ1Ms}T#zWh6)K$sN&2>+S^K3R7=Ce8B z?d=;9rF!HZFaj)BYpS~9Y$N>o$EzTvkU+$0yJE{yQC~j?(ZM?@cup426zueQSiLoP!t7uoW@ACKHlKj554DMiy%?6%w9#v(Z9(OPKR7A3+k zOHoSUoyUu(m!{XpybAR2_(HkJU*jyj;3u1tYwf4sGEww2joSL zHU?`gN))r%oZ)at6ouFzzze+wbzM_8HCdXG=LJa?5QQNE1SY^LMVchkbxmHD9p~dQqtOTv`N^)3Whq&fvRo|r@#6=k$P3QLV+KirK6NUhUX{l?$6r%w_nN945dVIHX0#Hv0N_un%?)}>w6R;iq(3><>iE%n;SlT z`pEtL!-<}^8^FWium^AH^PYQ@#NcU)h+Ly2%a zzVx|O!}IeqL0~D%imIy6T62DWjxnZ};)G1Sx**RBy!RwYg4T*SiWp`?q9_7{>+37( zy2W`<)6`sDU1P(5`-cbq^XH$;=X1)cq;rnWxi{8ivH0#c+g<;-YfW(K;F#wGK|e%B z89Y2TR$S}EGLWwl!4T*t4UKH@zb4ljhE<>_h0e7@j+KUc1lk=VWT P00000NkvXXu0mjfJtu?X literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/MarbleGravel.png b/src/main/resources/assets/textures/blocks/MarbleGravel.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef8d573d94d0f8b45705798b86e8bcea76e6ba3 GIT binary patch literal 2098 zcmV-22+jA2P)EX>4Tx04R}tkv&MmKpe$iQ$;BiK|6>zWN4i%ii$W&6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<`9$LO=im7)L~6rk+SIX5cx#?&0I>U6f~epZjz4DS49tK9P8i>4rtTK|Hf* z>74h8L#!kz#OK6g23?T&k?XR{Z=8z`3p_JqWK#3QA!4!E!Ey()lA#h$6NeR5qkJLj zvch?bvs$UK);;+PgL!Qw&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^ncx?gPjBLej70?oQ@e;?a+^91le16NwxUu^)hpQP8@ zTKEX)-v%zO+nT%wT+twLH7Y+b| z1VHdAlCnfnvg2vor%v+!`;eJF*ljb@bmB~G$Bre77Yigv;NT9N(+8#be!>3sUbBq1 zZ~volsZ3d|mROcWo)-lD0M~VCwPFwi zMA4BXj`2K?%gZ^2VbCf?r(?6*?a8tn%QOY=-+$oh>WZ=~Da(>Hm5c^Mmdk67#|W)8 zGEI5)>RXDkVDqq{+wD=+HCI>9Foj7N9s%h0`v_qm(-hb3VSN7mgANY|hQlGJ(}}?# zAdVBXR)B#p4D61L)|$)91w~P?+wD0CDJ4zQ(Cv1~^MbmrF-(D!k}S(eWy-^5i!e>b;}I9L3tYFyV!j{<0%r3I!tlWP ze8%%!#^VvckkabpU=pPoOkculf=oNJ1V6}k_4;Y@3Y(OsH&1~*P*H^vMfVuO<7e~ zmdS7s;Ce2T>6ARn2_HjD(_}ChVA(dex3@G+gJ}v3)8ze!-?(~q`9zTcoK7bWha*K% zVp$fgYWeq%KQf=qXxo-pO1?fm;(8wQ#hffniQ|MMkq7~<>r$2_lgWfv-~NR(P3d-f z{Pfd*F@E^r@A~%kh9pTy(+s5*P1A65vwlh&hO}+VY&Ihp3^+v*r_&i>nJg9yiaetz zO6-nJp5;%U7bWw>9AOv;0F5Tga@w|GI2=(|HTU=T6lICyIE3K=(5SX$G#VkL#4rq$ zRt!f&lu|^;i0yVqT~*vZzhOR`VcRxVzwh&P|A>?l%Q88HA&HdqdJb*dVhF+Q^IJ~m zggh^3ng+|V*za}>1_Rt)k2Fn*&oQPca9x*=zkMPI0zA*f>ewBEX+WOmw5`JPeO?T2 zP)ZRe65FyE4u?!96Fz?YM91l1I~|7h=&7z_gfIl_n>Fz{W;`CFl%lR{s;b5s35p6AiAEWltecuJYX z3C}JUltsyCJjVBZOw%MwGd_L#otH1aK}v~fn)rPmw5BMFC(-#XbyabSPFSAnQRD@! zYC*$td5z;ZoX=<8z59Ugd$^uUs~XPd6Q1j0nI>75v0ks(Znuji4MGTR)+>zHum7O|Oj9tM&uN>6H~;(> zFJFFxX_~lhkN6zpI9-~iVLTpjcXy9r7`SeiG<_1B<2aOM!Duujiq522hUdD7@nnQB z1w~O3MG;CVuCK4Tm`<5aCKw2srseW-f$w=7qlo`sT{T=@F8EX>4Tx04R}tkv&MmKpe$iQ>7wRhjtKg$WWau_=P%36^me@v=v%)FuC+YXws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi`@g@9g!FotP~nR+6*kx9)Fhl#~v8_R9XN`^{2NgPpBjq-)8 z%L?Z$&T6^Jn)l={4Cb}vG}mbkB928Qkc0>sRcxRP3sG7%QcR?1Kjz^daQsPf$>iDq zBgZ@{P$4;f@IUz7ty!2DcawrKp!3DHKZbz7F3_mi_V=-EH%pV2qvfY2?_z3TSX+{ftykfE-YZh(VB zV7N%xYaZ|JYVYmeGtK^f0OzQ3)+2RaiU0rr24YJ`L;&Cb%>cZLH-;1d000SaNLh0L z01m_e01m_fl`9S#00007bV*G`2jv0|6c#WsEQ%EX00l5fL_t(Y$32!?a~ru4g}=sa zE+mJftk_!TR{8(`CQrMSswA$sTx(krDN>vPW&m^^Myodz9=cDTKIZ`P+i(BWuIo5G zpZNUw&!iZ+-EPDbQB{KX7;C9jdHCglS}Ua#RKaxgWu;jvRoQNrLzPwONCg;o)Bb(ih>*YdG`0()) zUDuJOhBSAAkQFDb2J^LmCZD+oDx5M#wpH z8%Mgf#Tdh)GtL;H?>hig6=Mv}IZDoi;4#|`B^R0|tUzQ1GN(jZGV}S27(){Rw{axJ zgmacAG|VaCu9pkO8m#v;p+SJWEI98l#-gfNYXAY1S}V0wrfI@E3)XUexnOoXy0)cl z8l17@yiiKTPzz0Hc>Ml@+vSDt-@f8Qz=%NrQ5eSwtrZk%tt_RGtCC7#o)@~VrPPYn z%K7;j6_~~eRmJW0d#=|j`{RLH3U~MSfT9Sfq9`?ImXev%jEGQcp=(=8EhrFt;QaKH z#Rm$)>FJ4nvq7nt)AKVZ1m~zZ({FYNf{381ps?9(F=9Z3&@_mcH$SYXQ;Hbpan8{O z$8H!fMi5n;bsl34(|BWd_kpEkymPFo6E5dxYN<5+hU@E(GyBqM%QOe4-$V$|_6qZu>@~>YB&hz~EgL!6Q7 zp0RC**2>{-rA4a(ycY+MZ{Pl_##qvv0Kphxo@c5m%d*gffU%ZkUMRIb z0^7|7Yb>P{y!U|eaz4|v9Zp1W)x*3Iep7FuIHBeHD%rVhzdP-UOpO+a`Mc;}#9}x40 z>(@G}mFK4?swzfxy^JYgj6rox)v6We9NS^QT8DFMfLUwt-s3|6G31;nxga8M%28@n zcEiA&3kFrLmkX$pVkE`*9uv6~YAGyvA(z7Ce8L#Rc)b8%ty$@?mRc&c6tpS=Oerz! zb~u1>n(%qShlVBu(wx?)HL{NV_88rNe0YDktab0S`@`c@Qpp?S? zxL+yq!EEX>4Tx04R}tkv&MmKpe$iQ>7v;9oj*}AwzX)K~%(1s#pXIrLEAagUO{|(8Q3W zxHt-~1qVMCs}3&Cx;nTDg5U>;o12rOi;))n}g@7<3h$AF1Q%~m>^6(sA_we!cF2S?B&;2<Nu%s>LxK48fDJ&w53`EFipoTguBxu!0F_ESHq=$dl@n^^-ldA?s zj(KcAh2;3b|KNAGW_fbLO$sJ~{ukT+7zF~mK)Y$%-^aGyJ^}pCz?IhZZ?u4!Ptu!R zEp`Niw}Ff6t|spRmpj1FlP(#OBl&3xL0*7)(KpQzU=j3;9@n+>mDy&_5y;wT18e9vO| z^hBxZQYh%WeS5>nNtM}rj_7+1jb{y@K$6U;1RmY~kc(Gelg262`GBv!IwOu_Y|Exv z4cO&-oMMsbH00HbXY@y1ioQd%SkdkEv22Rk;}j6>VhLRr$g&JU(5U(zuIr*{7B63ZNwy4WG@68A$ZZtt7|4>%&CMnM`Q=B-r3ym6{k^l>(=ybynFPNhl(8I<0&(8W99lG)*N* zQWQldjx%ga=kaNXX=?0t0_Bp6X&LkfkC>*(!@~pRQkngF%VL@E{Pcv96VQ3M#c>>Z zy)j}GB^(CF>~>pPtp^OFK%Q(V7ELyrExzxwT5a(>k4nX35lsmEBgUf;+bXh(mpGL& zK@iYxcbU#-luABPl;Id9#PN7ew1`k;n{v5C6h%ze3p%YfdcmgCZc%n^{EE+HI^eke z9NV^;%@RaGq7symMGajuu`Cls*|W?R93J`Hc0M62CX0NYj!BY~AgHlSmb4#lIXi3O zSC07gmtUz?YixHBnx-=e=cuAYo@-cTnQWO7_|NGLZds;F@;s+f@laJ2avAaM<$qB% zl{}ZYYkfjDG)`)#Wa);>%eS08KcjtrO`hjGJq|didNi9&mfI=&d{3!d;_>mCWwfE! z?NPK{j_VC<%VxJ*A${$VZnwvge}p6|^hS?}vVdMNP*nvGh~tEVYCxXnL~%r` zb&=G0e)~6u-2t;S zWIkJBSSq@%V-yO^#xY7kMV4j4FvPGlDix2>aEPWFjK?FKlFMeDp@}j(Q9_hdo4S9B zs;N|~HCmrFq*GUkUa7<9Z$+Ki(q>62noK^=d^>tsqM>pIe`4G|o6bf5yj;_oQjcvqqDg zobSK?0pYjbE_2^EiRWu_ag8KeNUFweJ>}rA!S&S#5TI785yd+K&*tsh54`&FjBanj zK{a3!4$xJV**wAb%ZQ>ze=tH-K-?~uWXlY#pd$z>org9eOLE}u?uzHlm$V#S!I1eP#V`#_!=>W6Jairq1c4k0$MHFDHo3m}fL*jn zmwPld$1q*02Pvce3}HMR=O3?baoqy>R>HK3%ocsJY{$`&&tegwstPa8zogr1)9X)g ziUr2QDToTk$39UM;kq@l)s)Q|6h&aW+mP>N#LmM5u4@y93yQ7*V#aPSQ?35K0^dI* zO;dXPCjbr)J;K45(`FOH5V^kYU|AM zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3*bawNGGMgOr1Edkyv2R1@G(DHRIGK*$rq>w`D zjwabv#Z2ItYaY_idR!X+Kv4x-8C$9hg&%ax_ z`7HfS`LC3I{p9||>pwDWZa_b8gg;~`e|`VU*IoL4-TX}H&D)PV=lpf&->(Okf9?5` zHT^qh)pPcPm((gFIJM#{3NN4l=9adUqTCuwEHkAhrp};Yc1~Hw%yxJ zT5Q?ns-b!u7jyi||Mb`VCm%XT4dtAzU$J6cUY*7&lsV^&b$pDBxbp@z-2i|7{_&6U z8pvR}VXkbj+o3Cv{*l~wafO@czy}lGp9Xeiy%!)vtRS%%7s!CkE+m(oE#8~r9D%GP zsIzn*q93HirQ{cj^f81?a_9o?&F>U5{gha#p`JpD zDW#lBs;Q-(Lsp07T(S_gmr!C!C6`iaX{DPQYOJZ|T57GW_U2mvaZ{roTWziN&P_X4 z?)-M=1HBJF!iXb{Jj$q}jXu4ZVaAzeo@LhAW?z1VMIW!c%BriazTKvjcHC*_U3T4V z_d}_jaNpc|3T*d zoVUNq+Ul3+!p)G{P(ihU?%RbW)UdZZeTB2<AD?gbRP6sd;3i^4|&cQ@&PpmUtfMt97^_mOhY`Xbx+J#B&SA|z?* z)uyuGdyZ-7d)evCS&pd*=qfaQ&voqG6pJ#4+b7NfoJOKlAwc5Hx@=p6y6`P8OK5ZQ zRiHQ8HokB8V-v^|%7(vd;szwS#6H*^pX9#dSxxO>PbyKb@L~41>gYx9na&0jJgNhR z=rl(5uJ}2cr+!%m>#A#0Y|gb6Yw0VFVGAK;VM}u9#O|lDGY@`Zk*GDd21{SDZ0fz! zkAy3dheQzibbM|&!rQn}j8p|x+d7SQ)-t45McWVsj^^03aA{LZXmr}{JF)cMwe=L( z*uI72ec8L_mG+Gut2JcKX^(DirLG)+vyIdPO*Ch%)aBaqknb}`;$m^eQ$nIRMK7g= zqyC;?cB`)Bfii^^XQEQ8&u8qr@Zmc0<+QqO3WIvhoklvPo<(KQ=MX5Z?PE8?aSf_1 z=#`b?-cOB_EV|s00^es1LO%A;M(tUpJ&sjx)6rl_Z)uw}!d$)*Y#NTBhE#gvhPkcT zGS>k)KvtTXe9mj z5vxtV@(HdWA*vsBs}!4=gXnkAjw&vj^7E~YX4yBr=g6zNR${^-82}eTHAgrcmVy+As?xpn5krb~up)B$;YB*F2fMgS&&4CSp+(i)~b9<$1}wq;D4y3Biec$ia~{A=sW=UsqsXZ$ ziW1yn$I4)yx9A0&?9Z$|fy1$gZv|T-EkN-3@BnD`?u8~$8;J?%8>oe5OpWCfZc9a~ zA%Q1YB-t=3$jAM98YSA}2>~TK5(qm0OuE)msi^%1cn@w!rjB3tQWSrMY)xHoDh$>0 z3he;Db1sXt$<$DsN-T)b{Myui?GZ`(A!?pPLaD%%Xh9Orb>Y?! zl2A|{AfX%IvIMh2%TgAOLV%qYz-^PsJ`dU}+3((mu2{w-M?TcV&j4`hq$v;b>dFx; z#{jmFuTwT9QkLQU<)~dk;sV=*(n`L-x{A9Mc33P0vnP?BG}uUmGPH+;f@@@oUDggA z4a&1o@F~-D>;)Szi5ZkNJhedAi=;Odl`_0I?H&L{+Yx4DQ}!t{z`uMlLmSa$Y^sZB zU)sV;*>MQ~*abhSzY!AaM;u2uipH;6pt&nVx4`j7Kngz0Msw*`F}Cp3g6}gPk3|&0 z3L(Ey6{6}pAITOvBBmATFV+YGF;;N_p~r6|L`%AEDmfJK6}WA4v&2)_pxl?vcJ3)PY@ zew>^2QKYo;b;ANtwv#fX(aJv9Z4BtFCeOXr^15oesRg$LGEUUqr%;qtAUgNj(h*L@ z=L&Vv7uCPUnXj_nJ=vlx2L%qZ1VQ8Yj?L~PYrA<-E%flEh}z(PxK zM=_5APY5{b-YtnqRJXy*eklRW*Mi^ZmN>z%N86<1=iL&^TMmWf1#OVEo8s=Ccsq)dItzxeA~?XLM3i=>Id&*2t^V7WOF#oa{pZY_7Q8z=mYVpawpJ z@*Md>IfxdCJ{JPolWHV;ctNsxedNRk){3XLu5vR?*qx&S_6-|a7?G{#xzwvDDc9}+ z{7>8W4?&EPt3eA?n!jkO1av?;szUDU)GokYrW~L=43~3@CIsWTe!Iv3ze876*k%ge zHZ;kCID4(C?(13vTi3$1l4%plv13h848RNKi{2rRb38z0mqW1uxIp`&A3%f?!K@Jw z5HQHpZ1KQ}RbmHY!8*sYPAQ?B(ameonlp2usNn}w*1k#Os(DxAvz>9PgRaS3F4inJmid1P#lYys;vKmk&f452)_)EMo3 zBy%w`PMo02*o=rT*`g8br5Xe%2K8GVt!^|lMaNw2RWKB!I}PEADib>= zcB3w&MLcQph>?nwiSW=Y;2+yPZQOE%d&TP;2>W7SSp*3)uM(pTQZVW|*g^6Xss?G< zHqV zY?vBBN2KZS6duJLfDKWafju6H1k-76b=(;oVoScz^1@?dQEgm~$|w>c+Y)TdhFUgb zBND+L#PlJwTlwSAyDV#jTNGJD{3h$0-w>RfW*=Ax?k}08!oJc?(}Z3? ztvh^(zzID?^2uKpraFHq`hiq73UA`d`!f0jR?WRgMUi8#{BM@Pk~f)07$66HBmyv9 zq@EBGfP832T7>3;+i5o%XZ4~xRS1b5i)V3imfHYlYI~#7A8lsq*HyzOj&)fT7;E|hqfk){mh~PEh zfYDwrl!I*uY2YFNH{E}HP0dtxTpenVB8BR@sM*owK;ZPKI6W#hPg@gd0VA|)cX3b#&B7c%d? zL*9-Ee!#TFP+I_RxOO&OV99-NFs*}kE77MB&%<4c)w}R4 zlFU|uF@@oL{7nba;Cy0-J=2s25~H#+Zd|H=BXn?_vC_L9K~Simt$;-pbRSJKJ1H~@ z2R+J-cfcdZJk^D`>;~i()Jc-F1N5Y|^QK-99bY)wq*fHS$K;Bi!1Ec3hVFzKOfi~- z!AI+z{ox(a9*%b~%{yo+02HFFbQX(LjRW?P;7cgA3 z6Y2^X3Z-8AOo7yCMMPK|Rh!uNntDyN5>_5XZFlB2@B%b^lg4sDDfRR{qnJ@1+_0spk|8&+gP)x^!61{s zH%FOr@rGwX``Y|mn(7P>lj8|gFPiQYgJ|9wCLuPKbKg_1j;w&dv2g%=YZI@FTB;rC zu|NR4$Y~O6aBxgq+++>PH_}H9vnsp)@ez&O_JnUTO+-I8pe0O-3`_6(4=#x`EjUJ` zB`yms3cxy9s1NTAH{_JYJ-FMMePUx1y@MNlrw1O0*xuk2sgBScd(>178UD;OQ40^2 zOL~*;D04(?5l~P*kP93E{M=?#AEN>NP@!NtKu*6y2{h)2nw@RZ0o@=CB-UC5tjKe| z2H`P({bn(1h-eo2C|_IY5Gf7Ij*y9(0gMMb7r|oZQ)1~`{h(H+ms|*Yil=GXcSOpT zBj!xDtOPU`7!fsBesefI3rFrXbudeOhJ~bi#A_NB-H$-GH31jUC}>Z7zrmguCk)7= zK$~X1bl`aA{;x~$8#=JZ3>8wRNCo3fu8(3u`Q25)*7-BHC2GVL$dkL0pvE&u#NId- z57hP|Lng(5w~k76hW#ly$2RWuYjqCsRCZzIsJ;|GvCfSgrEfuo`0Mz^C^%_U^A;9SiQ z7g|W{^qJ(Qf^#*lwNMkh;R&qM0W1EU_vP=Al>`D!szF$w zL&7sr&|Dhkl=~1DVzbi0_k)qhi93D{60cCIfLEpnL4ctlc+gv9^E6bz`BPG;FjbqT zM!_J?y^aGU!|7RzSZES1nXBL>v1d8}IZXqVN-=`%=!WZNrl#3getHE@`<@q()}SH2 zTu>Na_}mH6etOgo{#r*Kr@bq*v4lHVDb>7ZJW!r+j@or(;jfF7Q>D?-I5cQ zYj{aUc}uT30lm_`T6)-KY(GeCm;uYD`LEB^>>~J`{vU^Yw3mYMBLq^DW8ps?-ZUXj zp)Q}WqW;S=A29yV%l_gb3<>I&AA@I$?qFkdoX*LgslN_^!nI@Ob7r%C&yNr^IKKxX zk#s@d!Q7R(qL;I8!Ry#h`T+K?-3$bu1{K%+K(voae@0-)gNPLX0;sZmhq>nwWstk*c!UIImle#;09k~^1yjoUM z+8ZHv>$CK^OPBnxbqu{dd(FMeY!*_QmFh_JdO^O%8 zbQvb|Qcy`P%}I)U1))pM*F_y&5p7__;B^M!@sZ<7E}i<2#+vl>7lacXW&FyAEP3j5 z29JJ|emUiv@@8DZRU(5c)RW@(@i-jO46kIh5?3o8K`x7fjI>pcaAI;V}r z1-KOFC=ZMr%gkG&@M-9(LAnGD*rcMSeGJHc+8il$mCMrd0$#egUBFz()XRg6YNkF`yM_%Oh$rAq}b>usZB2 zv;8{kqO$K0m;6Pe$0}Ucq4C$eI~<^000y^G1DedsQ)Qg*)Y-5^SdtZQ4OM^R zQR4IP$$OYM*XZJ>T&0o2A*Nq)-9kr35Zy2>J5KbVDu z^aY9xapDco5MKWVDj{o*o_mQJ&&nv&IpWttq{ys_8vkdYgdTfc*BRohp&8-<% zA?ctZx$SC?^Ler*N}knqop+Z90JvdvSljSvB6=OS9uiHUfn+u@O6UwijS3~(E!+`n z^8@VX=0i_A-Cg@~Uo_V>xVW(c4N%qL;3G}Q67JOox_9fz9Q>2NXDY>~CIS8)Wa~+a zT<=--&9k0Xk`l&M>)=?sMOPM`kkZr-gD2YFX=D-WxsRCOPt;deXk9K5XNpJ=PvF#~ zOQo_rmy^)>;XZyJfN0?F~Tv z!RUFO^1>f`6w7Ok=_e9|=hvB%q27SJ?+Lbsgz~f?VnS=%de4J;{XBg1X#UiOPcvxn00QM9vt#Qctf5@l9AU%<>rYN3($qVi(=$g;3spe{{jQ^YO^!JoIE(r;4h$FijIh zU30hD^6~KrnJ?GuRw-ByfN7kVr-3j|`SkgT-~aXlQ6#yR1@GT~Lo#U0?C6JyAWZ11 z0zC{62N-SW`kqz3q#p-V93bB9H_XNm1QOvxQ51MWBAw;i{f1O}3>J28?r7VQ0FN|F ziQ@?ATh8YTNhob#cPRmVBCyuN75{z?|Xt+ z(G?W|&^pU%z2fodMB5Hnz!!o{Eoj@8ejHdNDV`9Ru|qsxUU+)B@afAFNt$AW&w7!Q z#1XzH@McY54gdJ~FPgeWTF1-r$m{t;QI+&v&$Vg*sJfOcNy+k@$Mcnpw@=6ZAc=8QVP#nUg{R5 z6rvd?4%-#yqN3{uJm--wbJ8>gAj=jwK&g!9%Y{#;7hbLg+yqAWg0t|!ehvP2;~ zfpd=4dP!?$l)Pnmv!tqPvMk~0bRm>Jxl+t+g9rnTRfqLFx~V5m70XQVw~rsWTd&!z zR!GnDcsib_`+?nVO%wzizr50D!|%R1pdI*u-^NZE~y`hx%cyTeam7_!MzCJR459k~=0k@RpDV&6jq0i)4`GGORC4*NUI zG%?SX)oRIyUq5ia+tIhpFZ|4GZAGDkV>C*z69s!haO`L z!aDkPz-dj5BZ(Aonxcn^Bo29feWfZYvN*I7MvoKYI3h%do;CS0$9NutF#wF(P_`X1@qM(>NE~?_ z(hZv3;SGM^g0tWip24jnD8)2WhHk$C0|95T13| zX{7BsJiytBzN)c$MhLiEE{s}pyj(feJ+pCq|J?)on-t}TbmK@GM?60t31rA(kupq% zqHcMA*dcr&Fta6!BkH#2Tz++qZylJK-FC~QCl*=4o0|nUix^{OR;wGFb2LpwQ5C2l zz!*b$tqFZeo+Vgok%0;kPVo73MEVkA;4gpuJMZpyUxRK}{OWK=SvIV1GR9#biZiV6 z5q^W7XR5lT?gzH(70x-tFn(pBsE|$D5`-c9-7V62Xst2U@={#cZ8p3V9V$&wSqd^l z0R~_X_K}y%m2dCw5WdfA*&x$^e(JH>B45gp8#S{?Ba})BiS9)rIgJH-*fm%kz|@AQD5hB5i?tjiXw`>K{j2@e!b&%v-$tCSgmiU znv!c%^LDjhoi2F#? zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;eavVK#Mc=UsF9Gwg9E=g(ftT-dQPoXK-*1N< zwipu0?&>N4nR$l7}?~~*6`*@~hbF1a|6y|&VdEdXwz+a<(VkkbR>`LU{=xr&v@pJVy7S?TPplAA~ z&!zF+=&#?+=Tgs@{0=Ty{;e8e&|eoi-z)#}yRHf0`$`J=87a~7#uk2VpLPB3|NM6& zH=m)uA^#(!-=Exn@%pbwo4cT&H^N^L%HQw*@^zPfUN^r(dgJ!%$vJWDd%@mpQ+rRxNc~*?x!+eg}=#GEw;WIUzL)Wjx6fBG{2lZ(z#K{;pZcdZzgSEVruMb0^69hVUiciu%!cY!}&fB#Wj z0})JjnJW|QcIXa-efaAD&6Q^2mQ_XaExBS;L!1tMUx3&~|?i}$8D$3j*D z)ET-D(GSAnQu2#I`WQkcI8*`8<}=0JOMUXs%K#yPpz2I0#HNK#uwqQ)Pl=Tr>M5j{ zQp%~Mnp)~PWK~$sB@0n|2_=?Paw(;jR=TO7#+qubrPkVNZ@vW(H#O?9)z(_?JhXG? z&Zj#U^gjFuBaSrkD5H)x`t)Xo8E2Y#mRV<;efbp@b-eN_tFE^CcAHe%ai^Vk*>$(w z52<#-i6@SFYYoML91fG~LmnG~Gm6fq(gxAW<^Z|r^|mrTh2KXEez!vB9n&M0*MgUJ0e zZvQH3t6!oEH$o~yEvgMvUoXs+Ppkr>l{|Vqd)86TK69J~6pBk{SlQ&|1A`l^kDt-i z>2^G$bwG$g&CVK}J@~{JtVee%beEV+Mk(;x8oPU@xXoMqY=lgJFkGF7512CQI@dWU8{92!}8$z(byHVv#CQTZsWzR&_M; z^wM@NfofKl@7Af?$-5Is)5%(E^bQ&p5mf6>}y^m&azr82wB~4yEC$Uxxmtgd> zqW4UM--=?|c4$4F;Ks5kcybB=%y}s|W~IiUo?jrSqm?9wme2Y=HuJ6&%FtxVRG^l` z-FzEkXRl>wj%=73(b1$ej6N1mSk3xL&CC-SJ}FOW_8!VmK9!qK$MJYl2GMgLM*vM+ zv67QvD}N)2$A=mt7$b+B?DKoxA=;UK)+xm?S5}UBpJwQci2IR>-8p3ii5B&_2DJ{~ zQl?l&2{R>zi$a?a!sc;-arv?%Gs{XnG?M|i`AjTOV0C5ZLupfB#g}{Int`X>7!!4y zMoStIMaHro&!R`sO(5e;*h1{CLqx=G$9SZ!^m4HygTLwf$^K=F`V@DAcJ&3#` zwddgO;Q9hQ08RgdKClK1Dn$x#0CR*ypl=8}Fld*GdICmkRlw`CJrvvumbxC{8%m<+ zgGbbDS;gqfXqmOD#3gsbT21md_qhO{PI(o3%&>>P@t?5X2JtAcj5Xe%vtL)+Fqy;R&KYS z44BD=;aJ!aQH_*yV>0JxguFTCtvg{yeb;K8fHKd zCLJcY1W#m+SAO)*=jNc^Ch6!zQJ3fI(k}_h;~9)F?cUmoJvS37dKe`k-=hl&2{?CH zklBGEXlK@?r~cUCDWp2UIS2Bd2kVuIEw8)ea?H^=T}~ zF8#gegr-r0yBns24joE)hnIg1EMbVVV$UIt?&@iaKJ2C9`!&z;|E*Q6%DKLu9PO>vePM}ACshm6|S}`@n%{xHAv=>wwi|Nn| zUV}%EuDX>?LBgjJ)llZXXuGmQ6c7W%Bz0>dOTCy*>Ihx1%0rB87NT2<=!v`uTf8|n z^8tZRTL1Ptbs0_h2{@b~crJ29uE2&8Y| zAS5_4OCqdImU|T`t*%9ai^&`+3?bSvy-@!V1NEjPL5yaSq~}H6nH?4(K|=tyBd9K! zS}wXct+|OdEId*9eG`80aAtJbMZ<4e1)Gzp)UHGRH5PSN?~vb9G6uc3S?QeKHOP|H z{w6K&>U-b$axNpN4o}>MOT^WFn)V)x8~w`WP8T9F?Kx)_EVR8|;a-VPDM2!!1N95we0p>fx0K?zK?ii#6! ze>RdCOzS1?{c@hv5m=|GD7P_|G4msDc)(K1Ig_S`PGK*j#UGO*MWz$;FE zQ%#THNYP+^Al0j(0k~1_YGpEGG&zR#BYlp& z5cV>2ZPyz))QpJ$Qs$)Iy8=j^`X3_wOry3aNhQVi<$D?SLtZThJ6tktRSPn91 zqYj#S6>4Mv{n!q*cgmLlMi5_)`hnMu3A5A{VREurz9#7b*PCtli%O+i zT&LHT&1qxbE2y}O+IyNrI{tK()Lxm8L?CkcVeyjY^v3T}o5goAmv=|oBp8*=& zj!1Ea^7YT5PuxaGxFhX`Sfn&8g%MjqL58WMkAGGan()uFU{HSkQXcI$$Y8=6w+i| zHV#mcitMt&jD?i%MM&EO*zNWNSdAY9wgD0Rx1meTw5Js}&?4RmS$cW8g1FAMzv>tK z95CIO4ggOZktp)jx=>MqcBZB^Mu~*(v};E0&f;15!kRtFdKKT5>sFnXw2=g5sH}Xv z+Iz6(EH+hU88%FiuCeKoKo4m~$>j<^!@7(Kl`GK5pxMR8j#mO-MedqA*f7(WyX90}&0f`o&cjXk;^S z4fxwxB&qd;&okl975tSI++KUk@^Kf70a8b-5F>AoSvuPySBUx~7C1d0wc*(}H5(sf zRCYA(7Dbu!YD8-Oq6ekMOmOqvXtG^B$O~i^LkkFxpZ-;WS1F05#(bAbgNgvAVWC$q zYbI4yP;G5um`+fC!ZGTFT%87iezSc) zrM9`-lyhLs0*{a#MBYqd-_+eJZ*%7MW<1tK9ZoE5F}Dl%DtcaP<8~Ux?LG;iXDJV> z#uBIJq9jrGbdprkH^b_|K}t`uW{Mmp=pbe)rv*oSzLpy<{@KP8z}u|3k5cM1e@H{zTkNk`-PG=?4#o1Yoa{ZShJDv zpc=P?Hfr&X>e0?bgGH+m#zzjzdx%5OX@vM$B3w`30HcEvjD5BQ@*mwE(Ce4T%X06q zrpqG|d28Y465d z=QNfQYt@j)cMsyZH0P|nwYY{h;2fNtS}4t**(RQW(uVN>mIxk|s`;V=mUYjE;f|r*li*LHmapOj*g7QI&Q-Fk`f7t5j>=Z^8ZTeqU?Pb2^-aAH;dj=yNV=x z8vdXVbv8N~M(VCWE*s%n`4bxWu$mchyHVZ1CdMmJtGklx)7sDJnw&>MjDpT~m`v3B zCK&q?hEZeGY7qjO>F$69^orgbw`X$j|Q&LtB4&MNz)lW-bOgFcI19aMpQnwA>8!(fkN@BSr)mYg9vQ6MXSrYFi)*o4ewl`mg1so90t-X z=~7ogTMc~+hh7wv$?;wWQYvO@H=Ot8?01`$^}U@!CR7qU3m40q|I$7m=`$N8%++hCT^ethBq}Jq*6v2;2jNviL&dbt=7supGnc8HTC$%6lQCb&u&gEu`oYkk5>jaTGEk8%E6E4Q1+(Tki zv(@cPa&K#{j_}i84YwsWbhx9dmjj1u|0H^btlp~j!;-pRS3pQVn5!6IaFtwmy#k6R z6C@02YiJ?$NW3-?8v+?kmxi|UD|IV%^f=FG{?QjBdb5+`zVF)rdpdHMiDfD5gg^x} zq3UG=(5(J`ij=4s3=)DPICp|*qoqDr`PE>NAifxnL|k*A8Y;AF`@1tPVcv(KfIeL% zNT_a-cQ*>VKD%6VkSWcpg$rA6BKGW}l8rFMs8E7>8aAcP)wySC@Pq7!Y z)^#!gLVUYW)QHo8i1PLp2KL@He5S#(pbF5Dz=Z@A1Z1W1bBH><0reuuj<#$Bq)ko; zK45|G?lOjHPvQMGXQrQ4Gr0l8X@3W`c)L?JvZxwni#mcwQE>ln_YY7fG6-=N+e;ZD z3PAkuY+K^@i-te7kBcK1L?FlfcE*>Fm|Cl2DEG!bO8_=!&fQO>u<&n)AnF!}JXM}# zP@r~V5M5#z>emrT_#9aQBpEl3J*8@bQ@4!U|28gG5Z2=c8GOTXqXUK*TBlXSTd+)g z3jK_CN5VW?5+pt2!_dtkzrhDO7eMN*_9fb&PP+n(G3UcCZ7zVWlpK}hHNk8~CjCz_55gU3C_I!8y z!nXrm*1tTL1P(vA0|go#Tk%+ebIq9?>mt`5U5U@>cefb}AHv<|yefs^RkfdOW7+p} z{>P~Ec{{Nk8vo(5E+|J5_ZkreV6F$|kXnd7|{i_SDU7rX`lHpl;Pe$Y6?2?cF0!OS|@V4nG(_&cmvK?OHYJ9AF5o=CwZH zO#G`_{~Cl21A#(A`!P~9(lg;UZ5uKbByDwgN(7U^6nOCZ_*9($rV?C5jYb`TdaNPY zl7IHpnpLWMT*Zd`P}8PR(gf>+Nrl^8)GTWCdoTm4fYH0d&3v zU`JH&!~%<35cB%;?>mOKJZP^IAiuUwRmoV!rE_EwLPuIrrz_jDhcll&oO)$8Yt#}5 z*;>hV+k43GRrl$qPl}tbSoM1M!Xk-48UjeReA<0UxhtWi-VX3?J&+;1TCk{-T2c4+ zZ6uXnbzHKCQQnXSUrv=tqn`SJzZz(<^lB8NP`K(-s&nw+!k)E zplXR8xgeCUSRp3;?pboZeJsScY2_5q#*!g);F)%+&cwWe-$>oD;LSevXdv~1&Q)a! zYu&@m2(pZS0xY0vL}c0ULiz0GETL)g671*@pO+ z3*!?uQUju)gP-CRwo6mPxHt{1&WxcO8+6%519tmx9SS z}tw+VG2YU5y4oc@QyNgJQ#&-J&zjSo=3GCVt25^?A4?HM)q80nhrN}l+%arUn& z#hiKM8nQ%(hAc2{2X8?UI%TA}!*qY1P$kptU_(ZMp~|SNdn+-&(0A=(Qm7HVKgK|k7OD(t%~u#56BGt|DX5xS*t6c^UU%<8>l+6GX*TeUXZZK1w2o&W4p5GO|9=ASNqtP>WqC&c000JJ zOGiWi000000Qp0^e*gdg32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rg2ow|uI|r-7 z7ytkO8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b28T&RK~zY`CDB=O z+lB#v;U7ClfB-=f1W8e}q(oj~$4=A9WZG#n(?j&BC+IDFh~6k^`qECLIE`$@u`Ej5 zcVZ#2_aPVfUOwR;fB#!KoiFj+7UPEz{nI|{Af)ZN^!j~%e)ERQCzlAKMz~v&Wdgck z;PyKF=ezGP>JDw!L)R2m(=m(1l7fO-#X!|H#LLfKpsNziR*UB^Kc{9{Xp%_Hv`FKW zm%sapI8GUjM^r3}YTcqU7;ro$eD%jaV`>^A1&RoHnvoS5$0%mC*&xay^6mR~)a@FE zX^ad<@6HDpzx-Dz|7={ZS!Aj=Dm zam;M7MAKC!lNr5^M^P52S{2Xr2!fEN>$2YZ@8`Ch@ z@AnjvL|GOTMNYVn*ljjEd+{9C^{{Q5z-F5M|0b-J6 zByrB?uRdoqnxLsFH`h1(boB70xcsD6#@k6seeX z?uKLL%Nfb>NE&BUYZYWgQRoi_%qL^&R*k0XBC8UCu2Gg?+cpmmBhuuEuBqs{#Jid)9-S1^#hh^ar$TgMb05j zkyM346k(ZFthx;Xc-=1R-43g6GF!|Db|JlP7ekYY(}YU3N|EQtjb;Nu6q(QGNTP_{ zXmaAU$+9DPRaNRTK4G<7v)}BgHyl2xRw(m~C_K>hJihmNek4s(E*?MO>B|>{Sx&2eieWk=1w20ggj&rc%~K}h5mlqgWHLn-O42xIHJ=j( zKJg(UihR6ohuzjkdev>c{^gfnsTjYl*USoxr764p4!6;yTGe?N-jgO7kIqgJyB&`&fBy=rW?)pSNTNVlLLNn|r!!uD z@dbhiNs_WzZ7>@){nI{{U8C)J=(<9dCq#Q6Q4|nL0lQ|Ss0zW}M=Zn=r`{kh3&ztK z!{LZ`Z{L#UIfW#X*e!P97T0ajv~7|kB?(IKSFb9%iV zs;Xib2D90mx9{GPBstPwzxmVaLm1+EEn2N6X_nwPbvh@f@s>1A`S17NVpJ_Io;(3S+Xozv2U?95qA0Qo)?EGY6N)DDe`Xa* Ufu*Ubg8%>k07*qoM6N<$g3@?8X#fBK literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/GraniteMonolith.png b/src/main/resources/assets/textures/blocks/RedGraniteMonolith.png similarity index 100% rename from src/main/resources/assets/textures/blocks/GraniteMonolith.png rename to src/main/resources/assets/textures/blocks/RedGraniteMonolith.png diff --git a/src/main/resources/assets/textures/blocks/RedGraniteSand.png b/src/main/resources/assets/textures/blocks/RedGraniteSand.png new file mode 100644 index 0000000000000000000000000000000000000000..28abf603622a5e2f2c682c6b9fec27d9c69190db GIT binary patch literal 10019 zcmV+;C*0VHP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3;wawNHOrT=3UvxLAKSPq_M+JTlo-|@&~vHD)g zG&ZX0CRv%05dhr%JRG1q|M?%+{U83++KNk=uf3FqKdGl420ygt{WI*Vf0BKD|M7j# z|NXlAc_Z*rPo*~;hj!|Q?T!{_z&xzFJB{Od;jeBPLUzcD^H3hncN&+Fd@MgKnF z`P|rz&y8aEJUPApp6|4t(p&vKh4s1qe%`lb;D4ttDb`SO@ip-^g{Rii`MHHBRn~25 zpm&9?&*k~K(Les}zLy5Z6i)Q<;cL?fqyG1C@V)Vsf9skU`8mdFulIMPL@T(b@^k;L z>wo{}zZ<#x4*e7Ize4)+lm9PX{}pLx3;KN{{v$%==lj2X-RD2AyWb(Txcz!^DL+sC z>-Bs5`fJYLsOkTEcf0qzvm2=}{J)X;mh`*mj z&9=bbzyJKBxJDwFZJ8Sr9M9Ap2>;CfPjW>IbmYR!_qTw3-Jct8s`o5pBS3?phnT`7EI#M38DvN?7J@?+@N7O)y*V2 z>7=^(Sh)TI=@~UT~5X zGa?p}C*V~P@X>{!m_5y>6cjnd?CAo+92jI)aJE;(h+sNC7TLiaz2+`q={-$iW?Bf4l2QWOFDic{lS~EwkR2Rl6wYbYv7&9}w9DO5OC!=M}iCoUSpGr|=>tQvP<57bfk99!HwS&sFrIxfJG`}8B}1?l#ZTME>KpjOXbl( zoP%Hhm7hPWmG+!ZFLQWbNTI;`qgNip1bDJoGVthdE2LXdxyF5|()amP>RL9kT$p7V zC5Jf+Nj9Qq($7#>Y`DGOE1@;!1^K9={B-6WM(Sm60Oxi}atENV+zBA{lvkQ5fMqFqcax>cI4!yht&o~!l0-9(vsggOPZnOnS71pXR zMVM5jgfqkluL`}Y;H;H3H+KxXPFGpK#khliW(B}OUf_ng!i*FWcb`lWtxr840te1@ zP*H`m2-#_5Cq$YZOtbc)T5G5oa%QZc0a-o!r9Oq=;sdQ)5Cz#v0zAb}Sm~tRsIN7z z3nZvONcaLBcaUbV(tAC7&DGQ3kkarsRRhNezhz9GN} zyO7F}Cx{}1Et6@aJkpbl1912^I?EHYU7yRy883$ciVC*NsPz z3TQl%9f`ZBpa#e=5p|!?39=B6)OJOx0jse9dg@9osC}$oyozG+iGoDe2THxbf2^sd zi6EeO!*Et9)g+Ge4Z2MBNuT4+KCnvhtv^0YxpCKGGz_K+pmCuLy!PY(WHk)LH$eq; zGUA6NG{Jy~!*xI|d7I_)(()y1p|{?w{zxid0fcHU7!xf*WVq~Akoogeyc_w$<;`-p=>X^f$e}nck%5FajsW3C?f}eEVYl3z&K-LZ+Jp=LP|gc z3^djqcSk~!KLCJ?*DG{nw~$6Hm9vcdk=^#hOF_T!8z})$p!kn{ zMA210%+dK1(T7BgTomV-(sRAMQcqt&eJ<5tz#ak}a26m@xCk*u$zmX#Ps*PKz^xxmvSdz zw?L?4WckjRqVsZXfDa|HQFEL6$gBqpiv`dOfo3Gu>lG;FOdd90S>uVgkQ!mxdEXsr zDA}<;X6!+)*ZCJUT1P3bjUcm)ekP)60!oxW*?qon0b(5uzs0%B+wb20`+l|uRjX0 z?*fvwgU?FtknSv?r5bR~Y~c^JJu*4oZ9{~-+MxoIFfSlRE@xs)Zs2P$L})&&hC}Ue zo7J+EfWWt78BD4Z-9JJd_W+%PlxqwONJ(mbs4F%>^8=5$juHOlu~ypaAeI)@PJZFI zS0RZ=Zm~gwieAb2l#welr%qAaSS$AsdBHh_6=fsLYARo5N>%D7oKO%IKm;Vo5K2+b z9!1mGkk}NM)Wsr+npE-XK2k=XcHzz}$qEZ8(Kob2;!LU^>q@M6D5Vdhykv-Ga+#b$ zl_c3o_2JZS*cWTm!KW)r0*eE%x1Oh+*!a=^(^z2jk4w~vf5ce$sRGHxYL~>N=^p6y zFI3EBBEd^!qGo1L#*(fH2iZ!I>Tj4=N|C#wFh8JHC}NSkwew`Q%xTQoLDHZNOa6H~ zSc6w_xnejU{L<$UTV*<>ba(jlv4qNMl|p-f5NOM@AkA}1{x1-6$2|^G;b0;NVO_6DVy=)4Eb^UGm;a1ex>daiS5m^OP1;63feSOHd+B@V94_z{QdfSp+~- z`b38UJIxXeE}0oYvy-}71!_!Yg!~(yC*^O;^a-W-jIL$v`zN#9uhin%GeP8(V@Tk1 zCx=?FZlBuhco?FNl0diQyx}w{Q}o(EtR^SflRo;0K(Aw+UVJ&VLkKR(pw8-RiP3$E za?y?}4(eU@R=DoC8DF@3%bCJ^Fv(pHuL&ke*RN*O!xXkSwT57}vh4@k8^87K+DqA1 z;s_@I+D61Z-Yy_ zFsNquRkT!CrhOfGX_JEdA1sLsXZ^juK}k&5Yh}#wpT=%kyO3b>B|r0<-UMV09~(%a8xc!0 zy^ISy0q(s&(G5E-APL=n30M3kphC5S7#nDeF|BbhaJ3x&fY=D3Dlz`*H9*oWlcDLp zEYgHID^K-E)$@IKF<2Yw`RQn{{f-z?{G4z)W85| zi4;m$BA$g_8#IqWGpw?(Fl16r!u>Iz7JhkP#JW1*#D7*6s!j$&6_afJEfsXq*DL_# zYCm~Yl51D~o1{~(aTKYwUp`Y!=&)4+FELk<-PrIPQquE!fuD)vqSk;HL>hvvy#w9m z{>p2@JxcLvZ|VTXxMX=jI3-G?HJ)f0%Lnds9~4RxbIqKKRj-7WbR71uz_c`oz8fPQwRl-VBPDkjiw0Sbd*ApKZOWP?Qf1w?rlkx|s$ zklot3@53MgPr&wK$ZSB?w|FFJ;@7b`BwAl9L>!W~QkL2nm|z5&HtEnT@DwA~{@7J} zrCNIm2oi)3ZD*jn!4CKC1O?mN>v;9GhUj5c(l?eR6;CPc`}QOAD|5Vz65?=yNQCE* zTn?Ru4E^!ph|W1Z0IFNR2~a*Q-lZ0Io_I|1p5*k}7~{*NNUF!wAn36h+EAO)ld?-P zOR`Gj8m1DJyZf59dEDOKLb(7_il9jH+9XA1{|@%Rb&zYQ)HFT0m=OsG&<+El@iyz+ z@4IuFxhSeTln?@%8g`vBRU>TuroYN?s;u?4R8V8S1V!<+!%zduHey5PkgiD@-wo^u zMuvjj`O$}j!lZ2V65t1J?yNWxfT#|12|gi`j~fgojNWevCBjYAUf(R)6`xa5lO0O+ zMW`&G6exK$wcGi&MtDHdehYNfNh|cOlVyPk;lZFy5f~Bf`Po}N%WGpU{%hkta=lCr z>93c(izvgSRM!TuT(fdbG^hsuC-=f^UYpLK{lclD!PWXus+on-9?@`9U0ZJ2pI4== zXzkffk{BLd?LiH4_L+NPmSQuwlOY|+I(8@vfXTfWgh(bXwZREpJKJQIsxebCO4omE zj5iVraw-8jnF~AFM|S}kM%HAQmVxKiZD%d1H|0&SYVW|DefzzK^T0&fiq4_o0CAzt zy3V%u71YGeKd^?b6i6Mpz6b{Yk@9Ft)^eI44Y0D|4^zv1YJc~$8}iN+9E7={!c=_A zXs<&;j1HX$T$6NDlj35X5bHqIc7NGSbzDRY2%4S`1clN~pM6NR3#CJaeaQ6g`z%Mh zCbb(Lm5M&aAY$yo)@GD8$Rsm5$`B$$Nq}QW4OmM;!TyngN zItz$l>wZJ++ey!xE}UOo7}O(9wQ5fl#z~>{77+jd@8gm5vhO(NtW7Zt{M3H#$#3;b zOoJTDA_SD#*|@2=${AA$0V_-HSfjdc9b~CKf)RFX^K?YAlSLgV#dld=*M`iq&C6JWTR>HMaz0RVPK!5(t{w zp>i zuny|}nQj%ch5Ry`(+McB6(P}%ohS0;jy! zdUK@Je)opIanKo!LdI+mevJ6`i9pe|ot~mI4eP5fArst;W%(GNcA7-ZZi{k#nq8=V zu5UOY9LgIaS9MfDnqH0J{Y?V7Nu=cLO$|Tr2z#i01NDR{`bRBhkPn?5l5G}5ZE|SO z18J!iPhyn%EWZR-fLB_b3(hTrtpYYIpB*24f*pP!0uNA!F~8qU6D}1-a!B5F7ctVb^x8 zr9Ld!A6)kEho|Utnp)}LCorcTihA&$?Nvkt3A<+`g9ht_R#ST^7f&2;fD?BF|Ee6D z4yqhdO}|2T}(W#T)Z4ZLYvtL|-^p##FF z9;(_H+s|jNc67!sgRwe@v7W13t+;v?5g6HOfy}dgLDq(Ar)Ovml}=Y+_^Qo$^qT*@H{3ZIYI(Akfoy*KoB%!dvGs_6;EwrIA1#dAMc7ktJ7{(^fVx`)>K<_q+kRe@pt~)vNY76U+^)fuSk`z+k<-1ByY6+7G$pK09d47z}4+ zC|d^kX_Z=|l=v`avnm~Lqa#Mzxk?j*@SY(FsB2fFwM!CAkIN-0U^w*gbvKzbA{?He z2Ptml&!_Q5vJWh`ueP)7bhPzk#ss5J6eF`&(t2$SK|v70b9KgSZp?Ga`0KX|xw4(< zQv2N0g0n8B^3fXEQOB4UOfo4Wcf!w%g9=pIhW;m9ghkw7(D&iIYy6B=v@)re;QK*(Ld|ZLCUK4s_qjJr6iZ{l`M9jCBq`Z z5O5snGS6H(AoOOB8lM%NS+vZQ9M}UEmrxpdAF(01hD>o%3SFCiCv=^r4!gGs zNsk!=3Jbd!Nz-~_4Z;j5@}SO3)wvQ2%}y(c&l(z@wNvT2B%|MpP8*=G$zVCL?bNf-h#p1^t z0P_0SE+^It>^!p|n`?cXoiNeqG%6nPH{=oJKR>5T($qm%9rfBi;37e(&siB&Jw>;) zgR#~w!laf45(SQinc&l<@y0l_1>r=bf-9;CCn z-G7c~2v0k1EDE1D8TrJZH2))vSrx!b=gi}nZmI>#cvJ1R^*YnmQ4%>?HR)lk9bo;p zZ?^5^`}1o>S$l8^S z0%??fS-axBbey|8o#%f0jP30+{yiHVZEtd3Rqaj?^vPSejH5D!p2d^UK$YtmQaNjY zv4K=x+ReoT=ywYC2=+T7=zH5-CEkBFIdf}4J9&6pB3pCBwNE}BRB#aD)2~}B?Tg)t{T>4O-Lx~WUyp$i z3MTld=`Pcm#E9e(1+#^MDZl+@+0tSiv76QVWi`ga&;=dSfi}lPq~Q8R6(VA-HwoxA zpX-1j#2T?#m{^_seE=M(-0#U>P?m+$#Do$kFH_sntnkIQ192p?ex;HWK!JiA6zS2{ z*bQ%EJeR+Wr?!WQO#s;Xd<$FM!(>MpfQtI_>kp{$#H{zRHWZo;w(X_bw!`>+YRgmN z^1*XqGWGi+0Jio={lD1}0eFAdH`bP2y`}fd+w&TK{hC)u1y!Vfuz1f$-(K5*RR<$3lF1N^F0ss8^1B?DSyu{qGza9wCS(kl4(w7V7(5Q0)j@J z4Y^4Lw{2S?+Al4h0oH~XBFe?&9T(`>vs!IBCwtVqz>;(wkG>YTGqvgW zwpsgMZB{?Tpgn1?(h=LFLkdm3pt)5aP-gyhQm5ja>rb2K-B6R_7$(F>GHXD)PX`)H zc%#mh)}UVqwbQ(QwXulm`TVj9D%Tf4t1m1dq|7IV!Z8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b z2FOW7K~zY`1;I&gTn7Qb@&DV`neoh<&G9&1VkdD@QkphxMN?4JqOzPo0wICKrQ(Lf zl@tC3d;kte9QXuWP=Nyy5-n0o$>!McKA!PxZ?-pYo%bHUpYZ!%{VX5P7ql96#-7jJ zy}MjrUlW7@^+ugAj1jT~MK2J{N2ulsuIo~ADwK-_^x_KMV2JAu>2x~?fT4&K>=GOI z-aw25h420J=UfiQ^d~dC$rz{6#Hl!p-6{3v8oFr{BnhdaV--wf!=P9w5c?sW<0CFE z&nfB}x9{BL{-gJi6^-d)&eiLei0?iAfU9T!;okNJ@4x+kBm>>FAxWrJ%bXq_kO?BC zqQT|$5M9yOy}gT5tx{QSAS5xCDsw%!W-%JDxH?CXM7%}F)|>AlJ>FW|e|mgM5Qb!N zLS=0oNl1D5;suHr8+1aIgaY_;eq?y2^bB$?RsJemg`7Hbeoxy;jVWO%s z^FbGBr&->2>;mJ-jJH4dkUWWTuiBI=4vV?RV&Y;KiX0suA!T4FDhqGMd_Lpys!bS# z7`jFnh9t|FTX*iUSS*;#J<>Es_~UPXosR|s)^6Tp?hdg_CER|WMZBc7zD|Y!Sw^&s z(R1(vA4%0vb%P*DNTP^RsmQ3;AxkpiJf~vYXoi7NTtW0_6EbrC{;$s&xKmtrN~v68 z7RE%21+oB($p|&e*?jZ?x@9qOM|}R(*M#02NfB|HYi#V^r@p$%jYgH`_BPJ?CUbX) z@aNzCCU4xl#o4Q8NahMfRbVg};M5v;u1jw+WoLH>#VRqpJY(U_2}7Ul`wzG{I;2#q zFr9ihDuRCa>Ea#5jz(I(&(t>ZHDhgn**zw9igBylAtrv%_LC!Rue* zP9{{Ft33Sp`@DMo6kXHkcX|{|15uW#-MmGy)}T}@k)}(wTMeXlZ*T3-LLW;viQ|aV zt1h}GViikNYc)J~MCg0OQNr1EA0>?lT^B@w$;=~@Wi(Y`KAjRwMgS~kQ<_^_%qKIX zPk;QweO;2MZ{FhQ-~eZ3g|7~du{4eLRhve$Nwam6z?<{vqfd||i71Y!)@qb&lkMAk zuuPC-m67XmadFD}+B&0N4^bA7GXzvkXVz_FS{563?x83mGe1BUC4@BL;`k8DGWhpj z|3b+&5ppmso9=ZVMb>DnZ!#GVn2*O~x<Wxk4RIEP zh_D zkGGzDLZx0qQ#I^r9r2sr*rPufaPZ|9Ox+QEcScG^^~O5KhljK~T^d`v6ioxwv{>KX z<-y}8D2hUYfGkLK`$L+wGET{+ck~>V31+FxXaD#c!e@W_L!KoOz1Ih5hRJy5p$QqD zACSZmmSrJ|5@Fy|zjd4L>jMNqAd_UawzfGsIiXy%31%LZS`~LR!Zu8TAfV!u5y@h_ z!8MW~;Esmaip2BdQ=&A%&FU~HAL;=OJ z5ham>^ER3yljj-Iqt)`hJDnktBZ?xU>6}8PjA5A+3ng^BgcpQtx7G;agqb%d@#e^) z$VI2a@p+pp&Dh;&F=$_)83wI}LzZUvVT|0|+9g}Y96Wzcm@K(>_cnXqdcx5c|70|o zAqyfwlrRj2Xr_v#8N}oqy?V)7bB*=p4cuX$;c$SV>WFzp97X7M5hV(c8k)G@tk?PO zFFqw6^$>vZ#R*{$k|YV1uA^%*tvh!J=X2ir_y^27=j^@n9w#TK1fI)m?qMo2nrX9s z{~^7La|Z4hQ2=58mp{t)ws-j7i|15}MWSShsjGy`j7q(UEG&^!mC<;Lo@eA)j|j zeQlFkqlTzx*cAuUaS+IO=lyRp4I-{OR~VKJKpZc*vG)Mi?USY{(oeqg;eHZDAmkKG zlXBg`Dy*PuI@M+ii6u#zQLu|hvP`$v!*Qxi-2rjnQ!W)4dkg#^MAH>&Yb~ Date: Sat, 21 Aug 2021 23:05:54 +0300 Subject: [PATCH 61/63] Added rock DB and worldgen - Added Rocks container - Added DiscreteNoise and a DIY Worley generator - Added RockLayer - Used to generate rock strata - Reworked SurfaceTerrainGenerator to use contexts --- .../util/noise/discrete/DiscreteNoise.java | 25 ++ .../noise/discrete/WorleyProceduralNoise.java | 228 ++++++++++++++++++ .../generation/planet/PlanetGenerator.java | 2 +- .../planet/PlanetTerrainGenerator.java | 36 ++- .../world/generation/surface/Surface.java | 39 ++- .../surface/SurfaceFeatureGenerator.java | 26 +- .../surface/SurfaceTerrainGenerator.java | 51 ++-- .../generation/surface/TerrainLayer.java | 6 +- .../ru/windcorp/progressia/test/Rocks.java | 126 ++++++++++ .../windcorp/progressia/test/TestContent.java | 38 +-- .../progressia/test/gen/RockLayer.java | 57 +++++ .../test/gen/TestGenerationConfig.java | 44 ++-- 12 files changed, 574 insertions(+), 104 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/util/noise/discrete/DiscreteNoise.java create mode 100644 src/main/java/ru/windcorp/progressia/common/util/noise/discrete/WorleyProceduralNoise.java create mode 100644 src/main/java/ru/windcorp/progressia/test/Rocks.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java diff --git a/src/main/java/ru/windcorp/progressia/common/util/noise/discrete/DiscreteNoise.java b/src/main/java/ru/windcorp/progressia/common/util/noise/discrete/DiscreteNoise.java new file mode 100644 index 0000000..3e600f0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/noise/discrete/DiscreteNoise.java @@ -0,0 +1,25 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.util.noise.discrete; + +public interface DiscreteNoise { + + T get(double x, double y); + T get(double x, double y, double z); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/util/noise/discrete/WorleyProceduralNoise.java b/src/main/java/ru/windcorp/progressia/common/util/noise/discrete/WorleyProceduralNoise.java new file mode 100644 index 0000000..258e9b0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/noise/discrete/WorleyProceduralNoise.java @@ -0,0 +1,228 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.util.noise.discrete; + +import java.util.Collection; +import com.google.common.collect.ImmutableList; + +public class WorleyProceduralNoise implements DiscreteNoise { + + /* + * Stolen from OpenJDK's Random implementation + * *evil cackling* + */ + private static final long MULTIPLIER = 0x5DEECE66DL; + private static final long ADDEND = 0xBL; + private static final long MASK = (1L << 48) - 1; + private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) + + private static long permute(long seed) { + return (seed * MULTIPLIER + ADDEND) & MASK; + } + + private static double getDouble(long seed) { + final int mask26bits = (1 << 26) - 1; + final int mask27bits = (1 << 27) - 1; + + int randomBitsX26 = (int) (seed & 0xFFFFFFFF); + int randomBitsX27 = (int) ((seed >>> Integer.SIZE) & 0xFFFFFFFF); + + randomBitsX26 = randomBitsX26 & mask26bits; + randomBitsX27 = randomBitsX27 & mask27bits; + + return (((long) (randomBitsX26) << 27) + randomBitsX27) * DOUBLE_UNIT; + } + + public static class Entry { + private final T value; + private final double chance; + + public Entry(T value, double chance) { + this.value = value; + this.chance = chance; + } + } + + public static class Builder { + + com.google.common.collect.ImmutableList.Builder> builder = ImmutableList.builder(); + + public Builder add(T value, double chance) { + builder.add(new Entry<>(value, chance)); + return this; + } + + public WorleyProceduralNoise build(long seed) { + return new WorleyProceduralNoise<>(this, seed); + } + + } + + public static Builder builder() { + return new Builder<>(); + } + + private final Entry[] entries; + private final long seed; + + public WorleyProceduralNoise(Builder builder, long seed) { + this(builder.builder.build(), seed); + } + + public WorleyProceduralNoise(Collection> entries, long seed) { + this.entries = new Entry[entries.size()]; + + double chancesSum = 0; + for (Entry entry : entries) { + chancesSum += entry.chance; + } + + int i = 0; + for (Entry entry : entries) { + this.entries[i] = new Entry(entry.value, entry.chance / chancesSum); + i++; + } + + this.seed = seed; + } + + @Override + public T get(double x, double y) { + + int ox = (int) x; + int oy = (int) y; + + T closest = null; + double closestDistanceSq = Double.POSITIVE_INFINITY; + + for (int cellX = ox - 1; cellX <= ox + 1; ++cellX) { + for (int cellY = oy - 1; cellY <= oy + 1; ++cellY) { + + long cellSeed = permute(cellY ^ permute(cellX ^ seed)); + + int nodes = getNodeCount(cellSeed); + cellSeed = permute(cellSeed); + + for (int i = 0; i < nodes; ++i) { + + double nodeX = getDouble(cellSeed) + cellX; + cellSeed = permute(cellSeed); + + double nodeY = getDouble(cellSeed) + cellY; + cellSeed = permute(cellSeed); + + T value = getValue(getDouble(cellSeed)); + cellSeed = permute(cellSeed); + + double distanceSq = (x - nodeX) * (x - nodeX) + (y - nodeY) * (y - nodeY); + if (distanceSq < closestDistanceSq) { + closestDistanceSq = distanceSq; + closest = value; + } + + } + } + } + + return closest; + + } + + @Override + public T get(double x, double y, double z) { + + int ox = (int) x; + int oy = (int) y; + int oz = (int) z; + + T closest = null; + double closestDistanceSq = Double.POSITIVE_INFINITY; + + for (int cellX = ox - 1; cellX <= ox + 1; ++cellX) { + for (int cellY = oy - 1; cellY <= oy + 1; ++cellY) { + for (int cellZ = oz - 1; cellZ <= oz + 1; ++cellZ) { + + long cellSeed = permute(cellZ ^ permute(cellY ^ permute(cellX ^ seed))); + + int nodes = getNodeCount(cellSeed); + cellSeed = permute(cellSeed); + + for (int i = 0; i < nodes; ++i) { + + double nodeX = getDouble(cellSeed) + cellX; + cellSeed = permute(cellSeed); + + double nodeY = getDouble(cellSeed) + cellY; + cellSeed = permute(cellSeed); + + double nodeZ = getDouble(cellSeed) + cellZ; + cellSeed = permute(cellSeed); + + T value = getValue(getDouble(cellSeed)); + cellSeed = permute(cellSeed); + + double distanceSq = (x - nodeX) * (x - nodeX) + (y - nodeY) * (y - nodeY) + + (z - nodeZ) * (z - nodeZ); + if (distanceSq < closestDistanceSq) { + closestDistanceSq = distanceSq; + closest = value; + } + + } + } + } + } + + return closest; + + } + + @SuppressWarnings("unchecked") + private T getValue(double target) { + int i; + + for (i = 0; i < entries.length && target > entries[i].chance; ++i) { + target -= entries[i].chance; + } + + return (T) entries[i].value; + } + + private int getNodeCount(long seed) { + int uniform = ((int) seed) % 8; + + switch (uniform) { + case 0: + case 1: + case 2: + case 3: + return 1; + + case 4: + case 5: + return 2; + + case 6: + return 3; + + default: + return 4; + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java index b568639..b2c5c8c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java @@ -104,7 +104,7 @@ public class PlanetGenerator extends AbstractWorldGenerator { DefaultChunkData chunk = getWorldData().getChunk(chunkPos); if (chunk == null) { - chunk = terrainGenerator.generateTerrain(chunkPos); + chunk = terrainGenerator.generateTerrain(getServer(), chunkPos); getWorldData().addChunk(chunk); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java index ab081db..dba3b8a 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetTerrainGenerator.java @@ -17,6 +17,8 @@ */ package ru.windcorp.progressia.server.world.generation.planet; +import java.util.Map; + import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatRangeMap; @@ -26,6 +28,9 @@ import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.generic.GenericChunks; +import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.generation.surface.Surface; import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; import ru.windcorp.progressia.server.world.generation.surface.SurfaceTerrainGenerator; import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; @@ -33,25 +38,38 @@ import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; class PlanetTerrainGenerator { private final PlanetGenerator parent; - private final SurfaceTerrainGenerator surfaceGenerator; + private final Map surfaceGenerators; - public PlanetTerrainGenerator(PlanetGenerator generator, SurfaceFloatField heightMap, FloatRangeMap layers) { + public PlanetTerrainGenerator( + PlanetGenerator generator, + SurfaceFloatField heightMap, + FloatRangeMap layers + ) { this.parent = generator; + + int seaLevel = (int) parent.getPlanet().getRadius(); SurfaceFloatField adjustedHeightMap = (f, n, w) -> heightMap.get(f, n, w) + generator.getPlanet().getRadius(); - this.surfaceGenerator = new SurfaceTerrainGenerator(adjustedHeightMap, layers); + + this.surfaceGenerators = AbsFace.mapToFaces( + face -> new SurfaceTerrainGenerator( + new Surface(face, seaLevel), + adjustedHeightMap, + layers + ) + ); } public PlanetGenerator getGenerator() { return parent; } - public DefaultChunkData generateTerrain(Vec3i chunkPos) { + public DefaultChunkData generateTerrain(Server server, Vec3i chunkPos) { DefaultChunkData chunk = new DefaultChunkData(chunkPos, getGenerator().getWorldData()); if (isOrdinaryChunk(chunkPos)) { - generateOrdinaryTerrain(chunk); + generateOrdinaryTerrain(server, chunk); } else { - generateBorderTerrain(chunk); + generateBorderTerrain(server, chunk); } chunk.setGenerationHint(false); @@ -64,11 +82,11 @@ class PlanetTerrainGenerator { return sorted.x != sorted.y; } - private void generateOrdinaryTerrain(DefaultChunkData chunk) { - surfaceGenerator.generateTerrain(chunk); + private void generateOrdinaryTerrain(Server server, DefaultChunkData chunk) { + surfaceGenerators.get(chunk.getUp()).generateTerrain(server, chunk); } - private void generateBorderTerrain(DefaultChunkData chunk) { + private void generateBorderTerrain(Server server, DefaultChunkData chunk) { BlockData stone = BlockDataRegistry.getInstance().get("Test:Stone"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java index 296e3eb..08c9308 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/Surface.java @@ -17,18 +17,28 @@ */ package ru.windcorp.progressia.server.world.generation.surface; +import java.util.Random; + +import glm.Glm; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.util.CoordinatePacker; +import ru.windcorp.progressia.common.world.generic.ChunkGenericRO; import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceContextImpl; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceWorldContext; public class Surface { - + private final AbsFace up; private final int seaLevel; - + public Surface(AbsFace up, int seaLevel) { this.up = up; this.seaLevel = seaLevel; } - + /** * @return the up */ @@ -43,4 +53,27 @@ public class Surface { return seaLevel; } + public SurfaceWorldContext createContext(Server server, ChunkGenericRO chunk, long seed) { + + Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) ^ seed); + + SurfaceContextImpl context = new SurfaceContextImpl((ServerTileContext) server.createAbsoluteContext(), this); + context.setRandom(random); + + Vec3i tmpA = new Vec3i(); + Vec3i tmpB = new Vec3i(); + + chunk.getMinBIW(tmpA); + chunk.getMaxBIW(tmpB); + + context.toContext(tmpA, tmpA); + context.toContext(tmpB, tmpB); + + Glm.min(tmpA, tmpB, context.getMin()); + Glm.max(tmpA, tmpB, context.getMax()); + + return context; + + } + } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java index abfbcb3..3548184 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceFeatureGenerator.java @@ -19,15 +19,9 @@ package ru.windcorp.progressia.server.world.generation.surface; import java.util.ArrayList; import java.util.List; -import java.util.Random; - -import glm.Glm; -import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.context.ServerTileContext; -import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceContextImpl; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceWorldContext; public class SurfaceFeatureGenerator { @@ -48,23 +42,7 @@ public class SurfaceFeatureGenerator { } public void generateFeatures(Server server, DefaultChunkData chunk) { - - Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); - - SurfaceContextImpl context = new SurfaceContextImpl((ServerTileContext) server.createAbsoluteContext(), surface); - context.setRandom(random); - - Vec3i tmpA = new Vec3i(); - Vec3i tmpB = new Vec3i(); - - chunk.getMinBIW(tmpA); - chunk.getMaxBIW(tmpB); - - context.toContext(tmpA, tmpA); - context.toContext(tmpB, tmpB); - - Glm.min(tmpA, tmpB, context.getMin()); - Glm.max(tmpA, tmpB, context.getMax()); + SurfaceWorldContext context = surface.createContext(server, chunk, 0); for (SurfaceFeature feature : features) { feature.process(context); diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java index a3511bd..35b4a58 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/SurfaceTerrainGenerator.java @@ -17,60 +17,73 @@ */ package ru.windcorp.progressia.server.world.generation.surface; -import java.util.Random; - import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.util.CoordinatePacker; import ru.windcorp.progressia.common.util.FloatRangeMap; +import ru.windcorp.progressia.common.util.Vectors; import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.rels.AxisRotations; +import ru.windcorp.progressia.server.Server; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceWorldContext; public class SurfaceTerrainGenerator { - + + private final Surface surface; + private final SurfaceFloatField heightMap; private final FloatRangeMap layers; - public SurfaceTerrainGenerator(SurfaceFloatField heightMap, FloatRangeMap layers) { + public SurfaceTerrainGenerator(Surface surface, SurfaceFloatField heightMap, FloatRangeMap layers) { + this.surface = surface; this.heightMap = heightMap; this.layers = layers; } - - public void generateTerrain(DefaultChunkData chunk) { + + public void generateTerrain(Server server, DefaultChunkData chunk) { Vec3i relBIC = new Vec3i(); Vec3 offset = new Vec3(chunk.getMinX(), chunk.getMinY(), chunk.getMinZ()); AxisRotations.relativize(offset, chunk.getUp(), offset); - offset.z -= DefaultChunkData.CHUNK_RADIUS - 0.5f; - Random random = new Random(CoordinatePacker.pack3IntsIntoLong(chunk.getPosition()) /* ^ seed*/); + SurfaceWorldContext context = surface.createContext(server, chunk, 0); for (relBIC.x = 0; relBIC.x < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.x) { for (relBIC.y = 0; relBIC.y < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.y) { - generateColumn(chunk, relBIC, offset, random); + generateColumn(chunk, relBIC, offset, context); } } } - - public void generateColumn(DefaultChunkData chunk, Vec3i relBIC, Vec3 offset, Random random) { - - float north = relBIC.x + offset.x; - float west = relBIC.y + offset.y; - - float relSurface = heightMap.get(chunk.getUp(), north, west) - offset.z; - + + public void generateColumn(DefaultChunkData chunk, Vec3i relBIC, Vec3 offset, SurfaceWorldContext context) { + + int north = (int) (relBIC.x + offset.x); + int west = (int) (relBIC.y + offset.y); + + float relSurface = heightMap.get(chunk.getUp(), north, west) - offset.z + DefaultChunkData.CHUNK_RADIUS - 0.5f; + Vec3i location = Vectors.grab3i(); + for (relBIC.z = 0; relBIC.z < DefaultChunkData.BLOCKS_PER_CHUNK; ++relBIC.z) { float depth = relSurface - relBIC.z; - BlockData block = layers.get(depth).get(chunk.getUp(), north, west, depth, random); + int altitude = (int) (relBIC.z + offset.z); + location.set(north, west, altitude); + SurfaceBlockContext blockContext = context.push(location); + + BlockData block = layers.get(depth).get(blockContext, depth); + + blockContext.pop(); + chunk.resolve(relBIC, relBIC); chunk.setBlock(relBIC, block, false); chunk.relativize(relBIC, relBIC); } + Vectors.release(location); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java index 7af46fa..5ec131c 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java @@ -17,14 +17,12 @@ */ package ru.windcorp.progressia.server.world.generation.surface; -import java.util.Random; - import ru.windcorp.progressia.common.world.block.BlockData; -import ru.windcorp.progressia.common.world.rels.AbsFace; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; @FunctionalInterface public interface TerrainLayer { - BlockData get(AbsFace face, float north, float west, float depth, Random random); + BlockData get(SurfaceBlockContext context, float depth); } diff --git a/src/main/java/ru/windcorp/progressia/test/Rocks.java b/src/main/java/ru/windcorp/progressia/test/Rocks.java new file mode 100644 index 0000000..ebf31fe --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/Rocks.java @@ -0,0 +1,126 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test; + +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; + +import ru.windcorp.progressia.client.world.block.BlockRenderOpaqueCube; +import ru.windcorp.progressia.client.world.block.BlockRenderRegistry; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.block.BlockLogic; +import ru.windcorp.progressia.server.world.block.BlockLogicRegistry; + +public class Rocks { + + public enum RockType { + IGNEOUS, METAMORPHIC, SEDIMENTARY; + } + + public enum RockVariant { + + MONOLITH("Monolith"), + CRACKED("Cracked"), + GRAVEL("Gravel"), + SAND("Sand"); + + private final String name; + + private RockVariant(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + + public static class Rock { + + private final String name; + private final RockType type; + + private final Map blocks = new EnumMap<>(RockVariant.class); + + public Rock(String name, RockType type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public RockType getType() { + return type; + } + + public BlockData getBlock(RockVariant variant) { + return blocks.get(variant); + } + + private void register() { + for (RockVariant variant : RockVariant.values()) { + + String fullName = name + variant.getName(); + String id = "Test:" + fullName; + + BlockData blockData = new BlockData(id); + blocks.put(variant, blockData); + BlockDataRegistry.getInstance().register(blockData); + BlockLogicRegistry.getInstance().register(new BlockLogic(id)); + BlockRenderRegistry.getInstance() + .register(new BlockRenderOpaqueCube(id, BlockRenderRegistry.getBlockTexture(fullName))); + + } + } + + } + + private final Map rocksByName = Collections.synchronizedMap(new HashMap<>()); + private final Multimap rocksByType = Multimaps.synchronizedMultimap(HashMultimap.create()); + + public Rock create(RockType type, String name) { + Rock rock = new Rock(name, type); + rocksByName.put(name, rock); + rocksByType.put(type, rock); + return rock; + } + + public void registerAllRocks() { + getRocks().forEach(Rock::register); + } + + public Collection getRocks() { + return rocksByName.values(); + } + + public Collection getRocks(RockType type) { + return rocksByType.get(type); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 9e868b4..1244560 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -29,8 +29,6 @@ import java.util.Set; import java.util.function.Consumer; import org.lwjgl.glfw.GLFW; -import com.google.common.collect.ImmutableList; - import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.audio.Sound; @@ -59,6 +57,7 @@ import ru.windcorp.progressia.server.world.block.*; import ru.windcorp.progressia.server.world.entity.*; import ru.windcorp.progressia.server.world.generation.planet.PlanetGravityModel; import ru.windcorp.progressia.server.world.tile.*; +import ru.windcorp.progressia.test.Rocks.RockType; import ru.windcorp.progressia.test.gen.TestGravityModel; public class TestContent { @@ -69,6 +68,8 @@ public class TestContent { public static final List PLACEABLE_BLOCKS = new ArrayList<>(); public static final List PLACEABLE_TILES = new ArrayList<>(); + + public static final Rocks ROCKS = new Rocks(); public static void registerContent() { registerWorldContent(); @@ -150,33 +151,16 @@ public class TestContent { } private static void registerRocks() { - List rockNames = ImmutableList.of( - "BlackGranite", - "Dolomite", - "Eclogite", - "Gabbro", - "Limestone", - "Marble", - "RedGranite" - ); - List rockVariants = ImmutableList.of( - "Monolith", - "Cracked", - "Gravel", - "Sand" - ); + ROCKS.create(RockType.IGNEOUS, "BlackGranite"); + ROCKS.create(RockType.IGNEOUS, "RedGranite"); + ROCKS.create(RockType.IGNEOUS, "Gabbro"); + ROCKS.create(RockType.METAMORPHIC, "Marble"); + ROCKS.create(RockType.METAMORPHIC, "Eclogite"); + ROCKS.create(RockType.SEDIMENTARY, "Limestone"); + ROCKS.create(RockType.SEDIMENTARY, "Dolomite"); - for (String name : rockNames) { - for (String variant : rockVariants) { - String fullName = name + variant; - String id = "Test:" + fullName; - - register(new BlockData(id)); - register(new BlockRenderOpaqueCube(id, getBlockTexture(fullName))); - register(new BlockLogic(id)); - } - } + ROCKS.registerAllRocks(); } private static void registerTiles() { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java new file mode 100644 index 0000000..5b41ef1 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java @@ -0,0 +1,57 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.gen; + +import ru.windcorp.progressia.common.util.noise.discrete.DiscreteNoise; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; +import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class RockLayer implements TerrainLayer { + + private final DiscreteNoise strata; + private final SurfaceFloatField depthOffsets; + + private final double horizontalScale = 200; + private final double verticalScale = 10; + private final double depthInfluense = 0.1; + + public RockLayer(DiscreteNoise strata, SurfaceFloatField depthOffsets) { + this.strata = strata; + this.depthOffsets = depthOffsets; + } + + @Override + public BlockData get(SurfaceBlockContext context, float depth) { + + double z = context.getLocation().z; + z -= depth * depthInfluense; + z += depthOffsets.get(context); + z /= verticalScale; + + return strata + .get( + context.getLocation().x / horizontalScale, + context.getLocation().y / horizontalScale, + z + ) + .get(context, depth); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java index 22a66d7..cc1ff8b 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java @@ -26,6 +26,7 @@ import java.util.function.Function; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; import ru.windcorp.progressia.common.util.FloatRangeMap; +import ru.windcorp.progressia.common.util.noise.discrete.WorleyProceduralNoise; import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; @@ -36,15 +37,19 @@ import ru.windcorp.progressia.server.world.generation.planet.PlanetGenerator; import ru.windcorp.progressia.server.world.generation.surface.SurfaceFeature; import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; import ru.windcorp.progressia.server.world.generation.surface.TerrainLayer; +import ru.windcorp.progressia.test.Rocks.RockVariant; +import ru.windcorp.progressia.test.TestContent; public class TestGenerationConfig { + private static final long SEED = "No bugs please".hashCode(); + private static final float PLANET_RADIUS = Units.get("0.5 km"); private static final float SURFACE_GRAVITY = Units.get("9.8 m/s^2"); private static final float CURVATURE = Units.get("100 m"); private static final float INNER_RADIUS = Units.get("200 m"); - private static final Fields FIELDS = new Fields("No bugs please".hashCode()); + private static final Fields FIELDS = new Fields(SEED); public static Function createGenerator() { @@ -68,31 +73,36 @@ public class TestGenerationConfig { } private static void registerTerrainLayers(FloatRangeMap layers) { - BlockData granite = BlockDataRegistry.getInstance().get("Test:RedGraniteMonolith"); - BlockData graniteCracked = BlockDataRegistry.getInstance().get("Test:RedGraniteCracked"); - BlockData graniteGravel = BlockDataRegistry.getInstance().get("Test:RedGraniteGravel"); - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); SurfaceFloatField cliffs = FIELDS.get("Test:CliffSelector"); - layers.put(Float.NEGATIVE_INFINITY, 0, (f, n, w, d, r) -> air); - layers.put(0, 4, (f, n, w, d, r) -> { - if (cliffs.get(f, n, w) > 0) { - switch (r.nextInt(4)) { - case 0: - return granite; - case 1: - return graniteCracked; - default: - return graniteGravel; + WorleyProceduralNoise.Builder builder = WorleyProceduralNoise.builder(); + TestContent.ROCKS.getRocks().forEach(rock -> { + builder.add((c, d) -> { + if (c.getRandom().nextInt(3) == 0) { + return rock.getBlock(RockVariant.CRACKED); + } else { + return rock.getBlock(RockVariant.MONOLITH); } + }, 1); + }); + SurfaceFloatField rockDepthOffsets = FIELDS.register( + "Test:RockDepthOffsets", + () -> tweak(FIELDS.primitive(), 40, 5) + ); + RockLayer rockLayer = new RockLayer(builder.build(SEED), rockDepthOffsets); + + layers.put(Float.NEGATIVE_INFINITY, 0, (c, d) -> air); + layers.put(0, 4, (c, d) -> { + if (cliffs.get(c.getSurface().getUp(), c.getLocation().x, c.getLocation().y) > 0) { + return rockLayer.get(c, d); } else { return dirt; } }); - layers.put(4, Float.POSITIVE_INFINITY, (f, n, w, d, r) -> granite); + layers.put(4, Float.POSITIVE_INFINITY, rockLayer); } private static void registerFeatures(List features) { @@ -101,7 +111,7 @@ public class TestGenerationConfig { "Test:Forestiness", () -> squash(scale(FIELDS.primitive(), 200), 5) ); - + SurfaceFloatField floweriness = FIELDS.register( "Test:Floweriness", f -> multiply( From 59129f95c99d820d3e40b1875ec737bb7887c466 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Sun, 22 Aug 2021 14:04:42 -0400 Subject: [PATCH 62/63] Why -Idk this has to be "Sand" and not "Test:Sand" --- .../windcorp/progressia/test/TestEntityRenderFallingBlock.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java index dc789df..5d4ddab 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java @@ -21,7 +21,8 @@ public class TestEntityRenderFallingBlock extends EntityRender { public TestEntityRenderFallingBlock(String id) { super(id); - cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), BlockRenderRegistry.getBlockTexture(id) ) + String dflt = "Sand";//(String) TestEntityLogicFallingBlock.FallingBlocks.toArray()[0]; + cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), BlockRenderRegistry.getBlockTexture(dflt ) )// TODO idk actual ggood this .create(); } From 175f092673d5eaca32e95ec62aeb10052f16c457 Mon Sep 17 00:00:00 2001 From: opfromthestart Date: Mon, 23 Aug 2021 13:33:18 -0400 Subject: [PATCH 63/63] Fixed some stuff -Added default gravity block check in server -Some things I had to copy since i didnt merge right -Adds all gravity blocks to FallingBlock list -LogTop debug thing to check for good textures -Some texture rendering(see above) -Some control changes since I need to get to the edge quickly --- .../ru/windcorp/progressia/server/Server.java | 77 ++++ .../generation/planet/PlanetGenerator.java | 3 +- .../progressia/test/TestChunkCodec.java | 41 +- .../windcorp/progressia/test/TestContent.java | 4 + .../test/TestEntityDataFallingBlock.java | 9 +- .../test/TestEntityLogicFallingBlock.java | 125 ++++-- .../test/TestEntityRenderFallingBlock.java | 7 +- .../test/TestEntityRenderJavapony.java | 381 ++++++++++++++---- .../progressia/test/TestPlayerControls.java | 15 +- 9 files changed, 527 insertions(+), 135 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index e975b90..c3cbb03 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -18,6 +18,8 @@ package ru.windcorp.progressia.server; +import java.util.List; +import java.util.Random; import java.util.function.Consumer; import java.util.function.Function; @@ -25,12 +27,20 @@ import org.apache.logging.log4j.LogManager; import com.google.common.eventbus.EventBus; +import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.jputil.functions.ThrowingRunnable; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.TaskQueue; import ru.windcorp.progressia.common.util.crash.ReportingEventBus; +import ru.windcorp.progressia.common.world.ChunkDataListener; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DefaultWorldData; +import ru.windcorp.progressia.common.world.GravityModelRegistry; +import ru.windcorp.progressia.common.world.WorldDataListener; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.rels.AbsFace; import ru.windcorp.progressia.common.world.rels.AxisRotations; import ru.windcorp.progressia.server.comms.ClientManager; @@ -50,6 +60,8 @@ import ru.windcorp.progressia.server.world.tasks.WorldAccessor; import ru.windcorp.progressia.server.world.ticking.Change; import ru.windcorp.progressia.server.world.ticking.Evaluation; import ru.windcorp.progressia.server.world.ticking.TickerCoordinator; +import ru.windcorp.progressia.test.TestEntityDataFallingBlock; +import ru.windcorp.progressia.test.TestEntityLogicFallingBlock; public class Server { @@ -79,6 +91,71 @@ public class Server { private final TickingSettings tickingSettings = new TickingSettings(); public Server(DefaultWorldData world, Function generatorCreator) { + world.addListener(new WorldDataListener() { + @Override + public void onChunkLoaded(DefaultWorldData world, DefaultChunkData chunk) { + //PlanetGenerator.this.planet; + //LogManager.getLogger().info("Loaded chunk"); + GravityModelRegistry.getInstance().get("Test:PlanetGravityModel"); + chunk.addListener(new ChunkDataListener() { // Falling Block + // spawning logic + @Override + public void onChunkBlockChanged(DefaultChunkData chunk_2, Vec3i blockInChunk, BlockData previous, + BlockData current) { + Vec3i chunkWorldPos = new Vec3i(0,0,0); + Coordinates.getInWorld(chunk_2.getPosition(), blockInChunk, chunkWorldPos); + + /*List underBlocks = getGoodCardinals(fallBlock.getUpVector().negate_()); + + boolean notSupported = false; + for (Vec3i v3 : underBlocks) + { + Vec3i inWorld = occupiedBlock.sub_(v3); + if (context.getBlock(inWorld).getId()=="Test:Air") { + notSupported=true; + break; + } + }*/ + + //chunk.getPosition().mul_(16).add_(blockInChunk); + //LogManager.getLogger().info("Put block {} at {}<{}<{}",current.getId(),chunkWorldPos.x,chunkWorldPos.y,chunkWorldPos.z); + + if (TestEntityLogicFallingBlock.FallingBlocks + .contains(chunk_2.getWorld().getBlock(chunkWorldPos.add_(0, 0, 1)).getId())) { + chunk_2.getWorld().setBlock(chunkWorldPos.add_(0, 0, 1), BlockDataRegistry.getInstance() + .get(chunk_2.getWorld().getBlock(chunkWorldPos.add_(0, 0, 1)).getId()), true); + } + if (!TestEntityLogicFallingBlock.FallingBlocks.contains(current.getId())) { + return; + } + //LogManager.getLogger().info("Cont"); + if (chunk_2.getWorld().getBlock(chunkWorldPos.add_(0, 0, -1)).getId() == "Test:Air") { + LogManager.getLogger().info("Inserting FallingBlock {},{},{}", + chunkWorldPos.x,chunkWorldPos.y,chunkWorldPos.z); + + TestEntityDataFallingBlock fallingBlock = new TestEntityDataFallingBlock(current); + + Vec3i worldPos = chunk_2.getPosition().mul_(16).add_(blockInChunk); + Vec3 floatWorldPos = new Vec3(worldPos.x, worldPos.y, worldPos.z); + fallingBlock.setPosition(floatWorldPos); + + fallingBlock.setEntityId(("Test:FallingBlock" + floatWorldPos.toString() + + String.valueOf(new Random().nextFloat())).hashCode()); + + chunk.getWorld().addEntity(fallingBlock); + //invokeLater(() -> world.addEntity(fallingBlock)); + + //chunk.setBlock(blockInChunk, previous, false); + //invokeLater(() -> world.setBlock(chunkWorldPos, BlockDataRegistry.getInstance().get("Test:Air"), false)); + + + //LogManager.getLogger().info(String.valueOf(chunkWorldPos.x) + " " + // + String.valueOf(chunkWorldPos.y) + " " + String.valueOf(chunkWorldPos.z)); + } + } + }); + } + }); this.world = new DefaultWorldLogic( world, this, diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java index b2c5c8c..0b626c4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/planet/PlanetGenerator.java @@ -21,7 +21,6 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.List; - import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.FloatRangeMap; @@ -58,6 +57,8 @@ public class PlanetGenerator extends AbstractWorldGenerator { this.terrainGenerator = new PlanetTerrainGenerator(this, heightMap, layers); this.featureGenerator = new PlanetFeatureGenerator(this, features); + + } /** diff --git a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java index a9298a1..f4e81c5 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java +++ b/src/main/java/ru/windcorp/progressia/test/TestChunkCodec.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import java.io.DataInput; @@ -33,13 +33,14 @@ import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TObjectIntHashMap; import ru.windcorp.jputil.functions.ThrowingConsumer; import ru.windcorp.progressia.common.state.IOContext; -import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.DefaultChunkData; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.WorldData; +import ru.windcorp.progressia.common.world.DefaultWorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; -import ru.windcorp.progressia.common.world.block.BlockFace; +import ru.windcorp.progressia.common.world.generic.GenericChunks; import ru.windcorp.progressia.common.world.io.ChunkCodec; +import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileDataRegistry; @@ -75,7 +76,7 @@ public class TestChunkCodec extends ChunkCodec { } @Override - public boolean shouldEncode(ChunkData chunk, IOContext context) { + public boolean shouldEncode(DefaultChunkData chunk, IOContext context) { return true; } @@ -84,12 +85,14 @@ public class TestChunkCodec extends ChunkCodec { */ @Override - public ChunkData decode(WorldData world, Vec3i position, DataInputStream input, IOContext context) - throws DecodingException, IOException { + public DefaultChunkData decode(DefaultWorldData world, Vec3i position, DataInputStream input, IOContext context) + throws DecodingException, + IOException { BlockData[] blockPalette = readBlockPalette(input); TileData[] tilePalette = readTilePalette(input); - ChunkData chunk = new ChunkData(position, world); + DefaultChunkData chunk = new DefaultChunkData(position, world); + readBlocks(input, blockPalette, chunk); readTiles(input, tilePalette, chunk); @@ -118,9 +121,9 @@ public class TestChunkCodec extends ChunkCodec { return palette; } - private void readBlocks(DataInput input, BlockData[] blockPalette, ChunkData chunk) throws IOException { + private void readBlocks(DataInput input, BlockData[] blockPalette, DefaultChunkData chunk) throws IOException { try { - chunk.forEachBiC(guard(v -> { + GenericChunks.forEachBiC(guard(v -> { chunk.setBlock(v, blockPalette[input.readInt()], false); })); } catch (UncheckedIOException e) { @@ -128,7 +131,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void readTiles(DataInput input, TileData[] tilePalette, ChunkData chunk) throws IOException { + private void readTiles(DataInput input, TileData[] tilePalette, DefaultChunkData chunk) throws IOException { Vec3i bic = new Vec3i(); while (true) { @@ -137,7 +140,7 @@ public class TestChunkCodec extends ChunkCodec { break; bic.set(xOrEndMarker, input.readByte() & 0xFF, input.readByte() & 0xFF); - BlockFace face = BlockFace.getFaces().get(input.readByte() & 0xFF); + RelFace face = RelFace.getFaces().get(input.readByte() & 0xFF); int tiles = input.readByte() & 0xFF; @@ -154,7 +157,7 @@ public class TestChunkCodec extends ChunkCodec { */ @Override - public void encode(ChunkData chunk, DataOutputStream output, IOContext context) throws IOException { + public void encode(DefaultChunkData chunk, DataOutputStream output, IOContext context) throws IOException { Palette blockPalette = createBlockPalette(chunk); Palette tilePalette = createTilePalette(chunk); @@ -165,13 +168,13 @@ public class TestChunkCodec extends ChunkCodec { writeTiles(chunk, tilePalette, output); } - private Palette createBlockPalette(ChunkData chunk) { + private Palette createBlockPalette(DefaultChunkData chunk) { Palette blockPalette = new Palette<>(); - chunk.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); + GenericChunks.forEachBiC(v -> blockPalette.add(chunk.getBlock(v))); return blockPalette; } - private Palette createTilePalette(ChunkData chunk) { + private Palette createTilePalette(DefaultChunkData chunk) { Palette tilePalette = new Palette<>(); chunk.forEachTile((ts, t) -> tilePalette.add(t)); return tilePalette; @@ -193,9 +196,9 @@ public class TestChunkCodec extends ChunkCodec { } } - private void writeBlocks(ChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { + private void writeBlocks(DefaultChunkData chunk, Palette blockPalette, DataOutput output) throws IOException { try { - chunk.forEachBiC(guard(v -> { + GenericChunks.forEachBiC(guard(v -> { output.writeInt(blockPalette.getNid(chunk.getBlock(v))); })); } catch (UncheckedIOException e) { @@ -203,7 +206,7 @@ public class TestChunkCodec extends ChunkCodec { } } - private void writeTiles(ChunkData chunk, Palette tilePalette, DataOutput output) throws IOException { + private void writeTiles(DefaultChunkData chunk, Palette tilePalette, DataOutput output) throws IOException { Vec3i bic = new Vec3i(); try { diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 1244560..99c41fc 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -256,6 +256,10 @@ public class TestContent { register("Test:Statie", TestEntityDataStatie::new); register(new TestEntityRenderStatie("Test:Statie")); register(new TestEntityLogicStatie("Test:Statie")); + + register("Test:FallingBlock", TestEntityDataFallingBlock::new); + register(new TestEntityLogicFallingBlock("Test:FallingBlock")); + register(new TestEntityRenderFallingBlock("Test:FallingBlock")); } private static void regsiterControls() { diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java index 7d11bb6..705d1af 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityDataFallingBlock.java @@ -1,5 +1,7 @@ package ru.windcorp.progressia.test; +import org.apache.logging.log4j.LogManager; + import ru.windcorp.progressia.common.collision.AABB; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; @@ -17,13 +19,18 @@ public class TestEntityDataFallingBlock extends EntityData { private boolean hasDeleted = false; public TestEntityDataFallingBlock() { - this("Test:FallingBlock", new BlockData("Test:Sand")); + this("Test:FallingBlock", new BlockData("Test:LogTop")); + } + + public TestEntityDataFallingBlock(BlockData data) { + this("Test:FallingBlock", data); } protected TestEntityDataFallingBlock(String id, BlockData blockInput) { super(id); setCollisionModel(new AABB(0, 0, 0, 1, 1, 1)); block = blockInput; + LogManager.getLogger().info(blockInput.getId()); } public void setDestroyed() { diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java index 0730d63..03c725d 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityLogicFallingBlock.java @@ -1,6 +1,8 @@ package ru.windcorp.progressia.test; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.apache.logging.log4j.LogManager; @@ -10,9 +12,10 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.common.world.block.BlockDataRegistry; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.TickContext; +import ru.windcorp.progressia.server.world.context.ServerWorldContext; import ru.windcorp.progressia.server.world.entity.EntityLogic; +import ru.windcorp.progressia.test.Rocks.Rock; +import ru.windcorp.progressia.test.Rocks.RockVariant; /** * Logic for Test:FallingBlock @@ -26,6 +29,11 @@ public class TestEntityLogicFallingBlock extends EntityLogic { public void addFallables() { FallingBlocks.add("Test:Sand"); + for (Rock rock : TestContent.ROCKS.getRocks()) + { + FallingBlocks.add(rock.getBlock(RockVariant.GRAVEL).getId()); + FallingBlocks.add(rock.getBlock(RockVariant.SAND).getId()); + } } public TestEntityLogicFallingBlock(String id) { @@ -33,7 +41,7 @@ public class TestEntityLogicFallingBlock extends EntityLogic { addFallables(); } - private Vec3i trueMod(Vec3i input, Vec3i modulus) // Move this to a class in + /*private Vec3i trueMod(Vec3i input, Vec3i modulus) // Move this to a class in // Vec or something { return input.mod_(modulus).add_(modulus).mod_(modulus); @@ -45,28 +53,71 @@ public class TestEntityLogicFallingBlock extends EntityLogic { Vec3i temp = input.div_(divisor); temp.add(new Vec3i(input.x < 0 ? -1 : 0, input.y < 0 ? -1 : 0, input.z < 0 ? -1 : 0)); return temp; + }*/ + + public Vec3i getBestCardinal(Vec3 dir) + { + Vec3 a = dir.abs_(); + if (a.x>a.y && a.x>a.z) + { + return new Vec3i(dir.x>0 ? 1 : -1,0,0); + } + else if (a.y>a.z) + { + return new Vec3i(0,dir.y>0 ? 1 : -1,0); + } + return new Vec3i(0,0,dir.z>0 ? 1 : -1); + } + + public List getGoodCardinals(Vec3 dir) + { + return getGoodCardinals(dir,.05f); + } + + public List getGoodCardinals(Vec3 dir, float d) { + List list = new ArrayList<>(); + Vec3 a = dir.abs_(); + if (a.x>d) + { + list.add(new Vec3i(dir.x>0 ? 1 : -1,0,0)); + } + if (a.y>d) + { + list.add(new Vec3i(0,dir.y>0 ? 1 : -1,0)); + } + if (a.z>d) + { + list.add(new Vec3i(0,0,dir.z>0 ? 1 : -1)); + } + return list; } @Override - public void tick(EntityData entity, TickContext context) { // context.getWorldData() + public void tick(EntityData entity, ServerWorldContext context) { // context.getWorldData() // ClientState.getInstance().getWorld().getData() + if (entity == null) { return; } + // LogManager.getLogger().info("NotNull "+entity.toString()+" // "+String.valueOf(entity!=null) + " " + // context.toString()); super.tick(entity, context); + // friction Vec3 vel = entity.getVelocity(); float friction = 0f; vel = new Vec3(vel.x * friction, vel.y * friction, vel.z); entity.setVelocity(vel); + //TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) context.//context.getEntity(entity.getEntityId()); + TestEntityDataFallingBlock fallBlock = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld() - .getData().getEntity(entity.getEntityId()); // ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); + .getData().getEntity(entity.getEntityId()); + TestEntityDataFallingBlock fallBlock2 = (TestEntityDataFallingBlock) entity;// ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); // fallBlock = (TestEntityDataFallingBlock) entity; // LogManager.getLogger().info("NotNull FB @@ -74,46 +125,56 @@ public class TestEntityLogicFallingBlock extends EntityLogic { if (fallBlock == null) { return; } + + - if (fallBlock.isDone() || !context.getWorld().isBlockLoaded(fallBlock.getBlockInWorld(null))) { + if (fallBlock.isDone() || context.getBlock(fallBlock.getBlockInWorld(null)) == null) { return; } + + //LogManager.getLogger().info("wut"); if (!fallBlock.hasDestroyed()) { - // LogManager.getLogger().info(fallBlock.getStartPos()); - context.getAccessor().setBlock(fallBlock.getBlockInWorld(null), + LogManager.getLogger().info(fallBlock.getPosition().x); + context.setBlock(fallBlock.getBlockInWorld(null), BlockDataRegistry.getInstance().get("Test:Air")); fallBlock.setDestroyed(); } Vec3i occupiedBlock = fallBlock.getBlockInWorld(null); - Vec3i underBlock = occupiedBlock.sub_(0, 0, 1); + Vec3i underBlock = occupiedBlock.sub_(getBestCardinal(fallBlock.getUpVector())); + List underBlocks = getGoodCardinals(fallBlock.getUpVector()); + + boolean notSupported = false; + for (Vec3i v3 : underBlocks) + { + Vec3i inWorld = occupiedBlock.sub_(v3); + if (context.getBlock(inWorld).getId()=="Test:Air") { + notSupported=true; + break; + } + } - Vec3i chunkCoords = trueDiv(underBlock, new Vec3i(16)); - Vec3i inChunkCoords = trueMod(underBlock, new Vec3i(16)); + //LogManager.getLogger().info("InChunk + //"+String.valueOf(chunkCoords.x)+" "+String.valueOf(chunkCoords.y)+" + //"+String.valueOf(chunkCoords.z)+" "+String.valueOf(inChunkCoords.x)+" + ////"+String.valueOf(inChunkCoords.y)+" + //"+String.valueOf(inChunkCoords.z)); + /*LogManager.getLogger().info("FallingBlock is at {},{},{}", + String.valueOf(occupiedBlock.x), + String.valueOf(occupiedBlock.y), + String.valueOf(occupiedBlock.z));*/ + //LogManager.getLogger().info("Block is of type " + + //context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - // LogManager.getLogger().info("InChunk - // "+String.valueOf(chunkCoords.x)+" "+String.valueOf(chunkCoords.y)+" - // "+String.valueOf(chunkCoords.z)+" "+String.valueOf(inChunkCoords.x)+" - // "+String.valueOf(inChunkCoords.y)+" - // "+String.valueOf(inChunkCoords.z)); - // LogManager.getLogger().info("FallingBlock is at - // "+String.valueOf(occupiedBlock.x)+" - // "+String.valueOf(occupiedBlock.y)+" - // "+String.valueOf(occupiedBlock.z)); - // LogManager.getLogger().info("Block is of type " + - // context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId()); - - if (context.getWorldData().isBlockLoaded(occupiedBlock) - && context.getWorldData().getChunk(chunkCoords).getBlock(inChunkCoords).getId() != "Test:Air") { + if (context.getBlock(underBlock) != null + // && context.getBlock(underBlock).getId() != "Test:Air") { + && !notSupported) { LogManager.getLogger().info("Deleting FallingBlock at " + String.valueOf(occupiedBlock.x) + " " + String.valueOf(occupiedBlock.y) + " " + String.valueOf(occupiedBlock.z)); - // ClientState.getInstance().getWorld().getData().setBlock(occupiedBlock, - // fallBlock.getBlock(),true); - context.getAccessor().setBlock(occupiedBlock, fallBlock.getBlock()); - fallBlock.setInvisible(); // Until I know how to properly delete it. - //ClientState.getInstance().getWorld().getData().removeEntity(entity.getEntityId());// context.getWorldData().removeEntity(entity.getEntityId()); - Server server = context.getServer(); - server.invokeLater(() -> server.getWorld().getData().removeEntity(entity.getEntityId())); + context.setBlock(occupiedBlock, fallBlock2.getBlock()); + fallBlock.setInvisible(); + //server.invokeLater(() -> server.getWorld().getData().removeEntity(entity.getEntityId())); + context.removeEntity(fallBlock); } } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java index 5d4ddab..ab121e3 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderFallingBlock.java @@ -1,5 +1,6 @@ package ru.windcorp.progressia.test; +import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.Shapes; @@ -21,7 +22,7 @@ public class TestEntityRenderFallingBlock extends EntityRender { public TestEntityRenderFallingBlock(String id) { super(id); - String dflt = "Sand";//(String) TestEntityLogicFallingBlock.FallingBlocks.toArray()[0]; + String dflt = TestEntityLogicFallingBlock.FallingBlocks.toArray()[0].toString().substring(5); cube = new Shapes.PppBuilder(WorldRenderProgram.getDefault(), BlockRenderRegistry.getBlockTexture(dflt ) )// TODO idk actual ggood this .create(); } @@ -34,7 +35,7 @@ public class TestEntityRenderFallingBlock extends EntityRender { public EntityRenderable createRenderable(EntityData entity) { return new EntityRenderable(entity) { @Override - public void render(ShapeRenderHelper renderer) { + public void doRender(ShapeRenderHelper renderer) { // LogManager.getLogger().info("Rendering FallingBlock"); if (((TestEntityDataFallingBlock) entity).isDone()) { return; @@ -42,6 +43,8 @@ public class TestEntityRenderFallingBlock extends EntityRender { // SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/LogSide"), // new AtlasGroup("Blocks", 1 << 12)))); } + TestEntityDataFallingBlock fallEntity = (TestEntityDataFallingBlock) ClientState.getInstance().getWorld().getData().getEntity(entity.getEntityId()); + setTexture(BlockRenderRegistry.getBlockTexture(fallEntity.getBlock().getId().substring(5))); // setTexture(new // SimpleTexture(Atlases.getSprite(ResourceManager.getTextureResource("blocks/Sand"), // new AtlasGroup("Blocks", 1 << 12)))); diff --git a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java index aa3ad1b..56b71ea 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java +++ b/src/main/java/ru/windcorp/progressia/test/TestEntityRenderJavapony.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.test; import java.util.ArrayList; @@ -25,8 +25,8 @@ import glm.vec._3.Vec3; import ru.windcorp.progressia.client.graphics.Colors; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.backend.Usage; -import ru.windcorp.progressia.client.graphics.model.Face; -import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapeParts; import ru.windcorp.progressia.client.graphics.model.LambdaModel; import ru.windcorp.progressia.client.graphics.model.Renderable; import ru.windcorp.progressia.client.graphics.model.Shape; @@ -39,8 +39,8 @@ import ru.windcorp.progressia.client.world.entity.EntityRender; import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry; import ru.windcorp.progressia.client.world.entity.EntityRenderable; import ru.windcorp.progressia.client.world.entity.QuadripedModel; -import ru.windcorp.progressia.common.world.block.BlockFace; import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.common.world.rels.AbsFace; public class TestEntityRenderJavapony extends EntityRender { @@ -54,7 +54,11 @@ public class TestEntityRenderJavapony extends EntityRender { public TestEntityRenderJavapony(String id) { super(id); - ComplexTexture texture = new ComplexTexture(EntityRenderRegistry.getEntityTexture("javapony"), 256, 128); + ComplexTexture texture = new ComplexTexture( + EntityRenderRegistry.getEntityTexture("javapony"), + 256, + 128 + ); this.body = createBody(texture); this.head = createHead(texture); @@ -71,85 +75,230 @@ public class TestEntityRenderJavapony extends EntityRender { Texture tailStartTexture = texture.get(128, 96, 8, 32); - b.addStaticPart(new PppBuilder(WorldRenderProgram.getDefault(), - BlockFace.mapToFaces(tailStartTexture, tailStartTexture, tailStartTexture, tailStartTexture, - tailStartTexture, tailStartTexture)).setOrigin(-60, -4, 14).setDepth(32, 0, -16).setWidth(8) - .setHeight(8).create()); + b.addStaticPart( + new PppBuilder( + WorldRenderProgram.getDefault(), + tailStartTexture + ) + .setOrigin(-60, -4, 14) + .setDepth(32, 0, -16).setWidth(8).setHeight(8) + .create() + ); Texture neckTexture = texture.get(0, 48, 16, 16); - b.addStaticPart(new PppBuilder(WorldRenderProgram.getDefault(), - BlockFace.mapToFaces(neckTexture, neckTexture, neckTexture, neckTexture, neckTexture, neckTexture)) - .setOrigin(0, -8, 8).setWidth(16).setDepth(16).setHeight(2, 0, 16).create()); + b.addStaticPart( + new PppBuilder( + WorldRenderProgram.getDefault(), + neckTexture + ) + .setOrigin(0, -8, 8) + .setWidth(16).setDepth(16).setHeight(2, 0, 16) + .create() + ); - b.addDynamicPart(createTail(texture), - m -> m.translate(-60, 0, 24).rotateX(0.05f * Math.sin(GraphicsInterface.getTime())) - .rotateY(0.05f * Math.sin(Math.PI / 3 * GraphicsInterface.getTime()))); + b.addDynamicPart( + createTail(texture), + m -> m + .translate(-60, 0, 24) + .rotateX(0.05f * Math.sin(GraphicsInterface.getTime())) + .rotateY(0.05f * Math.sin(Math.PI / 3 * GraphicsInterface.getTime())) + ); return new LambdaModel(b); } private static Renderable createMainBody(ComplexTexture texture) { WorldRenderProgram program = WorldRenderProgram.getDefault(); - List faces = new ArrayList<>(); + List faces = new ArrayList<>(); // F BODY - faces.add(Faces.createRectangle(program, texture.get(80, 16, 32, 32), Colors.WHITE, new Vec3(+16, -16, -16), - new Vec3(0, +32, 0), new Vec3(0, 0, +32), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(80, 16, 32, 32), + Colors.WHITE, + new Vec3(+16, -16, -16), + new Vec3(0, +32, 0), + new Vec3(0, 0, +32), + false + ) + ); // NECK BASE - faces.add(Faces.createRectangle(program, texture.get(80, 48, 32, 16), Colors.WHITE, new Vec3(+16, -16, +16), - new Vec3(0, +32, 0), new Vec3(-16, 0, 0), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(80, 48, 32, 16), + Colors.WHITE, + new Vec3(+16, -16, +16), + new Vec3(0, +32, 0), + new Vec3(-16, 0, 0), + false + ) + ); // T BODY (BACK) - faces.add(Faces.createRectangle(program, texture.get(128, 0, 32, 48), Colors.WHITE, new Vec3(0, -16, +16), - new Vec3(0, +32, 0), new Vec3(-48, 0, 0), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(128, 0, 32, 48), + Colors.WHITE, + new Vec3(0, -16, +16), + new Vec3(0, +32, 0), + new Vec3(-48, 0, 0), + false + ) + ); // BOTTOM B (upper) - faces.add(Faces.createRectangle(program, texture.get(144, 48, 32, 16), Colors.WHITE, new Vec3(-48, -16, 0), - new Vec3(0, 32, 0), new Vec3(0, 0, 16), true)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(144, 48, 32, 16), + Colors.WHITE, + new Vec3(-48, -16, 0), + new Vec3(0, 32, 0), + new Vec3(0, 0, 16), + true + ) + ); // BOTTOM B (lower) - faces.add(Faces.createRectangle(program, texture.get(144, 48, 32, 16), Colors.WHITE, new Vec3(-48, -16, -16), - new Vec3(0, 32, 0), new Vec3(0, 0, 16), true)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(144, 48, 32, 16), + Colors.WHITE, + new Vec3(-48, -16, -16), + new Vec3(0, 32, 0), + new Vec3(0, 0, 16), + true + ) + ); // BOTTOM B (stomach) - faces.add(Faces.createRectangle(program, texture.get(144, 48, 32, 16), Colors.WHITE, new Vec3(-48, -16, -16), - new Vec3(0, 32, 0), new Vec3(16, 0, 0), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(144, 48, 32, 16), + Colors.WHITE, + new Vec3(-48, -16, -16), + new Vec3(0, 32, 0), + new Vec3(16, 0, 0), + false + ) + ); // STOMACH - faces.add(Faces.createRectangle(program, texture.get(224, 96, 32, 32), Colors.WHITE, new Vec3(-32, -16, -16), - new Vec3(0, 32, 0), new Vec3(32, 0, 0), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(224, 96, 32, 32), + Colors.WHITE, + new Vec3(-32, -16, -16), + new Vec3(0, 32, 0), + new Vec3(32, 0, 0), + false + ) + ); // BOTTOM F - faces.add(Faces.createRectangle(program, texture.get(112, 48, 32, 16), Colors.WHITE, new Vec3(+16, -16, -16), - new Vec3(0, 32, 0), new Vec3(-16, 0, 0), true)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(112, 48, 32, 16), + Colors.WHITE, + new Vec3(+16, -16, -16), + new Vec3(0, 32, 0), + new Vec3(-16, 0, 0), + true + ) + ); // BODY L - faces.add(Faces.createRectangle(program, texture.get(112, 16, 16, 32), Colors.WHITE, new Vec3(+16, +16, -16), - new Vec3(-16, 0, 0), new Vec3(0, 0, +32), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(112, 16, 16, 32), + Colors.WHITE, + new Vec3(+16, +16, -16), + new Vec3(-16, 0, 0), + new Vec3(0, 0, +32), + false + ) + ); // BODY SIDES (left) - faces.add(Faces.createRectangle(program, texture.get(96, 96, 32, 32), Colors.WHITE, new Vec3(0, +16, -16), - new Vec3(-32, 0, 0), new Vec3(0, 0, +32), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(96, 96, 32, 32), + Colors.WHITE, + new Vec3(0, +16, -16), + new Vec3(-32, 0, 0), + new Vec3(0, 0, +32), + false + ) + ); // QT MARK (left) - faces.add(Faces.createRectangle(program, texture.get(16, 96, 16, 32), Colors.WHITE, new Vec3(-32, +16, -16), - new Vec3(-16, 0, 0), new Vec3(0, 0, +32), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(16, 96, 16, 32), + Colors.WHITE, + new Vec3(-32, +16, -16), + new Vec3(-16, 0, 0), + new Vec3(0, 0, +32), + false + ) + ); // BODY R - faces.add(Faces.createRectangle(program, texture.get(64, 16, 16, 32), Colors.WHITE, new Vec3(0, -16, -16), - new Vec3(+16, 0, 0), new Vec3(0, 0, +32), false)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(64, 16, 16, 32), + Colors.WHITE, + new Vec3(0, -16, -16), + new Vec3(+16, 0, 0), + new Vec3(0, 0, +32), + false + ) + ); // BODY SIDES (right) - faces.add(Faces.createRectangle(program, texture.get(96, 96, 32, 32), Colors.WHITE, new Vec3(0, -16, -16), - new Vec3(-32, 0, 0), new Vec3(0, 0, +32), true)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(96, 96, 32, 32), + Colors.WHITE, + new Vec3(0, -16, -16), + new Vec3(-32, 0, 0), + new Vec3(0, 0, +32), + true + ) + ); // QT MARK (right) - faces.add(Faces.createRectangle(program, texture.get(16, 96, 16, 32), Colors.WHITE, new Vec3(-32, -16, -16), - new Vec3(-16, 0, 0), new Vec3(0, 0, +32), true)); + faces.add( + ShapeParts.createRectangle( + program, + texture.get(16, 96, 16, 32), + Colors.WHITE, + new Vec3(-32, -16, -16), + new Vec3(-16, 0, 0), + new Vec3(0, 0, +32), + true + ) + ); - return new Shape(Usage.STATIC, program, faces.toArray(new Face[faces.size()])); + return new Shape( + Usage.STATIC, + program, + faces.toArray(new ShapePart[faces.size()]) + ); } private static Renderable createHead(ComplexTexture texture) { @@ -157,42 +306,87 @@ public class TestEntityRenderJavapony extends EntityRender { StaticModel.Builder b = StaticModel.builder(); // Head - b.addPart(new PppBuilder(program, texture.getCuboidTextures(0, 64, 32)).setOrigin(-16, -16, 0).setSize(32) - .create()); + b.addPart( + new PppBuilder( + program, + texture.getCuboidTextures(0, 64, 32) + ).setOrigin(-16, -16, 0).setSize(32).create() + ); final float hairOffset = 1f; // Hair - b.addPart(new PppBuilder(program, texture.getCuboidTextures(128, 64, 32)) - .setOrigin(-16 - hairOffset, -16 - hairOffset, -hairOffset).setSize(32 + 2 * hairOffset).create()); + b.addPart( + new PppBuilder( + program, + texture.getCuboidTextures(128, 64, 32) + ) + .setOrigin(-16 - hairOffset, -16 - hairOffset, -hairOffset) + .setSize(32 + 2 * hairOffset) + .create() + ); // Right ear - b.addPart(new PppBuilder(program, texture.getCuboidTextures(48, 128 - 80, 8)).setOrigin(-16 + 3, -16, 32) - .setSize(8).create()); + b.addPart( + new PppBuilder( + program, + texture.getCuboidTextures(48, 128 - 80, 8) + ).setOrigin(-16 + 3, -16, 32).setSize(8).create() + ); // Left ear - b.addPart(new PppBuilder(program, texture.getCuboidTextures(48, 128 - 80, 8)).setOrigin(-16 + 3, +16, 32) - .setSize(8, -8, 8).flip().create()); + b.addPart( + new PppBuilder( + program, + texture.getCuboidTextures(48, 128 - 80, 8) + ).setOrigin(-16 + 3, +16, 32).setSize(8, -8, 8).flip().create() + ); // Muzzle - b.addPart(new PppBuilder(program, - BlockFace.mapToFaces(texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), - texture.get(32 + 8, 64, 16, 8), texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0))).setOrigin(16, -8, 0).setSize(4, 16, 8).create()); + b.addPart( + new PppBuilder( + program, + AbsFace.mapToFaces( + texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0), + texture.get(32 + 8, 64, 16, 8), + texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0) + ) + ).setOrigin(16, -8, 0).setSize(4, 16, 8).create() + ); // Nose - b.addPart(new PppBuilder(program, - BlockFace.mapToFaces(texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), - texture.get(32 + 12, 64 + 8, 8, 4), texture.get(32, 64, 0, 0), texture.get(32, 64, 0, 0), - texture.get(32, 64, 0, 0))).setOrigin(16, -4, 8).setSize(4, 8, 4).create()); + b.addPart( + new PppBuilder( + program, + AbsFace.mapToFaces( + texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0), + texture.get(32 + 12, 64 + 8, 8, 4), + texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0), + texture.get(32, 64, 0, 0) + ) + ).setOrigin(16, -4, 8).setSize(4, 8, 4).create() + ); return b.build(); } - private static Renderable createLeg(ComplexTexture texture, int textureX, int textureY, boolean isLeft) { - PppBuilder b = new PppBuilder(WorldRenderProgram.getDefault(), - texture.getCuboidTextures(textureX, textureY, 16, 48, 16)).setOrigin(-8, isLeft ? +8 : -8, -48) - .setSize(16, isLeft ? -16 : +16, 48); + private static Renderable createLeg( + ComplexTexture texture, + int textureX, + int textureY, + boolean isLeft + ) { + PppBuilder b = new PppBuilder( + WorldRenderProgram.getDefault(), + texture.getCuboidTextures(textureX, textureY, 16, 48, 16) + ) + .setOrigin(-8, isLeft ? +8 : -8, -48) + .setSize(16, isLeft ? -16 : +16, 48); if (isLeft) b.flip(); @@ -205,26 +399,59 @@ public class TestEntityRenderJavapony extends EntityRender { StaticModel.Builder b = StaticModel.builder(); // Main tail - b.addPart(new PppBuilder(program, - BlockFace.mapToFaces(texture.get(128, 96, 16, 16), texture.get(128, 96, 16, 16), - texture.get(128, 96, 16, 32), texture.get(128, 96, 16, 32), texture.get(144, 96, 16, 32), - texture.get(144, 96, 16, 32))).setOrigin(-8, -8, -32).setSize(16, 16, 32).create()); + b.addPart( + new PppBuilder( + program, + AbsFace.mapToFaces( + texture.get(128, 96, 16, 16), + texture.get(128, 96, 16, 16), + texture.get(128, 96, 16, 32), + texture.get(128, 96, 16, 32), + texture.get(144, 96, 16, 32), + texture.get(144, 96, 16, 32) + ) + ).setOrigin(-8, -8, -32).setSize(16, 16, 32).create() + ); return b.build(); } @Override public EntityRenderable createRenderable(EntityData entity) { - return new QuadripedModel(entity, + return new QuadripedModel( + entity, - new QuadripedModel.Body(body), - new QuadripedModel.Head(head, new Vec3(12, 0, 20), 120, 45, new Vec3(16, 0, 20)), - new QuadripedModel.Leg(leftForeLeg, new Vec3(6, +8.1f, -16), 0.0f), - new QuadripedModel.Leg(rightForeLeg, new Vec3(6, -8.1f, -16), 2.5f), - new QuadripedModel.Leg(leftHindLeg, new Vec3(-36, +8.2f, -16), 2.5f), - new QuadripedModel.Leg(rightHindLeg, new Vec3(-36, -8.2f, -16), 0.0f), + new QuadripedModel.Body(body), + new QuadripedModel.Head( + head, + new Vec3(12, 0, 20), + 120, + 45, + new Vec3(16, 0, 20) + ), + new QuadripedModel.Leg( + leftForeLeg, + new Vec3(6, +8.1f, -16), + 0.0f + ), + new QuadripedModel.Leg( + rightForeLeg, + new Vec3(6, -8.1f, -16), + 2.5f + ), + new QuadripedModel.Leg( + leftHindLeg, + new Vec3(-36, +8.2f, -16), + 2.5f + ), + new QuadripedModel.Leg( + rightHindLeg, + new Vec3(-36, -8.2f, -16), + 0.0f + ), - 1 / 96f); + 1 / 96f + ); } } diff --git a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java index ee42396..f535f3f 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java +++ b/src/main/java/ru/windcorp/progressia/test/TestPlayerControls.java @@ -22,6 +22,9 @@ import glm.Glm; import glm.mat._3.Mat3; import glm.mat._4.Mat4; import glm.vec._3.Vec3; + +import java.util.function.Function; + import org.lwjgl.glfw.GLFW; import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.graphics.GUI; @@ -58,6 +61,8 @@ public class TestPlayerControls { // Horizontal and vertical max control speed when flying private static final float FLYING_SPEED = Units.get("6 m/s"); + + private static final Function SPRINTING_FLYING_SPEED = (f) -> {return Math.pow(f,.75)+2*FLYING_SPEED;}; // (0; 1], 1 is instant change, 0 is no control authority private static final float FLYING_CONTROL_AUTHORITY = Units.get("2 1/s"); @@ -101,7 +106,8 @@ public class TestPlayerControls { final float speed, authority; if (isFlying) { - speed = FLYING_SPEED; + double timeSinceLastSpacePress = GraphicsInterface.getTime() - lastSprintPress; + speed = isSprinting ? SPRINTING_FLYING_SPEED.apply(timeSinceLastSpacePress).floatValue() : FLYING_SPEED; authority = FLYING_CONTROL_AUTHORITY; } else { speed = isSprinting ? SPRINTING_SPEED : WALKING_SPEED; @@ -256,10 +262,11 @@ public class TestPlayerControls { double timeSinceLastSpacePress = GraphicsInterface.getTime() - lastSpacePress; if (isPressed && timeSinceLastSpacePress < MODE_SWITCH_MAX_DELAY) { - isSprinting = false; + //isSprinting = false; isFlying = !isFlying; updateGUI(); movementUp = +1; + timeSinceLastSpacePress = MODE_SWITCH_MAX_DELAY; } else { if (isFlying) { movementUp += +1 * multiplier; @@ -274,10 +281,12 @@ public class TestPlayerControls { } private void handleSprint(KeyEvent event) { + + //LogManager.getLogger().info("hi"); double timeSinceLastSpacePress = GraphicsInterface.getTime() - lastSprintPress; - if (event.isPress() && timeSinceLastSpacePress < MODE_SPRINT_SWITCH_MAX_DELAY && !isFlying) { + if (event.isPress() && timeSinceLastSpacePress < MODE_SPRINT_SWITCH_MAX_DELAY) { isSprinting = !isSprinting; updateGUI(); }