From ec47ca1983643501ac807e87617375de753179c0 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Wed, 14 Jul 2021 04:51:50 -0400 Subject: [PATCH] THE SUPER DUPER COOL BUT TOTALLY NOT STABLE THING THATS NOT READY YET... --- build.gradle | 2 +- src/main/java/com/volmit/iris/Iris.java | 63 ++++++++++ .../generator/actuator/IrisBiomeActuator.java | 36 +++++- .../java/com/volmit/iris/nms/INMSBinding.java | 5 + .../volmit/iris/nms/v17_1/NMSBinding17_1.java | 65 ++++++++++ .../com/volmit/iris/nms/v1X/NMSBinding1X.java | 11 ++ .../com/volmit/iris/object/IrisBiome.java | 13 +- .../volmit/iris/object/IrisBiomeCustom.java | 113 ++++++++++++++++++ .../iris/object/IrisBiomeCustomCategory.java | 22 ++++ .../object/IrisBiomeCustomPrecipType.java | 19 +++ .../com/volmit/iris/object/IrisDimension.java | 51 ++++++++ .../scaffold/hunk/view/BiomeGridHunkView.java | 14 +++ .../volmit/iris/util/LinkedTerrainChunk.java | 5 + .../util/RegistryListBiomeDownfallType.java | 13 ++ 14 files changed, 423 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/volmit/iris/object/IrisBiomeCustom.java create mode 100644 src/main/java/com/volmit/iris/object/IrisBiomeCustomCategory.java create mode 100644 src/main/java/com/volmit/iris/object/IrisBiomeCustomPrecipType.java create mode 100644 src/main/java/com/volmit/iris/util/RegistryListBiomeDownfallType.java diff --git a/build.gradle b/build.gradle index f5a5b4bb9..8fa4064d6 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'com.volmit.iris' -version '1.4.15' +version '1.5-TOTALLY-UNSTABLE' def apiVersion = '1.17' def name = 'Iris' def main = 'com.volmit.iris.Iris' diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index fd87af8e7..50d036ac7 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -10,7 +10,9 @@ import com.volmit.iris.manager.link.MultiverseCoreLink; import com.volmit.iris.manager.link.MythicMobsLink; import com.volmit.iris.nms.INMS; import com.volmit.iris.object.IrisCompat; +import com.volmit.iris.object.IrisDimension; import com.volmit.iris.scaffold.IrisWorlds; +import com.volmit.iris.scaffold.data.DataProvider; import com.volmit.iris.scaffold.engine.EngineCompositeGenerator; import com.volmit.iris.util.*; import io.papermc.lib.PaperLib; @@ -61,6 +63,66 @@ public class Iris extends VolmitPlugin implements Listener { INMS.get(); IO.delete(new File("iris")); lowMemoryMode = Runtime.getRuntime().maxMemory() < 4000000000L; // 4 * 1000 * 1000 * 1000 // 4; + installDataPacks(); + } + + private void installDataPacks() { + Iris.info("Checking Data Packs..."); + boolean reboot = false; + File packs = new File("plugins/Iris/packs"); + File dpacks = null; + + look: for(File i : new File(".").listFiles()) + { + if(i.isDirectory()) + { + for(File j : i.listFiles()) + { + if(j.isDirectory() && j.getName().equals("datapacks")) + { + dpacks = j; + break look; + } + } + } + } + + if(dpacks == null) + { + Iris.error("Cannot find the datapacks folder! Please try generating a default world first maybe? Is this a new server?"); + return; + } + + if(packs.exists()) + { + for(File i : packs.listFiles()) + { + if(i.isDirectory()) + { + Iris.verbose("Checking Pack: " + i.getPath()); + IrisDataManager data = new IrisDataManager(i); + File dims = new File(i, "dimensions"); + + if(dims.exists()) + { + for(File j : dims.listFiles()) + { + if(j.getName().endsWith(".json")) + { + IrisDimension dim = data.getDimensionLoader().load(j.getName().split("\\Q.\\E")[0]); + Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); + if(dim.installDataPack(() -> data, dpacks)) + { + reboot = true; + } + } + } + } + } + } + } + + Iris.info("Data Packs Setup!"); } public static int getThreadCount() { @@ -377,6 +439,7 @@ public class Iris extends VolmitPlugin implements Listener { Iris.info("Server type & version: " + Bukkit.getVersion()); Iris.info("Bukkit version: " + Bukkit.getBukkitVersion()); Iris.info("Java version: " + getJavaVersion()); + Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes()); for (int i = 0; i < info.length; i++) { splash[i] += info[i]; } diff --git a/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java index 3c082c73a..6b1a315c0 100644 --- a/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/generator/actuator/IrisBiomeActuator.java @@ -1,8 +1,11 @@ package com.volmit.iris.generator.actuator; +import com.volmit.iris.nms.INMS; +import com.volmit.iris.object.IrisBiome; import com.volmit.iris.scaffold.engine.Engine; import com.volmit.iris.scaffold.engine.EngineAssignedActuator; import com.volmit.iris.scaffold.hunk.Hunk; +import com.volmit.iris.scaffold.hunk.view.BiomeGridHunkView; import com.volmit.iris.scaffold.parallel.BurstExecutor; import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.util.PrecisionStopwatch; @@ -26,9 +29,36 @@ public class IrisBiomeActuator extends EngineAssignedActuator { int zzf = zf; burst.queue(() -> { - Biome v = getComplex().getTrueBiomeStream().get(modX(xxf + x), modZ(zzf + z)).getSkyBiome(RNG.r, x, 0, z); - for (int i = 0; i < h.getHeight(); i++) { - h.set(xxf, i, zzf, v); + IrisBiome ib = getComplex().getTrueBiomeStream().get(modX(xxf + x), modZ(zzf + z)); + + if(ib.isCustom()) + { + try + { + Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey()+":"+ib.getCustom().getId()); + ((BiomeGridHunkView)h).forceBiomeBaseInto(x, 0, z, biomeBase); + + for (int i = 0; i < h.getHeight(); i++) { + ((BiomeGridHunkView)h).forceBiomeBaseInto(xxf, i, zzf, biomeBase); + } + } + + catch(Throwable e) + { + e.printStackTrace(); + Biome v = ib.getSkyBiome(RNG.r, x, 0, z); + for (int i = 0; i < h.getHeight(); i++) { + h.set(xxf, i, zzf, v); + } + } + } + + else + { + Biome v = ib.getSkyBiome(RNG.r, x, 0, z); + for (int i = 0; i < h.getHeight(); i++) { + h.set(xxf, i, zzf, v); + } } }); } diff --git a/src/main/java/com/volmit/iris/nms/INMSBinding.java b/src/main/java/com/volmit/iris/nms/INMSBinding.java index 6d98793d1..ef5650599 100644 --- a/src/main/java/com/volmit/iris/nms/INMSBinding.java +++ b/src/main/java/com/volmit/iris/nms/INMSBinding.java @@ -4,6 +4,7 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; import org.bukkit.block.Biome; +import org.bukkit.generator.ChunkGenerator; public interface INMSBinding { Object getBiomeBaseFromId(int id); @@ -29,4 +30,8 @@ public interface INMSBinding { default World createWorld(WorldCreator c) { return c.createWorld(); } + + int countCustomBiomes(); + + void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk); } diff --git a/src/main/java/com/volmit/iris/nms/v17_1/NMSBinding17_1.java b/src/main/java/com/volmit/iris/nms/v17_1/NMSBinding17_1.java index d6823c2b7..090f0addd 100644 --- a/src/main/java/com/volmit/iris/nms/v17_1/NMSBinding17_1.java +++ b/src/main/java/com/volmit/iris/nms/v17_1/NMSBinding17_1.java @@ -1,5 +1,6 @@ package com.volmit.iris.nms.v17_1; +import com.volmit.iris.Iris; import com.volmit.iris.nms.INMSBinding; import com.volmit.iris.util.KMap; import net.minecraft.core.IRegistry; @@ -7,18 +8,54 @@ import net.minecraft.core.IRegistryWritable; import net.minecraft.resources.MinecraftKey; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.chunk.BiomeStorage; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.v1_17_R1.CraftServer; import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.generator.ChunkGenerator; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding17_1 implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); + private Field biomeStorageCache = null; + + private Object getBiomeStorage(ChunkGenerator.BiomeGrid g) + { + try { + return getFieldForBiomeStorage(g).get(g); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + return null; + } + + private Field getFieldForBiomeStorage(Object storage) { + Field f = biomeStorageCache; + + if (f != null) + { + return f; + } + try { + + f = storage.getClass().getDeclaredField("biome"); + f.setAccessible(true); + return f; + } catch (Throwable e) { + e.printStackTrace(); + Iris.error(storage.getClass().getCanonicalName()); + } + + biomeStorageCache = f; + return null; + } private IRegistryWritable getCustomBiomeRegistry() { return ((CraftServer) Bukkit.getServer()).getHandle().getServer().getCustomRegistry().b(IRegistry.aO); @@ -148,6 +185,34 @@ public class NMSBinding17_1 implements INMSBinding { return biome.ordinal(); } + @Override + public int countCustomBiomes() { + AtomicInteger a = new AtomicInteger(0); + getCustomBiomeRegistry().d().stream().forEach((i) -> { + MinecraftKey k = i.getKey().a(); + + if(k.getNamespace().equals("minecraft")) + { + return; + } + + a.incrementAndGet(); + Iris.verbose("Custom Biome: " + k.toString()); + }); + + return a.get(); + } + + @Override + public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { + try { + BiomeStorage s = (BiomeStorage) getFieldForBiomeStorage(chunk).get(chunk); + s.setBiome(x,y,z, (BiomeBase) somethingVeryDirty); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + @Override public boolean isBukkit() { return false; diff --git a/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java b/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java index 3369dc926..991e9bfcd 100644 --- a/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java +++ b/src/main/java/com/volmit/iris/nms/v1X/NMSBinding1X.java @@ -4,6 +4,7 @@ import com.volmit.iris.nms.INMSBinding; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Biome; +import org.bukkit.generator.ChunkGenerator; public class NMSBinding1X implements INMSBinding { @Override @@ -54,4 +55,14 @@ public class NMSBinding1X implements INMSBinding { public int getBiomeId(Biome biome) { return biome.ordinal(); } + + @Override + public int countCustomBiomes() { + return 0; + } + + @Override + public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { + + } } diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index 962f83cc1..32d55ac23 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -31,11 +31,9 @@ public class IrisBiome extends IrisRegistrant implements IRare { @Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.") private String name = "A Biome"; - /* Needs to be implemented but it's not - @DontObfuscate - @Desc("The palette of blocks for 'water' in this biome (overwrites dimension)") - private IrisMaterialPalette fluidPalette = new IrisMaterialPalette().qclear().qadd("void_air"); - */ + @DontObfuscate + @Desc("If the biome type custom is defined, specify this") + private IrisBiomeCustom custom; @DontObfuscate @Desc("Entity spawns to override or add to this biome. Anytime an entity spawns, it has a chance to be replaced as one of these overrides.") @@ -201,6 +199,11 @@ public class IrisBiome extends IrisRegistrant implements IRare { return vanillaDerivative == null ? derivative : vanillaDerivative; } + public boolean isCustom() + { + return getCustom() != null; + } + public double getGenLinkMax(String loadKey) { Integer v = genCacheMax.aquire(() -> { diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeCustom.java b/src/main/java/com/volmit/iris/object/IrisBiomeCustom.java new file mode 100644 index 000000000..e9867ef54 --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisBiomeCustom.java @@ -0,0 +1,113 @@ +package com.volmit.iris.object; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.awt.*; + +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("A custom biome, generated through a datapack") +@Data +public class IrisBiomeCustom { + @DontObfuscate + @Required + @Desc("The resource key of this biome. Just a simple id such as 'plains' or something.") + private String id = ""; + + @MinNumber(-3) + @MaxNumber(3) + @DontObfuscate + @Desc("The biome's temperature") + private double temperature = 0.8; + + @MinNumber(-3) + @MaxNumber(3) + @DontObfuscate + @Desc("The biome's downfall amount (snow / rain), see preci") + private double humidity = 0.4; + + @DontObfuscate + @Desc("The biome's downfall type") + private IrisBiomeCustomPrecipType downfallType = IrisBiomeCustomPrecipType.rain; + + @DontObfuscate + @Desc("The biome's category type") + private IrisBiomeCustomCategory category = IrisBiomeCustomCategory.plains; + + @DontObfuscate + @Desc("The color of the sky, top half of sky. (hex format)") + private String skyColor = "#79a8e1"; + + @DontObfuscate + @Desc("The color of the fog, bottom half of sky. (hex format)") + private String fogColor = "#c0d8e1"; + + @DontObfuscate + @Desc("The color of the water (hex format). Leave blank / don't define to not change") + private String waterColor = "#3f76e4"; + + @DontObfuscate + @Desc("The color of water fog (hex format). Leave blank / don't define to not change") + private String waterFogColor = "#050533"; + + @DontObfuscate + @Desc("The color of the grass (hex format). Leave blank / don't define to not change") + private String grassColor = ""; + + @DontObfuscate + @Desc("The color of foliage (hex format). Leave blank / don't define to not change") + private String foliageColor = ""; + + public String generateJson() + { + JSONObject effects = new JSONObject(); + effects.put("sky_color", parseColor(getSkyColor())); + effects.put("fog_color", parseColor(getFogColor())); + effects.put("water_color", parseColor(getWaterColor())); + effects.put("water_fog_color", parseColor(getWaterFogColor())); + + if(getGrassColor() != null) + { + effects.put("grass_color", parseColor(getGrassColor())); + } + + if(getFoliageColor() != null) + { + effects.put("foliage_color", parseColor(getFoliageColor())); + } + + JSONObject j = new JSONObject(); + j.put("surface_builder", "minecraft:grass"); + j.put("depth", 0.125); + j.put("scale", 0.05); + j.put("temperature", getTemperature()); + j.put("downfall", getHumidity()); + j.put("precipitation", getDownfallType().toString().toLowerCase()); + j.put("category", getCategory().toString().toLowerCase()); + j.put("effects", effects); + j.put("starts", new JSONArray()); + j.put("spawners", new JSONObject()); + j.put("spawn_costs", new JSONObject()); + j.put("carvers", new JSONObject()); + j.put("features", new JSONArray()); + + return j.toString(4); + } + + private int parseColor(String c) { + String v = (c.startsWith("#") ? c : "#" + c).trim(); + try { + return Color.decode(v).getRGB(); + } catch (Throwable e) { + Iris.error("Error Parsing '''color''', (" + c+ ")"); + } + + return 0; + } +} diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeCustomCategory.java b/src/main/java/com/volmit/iris/object/IrisBiomeCustomCategory.java new file mode 100644 index 000000000..8f1ece8f6 --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisBiomeCustomCategory.java @@ -0,0 +1,22 @@ +package com.volmit.iris.object; + +public enum IrisBiomeCustomCategory +{ + beach, + desert, + extreme_hills, + forest, + icy, + jungle, + mesa, + mushroom, + nether, + none, + ocean, + plains, + river, + savanna, + swamp, + taiga, + the_end +} diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeCustomPrecipType.java b/src/main/java/com/volmit/iris/object/IrisBiomeCustomPrecipType.java new file mode 100644 index 000000000..7a618f34f --- /dev/null +++ b/src/main/java/com/volmit/iris/object/IrisBiomeCustomPrecipType.java @@ -0,0 +1,19 @@ +package com.volmit.iris.object; + +import com.volmit.iris.util.Desc; +import com.volmit.iris.util.DontObfuscate; + +public enum IrisBiomeCustomPrecipType +{ + @Desc("No downfall") + @DontObfuscate + none, + + @Desc("Rain downfall") + @DontObfuscate + rain, + + @Desc("Snow downfall") + @DontObfuscate + snow +} diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 4aadaf5bb..938cde1f7 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -1,5 +1,6 @@ package com.volmit.iris.object; +import com.volmit.iris.Iris; import com.volmit.iris.generator.noise.CNG; import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.scaffold.cache.AtomicCache; @@ -10,10 +11,14 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.World.Environment; import org.bukkit.block.data.BlockData; +import java.io.File; +import java.io.IOException; + @Accessors(chain = true) @AllArgsConstructor @NoArgsConstructor @@ -452,4 +457,50 @@ public class IrisDimension extends IrisRegistrant { return landBiomeStyle; } + + public boolean installDataPack(DataProvider data, File datapacks) + { + boolean write = false; + boolean changed = false; + + for(IrisBiome i : getAllBiomes(data)) + { + if(i.isCustom()) + { + write = true; + File output = new File(datapacks, "iris/data/" + getLoadKey() + "/worldgen/biome/" + i.getCustom().getId() + ".json"); + + if(!output.exists()) + { + changed = true; + } + + Iris.verbose(" Installing Data Pack Biome: " + output.getPath()); + output.getParentFile().mkdirs(); + try { + IO.writeAll(output, i.getCustom().generateJson()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + if(write) + { + File mcm = new File(datapacks, "iris/pack.mcmeta"); + try { + IO.writeAll(mcm, "{\n" + + " \"pack\": {\n" + + " \"description\": \"Iris Data Pack. This pack contains all installed Iris Packs' resources.\",\n" + + " \"pack_format\": 7\n" + + " }\n" + + "}\n"); + } catch (IOException e) { + e.printStackTrace(); + } + Iris.verbose(" Installing Data Pack MCMeta: " + mcm.getPath()); + } + + return changed; + } } diff --git a/src/main/java/com/volmit/iris/scaffold/hunk/view/BiomeGridHunkView.java b/src/main/java/com/volmit/iris/scaffold/hunk/view/BiomeGridHunkView.java index 0ae2190fe..f5a86d361 100644 --- a/src/main/java/com/volmit/iris/scaffold/hunk/view/BiomeGridHunkView.java +++ b/src/main/java/com/volmit/iris/scaffold/hunk/view/BiomeGridHunkView.java @@ -1,7 +1,12 @@ package com.volmit.iris.scaffold.hunk.view; +import com.volmit.iris.nms.INMS; import com.volmit.iris.scaffold.hunk.Hunk; +import com.volmit.iris.util.LinkedTerrainChunk; +import com.volmit.iris.util.TerrainChunk; +import net.minecraft.world.level.chunk.BiomeStorage; import org.bukkit.block.Biome; +import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator; import org.bukkit.generator.ChunkGenerator.BiomeGrid; public class BiomeGridHunkView implements Hunk { @@ -36,4 +41,13 @@ public class BiomeGridHunkView implements Hunk { public Biome getRaw(int x, int y, int z) { return chunk.getBiome(x, y, z); } + + public void forceBiomeBaseInto(int x, int y, int z, Object somethingVeryDirty) { + if(chunk instanceof LinkedTerrainChunk) + { + INMS.get().forceBiomeInto(x,y,z,somethingVeryDirty,((LinkedTerrainChunk) chunk).getRawBiome()); + return; + } + INMS.get().forceBiomeInto(x,y,z,somethingVeryDirty,chunk); + } } diff --git a/src/main/java/com/volmit/iris/util/LinkedTerrainChunk.java b/src/main/java/com/volmit/iris/util/LinkedTerrainChunk.java index ddb5a032f..c348369ce 100644 --- a/src/main/java/com/volmit/iris/util/LinkedTerrainChunk.java +++ b/src/main/java/com/volmit/iris/util/LinkedTerrainChunk.java @@ -85,6 +85,11 @@ public class LinkedTerrainChunk implements TerrainChunk { biome3D.setBiome(x, 0, z, bio); } + public BiomeGrid getRawBiome() + { + return storage; + } + @Override public void setBiome(int x, int y, int z, Biome bio) { if (storage != null) { diff --git a/src/main/java/com/volmit/iris/util/RegistryListBiomeDownfallType.java b/src/main/java/com/volmit/iris/util/RegistryListBiomeDownfallType.java new file mode 100644 index 000000000..402a1670f --- /dev/null +++ b/src/main/java/com/volmit/iris/util/RegistryListBiomeDownfallType.java @@ -0,0 +1,13 @@ +package com.volmit.iris.util; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target({PARAMETER, TYPE, FIELD}) +public @interface RegistryListBiomeDownfallType { + +}