From a85fc27f8b45eed030324200acf666f6c9bb1d4a Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Tue, 31 Aug 2021 17:27:08 +0300 Subject: [PATCH] Added _UNFINISHED_ water, beaches and mantle - Refactored terrain generation - Added PiecewiseLinearFunction - Added some placeholder content - Added Test:Water, the solid, opaque water - Added beaches - Added Test:Mantle - Tweaked rock distribution parameters --- .../common/util/math/FloatFunction.java | 25 ++++ .../common/util/math/FloatFunction2D.java | 24 ++++ .../common/util/math/FloatFunction3D.java | 24 ++++ .../util/math/PiecewiseLinearFunction.java | 124 ++++++++++++++++++ .../generation/planet/PlanetGenerator.java | 7 +- .../planet/PlanetTerrainGenerator.java | 7 +- .../surface/SurfaceTerrainGenerator.java | 9 +- ...TerrainLayer.java => TerrainSupplier.java} | 2 +- .../windcorp/progressia/test/TestContent.java | 2 + .../test/gen/TestGenerationConfig.java | 63 ++++----- .../MultiblockVegetationFeature.java | 2 +- .../gen/{ => feature}/TestBushFeature.java | 2 +- .../gen/{ => feature}/TestFlowerFeature.java | 2 +- .../gen/{ => feature}/TestGrassFeature.java | 14 +- .../gen/{ => feature}/TestTreeFeature.java | 2 +- .../progressia/test/gen/terrain/AirLayer.java | 42 ++++++ .../test/gen/terrain/BeachLayer.java | 55 ++++++++ .../test/gen/terrain/CliffLayer.java | 64 +++++++++ .../test/gen/terrain/CrustLayer.java | 69 ++++++++++ .../test/gen/terrain/LayeredTerrain.java | 61 +++++++++ .../test/gen/terrain/MantleLayer.java | 42 ++++++ .../RockStrata.java} | 35 +++-- .../test/gen/terrain/SoilLayer.java | 59 +++++++++ .../test/gen/terrain/TerrainLayer.java | 34 +++++ .../test/gen/terrain/WaterLayer.java | 45 +++++++ .../assets/textures/blocks/Mantle.png | Bin 0 -> 1529 bytes .../assets/textures/blocks/Water.png | Bin 0 -> 1605 bytes 27 files changed, 741 insertions(+), 74 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.java create mode 100644 src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java create mode 100644 src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java create mode 100644 src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.java rename src/main/java/ru/windcorp/progressia/server/world/generation/surface/{TerrainLayer.java => TerrainSupplier.java} (96%) rename src/main/java/ru/windcorp/progressia/test/gen/{ => feature}/MultiblockVegetationFeature.java (98%) rename src/main/java/ru/windcorp/progressia/test/gen/{ => feature}/TestBushFeature.java (97%) rename src/main/java/ru/windcorp/progressia/test/gen/{ => feature}/TestFlowerFeature.java (98%) rename src/main/java/ru/windcorp/progressia/test/gen/{ => feature}/TestGrassFeature.java (93%) rename src/main/java/ru/windcorp/progressia/test/gen/{ => feature}/TestTreeFeature.java (98%) create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.java rename src/main/java/ru/windcorp/progressia/test/gen/{RockLayer.java => terrain/RockStrata.java} (64%) create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.java create mode 100644 src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.java create mode 100644 src/main/resources/assets/textures/blocks/Mantle.png create mode 100644 src/main/resources/assets/textures/blocks/Water.png diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.java b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.java new file mode 100644 index 0000000..f2438b3 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction.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.math; + +@FunctionalInterface +public interface FloatFunction { + + float apply(float x); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java new file mode 100644 index 0000000..f41ea25 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction2D.java @@ -0,0 +1,24 @@ +/* + * 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.math; + +public interface FloatFunction2D { + + float apply(float x, float y); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java new file mode 100644 index 0000000..3e5e7a7 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/math/FloatFunction3D.java @@ -0,0 +1,24 @@ +/* + * 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.math; + +public interface FloatFunction3D { + + float apply(float x, float y, float z); + +} diff --git a/src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.java b/src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.java new file mode 100644 index 0000000..051d7f2 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/util/math/PiecewiseLinearFunction.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.util.math; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import glm.vec._2.Vec2; + +public class PiecewiseLinearFunction implements FloatFunction { + + public static class Builder { + + private final List points = new ArrayList<>(); + private float slopeAtNegInf = 0; + private float slopeAtPosInf = 0; + + public Builder add(float x, float y) { + points.add(new Vec2(x, y)); + return this; + } + + public Builder setNegativeSlope(float slope) { + slopeAtNegInf = slope; + return this; + } + + public Builder setPositiveSlope(float slope) { + slopeAtPosInf = slope; + return this; + } + + public Builder setDefaultUndefined() { + slopeAtPosInf = Float.NaN; + slopeAtNegInf = Float.NaN; + return this; + } + + public PiecewiseLinearFunction build() { + float[] pointXs = new float[points.size()]; + float[] pointYs = new float[points.size()]; + + points.sort(Comparator.comparingDouble(v -> v.x)); + for (int i = 0; i < points.size(); ++i) { + pointXs[i] = points.get(i).x; + pointYs[i] = points.get(i).y; + } + + return new PiecewiseLinearFunction(pointXs, pointYs, slopeAtNegInf, slopeAtPosInf); + } + + } + + public static Builder builder() { + return new Builder(); + } + + /** + * The set of the X coordinates of all defining points, sorted in increasing order + */ + private final float[] pointXs; + + /** + * The set of the Y coordinates of all defining points, sorted to match the order of {@link #pointXs} + */ + private final float[] pointYs; + + /** + * Slope of the segment (-inf; x[0]), or NaN to exclude the segment from the function + */ + private final float slopeAtNegInf; + + /** + * Slope of the segment (x[x.length - 1]; +inf), or NaN to exclude the segment from the function + */ + private final float slopeAtPosInf; + + protected PiecewiseLinearFunction(float[] pointXs, float[] pointYs, float slopeAtNegInf, float slopeAtPosInf) { + this.pointXs = pointXs; + this.pointYs = pointYs; + this.slopeAtNegInf = slopeAtNegInf; + this.slopeAtPosInf = slopeAtPosInf; + } + + @Override + public float apply(float x) { + int index = Arrays.binarySearch(pointXs, x); + + if (index >= 0) { + // Wow, exact match, me surprised + return pointYs[index]; + } + + int bigger = -index - 1; + int smaller = bigger - 1; + + if (smaller == -1) { + return pointYs[bigger] + (x - pointXs[bigger]) * slopeAtNegInf; + } else if (bigger == pointXs.length) { + return pointYs[smaller] + (x - pointXs[smaller]) * slopeAtPosInf; + } else { + float t = (x - pointXs[smaller]) / (pointXs[bigger] - pointXs[smaller]); + return pointYs[smaller] * (1 - t) + pointYs[bigger] * t; + } + } + +} 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..dad0435 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 @@ -24,7 +24,6 @@ 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; @@ -32,7 +31,7 @@ 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; +import ru.windcorp.progressia.server.world.generation.surface.TerrainSupplier; public class PlanetGenerator extends AbstractWorldGenerator { @@ -46,7 +45,7 @@ public class PlanetGenerator extends AbstractWorldGenerator { Server server, Planet planet, SurfaceFloatField heightMap, - FloatRangeMap layers, + TerrainSupplier terrain, List features ) { super(id, server, Boolean.class, "Test:PlanetGravityModel"); @@ -56,7 +55,7 @@ public class PlanetGenerator extends AbstractWorldGenerator { PlanetGravityModel model = (PlanetGravityModel) this.getGravityModel(); model.configure(planet.getGravityModelSettings()); - this.terrainGenerator = new PlanetTerrainGenerator(this, heightMap, layers); + this.terrainGenerator = new PlanetTerrainGenerator(this, heightMap, terrain); this.featureGenerator = new PlanetFeatureGenerator(this, features); } 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 cb4507c..368a59a 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 @@ -21,7 +21,6 @@ import java.util.Map; 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.Coordinates; @@ -33,7 +32,7 @@ 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; +import ru.windcorp.progressia.server.world.generation.surface.TerrainSupplier; class PlanetTerrainGenerator { @@ -43,7 +42,7 @@ class PlanetTerrainGenerator { public PlanetTerrainGenerator( PlanetGenerator generator, SurfaceFloatField heightMap, - FloatRangeMap layers + TerrainSupplier terrain ) { this.parent = generator; @@ -53,7 +52,7 @@ class PlanetTerrainGenerator { face -> new SurfaceTerrainGenerator( new Surface(face, seaLevel), heightMap, - layers + terrain ) ); } 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 ea7cb9b..ead1d47 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 @@ -19,7 +19,6 @@ package ru.windcorp.progressia.server.world.generation.surface; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; -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; @@ -33,12 +32,12 @@ public class SurfaceTerrainGenerator { private final Surface surface; private final SurfaceFloatField heightMap; - private final FloatRangeMap layers; + private final TerrainSupplier terrain; - public SurfaceTerrainGenerator(Surface surface, SurfaceFloatField heightMap, FloatRangeMap layers) { + public SurfaceTerrainGenerator(Surface surface, SurfaceFloatField heightMap, TerrainSupplier terrain) { this.surface = surface; this.heightMap = heightMap; - this.layers = layers; + this.terrain = terrain; } public void generateTerrain(Server server, DefaultChunkData chunk) { @@ -74,7 +73,7 @@ public class SurfaceTerrainGenerator { location.set(north, west, altitude); SurfaceBlockContext blockContext = context.push(location); - BlockData block = layers.get(depth).get(blockContext, depth); + BlockData block = terrain.get(blockContext, depth); blockContext.pop(); 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/TerrainSupplier.java similarity index 96% rename from src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainLayer.java rename to src/main/java/ru/windcorp/progressia/server/world/generation/surface/TerrainSupplier.java index 5ec131c..a3a1376 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/TerrainSupplier.java @@ -21,7 +21,7 @@ import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; @FunctionalInterface -public interface TerrainLayer { +public interface TerrainSupplier { BlockData get(SurfaceBlockContext context, float depth); diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index 8396e21..75e32e4 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -104,6 +104,8 @@ public class TestContent { registerSimplestBlock("Dirt"); registerSimplestBlock("Chernozem"); registerSimplestBlock("Stone"); + registerSimplestBlock("Mantle"); + registerSimplestBlock("Water"); registerSimplestBlock("Brick"); registerSimplestBlock("BrickWhite"); registerSimplestBlock("Sand"); 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 ee0f312..2147889 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestGenerationConfig.java @@ -24,21 +24,18 @@ 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.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; 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; -import ru.windcorp.progressia.test.Rocks.RockVariant; +import ru.windcorp.progressia.test.Rocks.Rock; import ru.windcorp.progressia.test.TestContent; +import ru.windcorp.progressia.test.gen.feature.*; +import ru.windcorp.progressia.test.gen.terrain.*; public class TestGenerationConfig { @@ -62,47 +59,45 @@ public class TestGenerationConfig { TestHeightMap heightMap = new TestHeightMap(planet, planet.getRadius() / 4, FIELDS); - FloatRangeMap layers = new ArrayFloatRangeMap<>(); - registerTerrainLayers(layers); + LayeredTerrain terrain = new LayeredTerrain(); + registerTerrainLayers(terrain); List features = new ArrayList<>(); registerFeatures(features); - return server -> new PlanetGenerator("Test:PlanetGenerator", server, planet, heightMap, layers, features); + return server -> new PlanetGenerator("Test:PlanetGenerator", server, planet, heightMap, terrain, features); } - private static void registerTerrainLayers(FloatRangeMap layers) { - BlockData dirt = BlockDataRegistry.getInstance().get("Test:Dirt"); - BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); - + private static void registerTerrainLayers(LayeredTerrain terrain) { SurfaceFloatField cliffs = FIELDS.get("Test:Cliff"); + SurfaceFloatField beaches = FIELDS.register( + "Test:Beach", + f -> multiply( + anti(FIELDS.get("Test:Cliff", f)) + ) + ); + RockStrata rockStrata = createStrata(); - 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); - }); + terrain.addLayer(new AirLayer("Test:Air")); + terrain.addLayer(new MantleLayer("Test:Mantle")); + terrain.addLayer(new CrustLayer("Test:Crust", rockStrata)); + terrain.addLayer(new WaterLayer("Test:Water")); + terrain.addLayer(new SoilLayer("Test:Soil")); + terrain.addLayer(new CliffLayer("Test:Cliffs", cliffs, rockStrata)); + terrain.addLayer(new BeachLayer("Test:Beaches", beaches, rockStrata)); + } + + private static RockStrata createStrata() { + WorleyProceduralNoise.Builder builder = WorleyProceduralNoise.builder(); + TestContent.ROCKS.getRocks().forEach(rock -> builder.add(rock, 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, rockLayer); + + return new RockStrata(builder.build(SEED), rockDepthOffsets); } private static void registerFeatures(List features) { diff --git a/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/MultiblockVegetationFeature.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java rename to src/main/java/ru/windcorp/progressia/test/gen/feature/MultiblockVegetationFeature.java index 5cfcc43..ecd738d 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/MultiblockVegetationFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/MultiblockVegetationFeature.java @@ -15,7 +15,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.feature; import java.util.Set; import java.util.function.Consumer; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java similarity index 97% rename from src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java index ca2765c..b559582 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestBushFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java @@ -15,7 +15,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.feature; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestFlowerFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestFlowerFeature.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/test/gen/TestFlowerFeature.java rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestFlowerFeature.java index 33460a1..19a97aa 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestFlowerFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestFlowerFeature.java @@ -15,7 +15,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.feature; import java.util.Set; import java.util.function.Function; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestGrassFeature.java similarity index 93% rename from src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestGrassFeature.java index 2c564b7..add06ec 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestGrassFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestGrassFeature.java @@ -15,7 +15,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.feature; import java.util.List; import java.util.Set; @@ -104,7 +104,17 @@ public class TestGrassFeature extends SurfaceTopLayerFeature { } private void growGrass(SurfaceBlockContext context, double grassiness) { - TileData flatGrass = flatGrasses.get((float) grassiness); + + double flatGrassiness = grassiness; + BlockData soil = context.getBlock(); + if (soil.getId().endsWith("Sand")) { + flatGrassiness = flatGrassiness / 2 - 0.2; + if (flatGrassiness < 0) { + flatGrassiness = 0; + } + } + + TileData flatGrass = flatGrasses.get((float) flatGrassiness); if (flatGrass != null) { for (RelFace face : RelFace.getFaces()) { if (face == RelFace.DOWN) diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java similarity index 98% rename from src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java rename to src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java index d08862e..611ec07 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestTreeFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java @@ -15,7 +15,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.feature; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.block.BlockData; diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.java new file mode 100644 index 0000000..dbafbd4 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/AirLayer.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.test.gen.terrain; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class AirLayer extends TerrainLayer { + + private final BlockData air = BlockDataRegistry.getInstance().get("Test:Air"); + + public AirLayer(String id) { + super(id); + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + return air; + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + return depth <= 0 ? 1 : 0; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java new file mode 100644 index 0000000..24880ab --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/BeachLayer.java @@ -0,0 +1,55 @@ +/* + * 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.terrain; + +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.context.SurfaceBlockContext; +import ru.windcorp.progressia.test.Rocks.RockVariant; + +public class BeachLayer extends TerrainLayer { + + private final SurfaceFloatField beachSelector; + private final RockStrata strata; + + public BeachLayer(String id, SurfaceFloatField beachSelector, RockStrata strata) { + super(id); + this.beachSelector = beachSelector; + this.strata = strata; + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + return strata.get(context, depth).getBlock(RockVariant.SAND); + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + if (depth < 0 || depth > 3) { + return 0; + } + + float altitude = context.getLocation().z; + if (altitude < -5| altitude > 1) { + return 0; + } + + return 3 * beachSelector.get(context); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.java new file mode 100644 index 0000000..59f487a --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CliffLayer.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.terrain; + +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.context.SurfaceBlockContext; +import ru.windcorp.progressia.test.Rocks.RockVariant; + +public class CliffLayer extends TerrainLayer { + + private final SurfaceFloatField cliffSelector; + private final RockStrata strata; + + public CliffLayer(String id, SurfaceFloatField cliffSelector, RockStrata strata) { + super(id); + this.cliffSelector = cliffSelector; + this.strata = strata; + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + + RockVariant variant; + switch (context.getRandom().nextInt(4)) { + case 0: + variant = RockVariant.GRAVEL; + break; + case 1: + variant = RockVariant.MONOLITH; + break; + default: + variant = RockVariant.CRACKED; + break; + } + + return strata.get(context, depth).getBlock(variant); + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + if (depth < 0 || depth > 7) { + return 0; + } + + return 100 * cliffSelector.get(context); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.java new file mode 100644 index 0000000..2ce53a6 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/CrustLayer.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.terrain; + +import ru.windcorp.progressia.common.util.ArrayFloatRangeMap; +import ru.windcorp.progressia.common.util.FloatRangeMap; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; +import ru.windcorp.progressia.test.Rocks.RockVariant; + +public class CrustLayer extends TerrainLayer { + + private static final FloatRangeMap WEAR_TABLE = new ArrayFloatRangeMap<>(); + static { + WEAR_TABLE.put(Float.NEGATIVE_INFINITY, 0.25f, RockVariant.MONOLITH); + WEAR_TABLE.put(0.25f, 0.5f, RockVariant.CRACKED); + WEAR_TABLE.put(0.5f, 0.75f, RockVariant.GRAVEL); + WEAR_TABLE.put(0.75f, Float.POSITIVE_INFINITY, RockVariant.SAND); + } + + private final RockStrata strata; + + public CrustLayer(String id, RockStrata strata) { + super(id); + this.strata = strata; + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + + RockVariant variant; + if (depth < 8) { + float wear = 1 - depth / 8; + float offset = (context.getRandom().nextFloat() * 2 - 1) * 0.5f; + variant = WEAR_TABLE.get(wear + offset); + } else { + variant = RockVariant.MONOLITH; + } + + return strata.get(context, depth).getBlock(variant); + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + if (depth < 0) { + return 0; + } else if (context.getLocation().z > -100) { + return 1; + } else { + return 0; + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java new file mode 100644 index 0000000..ac802c2 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/LayeredTerrain.java @@ -0,0 +1,61 @@ +/* + * 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.terrain; + +import java.util.ArrayList; +import java.util.List; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.server.world.generation.surface.TerrainSupplier; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class LayeredTerrain implements TerrainSupplier { + + private final List layers = new ArrayList<>(); + + public void addLayer(TerrainLayer layer) { + this.layers.add(layer); + } + + @Override + public BlockData get(SurfaceBlockContext context, float depth) { + TerrainLayer layer = null; + float intensity = 0; + + for (int i = 0; i < layers.size(); ++i) { + TerrainLayer currentLayer = layers.get(i); + + float currentIntensity = currentLayer.getIntensity(context, depth); + if (currentIntensity <= 0) { + continue; + } + + if (intensity < currentIntensity) { + intensity = currentIntensity; + layer = currentLayer; + } + } + + if (layer == null) { + layer = layers.get(0); + } + + return layer.generate(context, depth, intensity); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.java new file mode 100644 index 0000000..a72f95e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/MantleLayer.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.test.gen.terrain; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class MantleLayer extends TerrainLayer { + + private final BlockData material = BlockDataRegistry.getInstance().get("Test:Mantle"); + + public MantleLayer(String id) { + super(id); + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + return material; + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + return context.getLocation().z <= -100 ? 1 : 0; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/RockStrata.java similarity index 64% rename from src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java rename to src/main/java/ru/windcorp/progressia/test/gen/terrain/RockStrata.java index 5b41ef1..218b51a 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/RockLayer.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/RockStrata.java @@ -15,43 +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.test.gen; +package ru.windcorp.progressia.test.gen.terrain; 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; +import ru.windcorp.progressia.test.Rocks.Rock; -public class RockLayer implements TerrainLayer { - - private final DiscreteNoise strata; +public class RockStrata { + + private final DiscreteNoise distribution; private final SurfaceFloatField depthOffsets; - private final double horizontalScale = 200; - private final double verticalScale = 10; - private final double depthInfluense = 0.1; + private final double horizontalScale = 800; + private final double verticalScale = 20; + private final double depthInfluence = 0.1; - public RockLayer(DiscreteNoise strata, SurfaceFloatField depthOffsets) { - this.strata = strata; + public RockStrata(DiscreteNoise distribution, SurfaceFloatField depthOffsets) { + this.distribution = distribution; this.depthOffsets = depthOffsets; } - - @Override - public BlockData get(SurfaceBlockContext context, float depth) { - + + public Rock get(SurfaceBlockContext context, float depth) { double z = context.getLocation().z; - z -= depth * depthInfluense; + z -= depth * depthInfluence; z += depthOffsets.get(context); z /= verticalScale; - return strata - .get( + return distribution.get( context.getLocation().x / horizontalScale, context.getLocation().y / horizontalScale, z - ) - .get(context, depth); + ); } } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java new file mode 100644 index 0000000..44875a0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/SoilLayer.java @@ -0,0 +1,59 @@ +/* + * 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.terrain; + +import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.util.math.PiecewiseLinearFunction; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class SoilLayer extends TerrainLayer { + + private static final PiecewiseLinearFunction THICKNESS = PiecewiseLinearFunction.builder() + .add(Units.get("-5 m"), Units.get("1 m")) + .add(Units.get("0 m"), Units.get("4 m")) + .add(Units.get("5 km"), Units.get("0 m")) + .build(); + + private final BlockData soil = BlockDataRegistry.getInstance().get("Test:Dirt"); + + public SoilLayer(String id) { + super(id); + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + return soil; + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + if (depth < 0) return 0; + + float altitude = context.getLocation().z; + float thickness = THICKNESS.apply(altitude); + + if (depth < thickness) { + return 2; + } else { + return 0; + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.java new file mode 100644 index 0000000..e9eeb4b --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/TerrainLayer.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.terrain; + +import ru.windcorp.progressia.common.util.namespaces.Namespaced; +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public abstract class TerrainLayer extends Namespaced { + + public TerrainLayer(String id) { + super(id); + } + + public abstract BlockData generate(SurfaceBlockContext context, float depth, float intensity); + + public abstract float getIntensity(SurfaceBlockContext context, float depth); + +} diff --git a/src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.java b/src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.java new file mode 100644 index 0000000..3813f68 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/gen/terrain/WaterLayer.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.gen.terrain; + +import ru.windcorp.progressia.common.world.block.BlockData; +import ru.windcorp.progressia.common.world.block.BlockDataRegistry; +import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; + +public class WaterLayer extends TerrainLayer { + + private final BlockData water = BlockDataRegistry.getInstance().get("Test:Water"); + + public WaterLayer(String id) { + super(id); + } + + @Override + public BlockData generate(SurfaceBlockContext context, float depth, float intensity) { + return water; + } + + @Override + public float getIntensity(SurfaceBlockContext context, float depth) { + if (depth <= 0 && context.getLocation().z <= 0) { + return 2; + } + return 0; + } + +} diff --git a/src/main/resources/assets/textures/blocks/Mantle.png b/src/main/resources/assets/textures/blocks/Mantle.png new file mode 100644 index 0000000000000000000000000000000000000000..838daff45e1cfd8408fcfc730898705503361358 GIT binary patch literal 1529 zcmV}^ANIZa%Sgf_ZUhnSQ(>;CG(N)FwfnWdn=aAS*h3Y+|Lk zRv4jGo2|n`|fdr z0$}Wzzz9a^C@}G+ZIRXpnE@f&vVwBBz56h1J+710 z>g)4{4MWE`6jDN9WO0}$aVG{Q1^^)CB1>Y3p;WYK>#pS{MnVXwRNHl@s*%dDZ0Ezn zBZPPmiZh0hp(j~-xk&e?>QEGhHfEE2cRU#oB))sKod5gwqm9id3}qMq4Vd7Bc*nA8 z`qs7VG!E6NjG_=%eVfJ6x$4h#N4db*>^gd}m|6%0f%nh%x7Ulw?fsKcpCdmQq#UF? zlxGM5aa_kX7Z~&q2-f4sCq>D9?o{xe{weeSzHO8k9<>3niGI1c(g-$GM8qqbMgzdA8h9j66VLT1rIhml zS=-Z@b6QlDp^Vuy-&XamrVN`Whz$eAQ3xRbyr-UHS3SMRbKJBYGO-~^KwQsxaWOmA zjZ%6wpPIIFy_o*|``@g0M{MB(#)Fb|U0asfQHmRzU>o(Emt_?QF#%GNWUp1-_84lW zjYXDydfuo(IkvekO9eD>EiQ(ZviUeAj`OtLzO)Q9io&Yz8Kaa7d*C>qd^uOIFBean zZ4!ExW5*r|eF7o$9LMz>)>CLG7h7={o~yH#^73+}>l*#-mp_h2A%-Z6LMtNAhhjOO zfB5o{C!?N=e3S|~P$44UPm^Fd9u-wp9?Bob@k8CFqikQ4hvTWUJ#@8LW~0EhZ3BRi zgwt8}>Hce;X2rRf=h^+^v*$UY@2jq@>eh9ghEhkX+wCz4gTuLEf~RQ~5)WO@XMNWz zU}&W`ha&>WC!}qwH#aYK`;!6T$A`5vP*v3yhS)?}!S4tDpP~V_qm@J$yQV1^hu5oV zmPSAuoHLBf&Aw>+jtc$$!zZa!({o@L7~__*h7JgtWm)~Nq01!Ja+pnLCPt^S416DY z4tkX)1cUh`9f$tKd;SuVmhI$ zK`&M-O)0i;-?O&wDeI*igpeU|ER4$2@e1ktvKz&rW#Xs(Nh#n5zGY(Ha{@wuVHC&1 zd^*7v#1z{?3|h-L@`5-~Qa!8>Ro!;`ljr+8k627TZ4XIAjA4k0*9z8CrW~_lLdfBD zn%v(%qSbshio$6Uj`OTIH=EsQy)U9L6ik@N@QBSQHvm8oC4{t;QO<2_HEnBJRu*|u f4fm(>Xf*mi0i;XR%b^Q200000NkvXXu0mjfJg3>@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/Water.png b/src/main/resources/assets/textures/blocks/Water.png new file mode 100644 index 0000000000000000000000000000000000000000..e609712fefc2816886f21bd4dc3276dccaa0100b GIT binary patch literal 1605 zcmV-L2DEX>4Tx04R}tkv&MmKpe$iQ>8^Jf_4xQ$xxlFh>8diyL*qjcYshUG1crC2UN{6 z648j5&a8^QSNJi6UW{Q@Vx}HTE~e0SeBHyt*Sj#!YJcv}(XC`n26#l`Ii?#H@dokq zrloV$2XA8`C}a>?W> zf{|kZWvGxGKlmT~?$*prPPj>d2+;Xr+aJS#Zx^UnZTtJ!w(BQ=_Zhg-n*MSPnE52V z+SEcvK+iUCaoyD9J>YT&=zr2BLvkc9O(B;9-p}ZpGC@V1PFdS8{+@~02y>eSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{ z00b>bL_t(I%O%rWlG{WS0MPsFmMnW_m;fn?eX$?bzz+E#RY{SIEld5l4?Z}1IQYk( ze`O{DAW>a6vl(W@Y;!OR64@L`lpd@KfMElW(p~B@`w0LUfy{yc0U73q*mHL?)-ro{ zw{Xi$fE2AHf{5Xs0AYi*%zgkM003ecPKb{}oNR$v~Z!8)ffCM($@vQ4QdJ8jThV)FxOe8Ax zQkTv9A#++k96HkRem+rg|zBC1lV)*Hzp}O>Tqz^N@TwmN`yS-#Ov4mM`Bf@;N zL`Xyy_1+D~a=B$@(c)%uKJU!pW-K!L8IZ@_koocNm$GiN4`j5~h=^ENw3HIn6SXS<13puCI_tEMcDR0zh;0WqXlwxz$3h}-M?>|N_p z>J=%E$A^uvZr3?xy}ru#FMks=5!oCp%A%10h(O4!ub)4u3Pgn2^pH~aAKwr$GXa1I zZBAqw=PujpI{^6Tq7{ioKeevR%u=)#OhAD1JP~oU10Vs>&9p31YepghvJjxSO|1(q zDs_2t#tIr$F6o0LM#%&Lp_^MG{ElyU5{pCn2|?U+)kn}rPk z)a61_q$DzD1QCZ>S%HX-$9;~@Dnx8&2S|}+i3p#=BdC<|+)+q$K_X_(aO>UY@UT)> z04(bTGGBiBl!OuKHr-5$%Cfyh*m?gBB0h)K>NX=oP>Cg3*Lp#~^YNWTby?ef2fz%_ zbz4`lK`(DVg}Xd|d_`trA*3K?Da;B0;iElUW{4DblTsmbwo_CAaLn`Ee;_jeWF{g? zW@7w5%#pc|4ge^UW^PkT4f5HW&#v`yK0eB}r5hkht>ORIK>!dU%8Ya;k(W=u&e46E z6z#`RMKZiScVZ@Htrg%k+>kZh>*eLR{|f*%x|I4KNF^+*b&3H^00000NkvXXu0mjf Dw$tC0 literal 0 HcmV?d00001