diff --git a/README.md b/README.md index 32c904584..e0800e0fb 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ For 1.16 and below, see the 1.14-1.16 branch. The master branch is for the latest version of minecraft. -# [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://docs.volmit.com/iris/) ** - -|** [Git](https://github.com/IrisDimensions) +# [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://docs.volmit.com/iris/) **|** [Git](https://github.com/IrisDimensions) ## Iris Toolbelt @@ -17,26 +15,26 @@ package com.volmit.iris.core.tools IrisToolbelt.access(anyWorld).getCompound().getData(); // Get Default Engine from world - IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine(); +IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine(); // Get the engine at the given height - IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68); +IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68); // IS THIS THING ON? - boolean yes=IrisToolbelt.isIrisWorld(world); +boolean yes=IrisToolbelt.isIrisWorld(world); // GTFO for worlds (moves players to any other world, just not this one) - IrisToolbelt.evacuate(world); +IrisToolbelt.evacuate(world); - IrisAccess access=IrisToolbelt.createWorld() // If you like builders... - .name("myWorld") // The world name - .dimension("terrifyinghands") - .seed(69133742) // The world seed - .headless(true) // Headless make gen go fast - .pregen(PregenTask // Define a pregen job to run - .builder() - .center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks) - .radius(4) // Radius in REGIONS. Rad of 4 means a 9x9 Region map. - .build()) - .create(); +IrisAccess access=IrisToolbelt.createWorld() // If you like builders... + .name("myWorld") // The world name + .dimension("terrifyinghands") + .seed(69133742) // The world seed + .headless(true) // Headless make gen go fast + .pregen(PregenTask // Define a pregen job to run + .builder() + .center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks) + .radius(4) // Radius in REGIONS. Rad of 4 means a 9x9 Region map. + .build()) + .create(); ``` diff --git a/build.gradle b/build.gradle index 7f62a12b7..0cc7bd840 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ plugins { } group 'com.volmit.iris' -version '1.6.2' +version '1.6.5' 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 da553c005..51d28fe8e 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -57,7 +57,6 @@ import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Queue; import com.volmit.iris.util.scheduling.ShurikenQueue; import io.papermc.lib.PaperLib; -import net.kyori.adventure.platform.AudienceProvider; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.serializer.ComponentSerializer; import org.bukkit.Bukkit; @@ -74,7 +73,7 @@ import org.bukkit.plugin.Plugin; import java.io.*; import java.lang.annotation.Annotation; import java.net.URL; -import java.util.*; +import java.util.Date; @SuppressWarnings("CanBeFinal") public class Iris extends VolmitPlugin implements Listener { @@ -135,6 +134,7 @@ public class Iris extends VolmitPlugin implements Listener { super.onEnable(); Bukkit.getPluginManager().registerEvents(this, this); J.s(this::lateBind); + splash(); } public static void callEvent(Event e) { @@ -166,7 +166,6 @@ public class Iris extends VolmitPlugin implements Listener { J.a(() -> PaperLib.suggestPaper(this)); J.a(() -> IO.delete(getTemp())); J.a(this::bstats); - J.a(this::splash, 20); J.ar(this::checkConfigHotload, 60); J.sr(this::tickQueue, 0); J.s(this::setupPapi); @@ -251,7 +250,7 @@ public class Iris extends VolmitPlugin implements Listener { @Override public String getTag(String subTag) { - return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GREEN + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": "; + return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": "; } private void checkConfigHotload() { @@ -424,7 +423,7 @@ public class Iris extends VolmitPlugin implements Listener { } public void imsg(CommandSender s, String msg) { - s.sendMessage(C.GREEN + "[" + C.DARK_GRAY + "Iris" + C.GREEN + "]" + C.GRAY + ": " + msg); + s.sendMessage(C.IRIS + "[" + C.DARK_GRAY + "Iris" + C.IRIS + "]" + C.GRAY + ": " + msg); } @@ -443,9 +442,12 @@ public class Iris extends VolmitPlugin implements Listener { public static void msg(String string) { try { sender.sendMessage(string); - } catch (Throwable e) { - System.out.println(string); - Iris.reportError(e); + } catch (Throwable ignored) { + try { + System.out.println(string); + } catch (Throwable ignored1) { + + } } } @@ -523,7 +525,29 @@ public class Iris extends VolmitPlugin implements Listener { return; } - msg(C.LIGHT_PURPLE + string); + try { + throw new RuntimeException(); + } catch (Throwable e) { + try { + String[] cc = e.getStackTrace()[1].getClassName().split("\\Q.\\E"); + + if (cc.length > 5) { + debug(cc[3] + "/" + cc[4] + "/" + cc[cc.length - 1], e.getStackTrace()[1].getLineNumber(), string); + } else { + debug(cc[3] + "/" + cc[4], e.getStackTrace()[1].getLineNumber(), string); + } + } catch (Throwable ex) { + debug("Origin", -1, string); + } + } + } + + public static void debug(String category, int line, String string) { + if (!IrisSettings.get().getGeneral().isDebug()) { + return; + } + + msg("" + category + " <#bf3b76>" + line + " " + C.LIGHT_PURPLE + string.replaceAll("\\Q<\\E", "[").replaceAll("\\Q>\\E", "]")); } public static void verbose(String string) { @@ -538,7 +562,7 @@ public class Iris extends VolmitPlugin implements Listener { } public static void success(String string) { - msg(C.GREEN + string); + msg(C.IRIS + string); } public static void info(String string) { @@ -558,9 +582,9 @@ public class Iris extends VolmitPlugin implements Listener { // @NoArgsConstructor String padd = Form.repeat(" ", 8); String padd2 = Form.repeat(" ", 4); - String[] info = {"", "", "", "", "", padd2 + C.GREEN + " Iris", padd2 + C.GRAY + " by " + C.randomColor() + "V" + C.randomColor() + "o" + C.randomColor() + "l" + C.randomColor() + "m" + C.randomColor() + "i" + C.randomColor() + "t" + C.randomColor() + "S" + C.randomColor() + "o" + C.randomColor() + "f" + C.randomColor() + "t" + C.randomColor() + "w" + C.randomColor() + "a" + C.randomColor() + "r" + C.randomColor() + "e", padd2 + C.GRAY + " v" + getDescription().getVersion(), + String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "Volmit Software", padd2 + C.GRAY + " v" + C.IRIS + getDescription().getVersion(), }; - String[] splash = {padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@", padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.GREEN + " .(((()))). ", padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.GREEN + " .((((((())))))). ", padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.GREEN + " ((((((((())))))))) " + C.GRAY + " @", padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.GREEN + " ((((((((-))))))))) " + C.GRAY + " @@", padd + C.GRAY + "@@@&&" + C.GREEN + " ((((((({ })))))))) " + C.GRAY + " &&@@@", padd + C.GRAY + "@@" + C.GREEN + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@", padd + C.GRAY + "@" + C.GREEN + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@", padd + C.GRAY + "" + C.GREEN + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@", padd + C.GRAY + "" + C.GREEN + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@", padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@" + String[] splash = {padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@", padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.IRIS + " .(((()))). ", padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.IRIS + " .((((((())))))). ", padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.IRIS + " ((((((((())))))))) " + C.GRAY + " @", padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.IRIS + " ((((((((-))))))))) " + C.GRAY + " @@", padd + C.GRAY + "@@@&&" + C.IRIS + " ((((((({ })))))))) " + C.GRAY + " &&@@@", padd + C.GRAY + "@@" + C.IRIS + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@", padd + C.GRAY + "@" + C.IRIS + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@", padd + C.GRAY + "" + C.IRIS + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@", padd + C.GRAY + "" + C.IRIS + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@", padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@" }; //@done Iris.info("Server type & version: " + Bukkit.getVersion()); diff --git a/src/main/java/com/volmit/iris/core/ConversionManager.java b/src/main/java/com/volmit/iris/core/ConversionManager.java index 2b0397d52..c24f2adc2 100644 --- a/src/main/java/com/volmit/iris/core/ConversionManager.java +++ b/src/main/java/com/volmit/iris/core/ConversionManager.java @@ -28,7 +28,6 @@ import com.volmit.iris.engine.object.objects.IrisDirection; import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.data.B; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.function.Consumer2; import com.volmit.iris.util.io.Converter; @@ -42,8 +41,6 @@ import com.volmit.iris.util.nbt.tag.IntTag; import com.volmit.iris.util.nbt.tag.ListTag; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; -import net.kyori.adventure.text.minimessage.parser.Token; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.Jigsaw; diff --git a/src/main/java/com/volmit/iris/core/DolphinManager.java b/src/main/java/com/volmit/iris/core/DolphinManager.java index 3a2041946..65e6e04b6 100644 --- a/src/main/java/com/volmit/iris/core/DolphinManager.java +++ b/src/main/java/com/volmit/iris/core/DolphinManager.java @@ -1,6 +1,5 @@ package com.volmit.iris.core; -import com.volmit.iris.Iris; import com.volmit.iris.core.tools.IrisToolbelt; import org.bukkit.Material; import org.bukkit.entity.EntityType; @@ -15,13 +14,13 @@ public class DolphinManager implements Listener { * Note: This results in odd dolphin behaviour, but it's the best we can do. */ @EventHandler - public void on(PlayerInteractEntityEvent event){ - if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())){ + public void on(PlayerInteractEntityEvent event) { + if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())) { return; } Material hand = event.getPlayer().getInventory().getItem(event.getHand()).getType(); - if (event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))){ + if (event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))) { event.setCancelled(true); } } diff --git a/src/main/java/com/volmit/iris/core/IrisSettings.java b/src/main/java/com/volmit/iris/core/IrisSettings.java index 1c87528fa..ed02347d9 100644 --- a/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -107,6 +107,9 @@ public class IrisSettings { public boolean pluginMetrics = true; public boolean splashLogoStartup = true; public String forceMainWorld = ""; + public int spinh = -20; + public int spins = 7; + public int spinb = 8; } @Data diff --git a/src/main/java/com/volmit/iris/core/VillagerManager.java b/src/main/java/com/volmit/iris/core/VillagerManager.java index c7bd8bfda..9bd562cbd 100644 --- a/src/main/java/com/volmit/iris/core/VillagerManager.java +++ b/src/main/java/com/volmit/iris/core/VillagerManager.java @@ -14,8 +14,8 @@ public class VillagerManager implements Listener { * Replace or disable villager trade add event to prevent explorer map */ @EventHandler - public void on(VillagerAcquireTradeEvent event){ - if (!IrisToolbelt.isIrisWorld((event.getEntity().getWorld()))){ + public void on(VillagerAcquireTradeEvent event) { + if (!IrisToolbelt.isIrisWorld((event.getEntity().getWorld()))) { return; } @@ -26,13 +26,13 @@ public class VillagerManager implements Listener { IrisVillagerOverride override = IrisToolbelt.access(event.getEntity().getWorld()).getCompound().getRootDimension().getPatchCartographers(); - if (override.isDisableTrade()){ + if (override.isDisableTrade()) { event.setCancelled(true); Iris.debug("Cancelled cartographer trade @ " + event.getEntity().getLocation()); return; } - if (override.getValidItems() == null){ + if (override.getValidItems() == null) { event.setCancelled(true); Iris.debug("Cancelled cartographer trade because no override items are valid @ " + event.getEntity().getLocation()); return; diff --git a/src/main/java/com/volmit/iris/core/WandManager.java b/src/main/java/com/volmit/iris/core/WandManager.java index ea683439a..7f365f752 100644 --- a/src/main/java/com/volmit/iris/core/WandManager.java +++ b/src/main/java/com/volmit/iris/core/WandManager.java @@ -26,14 +26,12 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.Cuboid; import com.volmit.iris.util.format.C; import com.volmit.iris.util.math.M; -import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.WorldMatter; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import org.bukkit.*; import org.bukkit.block.Block; -import org.bukkit.block.data.BlockData; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -68,8 +66,7 @@ public class WandManager implements Listener { } public void tick(Player p) { - try - { + try { try { if (isWand(p.getInventory().getItemInMainHand())) { Location[] d = getCuboid(p.getInventory().getItemInMainHand()); @@ -78,10 +75,7 @@ public class WandManager implements Listener { } catch (Throwable e) { Iris.reportError(e); } - } - - catch(Throwable e) - { + } catch (Throwable e) { e.printStackTrace(); } } diff --git a/src/main/java/com/volmit/iris/core/command/CommandIris.java b/src/main/java/com/volmit/iris/core/command/CommandIris.java index 49edcc0f7..a8f4250c8 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIris.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIris.java @@ -76,6 +76,9 @@ public class CommandIris extends MortarCommand { @Command private CommandIrisReload reload; + @Command + private CommandIrisAura aura; + public CommandIris() { super("iris", "ir", "irs"); requiresPermission(Iris.perm); diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisAura.java b/src/main/java/com/volmit/iris/core/command/CommandIrisAura.java new file mode 100644 index 000000000..37f9e0922 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisAura.java @@ -0,0 +1,62 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.core.command; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisAura extends MortarCommand { + public CommandIrisAura() { + super("aura", "au"); + requiresPermission(Iris.perm.studio); + setDescription("Set aura spins"); + setCategory("Studio"); + } + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + try { + int h = Integer.parseInt(args[0]); + int s = Integer.parseInt(args[1]); + int b = Integer.parseInt(args[2]); + IrisSettings.get().getGeneral().setSpinh(h); + IrisSettings.get().getGeneral().setSpins(s); + IrisSettings.get().getGeneral().setSpinb(b); + IrisSettings.get().forceSave(); + sender.sendMessage("Aura Spins updated to " + h + " " + s + " " + b); + } catch (Throwable b) { + sender.sendMessage(getArgsUsage()); + } + + return true; + } + + @Override + protected String getArgsUsage() { + return " "; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java b/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java index 184948e03..838e8473d 100644 --- a/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisDebug.java @@ -21,10 +21,14 @@ package com.volmit.iris.core.command; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.Command; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; public class CommandIrisDebug extends MortarCommand { + @Command + private CommandIrisDebugSpawnerBoost boost; + public CommandIrisDebug() { super("debug", "dbg"); requiresPermission(Iris.perm.studio); diff --git a/src/main/java/com/volmit/iris/core/command/CommandIrisDebugSpawnerBoost.java b/src/main/java/com/volmit/iris/core/command/CommandIrisDebugSpawnerBoost.java new file mode 100644 index 000000000..1b7e195b1 --- /dev/null +++ b/src/main/java/com/volmit/iris/core/command/CommandIrisDebugSpawnerBoost.java @@ -0,0 +1,53 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.core.command; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisToolbelt; +import com.volmit.iris.engine.IrisEngine; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.MortarCommand; +import com.volmit.iris.util.plugin.VolmitSender; + +public class CommandIrisDebugSpawnerBoost extends MortarCommand { + public CommandIrisDebugSpawnerBoost() { + super("charge", "zzt"); + requiresPermission(Iris.perm.studio); + setDescription("Charge spawner energy"); + setCategory("Studio"); + } + + + @Override + public void addTabOptions(VolmitSender sender, String[] args, KList list) { + + } + + @Override + public boolean handle(VolmitSender sender, String[] args) { + ((IrisEngine) + IrisToolbelt.access(sender.player().getWorld()).getEngineAccess(sender.player().getLocation().getBlockY())).getWorldManager().chargeEnergy(); + return true; + } + + @Override + protected String getArgsUsage() { + return " [|,&,^,>>,<<,%] "; + } +} diff --git a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java index f574178fc..c22716eaa 100644 --- a/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java +++ b/src/main/java/com/volmit/iris/core/command/object/CommandIrisObjectSaveMatter.java @@ -22,7 +22,6 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.WandManager; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioBeautify.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioBeautify.java index 1046053bb..16b465c3b 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioBeautify.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioBeautify.java @@ -23,11 +23,13 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.json.JSONArray; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.VolmitSender; import java.io.File; +import java.io.IOException; public class CommandIrisStudioBeautify extends MortarCommand { public CommandIrisStudioBeautify() { @@ -80,7 +82,7 @@ public class CommandIrisStudioBeautify extends MortarCommand { } } else if (clean.getName().endsWith(".json")) { try { - IO.writeAll(clean, new JSONObject(IO.readAll(clean)).toString(4)); + clean(clean); } catch (Throwable e) { Iris.reportError(e); Iris.error("Failed to beautify " + clean.getAbsolutePath() + " You may have errors in your json!"); @@ -92,6 +94,43 @@ public class CommandIrisStudioBeautify extends MortarCommand { return c; } + private void clean(File clean) throws IOException { + JSONObject obj = new JSONObject(IO.readAll(clean)); + fixBlocks(obj, clean); + + IO.writeAll(clean, obj.toString(4)); + } + + private void fixBlocks(JSONObject obj, File f) { + for (String i : obj.keySet()) { + Object o = obj.get(i); + + if (i.equals("block") && o instanceof String && !o.toString().trim().isEmpty() && !o.toString().contains(":")) { + obj.put(i, "minecraft:" + o); + Iris.debug("Updated Block Key: " + o + " to " + obj.getString(i) + " in " + f.getPath()); + } + + if (o instanceof JSONObject) { + fixBlocks((JSONObject) o, f); + } else if (o instanceof JSONArray) { + fixBlocks((JSONArray) o, f); + } + } + } + + private void fixBlocks(JSONArray obj, File f) { + for (int i = 0; i < obj.length(); i++) { + Object o = obj.get(i); + + if (o instanceof JSONObject) { + fixBlocks((JSONObject) o, f); + } else if (o instanceof JSONArray) { + fixBlocks((JSONArray) o, f); + } + } + } + + @Override protected String getArgsUsage() { return "[project]"; diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java index fca53bec8..603b42d66 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioSummon.java @@ -20,6 +20,7 @@ package com.volmit.iris.core.command.studio; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.tools.IrisWorlds; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.IrisAccess; @@ -41,7 +42,16 @@ public class CommandIrisStudioSummon extends MortarCommand { @Override public void addTabOptions(VolmitSender sender, String[] args, KList list) { - + if ((args.length == 0 || args.length == 1) && sender.isPlayer() && IrisWorlds.isIrisWorld(sender.player().getWorld())) { + IrisData data = IrisWorlds.access(sender.player().getWorld()).getData(); + if (data == null) { + sender.sendMessage("Tab complete options only work for summons while in an Iris world."); + } else if (args.length == 0) { + list.add(data.getEntityLoader().getPossibleKeys()); + } else if (args.length == 1) { + list.add(data.getEntityLoader().getPossibleKeys(args[0])); + } + } } @Override diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java index 87ac5bd22..6890d8082 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java @@ -60,27 +60,23 @@ public class CommandIrisStudioUpdate extends MortarCommand { return true; } - for(String i : args) - { - if(i.equals("--rewrite-objects")) - { + for (String i : args) { + if (i.equals("--rewrite-objects")) { IrisData data = new IrisData(Iris.proj.getWorkspaceFolder(args[0])); int t = data.getObjectLoader().getPossibleKeys().length; ChronoLatch cl = new ChronoLatch(250, false); - MultiBurst bx = new MultiBurst("Object Rewriter",Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst bx = new MultiBurst("Object Rewriter", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors()); BurstExecutor b = bx.burst(); int g = 0; - for(String f : data.getObjectLoader().getPossibleKeys()) - { + for (String f : data.getObjectLoader().getPossibleKeys()) { int finalG1 = g; b.queue(() -> { - if(cl.flip()) - { + if (cl.flip()) { Iris.info("Rewriting: " + Form.f(t - finalG1) + " Objects Left"); } File ff = data.getObjectLoader().findFile(f); - IrisObject oo = new IrisObject(0,0,0); + IrisObject oo = new IrisObject(0, 0, 0); try { oo.read(ff); } catch (Throwable e) { @@ -88,8 +84,7 @@ public class CommandIrisStudioUpdate extends MortarCommand { return; } - if(oo == null) - { + if (oo == null) { Iris.error("FAILER TO READ: " + f); return; } diff --git a/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java b/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java index 255138372..b89c76ccf 100644 --- a/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java +++ b/src/main/java/com/volmit/iris/core/link/MythicMobsLink.java @@ -31,11 +31,13 @@ public class MythicMobsLink { /** * Spawn a mythic mob at this location - * @param mob The mob + * + * @param mob The mob * @param location The location * @return The mob, or null if it can't be spawned */ - public @Nullable Entity spawnMob(String mob, Location location) { + public @Nullable + Entity spawnMob(String mob, Location location) { if (!isEnabled()) return null; if (spawnMobFunction != null) { @@ -72,7 +74,7 @@ public class MythicMobsLink { return mobs; } - if(isEnabled()) { + if (isEnabled()) { try { Class mythicMobClass = Class.forName("io.lumine.xikage.mythicmobs.MythicMobs"); diff --git a/src/main/java/com/volmit/iris/core/link/OraxenLink.java b/src/main/java/com/volmit/iris/core/link/OraxenLink.java index c19d82aaa..4f9afe70d 100644 --- a/src/main/java/com/volmit/iris/core/link/OraxenLink.java +++ b/src/main/java/com/volmit/iris/core/link/OraxenLink.java @@ -18,11 +18,7 @@ package com.volmit.iris.core.link; -import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.data.B; -import io.th0rgal.oraxen.items.ItemBuilder; import io.th0rgal.oraxen.items.OraxenItems; import io.th0rgal.oraxen.mechanics.Mechanic; import io.th0rgal.oraxen.mechanics.MechanicFactory; @@ -33,7 +29,6 @@ import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanic import io.th0rgal.oraxen.utils.Utils; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.MultipleFacing; import org.bukkit.plugin.Plugin; @@ -49,40 +44,32 @@ public class OraxenLink { } public BlockData getBlockDataFor(String id) { - if(!supported()) - { + if (!supported()) { return null; } MechanicFactory f = getFactory(id); - if(f == null) - { + if (f == null) { return null; } Mechanic m = f.getMechanic(id); // TODO: Why isnt there a simple getBlockData() function? - if(m.getFactory() instanceof NoteBlockMechanicFactory) - { + if (m.getFactory() instanceof NoteBlockMechanicFactory) { return ((NoteBlockMechanicFactory) m.getFactory()).createNoteBlockData(id); - } - - else if(m.getFactory() instanceof BlockMechanicFactory) - { - MultipleFacing newBlockData = (MultipleFacing)Bukkit.createBlockData(Material.MUSHROOM_STEM); - Utils.setBlockFacing(newBlockData, ((BlockMechanic)m).getCustomVariation()); + } else if (m.getFactory() instanceof BlockMechanicFactory) { + MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM); + Utils.setBlockFacing(newBlockData, ((BlockMechanic) m).getCustomVariation()); return newBlockData; } return null; } - public MechanicFactory getFactory(String id) - { - if(!supported()) - { + public MechanicFactory getFactory(String id) { + if (!supported()) { return null; } @@ -91,10 +78,8 @@ public class OraxenLink { f.setAccessible(true); Map map = (Map) f.get(null); - for(MechanicFactory i : map.values()) - { - if(i.getItems().contains(id)) - { + for (MechanicFactory i : map.values()) { + if (i.getItems().contains(id)) { return i; } } @@ -106,17 +91,14 @@ public class OraxenLink { } public String[] getItemTypes() { - if(!supported()) - { + if (!supported()) { return EMPTY; } KList v = new KList<>(); - for(String i : OraxenItems.getItemNames()) - { - if(getBlockDataFor(i) != null) - { + for (String i : OraxenItems.getItemNames()) { + if (getBlockDataFor(i) != null) { v.add(i); } } diff --git a/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index 6d96606b8..78c242df1 100644 --- a/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -23,7 +23,6 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; import org.bukkit.block.Biome; -import org.bukkit.block.TileState; import org.bukkit.entity.Entity; import org.bukkit.generator.ChunkGenerator; diff --git a/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java b/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java index 132ddb4a8..a0a3f92b0 100644 --- a/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java +++ b/src/main/java/com/volmit/iris/core/nms/v17_1/NMSBinding17_1.java @@ -23,14 +23,17 @@ import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.tag.CompoundTag; -import com.volmit.iris.util.nbt.tag.IntTag; import net.minecraft.core.BlockPosition; import net.minecraft.core.IRegistry; import net.minecraft.core.IRegistryWritable; -import net.minecraft.nbt.*; +import net.minecraft.nbt.NBTCompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagDouble; +import net.minecraft.nbt.NBTTagList; import net.minecraft.resources.MinecraftKey; import net.minecraft.resources.ResourceKey; import net.minecraft.server.level.WorldServer; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.biome.BiomeBase; import net.minecraft.world.level.block.entity.TileEntity; import net.minecraft.world.level.block.state.IBlockData; @@ -44,7 +47,6 @@ import org.bukkit.block.Biome; import org.bukkit.craftbukkit.v1_17_R1.CraftServer; import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; -import net.minecraft.world.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.generator.ChunkGenerator; @@ -74,15 +76,14 @@ public class NMSBinding17_1 implements INMSBinding { @Override public boolean hasTile(Location l) { - return ((CraftWorld)l.getWorld()).getHandle().getTileEntity(new BlockPosition(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; + return ((CraftWorld) l.getWorld()).getHandle().getTileEntity(new BlockPosition(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; } @Override public CompoundTag serializeTile(Location location) { - TileEntity e = ((CraftWorld)location.getWorld()).getHandle().getTileEntity(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true); + TileEntity e = ((CraftWorld) location.getWorld()).getHandle().getTileEntity(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true); - if(e == null) - { + if (e == null) { return null; } @@ -95,12 +96,11 @@ public class NMSBinding17_1 implements INMSBinding { public void deserializeTile(CompoundTag s, Location newPosition) { NBTTagCompound c = convert(s); - if(c != null) - { + if (c != null) { int x = newPosition.getBlockX(); int y = newPosition.getBlockY(); int z = newPosition.getBlockZ(); - WorldServer w = ((CraftWorld)newPosition.getWorld()).getHandle(); + WorldServer w = ((CraftWorld) newPosition.getWorld()).getHandle(); Chunk ch = w.getChunkAt(x >> 4, z >> 4); ChunkSection sect = ch.getSections()[y >> 4]; IBlockData block = sect.getBlocks().a(x & 15, y & 15, z & 15); @@ -109,8 +109,7 @@ public class NMSBinding17_1 implements INMSBinding { } } - private NBTTagCompound convert(CompoundTag tag) - { + private NBTTagCompound convert(CompoundTag tag) { try { ByteArrayOutputStream boas = new ByteArrayOutputStream(); NBTUtil.write(tag, boas, false); @@ -118,18 +117,14 @@ public class NMSBinding17_1 implements INMSBinding { NBTTagCompound c = NBTCompressedStreamTools.a((DataInput) din); din.close(); return c; - } - - catch(Throwable e) - { + } catch (Throwable e) { e.printStackTrace(); } return null; } - private CompoundTag convert(NBTTagCompound tag) - { + private CompoundTag convert(NBTTagCompound tag) { try { ByteArrayOutputStream boas = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(boas); @@ -145,7 +140,7 @@ public class NMSBinding17_1 implements INMSBinding { @Override public CompoundTag serializeEntity(org.bukkit.entity.Entity be) { - Entity entity = ((CraftEntity)be).getHandle(); + Entity entity = ((CraftEntity) be).getHandle(); NBTTagCompound tag = new NBTTagCompound(); entity.save(tag); CompoundTag t = convert(tag); @@ -165,7 +160,7 @@ public class NMSBinding17_1 implements INMSBinding { pos.a(2, NBTTagDouble.a(newPosition.getZ())); tag.set("Pos", pos); org.bukkit.entity.Entity be = newPosition.getWorld().spawnEntity(newPosition, type); - ((CraftEntity)be).getHandle().load(tag); + ((CraftEntity) be).getHandle().load(tag); return be; } diff --git a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index c39b17c23..27820352f 100644 --- a/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -28,9 +28,6 @@ import com.volmit.iris.util.data.B; import com.volmit.iris.util.json.JSONArray; import com.volmit.iris.util.json.JSONObject; import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.material.MaterialData; import org.bukkit.potion.PotionEffectType; import java.awt.*; @@ -225,11 +222,10 @@ public class SchemaBuilder { prop.put("$ref", "#/definitions/" + key); description.add(SYMBOL_TYPE__N + " Must be a valid Item Type (use ctrl+space for auto complete!)"); - } else if(k.isAnnotationPresent(RegistryListSpecialEntity.class)) { + } else if (k.isAnnotationPresent(RegistryListSpecialEntity.class)) { String key = "enum-reg-specialentity"; - if(!definitions.containsKey(key)) - { + if (!definitions.containsKey(key)) { JSONObject j = new JSONObject(); KList list = new KList<>(); list.addAll(Iris.linkMythicMobs.getMythicMobTypes().stream().map(s -> "MythicMobs:" + s).collect(Collectors.toList())); @@ -540,7 +536,7 @@ public class SchemaBuilder { return "number"; } - if (c.equals(boolean.class)||c.equals(Boolean.class)) { + if (c.equals(boolean.class) || c.equals(Boolean.class)) { return "boolean"; } @@ -570,7 +566,7 @@ public class SchemaBuilder { } // suppress warnings on bukkit classes - if (r.getDeclaringClass().getName().startsWith("org.bukkit.")){ + if (r.getDeclaringClass().getName().startsWith("org.bukkit.")) { return "Bukkit package classes and enums have no descriptions"; } diff --git a/src/main/java/com/volmit/iris/core/wand/WandSelection.java b/src/main/java/com/volmit/iris/core/wand/WandSelection.java index 11942f9b4..1a85cbd00 100644 --- a/src/main/java/com/volmit/iris/core/wand/WandSelection.java +++ b/src/main/java/com/volmit/iris/core/wand/WandSelection.java @@ -18,7 +18,6 @@ package com.volmit.iris.core.wand; -import com.volmit.iris.Iris; import com.volmit.iris.util.data.Cuboid; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; @@ -33,23 +32,18 @@ public class WandSelection { private final Cuboid c; private final Player p; - public WandSelection(Cuboid c, Player p) - { + public WandSelection(Cuboid c, Player p) { this.c = c; this.p = p; } - public void draw() - { + public void draw() { double accuracy = M.lerpInverse(0, 64 * 64, p.getLocation().distanceSquared(c.getCenter())); double dist = M.lerp(0.125, 3.5, accuracy); - for(double i = c.getLowerX()-1; i < c.getUpperX()+1; i+=0.25) - { - for(double j = c.getLowerY()-1; j < c.getUpperY()+1; j+=0.25) - { - for(double k = c.getLowerZ()-1; k < c.getUpperZ()+1; k+=0.25) - { + for (double i = c.getLowerX() - 1; i < c.getUpperX() + 1; i += 0.25) { + for (double j = c.getLowerY() - 1; j < c.getUpperY() + 1; j += 0.25) { + for (double k = c.getLowerZ() - 1; k < c.getUpperZ() + 1; k += 0.25) { boolean ii = i == c.getLowerX() || i == c.getUpperX(); boolean jj = j == c.getLowerY() || j == c.getUpperY(); boolean kk = k == c.getLowerZ() || k == c.getUpperZ(); @@ -85,28 +79,23 @@ public class WandSelection { accuracy = M.lerpInverse(0, 64 * 64, p.getLocation().distanceSquared(a)); dist = M.lerp(0.125, 3.5, accuracy); - if(M.r(M.min(dist, 1D) * 0.99)) - { + if (M.r(M.min(dist * 5, 0.9D) * 0.995)) { continue; } - if(ii && jj) - { + if (ii && jj) { a.add(0, 0, RNG.r.d(-0.3, 0.3)); } - if(kk && jj) - { + if (kk && jj) { a.add(RNG.r.d(-0.3, 0.3), 0, 0); } - if(ii && kk) - { + if (ii && kk) { a.add(0, RNG.r.d(-0.3, 0.3), 0); } - if(p.getLocation().distanceSquared(a) < 256 * 256) - { + if (p.getLocation().distanceSquared(a) < 256 * 256) { Color color = Color.getHSBColor((float) (0.5f + (Math.sin((i + j + k + (p.getTicksLived() / 2f)) / (20f)) / 2)), 1, 1); int r = color.getRed(); int g = color.getGreen(); @@ -115,7 +104,7 @@ public class WandSelection { p.spawnParticle(Particle.REDSTONE, a.getX(), a.getY(), a.getZ(), 1, 0, 0, 0, 0, new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b), - (float) dist*2f)); + (float) dist * 3f)); } } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index bf41850d0..6be28e39f 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -20,7 +20,6 @@ package com.volmit.iris.engine; import com.google.gson.Gson; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.events.IrisEngineHotloadEvent; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.*; @@ -29,13 +28,9 @@ import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer; import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.engine.object.engine.IrisEngineData; import com.volmit.iris.engine.object.objects.IrisObjectPlacement; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; -import com.volmit.iris.util.format.C; -import com.volmit.iris.util.format.Form; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.math.RNG; @@ -228,24 +223,10 @@ public class IrisEngine extends BlockPopulator implements Engine { } case ISLANDS -> { getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); - } } getMetrics().getTotal().put(p.getMilliseconds()); - - if (IrisSettings.get().getGeneral().isDebug()) { - KList v = new KList<>(); - KMap g = getMetrics().pull(); - - for (String i : g.sortKNumber()) { - if (g.get(i) != null) { - v.add(C.RESET + "" + C.LIGHT_PURPLE + i + ": " + C.UNDERLINE + C.BLUE + Form.duration(g.get(i), 0) + C.RESET + C.GRAY + ""); - } - } - - Iris.debug(v.toString(", ")); - } } catch (Throwable e) { Iris.reportError(e); fail("Failed to generate " + x + ", " + z, e); @@ -258,7 +239,9 @@ public class IrisEngine extends BlockPopulator implements Engine { f.getParentFile().mkdirs(); try { IO.writeAll(f, new Gson().toJson(getEngineData())); + Iris.debug("Saved Engine Data"); } catch (IOException e) { + Iris.error("Failed to save Engine Data"); e.printStackTrace(); } } diff --git a/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java new file mode 100644 index 000000000..f9f0994c3 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -0,0 +1,38 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.engine; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.EngineMantle; +import com.volmit.iris.util.mantle.Mantle; +import lombok.Data; + +import java.io.File; + +@Data +public class IrisEngineMantle implements EngineMantle { + private final Engine engine; + private final Mantle mantle; + + public IrisEngineMantle(Engine engine) + { + this.engine = engine; + this.mantle = new Mantle(new File(engine.getWorld().worldFolder(), "mantle/" + engine.getIndex()), engine.getTarget().getHeight()); + } +} diff --git a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 6a2c07bb1..04e9cf732 100644 --- a/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -25,6 +25,7 @@ import com.volmit.iris.engine.framework.EngineAssignedWorldManager; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.block.IrisBlockDrops; import com.volmit.iris.engine.object.common.IRare; +import com.volmit.iris.engine.object.engine.IrisEngineChunkData; import com.volmit.iris.engine.object.engine.IrisEngineData; import com.volmit.iris.engine.object.engine.IrisEngineSpawnerCooldown; import com.volmit.iris.engine.object.entity.IrisEntitySpawn; @@ -61,6 +62,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager { private int entityCount = 0; private final ChronoLatch cl; private final ChronoLatch ecl; + private final ChronoLatch cln; + private long charge = 0; private int actuallySpawned = 0; private int cooldown = 0; private List precount = new KList<>(); @@ -69,12 +72,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager { super(null); cl = null; ecl = null; + cln = null; chunkCooldowns = null; looper = null; } public IrisWorldManager(Engine engine) { super(engine); + cln = new ChronoLatch(60000); cl = new ChronoLatch(3000); ecl = new ChronoLatch(250); chunkCooldowns = new KMap<>(); @@ -82,6 +87,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager { looper = new Looper() { @Override protected long loop() { + if (M.ms() < charge) { + energy += 70; + } + + if (cln.flip()) { + engine.getEngineData().cleanup(getEngine()); + } + if (precount != null) { entityCount = 0; for (Entity i : precount) { @@ -137,7 +150,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager { J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); } - int maxGroups = 1; int chunkCooldownSeconds = 60; for (Long i : chunkCooldowns.k()) { @@ -158,7 +170,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { Chunk c = cc[RNG.r.nextInt(cc.length)]; IrisBiome biome = getEngine().getSurfaceBiome(c); IrisRegion region = getEngine().getRegion(c); - spawnIn(c, biome, region, maxGroups); + spawnIn(c, biome, region); chunkCooldowns.put(Cache.key(c), M.ms()); } @@ -170,15 +182,9 @@ public class IrisWorldManager extends EngineAssignedWorldManager { energy = M.clip(energy, 1D, 1000D); } - private void spawnIn(Chunk c, IrisBiome biome, IrisRegion region, int max) { - for (Entity i : c.getEntities()) { - if (i instanceof LivingEntity) { - return; - } - } - + private void spawnIn(Chunk c, IrisBiome biome, IrisRegion region) { //@builder - spawnRandomly(Stream.concat(Stream.concat( + IrisEntitySpawn v = spawnRandomly(Stream.concat(Stream.concat( getData().getSpawnerLoader() .loadAll(getDimension().getEntitySpawners()) .shuffleCopy(RNG.r).stream().filter(this::canSpawn), @@ -197,16 +203,57 @@ public class IrisWorldManager extends EngineAssignedWorldManager { .shuffleCopy(RNG.r).stream().filter(this::canSpawn) .flatMap(this::stream))) .collect(Collectors.toList())) - .popRandom(RNG.r, max).forEach((i) -> spawn(c, i)); + .popRandom(RNG.r); + + if (v != null && v.getReferenceSpawner() != null) { + int maxEntCount = v.getReferenceSpawner().getMaxEntitiesPerChunk(); + + for (Entity i : c.getEntities()) { + if (i instanceof LivingEntity) { + if (-maxEntCount <= 0) { + return; + } + } + } + + spawn(c, v); + } //@done } private void spawn(Chunk c, IrisEntitySpawn i) { - int s = i.spawn(getEngine(), c, RNG.r); - actuallySpawned += s; - if (s > 0) { - getCooldown(i.getReferenceSpawner()).spawn(getEngine()); - energy -= s * ((i.getEnergyMultiplier() * i.getReferenceSpawner().getEnergyMultiplier() * 1)); + boolean allow = true; + + if (!i.getReferenceSpawner().getMaximumRatePerChunk().isInfinite()) { + allow = false; + IrisEngineChunkData cd = getEngine().getEngineData().getChunk(c.getX(), c.getZ()); + IrisEngineSpawnerCooldown sc = null; + for (IrisEngineSpawnerCooldown j : cd.getCooldowns()) { + if (j.getSpawner().equals(i.getReferenceSpawner().getLoadKey())) { + sc = j; + break; + } + } + + if (sc == null) { + sc = new IrisEngineSpawnerCooldown(); + sc.setSpawner(i.getReferenceSpawner().getLoadKey()); + cd.getCooldowns().add(sc); + } + + if (sc.canSpawn(i.getReferenceSpawner().getMaximumRatePerChunk())) { + sc.spawn(getEngine()); + allow = true; + } + } + + if (allow) { + int s = i.spawn(getEngine(), c, RNG.r); + actuallySpawned += s; + if (s > 0) { + getCooldown(i.getReferenceSpawner()).spawn(getEngine()); + energy -= s * ((i.getEnergyMultiplier() * i.getReferenceSpawner().getEnergyMultiplier() * 1)); + } } } @@ -278,6 +325,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { fixEnergy(); } + @Override + public void chargeEnergy() { + charge = M.ms() + 3000; + } + @Override public void onBlockBreak(BlockBreakEvent e) { if (e.getBlock().getWorld().equals(getTarget().getWorld().realWorld()) && getEngine().contains(e.getBlock().getLocation())) { diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java b/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java index e025f23ac..e80c2ab53 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java @@ -43,4 +43,6 @@ public interface EngineWorldManager { void onBlockPlace(BlockPlaceEvent e); void onChunkLoad(Chunk e, boolean generated); + + void chargeEnergy(); } diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java new file mode 100644 index 000000000..97e55341c --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -0,0 +1,147 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.engine.mantle; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.project.loader.IrisData; +import com.volmit.iris.engine.IrisComplex; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.EngineComponent; +import com.volmit.iris.engine.framework.EngineFramework; +import com.volmit.iris.engine.framework.EngineTarget; +import com.volmit.iris.engine.object.common.IObjectPlacer; +import com.volmit.iris.engine.object.dimensional.IrisDimension; +import com.volmit.iris.engine.object.tile.TileData; +import com.volmit.iris.engine.parallax.ParallaxAccess; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.mantle.Mantle; +import org.bukkit.block.TileState; +import org.bukkit.block.data.BlockData; + +public interface EngineMantle extends IObjectPlacer +{ + BlockData AIR = B.get("AIR"); + + Mantle getMantle(); + + Engine getEngine(); + + default int getHighest(int x, int z) { + return getHighest(x, z, getData()); + } + + default int getHighest(int x, int z, boolean ignoreFluid) { + return getHighest(x, z, getData(), ignoreFluid); + } + + @Override + default int getHighest(int x, int z, IrisData data) { + return getHighest(x, z, data, false); + } + + @Override + default int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { + return ignoreFluid ? trueHeight(x, z) : Math.max(trueHeight(x, z), getEngine().getDimension().getFluidHeight()); + } + + default int trueHeight(int x, int z) { + return getComplex().getTrueHeightStream().get(x, z); + } + + @Override + default void set(int x, int y, int z, BlockData d) { + getMantle().set(x,y,z,d == null ? AIR : d); + } + + @Override + default void setTile(int x, int y, int z, TileData d) { + // TODO SET TILE + Iris.warn("Unable to set tile data in mantles yet."); + } + + @Override + default BlockData get(int x, int y, int z) { + BlockData block = getMantle().get(x,y,z,BlockData.class); + + if (block == null) { + return AIR; + } + + return block; + } + + @Override + default boolean isPreventingDecay() { + return getEngine().getDimension().isPreventLeafDecay(); + } + + @Override + default boolean isSolid(int x, int y, int z) { + return B.isSolid(get(x, y, z)); + } + + @Override + default boolean isUnderwater(int x, int z) { + return getHighest(x, z, true) <= getFluidHeight(); + } + + @Override + default int getFluidHeight() { + return getEngine().getDimension().getFluidHeight(); + } + + @Override + default boolean isDebugSmartBore() { + return getEngine().getDimension().isDebugSmartBore(); + } + + default void trim(long dur) + { + getMantle().trim(dur); + } + + default IrisData getData() { + return getEngine().getData(); + } + + default ParallaxAccess getParallax() { + return getEngine().getParallax(); + } + + default EngineTarget getTarget() { + return getEngine().getTarget(); + } + + default IrisDimension getDimension() { + return getEngine().getDimension(); + } + + default EngineFramework getFramework() { + return getEngine().getFramework(); + } + + default IrisComplex getComplex() { + return getFramework().getComplex(); + } + + default void close() + { + getMantle().close(); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java b/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java index 39374f94d..7bcd8c345 100644 --- a/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java +++ b/src/main/java/com/volmit/iris/engine/object/annotations/RegistryListSpecialEntity.java @@ -21,9 +21,7 @@ package com.volmit.iris.engine.object.annotations; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) diff --git a/src/main/java/com/volmit/iris/engine/object/basic/IrisRate.java b/src/main/java/com/volmit/iris/engine/object/basic/IrisRate.java index bedd1b312..d7c8f93d1 100644 --- a/src/main/java/com/volmit/iris/engine/object/basic/IrisRate.java +++ b/src/main/java/com/volmit/iris/engine/object/basic/IrisRate.java @@ -48,4 +48,8 @@ public class IrisRate { public ChronoLatch toChronoLatch() { return new ChronoLatch(getInterval()); } + + public boolean isInfinite() { + return per.toMilliseconds() == 0; + } } diff --git a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java index 6e796df3b..28ec3d367 100644 --- a/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java +++ b/src/main/java/com/volmit/iris/engine/object/block/IrisBlockData.java @@ -149,10 +149,8 @@ public class IrisBlockData extends IrisRegistrant { }); } - private String keyify(String dat) - { - if(dat.contains(":")) - { + private String keyify(String dat) { + if (dat.contains(":")) { return dat; } diff --git a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java index 34b8ac4e9..7e632b308 100644 --- a/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java +++ b/src/main/java/com/volmit/iris/engine/object/dimensional/IrisDimension.java @@ -34,7 +34,6 @@ import com.volmit.iris.engine.object.carve.IrisCaveFluid; import com.volmit.iris.engine.object.carve.IrisCaveLayer; import com.volmit.iris.engine.object.carve.IrisCaverns; import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; -import com.volmit.iris.engine.object.villager.IrisVillagerOverride; import com.volmit.iris.engine.object.feature.IrisFeaturePositional; import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure; @@ -47,6 +46,7 @@ import com.volmit.iris.engine.object.objects.IrisObjectPlacement; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.engine.object.trees.IrisTreeSettings; +import com.volmit.iris.engine.object.villager.IrisVillagerOverride; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.io.IO; diff --git a/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineChunkData.java b/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineChunkData.java new file mode 100644 index 000000000..41a13d406 --- /dev/null +++ b/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineChunkData.java @@ -0,0 +1,44 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.engine.object.engine; + +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.spawners.IrisSpawner; +import com.volmit.iris.util.collection.KList; +import lombok.Data; + +@Data +public class IrisEngineChunkData { + private long chunk; + private KList cooldowns = new KList<>(); + + public void cleanup(Engine engine) { + for (IrisEngineSpawnerCooldown i : getCooldowns().copy()) { + IrisSpawner sp = engine.getData().getSpawnerLoader().load(i.getSpawner()); + + if (sp == null || i.canSpawn(sp.getMaximumRate())) { + getCooldowns().remove(i); + } + } + } + + public boolean isEmpty() { + return cooldowns.isEmpty(); + } +} diff --git a/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineData.java b/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineData.java index f85efe3e4..395b8baa6 100644 --- a/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineData.java +++ b/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineData.java @@ -18,6 +18,9 @@ package com.volmit.iris.engine.object.engine; +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.util.collection.KList; import lombok.Data; @@ -25,4 +28,43 @@ import lombok.Data; public class IrisEngineData { private IrisEngineStatistics statistics = new IrisEngineStatistics(); private KList spawnerCooldowns = new KList<>(); + private KList chunks = new KList<>(); + + public void removeChunk(int x, int z) { + long k = Cache.key(x, z); + chunks.removeWhere((i) -> i.getChunk() == k); + } + + public IrisEngineChunkData getChunk(int x, int z) { + long k = Cache.key(x, z); + + for (IrisEngineChunkData i : chunks) { + if (i.getChunk() == k) { + return i; + } + } + + IrisEngineChunkData c = new IrisEngineChunkData(); + c.setChunk(k); + chunks.add(c); + return c; + } + + public void cleanup(Engine engine) { + for (IrisEngineSpawnerCooldown i : getSpawnerCooldowns().copy()) { + IrisSpawner sp = engine.getData().getSpawnerLoader().load(i.getSpawner()); + + if (sp == null || i.canSpawn(sp.getMaximumRate())) { + getSpawnerCooldowns().remove(i); + } + } + + for (IrisEngineChunkData i : chunks.copy()) { + i.cleanup(engine); + + if (i.isEmpty()) { + getChunks().remove(i); + } + } + } } diff --git a/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineSpawnerCooldown.java b/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineSpawnerCooldown.java index 5fa28dbef..12de56329 100644 --- a/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineSpawnerCooldown.java +++ b/src/main/java/com/volmit/iris/engine/object/engine/IrisEngineSpawnerCooldown.java @@ -25,7 +25,7 @@ import lombok.Data; @Data public class IrisEngineSpawnerCooldown { - private long lastSpawn; + private long lastSpawn = 0; private String spawner; public void spawn(Engine engine) { diff --git a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java index b95ddecac..16d591103 100644 --- a/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java +++ b/src/main/java/com/volmit/iris/engine/object/objects/IrisObject.java @@ -36,8 +36,9 @@ import com.volmit.iris.util.math.BlockPosition; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.scheduling.IrisLock; -import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; import lombok.experimental.Accessors; import org.bukkit.Location; import org.bukkit.Material; @@ -56,26 +57,37 @@ import java.util.function.Consumer; @SuppressWarnings("DefaultAnnotationParam") @Accessors(chain = true) -@Data @EqualsAndHashCode(callSuper = false) public class IrisObject extends IrisRegistrant { - private static final Vector HALF = new Vector(0.5, 0.5, 0.5); - private static final BlockData AIR = B.get("CAVE_AIR"); - private static final BlockData VAIR = B.get("VOID_AIR"); - private static final BlockData VAIR_DEBUG = B.get("COBWEB"); - private static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")}; - public static boolean shitty = false; + protected static final Vector HALF = new Vector(0.5, 0.5, 0.5); + protected static final BlockData AIR = B.get("CAVE_AIR"); + protected static final BlockData VAIR = B.get("VOID_AIR"); + protected static final BlockData VAIR_DEBUG = B.get("COBWEB"); + protected static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")}; + private KMap blocks; private KMap> states; + @Getter + @Setter private int w; + @Getter + @Setter private int d; + @Getter + @Setter private int h; - private transient final IrisLock readLock = new IrisLock("read-conclock"); + protected transient final IrisLock readLock = new IrisLock("read-conclock"); + @Getter + @Setter private transient BlockVector center; - private transient volatile boolean smartBored = false; - private transient IrisLock lock = new IrisLock("Preloadcache"); - private transient AtomicCache aabb = new AtomicCache<>(); - + @Getter + @Setter + protected transient volatile boolean smartBored = false; + @Getter + @Setter + protected transient IrisLock lock = new IrisLock("Preloadcache"); + @Setter + protected transient AtomicCache aabb = new AtomicCache<>(); public IrisObject(int w, int h, int d) { blocks = new KMap<>(); @@ -330,10 +342,6 @@ public class IrisObject extends IrisRegistrant { } public void read(File file) throws IOException { - if (shitty) { - return; - } - FileInputStream fin = new FileInputStream(file); try { read(fin); @@ -348,8 +356,7 @@ public class IrisObject extends IrisRegistrant { } public void write(File file) throws IOException { - if(file == null) - { + if (file == null) { return; } @@ -862,7 +869,7 @@ public class IrisObject extends IrisRegistrant { } } - setBlocks(b); + blocks = b; } public void tricubic(int rad) { @@ -891,7 +898,7 @@ public class IrisObject extends IrisRegistrant { } } - setBlocks(b); + blocks = b; } public void trihermite(int rad) { @@ -924,7 +931,7 @@ public class IrisObject extends IrisRegistrant { } } - setBlocks(b); + blocks = b; } private BlockData nearestBlockData(int x, int y, int z) { diff --git a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java index 762fa32f9..116f2afdb 100644 --- a/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java +++ b/src/main/java/com/volmit/iris/engine/object/spawners/IrisSpawner.java @@ -48,6 +48,9 @@ public class IrisSpawner extends IrisRegistrant { @Desc("The energy multiplier when calculating spawn energy usage") private double energyMultiplier = 1; + @Desc("This spawner will not spawn in a given chunk if that chunk has more than the defined amount of living entities.") + private int maxEntitiesPerChunk = 1; + @Desc("The block of 24 hour time to contain this spawn in.") private IrisTimeBlock timeBlock = new IrisTimeBlock(); @@ -57,6 +60,9 @@ public class IrisSpawner extends IrisRegistrant { @Desc("The maximum rate this spawner can fire") private IrisRate maximumRate = new IrisRate(); + @Desc("The maximum rate this spawner can fire on a specific chunk") + private IrisRate maximumRatePerChunk = new IrisRate(); + @Desc("Where should these spawns be placed") private IrisSpawnGroup group = IrisSpawnGroup.NORMAL; diff --git a/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerOverride.java b/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerOverride.java index 2f2a2c6c4..dca836015 100644 --- a/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerOverride.java +++ b/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerOverride.java @@ -22,11 +22,11 @@ import org.bukkit.inventory.ItemStack; @EqualsAndHashCode(callSuper = false) public class IrisVillagerOverride { @Desc(""" - Disable the trade altogether. - If a cartographer villager gets a new explorer map trade: - If this is enabled -> the trade is removed - If this is disabled -> the trade is replaced with the "override" setting below - Default is true, so if you omit this, trades will be removed.""") + Disable the trade altogether. + If a cartographer villager gets a new explorer map trade: + If this is enabled -> the trade is removed + If this is disabled -> the trade is replaced with the "override" setting below + Default is true, so if you omit this, trades will be removed.""") private boolean disableTrade = true; @DependsOn("disableTrade") @@ -44,7 +44,7 @@ public class IrisVillagerOverride { .setMinTrades(3) .setMaxTrades(5)); - public KList getValidItems(){ + public KList getValidItems() { KList valid = new KList<>(); getItems().stream().filter(IrisVillagerTrade::isValidItems).forEach(valid::add); return valid.size() == 0 ? null : valid; diff --git a/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerTrade.java b/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerTrade.java index e11356d0b..e0694c84b 100644 --- a/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerTrade.java +++ b/src/main/java/com/volmit/iris/engine/object/villager/IrisVillagerTrade.java @@ -4,9 +4,7 @@ package com.volmit.iris.engine.object.villager; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.scheduling.S; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -58,7 +56,7 @@ public class IrisVillagerTrade { * mintrades > 0, maxtrades > 0, maxtrades > mintrades, and
* ingredient 1, (if defined ingredient 2) and the result are valid items */ - public boolean isValidItems(){ + public boolean isValidItems() { KList warnings = new KList<>(); if (ingredient1 == null) { warnings.add("Ingredient 1 is null"); @@ -80,15 +78,15 @@ public class IrisVillagerTrade { warnings.add("More minimal than maximal trades"); } - if (ingredient1 != null && !ingredient1.getType().isItem()){ + if (ingredient1 != null && !ingredient1.getType().isItem()) { warnings.add("Ingredient 1 is not an item"); } - if (ingredient2 != null && !ingredient2.getType().isItem()){ + if (ingredient2 != null && !ingredient2.getType().isItem()) { warnings.add("Ingredient 2 is not an item"); } - if (result != null && !result.getType().isItem()){ + if (result != null && !result.getType().isItem()) { warnings.add("Result is not an item"); } @@ -103,10 +101,11 @@ public class IrisVillagerTrade { /** * Get the ingredients + * * @return The list of 1 or 2 ingredients (depending on if ing2 is null) */ public List getIngredients() { - if (!isValidItems()){ + if (!isValidItems()) { return null; } return ingredient2 == null ? new KList<>(ingredient1) : new KList<>(ingredient1, ingredient2); @@ -122,7 +121,7 @@ public class IrisVillagerTrade { /** * @return the trade as a merchant recipe */ - public MerchantRecipe convert(){ + public MerchantRecipe convert() { MerchantRecipe recipe = new MerchantRecipe(getResult(), getAmount()); recipe.setIngredients(getIngredients()); return recipe; diff --git a/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java b/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java index 332d2c903..a8892ecab 100644 --- a/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java +++ b/src/main/java/com/volmit/iris/engine/parallax/ParallaxWorld.java @@ -114,6 +114,7 @@ public class ParallaxWorld implements ParallaxAccess { if (lr != null) { v += lr.unload(); + Iris.debug("Unloaded Parallax Region " + C.RED + x + " " + z); } } @@ -128,6 +129,7 @@ public class ParallaxWorld implements ParallaxAccess { ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z); loadedRegions.put(key(x, z), v); + Iris.debug("Loaded Parallax Region " + C.RED + x + " " + z); return v; } diff --git a/src/main/java/com/volmit/iris/util/data/B.java b/src/main/java/com/volmit/iris/util/data/B.java index 6cdb1c417..ff96be0b9 100644 --- a/src/main/java/com/volmit/iris/util/data/B.java +++ b/src/main/java/com/volmit/iris/util/data/B.java @@ -572,15 +572,11 @@ public class B { } } - try - { + try { for (String i : Iris.linkOraxen.getItemTypes()) { bt.add("oraxen:" + i); } - } - - catch(Throwable e) - { + } catch (Throwable e) { e.printStackTrace(); } diff --git a/src/main/java/com/volmit/iris/util/format/C.java b/src/main/java/com/volmit/iris/util/format/C.java index f69f47997..5cda679ea 100644 --- a/src/main/java/com/volmit/iris/util/format/C.java +++ b/src/main/java/com/volmit/iris/util/format/C.java @@ -19,16 +19,13 @@ package com.volmit.iris.util.format; import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.engine.object.biome.IrisBiomeCustom; -import com.volmit.iris.util.plugin.VolmitSender; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.Color; import org.bukkit.DyeColor; -import java.awt.color.ColorSpace; -import java.util.Arrays; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -139,6 +136,14 @@ public enum C { return net.md_5.bungee.api.ChatColor.GREEN; } }, + + IRIS("<#1bb19e>", 'a', 0xA) { + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.GREEN; + } + }, + /** * Represents aqua */ @@ -238,8 +243,10 @@ public enum C { public net.md_5.bungee.api.ChatColor asBungee() { return net.md_5.bungee.api.ChatColor.RESET; } - }; + }, + + ; /** * The special character which prefixes all chat colour codes. Use this if you * need to dynamically convert colour codes from your custom format. @@ -263,6 +270,7 @@ public enum C { static { chatHexMap.put(C.BLACK, "#000000"); chatHexMap.put(C.DARK_BLUE, "#0000AA"); + chatHexMap.put(C.IRIS, "#1bb19e"); chatHexMap.put(C.DARK_GREEN, "#00AA00"); chatHexMap.put(C.DARK_AQUA, "#00AAAA"); chatHexMap.put(C.DARK_RED, "#AA0000"); @@ -319,9 +327,10 @@ public enum C { this(token, code, intCode, false); } - C( char code, int intCode, boolean isFormat) { + C(char code, int intCode, boolean isFormat) { this("^", code, intCode, false); } + C(String token, char code, int intCode, boolean isFormat) { this.code = code; this.token = token.equalsIgnoreCase("^") ? "<" + name().toLowerCase(Locale.ROOT) + ">" : token; @@ -330,50 +339,59 @@ public enum C { this.toString = new String(new char[]{COLOR_CHAR, code}); } - public static float[] spin(float[] c, int shift) - { - return new float[]{spin(c[0], shift),spin(c[1], shift),spin(c[2], shift)}; + public static float[] spin(float[] c, int shift) { + return new float[]{spin(c[0], shift), spinc(c[1], shift), spinc(c[2], shift)}; } - public static float[] spin(float[] c, int a,int b, int d) - { - return new float[]{spin(c[0], a),spin(c[1], b),spin(c[2], d)}; + public static float[] spin(float[] c, int a, int b, int d) { + return new float[]{spin(c[0], a), spinc(c[1], b), spinc(c[2], d)}; } - public static float spin(float c, int shift) - { - float g = ((((int)Math.floor(c * 360)) + shift) % 360) / 360F; + public static float spin(float c, int shift) { + float g = ((((int) Math.floor(c * 360)) + shift) % 360) / 360F; return g < 0 ? 1f - g : g; } - public static String aura(String msg, int hrad, int srad, int vrad) { + public static float spinc(float c, int shift) { + float g = ((((int) Math.floor(c * 255)) + shift)) / 255F; + return Math.max(0f, Math.min(g, 1f)); + } + + public static java.awt.Color spin(java.awt.Color c, int h, int s, int b) { + float[] hsb = java.awt.Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null); + hsb = spin(hsb, h, s, b); + return java.awt.Color.getHSBColor(hsb[0], hsb[1], hsb[2]); + } + + public static String spinToHex(C color, int h, int s, int b) { + return "#" + Integer.toHexString(spin(color.awtColor(), h, s, b).getRGB()).substring(2); + } + + public static String aura(String s, int hrad, int srad, int vrad) { + String msg = compress(s); StringBuilder b = new StringBuilder(); boolean c = false; - for(char i : msg.toCharArray()) - { - if(c) - { + for (char i : msg.toCharArray()) { + if (c) { c = false; C o = C.getByChar(i); - if(hrad != 0 || srad != 0 || vrad != 0) - { - //TODO: Spin to win - b.append(C.getByChar(i).token); - } - - else - { + if (hrad != 0 || srad != 0 || vrad != 0) { + b.append(""); + } else { b.append(C.getByChar(i).token); } continue; } - if(i == C.COLOR_CHAR) - { + if (i == C.COLOR_CHAR) { c = true; continue; } @@ -384,6 +402,10 @@ public enum C { return b.toString(); } + public static String compress(String c) { + return BaseComponent.toLegacyText(TextComponent.fromLegacyText(c)); + } + public net.md_5.bungee.api.ChatColor asBungee() { return net.md_5.bungee.api.ChatColor.RESET; } @@ -399,7 +421,7 @@ public enum C { @Override public String toString() { - return toString; + return intCode == -1 ? token : toString; } /** @@ -413,6 +435,10 @@ public enum C { return chatToHex(this); } + public java.awt.Color awtColor() { + return java.awt.Color.decode(hex()); + } + /** * Checks if this code is a format code as opposed to a color code. * @@ -638,6 +664,7 @@ public enum C { case RED -> (byte) 12; case WHITE -> (byte) 15; case YELLOW -> (byte) 14; + default -> (byte) 15; }; } @@ -657,6 +684,7 @@ public enum C { case GREEN -> (byte) 5; case LIGHT_PURPLE -> (byte) 2; case WHITE -> (byte) 0; + default -> (byte) 15; }; } diff --git a/src/main/java/com/volmit/iris/util/hunk/Hunk.java b/src/main/java/com/volmit/iris/util/hunk/Hunk.java index ff5e8874c..e81c9673c 100644 --- a/src/main/java/com/volmit/iris/util/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/Hunk.java @@ -61,6 +61,14 @@ public interface Hunk { return new HunkView(src); } + default boolean isMapped() { + return false; + } + + default int getEntryCount() { + return getWidth() * getHeight() * getDepth(); + } + static Hunk convertedReadView(Hunk src, Function reader) { return new FunctionalHunkView(src, reader, null); } @@ -1059,6 +1067,42 @@ public interface Hunk { setRaw(x, y, z, t); } + /** + * Create a hunk that is optimized for specific uses + * + * @param w width + * @param h height + * @param d depth + * @param type the class type + * @param packed if the hunk is generally more than 50% full (non-null nodes) + * @param concurrent if this hunk must be thread safe + * @param the type + * @return the hunk + */ + static Hunk newHunk(int w, int h, int d, Class type, boolean packed, boolean concurrent) { + if (type.equals(Double.class)) { + return concurrent ? + packed ? (Hunk) newAtomicDoubleHunk(w, h, d) : newMappedHunk(w, h, d) + : packed ? newArrayHunk(w, h, d) : newMappedHunkSynced(w, h, d); + } + + if (type.equals(Integer.class)) { + return concurrent ? + packed ? (Hunk) newAtomicIntegerHunk(w, h, d) : newMappedHunk(w, h, d) + : packed ? newArrayHunk(w, h, d) : newMappedHunkSynced(w, h, d); + } + + if (type.equals(Long.class)) { + return concurrent ? + packed ? (Hunk) newAtomicLongHunk(w, h, d) : newMappedHunk(w, h, d) + : packed ? newArrayHunk(w, h, d) : newMappedHunkSynced(w, h, d); + } + + return concurrent ? + packed ? newAtomicHunk(w, h, d) : newMappedHunk(w, h, d) + : packed ? newArrayHunk(w, h, d) : newMappedHunkSynced(w, h, d); + } + default void setIfExists(int x, int y, int z, T t) { if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) { return; @@ -1401,4 +1445,8 @@ public interface Hunk { c[0] = x; c[1] = y; } + + default boolean isEmpty() { + return false; + } } diff --git a/src/main/java/com/volmit/iris/util/hunk/HunkFactory.java b/src/main/java/com/volmit/iris/util/hunk/HunkFactory.java new file mode 100644 index 000000000..e7ed21135 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/HunkFactory.java @@ -0,0 +1,24 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.util.hunk; + +@FunctionalInterface +public interface HunkFactory { + Hunk create(int w, int h, int d); +} diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java index dc50bb27a..4d5d9fba8 100644 --- a/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/storage/MappedHunk.java @@ -43,6 +43,14 @@ public class MappedHunk extends StorageHunk implements Hunk { return data.size(); } + public boolean isMapped() { + return true; + } + + public boolean isEmpty() { + return data.isEmpty(); + } + @Override public void setRaw(int x, int y, int z, T t) { if (t == null) { diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java new file mode 100644 index 000000000..f2026c452 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -0,0 +1,290 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.util.mantle; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.data.cache.Cache; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.documentation.BlockCoordinates; +import com.volmit.iris.util.documentation.RegionCoordinates; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.matter.Matter; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.HyperLock; +import com.volmit.iris.util.parallel.MultiBurst; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * The mantle can store any type of data slice anywhere and manage regions & IO on it's own. + * This class is fully thread safe read & write + */ +public class Mantle { + private final File dataFolder; + private final int worldHeight; + private final Map lastUse; + private final Map loadedRegions; + private final HyperLock hyperLock; + private final KSet unload; + private final AtomicBoolean closed; + private final MultiBurst ioBurst; + + /** + * Create a new mantle + * + * @param dataFolder the data folder + * @param worldHeight the world's height (in blocks) + */ + @BlockCoordinates + public Mantle(File dataFolder, int worldHeight) { + this.hyperLock = new HyperLock(); + this.closed = new AtomicBoolean(false); + this.dataFolder = dataFolder; + this.worldHeight = worldHeight; + dataFolder.mkdirs(); + unload = new KSet<>(); + loadedRegions = new KMap<>(); + lastUse = new KMap<>(); + ioBurst = new MultiBurst("Iris Mantle[" + dataFolder.hashCode() + "]", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() / 2); + Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); + } + + /** + * Set data T at the given block position. This method will attempt to find a + * Tectonic Plate either by loading it or creating a new one. This method uses + * the hyper lock packaged with each Mantle. The hyperlock allows locking of multiple + * threads at a single region while still allowing other threads to continue + * reading & writing other regions. Hyperlocks are slow sync, but in multicore + * environments, they drastically speed up loading & saving large counts of plates + * + * @param x the block's x coordinate + * @param y the block's y coordinate + * @param z the block's z coordinate + * @param t the data to set at the block + * @param the type of data (generic method) + */ + @BlockCoordinates + public void set(int x, int y, int z, T t) { + if (closed.get()) { + throw new RuntimeException("The Mantle is closed"); + } + + Matter matter = null; + try { + matter = get((x >> 4) >> 5, (z >> 4) >> 5).get() + .getOrCreate((x >> 4) & 31, (z >> 4) & 31) + .getOrCreate(y >> 4); + } catch (InterruptedException e) { + Iris.error("Failed to get Tectonic Plate " + ((x >> 4) >> 5) + " " + ((z >> 4) >> 5) + " Due to a thread intterruption"); + Iris.reportError(e); + e.printStackTrace(); + } catch (ExecutionException e) { + Iris.error("Failed to get Tectonic Plate " + ((x >> 4) >> 5) + " " + ((z >> 4) >> 5) + " Due to a thread execution exception"); + Iris.reportError(e); + e.printStackTrace(); + } + + if (matter == null) { + return; + } + + matter.slice(matter.getClass(t)) + .set(x & 15, y & 15, z & 15, t); + } + + /** + * Gets the data tat the current block position This method will attempt to find a + * Tectonic Plate either by loading it or creating a new one. This method uses + * the hyper lock packaged with each Mantle. The hyperlock allows locking of multiple + * threads at a single region while still allowing other threads to continue + * reading & writing other regions. Hyperlocks are slow sync, but in multicore + * environments, they drastically speed up loading & saving large counts of plates + * + * @param x the block's x coordinate + * @param y the block's y coordinate + * @param z the block's z coordinate + * @param t the class representing the type of data being requested + * @param the type assumed from the provided class + * @return the returned result (or null) if it doesnt exist + */ + @SuppressWarnings("unchecked") + @BlockCoordinates + public T get(int x, int y, int z, Class t) { + if (closed.get()) { + throw new RuntimeException("The Mantle is closed"); + } + + try { + return (T) get((x >> 4) >> 5, (z >> 4) >> 5).get() + .getOrCreate((x >> 4) & 31, (z >> 4) & 31) + .getOrCreate(y >> 4).slice(t) + .get(x & 15, y & 15, z & 15); + } catch (InterruptedException e) { + Iris.error("Failed to get Tectonic Plate " + ((x >> 4) >> 5) + " " + ((z >> 4) >> 5) + " Due to a thread intterruption"); + Iris.reportError(e); + e.printStackTrace(); + } catch (ExecutionException e) { + Iris.error("Failed to get Tectonic Plate " + ((x >> 4) >> 5) + " " + ((z >> 4) >> 5) + " Due to a thread execution exception"); + Iris.reportError(e); + e.printStackTrace(); + } + + return null; + } + + /** + * Closes the Mantle. By closing the mantle, you can no longer read or write + * any data to the mantle or it's Tectonic Plates. Closing will also flush any + * loaded regions to the disk in parallel. + */ + public synchronized void close() { + Iris.debug("Closing The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); + if (closed.get()) { + throw new RuntimeException("The Mantle is closed"); + } + + closed.set(true); + BurstExecutor b = ioBurst.burst(loadedRegions.size()); + for (Long i : loadedRegions.keySet()) { + b.queue(() -> { + try { + loadedRegions.get(i).write(fileForRegion(dataFolder, i)); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + + b.complete(); + ioBurst.shutdownNow(); + Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath()); + } + + /** + * Save & unload regions that have not been used for more than the + * specified amount of milliseconds + * + * @param idleDuration the duration + */ + public synchronized void trim(long idleDuration) { + if (closed.get()) { + throw new RuntimeException("The Mantle is closed"); + } + + Iris.debug("Trimming Tectonic Plates older than " + Form.duration((double) idleDuration, 0)); + unload.clear(); + + for (Long i : lastUse.keySet()) { + if (M.ms() - lastUse.get(i) >= idleDuration) { + unload.add(i); + } + } + + for (Long i : unload) { + TectonicPlate m = loadedRegions.remove(i); + lastUse.remove(i); + Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + i); + + if (m != null) { + ioBurst.lazy(() -> { + try { + m.write(fileForRegion(dataFolder, i)); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + } + } + + /** + * This retreives a future of the Tectonic Plate at the given coordinates. + * All methods accessing tectonic plates should go through this method + * + * @param x the region x + * @param z the region z + * @return the future of a tectonic plate. + */ + @RegionCoordinates + private CompletableFuture get(int x, int z) { + return ioBurst.completeValue(() -> hyperLock.withResult(x, z, () -> { + Long k = key(x, z); + lastUse.put(k, M.ms()); + TectonicPlate region = loadedRegions.get(k); + + if (region != null) { + return region; + } + + File file = fileForRegion(dataFolder, x, z); + + if (file.exists()) { + try { + FileInputStream fin = new FileInputStream(file); + DataInputStream din = new DataInputStream(fin); + region = new TectonicPlate(worldHeight, din); + din.close(); + loadedRegions.put(k, region); + Iris.debug("Loaded Tectonic Plate " + C.DARK_GREEN + x + " " + z + C.DARK_AQUA + " " + file.getName()); + } catch (Throwable e) { + Iris.error("Failed to read Tectonic Plate " + file.getAbsolutePath() + " creating a new chunk instead."); + Iris.reportError(e); + e.printStackTrace(); + region = new TectonicPlate(worldHeight); + loadedRegions.put(k, region); + Iris.debug("Created new Tectonic Plate (Due to Load Failure) " + C.DARK_GREEN + x + " " + z); + } + + return region; + } + + region = new TectonicPlate(worldHeight); + loadedRegions.put(k, region); + Iris.debug("Created new Tectonic Plate (Due to Load Failure) " + C.DARK_GREEN + x + " " + z); + return region; + })); + } + + public static File fileForRegion(File folder, int x, int z) { + return fileForRegion(folder, key(x, z)); + } + + public static File fileForRegion(File folder, Long key) { + String id = UUID.nameUUIDFromBytes(("TectonicPlate:" + key).getBytes(StandardCharsets.UTF_8)).toString(); + File f = new File(folder, id.substring(0, 2) + "/" + id.split("\\Q-\\E")[3] + "/" + id + ".ttp"); + f.getParentFile().mkdirs(); + return f; + } + + public static Long key(int x, int z) { + return Cache.key(x, z); + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java new file mode 100644 index 000000000..136c3b27e --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -0,0 +1,145 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.util.mantle; + +import com.volmit.iris.util.data.Varint; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.matter.IrisMatter; +import com.volmit.iris.util.matter.Matter; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicReferenceArray; + +/** + * Represents a mantle chunk. Mantle chunks contain sections of matter (see matter api) + * Mantle Chunks are fully atomic & thread safe + */ +public class MantleChunk { + private final AtomicReferenceArray sections; + + /** + * Create a mantle chunk + * + * @param sectionHeight the height of the world in sections (blocks >> 4) + */ + @ChunkCoordinates + public MantleChunk(int sectionHeight) { + sections = new AtomicReferenceArray<>(sectionHeight); + } + + /** + * Load a mantle chunk from a data stream + * + * @param sectionHeight the height of the world in sections (blocks >> 4) + * @param din the data input + * @throws IOException shit happens + * @throws ClassNotFoundException shit happens + */ + public MantleChunk(int sectionHeight, DataInputStream din) throws IOException, ClassNotFoundException { + this(sectionHeight); + int s = Varint.readUnsignedVarInt(din); + + for (int i = 0; i < s; i++) { + if (din.readBoolean()) { + sections.set(i, Matter.read(din)); + } + } + } + + /** + * Check if a section exists (same as get(section) != null) + * + * @param section the section (0 - (worldHeight >> 4)) + * @return true if it exists + */ + @ChunkCoordinates + public boolean exists(int section) { + return get(section) != null; + } + + /** + * Get thje matter at the given section or null if it doesnt exist + * + * @param section the section (0 - (worldHeight >> 4)) + * @return the matter or null if it doesnt exist + */ + @ChunkCoordinates + public Matter get(int section) { + return sections.get(section); + } + + /** + * Clear all matter from this chunk + */ + public void clear() { + for (int i = 0; i < sections.length(); i++) { + delete(i); + } + } + + /** + * Delete the matter from the given section + * + * @param section the section (0 - (worldHeight >> 4)) + */ + @ChunkCoordinates + public void delete(int section) { + sections.set(section, null); + } + + /** + * Get or create a new matter section at the given section + * + * @param section the section (0 - (worldHeight >> 4)) + * @return the matter + */ + @ChunkCoordinates + public Matter getOrCreate(int section) { + Matter matter = get(section); + + if (matter == null) { + matter = new IrisMatter(16, 16, 16); + sections.set(section, matter); + } + + return matter; + } + + /** + * Write this chunk to a data stream + * + * @param dos the stream + * @throws IOException shit happens + */ + public void write(DataOutputStream dos) throws IOException { + Varint.writeUnsignedVarInt(sections.length(), dos); + + for (int i = 0; i < sections.length(); i++) { + if (exists(i)) { + dos.writeBoolean(true); + Matter matter = get(i); + matter.writeDos(dos); + } else { + dos.writeBoolean(false); + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java new file mode 100644 index 000000000..a09d18299 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -0,0 +1,162 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * 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 com.volmit.iris.util.mantle; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.documentation.ChunkCoordinates; +import com.volmit.iris.util.format.C; + +import java.io.*; +import java.util.concurrent.atomic.AtomicReferenceArray; + +/** + * Tectonic Plates are essentially representations of regions in minecraft. + * Tectonic Plates are fully atomic & thread safe + */ +public class TectonicPlate { + private final int sectionHeight; + private final AtomicReferenceArray chunks; + + /** + * Create a new tectonic plate + * + * @param worldHeight the height of the world + */ + public TectonicPlate(int worldHeight) { + this.sectionHeight = worldHeight >> 4; + this.chunks = new AtomicReferenceArray<>(1024); + } + + /** + * Load a tectonic plate from a data stream + * + * @param worldHeight the height of the world + * @param din the data input + * @throws IOException shit happens yo + * @throws ClassNotFoundException real shit bro + */ + public TectonicPlate(int worldHeight, DataInputStream din) throws IOException, ClassNotFoundException { + this(worldHeight); + + for (int i = 0; i < chunks.length(); i++) { + if (din.readBoolean()) { + chunks.set(i, new MantleChunk(sectionHeight, din)); + } + } + } + + /** + * Check if a chunk exists in this plate or not (same as get(x, z) != null) + * + * @param x the chunk relative x (0-31) + * @param z the chunk relative z (0-31) + * @return true if the chunk exists + */ + @ChunkCoordinates + public boolean exists(int x, int z) { + return get(x, z) != null; + } + + /** + * Get a chunk at the given coordinates or null if it doesnt exist + * + * @param x the chunk relative x (0-31) + * @param z the chunk relative z (0-31) + * @return the chunk or null if it doesnt exist + */ + @ChunkCoordinates + public MantleChunk get(int x, int z) { + return chunks.get(index(x, z)); + } + + /** + * Clear all chunks from this tectonic plate + */ + public void clear() { + for (int i = 0; i < chunks.length(); i++) { + chunks.set(i, null); + } + } + + /** + * Delete a chunk from this tectonic plate + * + * @param x the chunk relative x (0-31) + * @param z the chunk relative z (0-31) + */ + @ChunkCoordinates + public void delete(int x, int z) { + chunks.set(index(x, z), null); + } + + /** + * Get a tectonic plate, or create one and insert it & return it if it diddnt exist + * + * @param x the chunk relative x (0-31) + * @param z the chunk relative z (0-31) + * @return the chunk (read or created & inserted) + */ + @ChunkCoordinates + public MantleChunk getOrCreate(int x, int z) { + MantleChunk chunk = get(x, z); + + if (chunk == null) { + chunk = new MantleChunk(sectionHeight); + chunks.set(index(x, z), chunk); + } + + return chunk; + } + + @ChunkCoordinates + private int index(int x, int z) { + return (x & 0x1F) + (z & 0x1F) * 32; + } + + /** + * Write this tectonic plate to file + * + * @param file the file to write it to + * @throws IOException shit happens + */ + public void write(File file) throws IOException { + FileOutputStream fos = new FileOutputStream(file); + DataOutputStream dos = new DataOutputStream(fos); + write(dos); + dos.close(); + Iris.debug("Saved Tectonic Plate " + C.DARK_GREEN + file.getName().split("\\Q.\\E")[0]); + } + + /** + * Write this tectonic plate to a data stream + * + * @param dos the data output + * @throws IOException shit happens + */ + public void write(DataOutputStream dos) throws IOException { + for (int i = 0; i < chunks.length(); i++) { + MantleChunk chunk = chunks.get(i); + dos.writeBoolean(chunk != null); + + if (chunk != null) { + chunk.write(dos); + } + } + } +} diff --git a/src/main/java/com/volmit/iris/util/matter/IrisMatter.java b/src/main/java/com/volmit/iris/util/matter/IrisMatter.java index ee4e8b678..48412ace9 100644 --- a/src/main/java/com/volmit/iris/util/matter/IrisMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/IrisMatter.java @@ -23,7 +23,7 @@ import com.volmit.iris.util.collection.KMap; import lombok.Getter; public class IrisMatter implements Matter { - private static final KMap, MatterSlice> slicers = buildSlicers(); + protected static final KMap, MatterSlice> slicers = buildSlicers(); @Getter private final MatterHeader header; diff --git a/src/main/java/com/volmit/iris/util/matter/Matter.java b/src/main/java/com/volmit/iris/util/matter/Matter.java index 7f0e701c3..d81cbe08a 100644 --- a/src/main/java/com/volmit/iris/util/matter/Matter.java +++ b/src/main/java/com/volmit/iris/util/matter/Matter.java @@ -18,11 +18,16 @@ package com.volmit.iris.util.matter; +import com.volmit.iris.Iris; import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.data.Varint; +import com.volmit.iris.util.format.C; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.BlockPosition; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Entity; import java.io.*; import java.util.Map; @@ -87,7 +92,7 @@ public interface Matter { } /** - * Create a slice from the given type + * Create a slice from the given type (full is false) * * @param type the type class * @param matter the matter this slice will go into (size provider) @@ -166,11 +171,26 @@ public interface Matter { return (MatterSlice) getSliceMap().put(c, slice); } + default Class getClass(Object w) { + Class c = w.getClass(); + + if (w instanceof World) { + c = World.class; + } else if (w instanceof BlockData) { + c = BlockData.class; + } else if (w instanceof Entity) { + c = Entity.class; + } + + return c; + } + default MatterSlice slice(Class c) { if (!hasSlice(c)) { MatterSlice s = createSlice(c, this); if (s == null) { + Iris.error("Unable to find a slice for class " + C.DARK_RED + c.getCanonicalName()); return null; } @@ -244,16 +264,12 @@ public interface Matter { /** * Remove any slices that are empty */ - default void trimSlices() - { + default void trimSlices() { Set> drop = null; - for(Class i : getSliceTypes()) - { - if(getSlice(i).getCount() == 0) - { - if(drop == null) - { + for (Class i : getSliceTypes()) { + if (getSlice(i).getEntryCount() == 0) { + if (drop == null) { drop = new KSet<>(); } @@ -261,10 +277,8 @@ public interface Matter { } } - if(drop != null) - { - for(Class i : drop) - { + if (drop != null) { + for (Class i : drop) { deleteSlice(i); } } @@ -278,8 +292,11 @@ public interface Matter { * @throws IOException shit happens yo */ default void write(OutputStream out) throws IOException { + writeDos(new DataOutputStream(out)); + } + + default void writeDos(DataOutputStream dos) throws IOException { trimSlices(); - DataOutputStream dos = new DataOutputStream(out); Varint.writeUnsignedVarInt(getWidth(), dos); Varint.writeUnsignedVarInt(getHeight(), dos); Varint.writeUnsignedVarInt(getDepth(), dos); @@ -289,8 +306,6 @@ public interface Matter { for (Class i : getSliceTypes()) { getSlice(i).write(dos); } - - dos.flush(); } static Matter read(File f) throws IOException, ClassNotFoundException { @@ -325,16 +340,12 @@ public interface Matter { while (sliceCount-- > 0) { String cn = din.readUTF(); - try - { + try { Class type = Class.forName(cn); MatterSlice slice = matter.createSlice(type, matter); slice.read(din); matter.putSlice(type, slice); - } - - catch(Throwable e) - { + } catch (Throwable e) { e.printStackTrace(); throw new IOException("Can't read class '" + cn + "' (slice count reverse at " + sliceCount + ")"); } @@ -342,4 +353,14 @@ public interface Matter { return matter; } + + default int getTotalCount() { + int m = 0; + + for (MatterSlice i : getSliceMap().values()) { + m += i.getEntryCount(); + } + + return m; + } } diff --git a/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java b/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java index 96a21216a..01c5b275c 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterEntityGroup.java @@ -19,8 +19,6 @@ package com.volmit.iris.util.matter; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.nbt.tag.CompoundTag; -import lombok.AllArgsConstructor; import lombok.Data; @Data diff --git a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java index 27347c870..e05194d56 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java @@ -18,15 +18,14 @@ package com.volmit.iris.util.matter; -import com.volmit.iris.Iris; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.hunk.storage.MappedHunk; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; +import org.bukkit.util.BlockVector; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -68,7 +67,7 @@ public interface MatterSlice extends Hunk { return false; } - iterateSync((a,b,c,t) -> injector.writeMatter(w, t, a+x, b+y, c+z)); + iterateSync((a, b, c, t) -> injector.writeMatter(w, t, a + x, b + y, c + z)); return true; } @@ -89,8 +88,7 @@ public interface MatterSlice extends Hunk { for (int k = z; k < z + getDepth(); k++) { T v = ejector.readMatter(w, i, j, k); - if(v != null) - { + if (v != null) { set(i - x, j - y, k - z, v); } } @@ -100,14 +98,6 @@ public interface MatterSlice extends Hunk { return true; } - // BlockMatter - // RawMatter ex MappedHunk - // IMatterSlice ex Hunk - - default int getCount() { - return ((MappedHunk) this).getEntryCount(); - } - default boolean canWrite(Class mediumType) { return writeInto(mediumType) != null; } @@ -123,28 +113,49 @@ public interface MatterSlice extends Hunk { MatterPalette palette = new MatterPalette(this); iterateSync((x, y, z, b) -> palette.assign(b)); palette.writePalette(dos); - Varint.writeUnsignedVarInt(getCount(), dos); - iterateSyncIO((x, y, z, b) -> { - Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos); - palette.writeNode(b, dos); - }); + dos.writeBoolean(isMapped()); + + if (isMapped()) { + Varint.writeUnsignedVarInt(getEntryCount(), dos); + iterateSyncIO((x, y, z, b) -> { + Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos); + palette.writeNode(b, dos); + }); + } else { + iterateSyncIO((x, y, z, b) -> palette.writeNode(b, dos)); + } } default void read(DataInputStream din) throws IOException { int w = getWidth(); int h = getHeight(); - MatterPalette palette = new MatterPalette(this, din); - int nodes = Varint.readUnsignedVarInt(din); - int[] pos; + if (din.readBoolean()) { + int nodes = Varint.readUnsignedVarInt(din); + int[] pos; - while (nodes-- > 0) { - pos = Cache.to3D(Varint.readUnsignedVarInt(din), w, h); - setRaw(pos[0], pos[1], pos[2], palette.readNode(din)); + while (nodes-- > 0) { + pos = Cache.to3D(Varint.readUnsignedVarInt(din), w, h); + setRaw(pos[0], pos[1], pos[2], palette.readNode(din)); + } + } else { + iterateSyncIO((x, y, z, b) -> setRaw(x, y, z, palette.readNode(din))); } } default void rotateSliceInto(Matter n, double x, double y, double z) { rotate(x, y, z, (_x, _y, _z) -> n.slice(getType())); } + + default boolean containsKey(BlockVector v) { + return get(v.getBlockX(), v.getBlockY(), v.getBlockZ()) != null; + } + + default void put(BlockVector v, T d) { + set(v.getBlockX(), v.getBlockY(), v.getBlockZ(), d); + } + + default T get(BlockVector v) { + return get(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + } } diff --git a/src/main/java/com/volmit/iris/util/matter/WorldMatter.java b/src/main/java/com/volmit/iris/util/matter/WorldMatter.java index 88b790fdc..7edc6255b 100644 --- a/src/main/java/com/volmit/iris/util/matter/WorldMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/WorldMatter.java @@ -24,26 +24,21 @@ import org.bukkit.Location; import org.bukkit.block.data.BlockData; public class WorldMatter { - public static void placeMatter(Matter matter, Location at) - { - if(matter.hasSlice(BlockData.class)) - { + public static void placeMatter(Matter matter, Location at) { + if (matter.hasSlice(BlockData.class)) { matter.slice(BlockData.class).writeInto(at); } - if(matter.hasSlice(MatterEntityGroup.class)) - { + if (matter.hasSlice(MatterEntityGroup.class)) { matter.slice(MatterEntityGroup.class).writeInto(at); } - if(matter.hasSlice(MatterTile.class)) - { + if (matter.hasSlice(MatterTile.class)) { matter.slice(MatterTile.class).writeInto(at); } } - public static Matter createMatter(String author, Location a, Location b) - { + public static Matter createMatter(String author, Location a, Location b) { Cuboid c = new Cuboid(a, b); Matter s = new IrisMatter(c.getSizeX(), c.getSizeY(), c.getSizeZ()); Iris.info(s.getWidth() + " " + s.getHeight() + " " + s.getDepth()); diff --git a/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java index 08907a686..5790e758a 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java @@ -18,8 +18,6 @@ package com.volmit.iris.util.matter.slices; -import com.volmit.iris.engine.parallax.ParallaxAccess; -import com.volmit.iris.engine.parallax.ParallaxWorld; import com.volmit.iris.util.data.B; import com.volmit.iris.util.matter.Sliced; import org.bukkit.World; @@ -38,12 +36,10 @@ public class BlockMatter extends RawMatter { public BlockMatter(int width, int height, int depth) { super(width, height, depth, BlockData.class); registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d))); - registerWriter(ParallaxWorld.class, (w, d, x, y, z) -> w.setBlock(x, y, z, d)); registerReader(World.class, (w, x, y, z) -> { BlockData d = w.getBlockAt(x, y, z).getBlockData(); return d.getMaterial().isAir() ? null : d; }); - registerReader(ParallaxWorld.class, ParallaxAccess::getBlock); } @Override diff --git a/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java index 48f02db87..03ea0a713 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/EntityMatter.java @@ -18,13 +18,15 @@ package com.volmit.iris.util.matter.slices; -import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.Varint; -import com.volmit.iris.util.matter.*; +import com.volmit.iris.util.matter.MatterEntity; +import com.volmit.iris.util.matter.MatterEntityGroup; +import com.volmit.iris.util.matter.MatterReader; +import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.tag.CompoundTag; import org.bukkit.Location; @@ -47,20 +49,17 @@ public class EntityMatter extends RawMatter { public EntityMatter(int width, int height, int depth) { super(width, height, depth, MatterEntityGroup.class); registerWriter(World.class, ((w, d, x, y, z) -> { - for(MatterEntity i : d.getEntities()) - { - Location realPosition = new Location(w, x+i.getXOff(), y+i.getYOff(), z+i.getZOff()); + for (MatterEntity i : d.getEntities()) { + Location realPosition = new Location(w, x + i.getXOff(), y + i.getYOff(), z + i.getZOff()); INMS.get().deserializeEntity(i.getEntityData(), realPosition); } })); registerReader(World.class, (w, x, y, z) -> { - IrisPosition pos = new IrisPosition(x,y,z); + IrisPosition pos = new IrisPosition(x, y, z); KList entities = entityCache.get(pos); MatterEntityGroup g = new MatterEntityGroup(); - if(entities != null) - { - for(Entity i : entities) - { + if (entities != null) { + for (Entity i : entities) { g.getEntities().add(new MatterEntity( Math.abs(i.getLocation().getX()) - Math.abs(i.getLocation().getBlockX()), Math.abs(i.getLocation().getY()) - Math.abs(i.getLocation().getBlockY()), @@ -81,17 +80,17 @@ public class EntityMatter extends RawMatter { * across every block position, we simply use getNearbyEntities and cache each * block position with a list of entities within that block, and directly feed * the reader with the entities we capture. - * @param w the world - * @param x the x offset - * @param y the y offset - * @param z the z offset + * + * @param w the world + * @param x the x offset + * @param y the y offset + * @param z the z offset * @param the type * @return true if we read */ @Override public synchronized boolean readFrom(W w, int x, int y, int z) { - if(!(w instanceof World)) - { + if (!(w instanceof World)) { return super.readFrom(w, x, y, z); } @@ -103,18 +102,15 @@ public class EntityMatter extends RawMatter { entityCache = new KMap<>(); - for(Entity i : ((World) w).getNearbyEntities(new BoundingBox(x, y, z, x + getWidth(), y + getHeight(), z + getHeight()))) - { + for (Entity i : ((World) w).getNearbyEntities(new BoundingBox(x, y, z, x + getWidth(), y + getHeight(), z + getHeight()))) { entityCache.compute(new IrisPosition(i.getLocation()), (k, v) -> v == null ? new KList<>() : v).add(i); } - for(IrisPosition i : entityCache.keySet()) - { + for (IrisPosition i : entityCache.keySet()) { MatterEntityGroup g = reader.readMatter(w, i.getX(), i.getY(), i.getZ()); - if(g != null) - { + if (g != null) { set(i.getX() - x, i.getY() - y, i.getZ() - z, g); } } @@ -127,11 +123,10 @@ public class EntityMatter extends RawMatter { @Override public void writeNode(MatterEntityGroup b, DataOutputStream dos) throws IOException { Varint.writeUnsignedVarInt(b.getEntities().size(), dos); - for(MatterEntity i : b.getEntities()) - { - dos.writeByte((int)(i.getXOff() * 255) + Byte.MIN_VALUE); - dos.writeByte((int)(i.getYOff() * 255) + Byte.MIN_VALUE); - dos.writeByte((int)(i.getZOff() * 255) + Byte.MIN_VALUE); + for (MatterEntity i : b.getEntities()) { + dos.writeByte((int) (i.getXOff() * 255) + Byte.MIN_VALUE); + dos.writeByte((int) (i.getYOff() * 255) + Byte.MIN_VALUE); + dos.writeByte((int) (i.getZOff() * 255) + Byte.MIN_VALUE); NBTUtil.write(i.getEntityData(), dos, false); } } @@ -141,12 +136,11 @@ public class EntityMatter extends RawMatter { MatterEntityGroup g = new MatterEntityGroup(); int c = Varint.readUnsignedVarInt(din); - while(c-- > 0) - { + while (c-- > 0) { g.getEntities().add(new MatterEntity( - ((int)din.readByte() - Byte.MIN_VALUE) / 255F, - ((int)din.readByte() - Byte.MIN_VALUE) / 255F, - ((int)din.readByte() - Byte.MIN_VALUE) / 255F, + ((int) din.readByte() - Byte.MIN_VALUE) / 255F, + ((int) din.readByte() - Byte.MIN_VALUE) / 255F, + ((int) din.readByte() - Byte.MIN_VALUE) / 255F, (CompoundTag) NBTUtil.read(din, false).getTag())); } diff --git a/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java index a4f009c23..ad79dc32c 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/TileMatter.java @@ -19,8 +19,6 @@ package com.volmit.iris.util.matter.slices; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.engine.parallax.ParallaxAccess; -import com.volmit.iris.engine.parallax.ParallaxWorld; import com.volmit.iris.util.matter.MatterTile; import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.nbt.io.NBTUtil; @@ -43,12 +41,10 @@ public class TileMatter extends RawMatter { registerWriter(World.class, ((w, d, x, y, z) -> INMS.get().deserializeTile(d.getTileData(), new Location(w, x, y, z)))); registerReader(World.class, (w, x, y, z) -> { Location l = new Location(w, x, y, z); - if(INMS.get().hasTile(l)) - { + if (INMS.get().hasTile(l)) { CompoundTag tag = INMS.get().serializeTile(l); - if(tag != null) - { + if (tag != null) { return new MatterTile(tag); } } diff --git a/src/main/java/com/volmit/iris/util/parallel/HyperLock.java b/src/main/java/com/volmit/iris/util/parallel/HyperLock.java index fc7bcbc4a..f93358a29 100644 --- a/src/main/java/com/volmit/iris/util/parallel/HyperLock.java +++ b/src/main/java/com/volmit/iris/util/parallel/HyperLock.java @@ -64,14 +64,34 @@ public class HyperLock { public void withNasty(int x, int z, NastyRunnable r) throws Throwable { lock(x, z); - r.run(); - unlock(x, z); + Throwable ee = null; + try { + r.run(); + } catch (Throwable e) { + ee = e; + } finally { + unlock(x, z); + + if (ee != null) { + throw ee; + } + } } public void withIO(int x, int z, IORunnable r) throws IOException { lock(x, z); - r.run(); - unlock(x, z); + IOException ee = null; + try { + r.run(); + } catch (IOException e) { + ee = e; + } finally { + unlock(x, z); + + if (ee != null) { + throw ee; + } + } } public T withResult(int x, int z, Supplier r) { diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index 4e69de674..99dc91627 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -27,6 +27,7 @@ import com.volmit.iris.util.scheduling.Looper; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Supplier; public class MultiBurst { public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); @@ -53,13 +54,13 @@ public class MultiBurst { if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) { service.shutdown(); service = null; - Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resource."); + Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources."); } return 60000; } }; - heartbeat.setName(name); + heartbeat.setName(name + " Monitor"); heartbeat.start(); } @@ -123,6 +124,10 @@ public class MultiBurst { return CompletableFuture.runAsync(o, getService()); } + public CompletableFuture completeValue(Supplier o) { + return CompletableFuture.supplyAsync(o, getService()); + } + public void shutdownNow() { Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); heartbeat.interrupt(); diff --git a/src/main/java/com/volmit/iris/util/plugin/MortarCommand.java b/src/main/java/com/volmit/iris/util/plugin/MortarCommand.java index 04db9e6f9..631b58dea 100644 --- a/src/main/java/com/volmit/iris/util/plugin/MortarCommand.java +++ b/src/main/java/com/volmit/iris/util/plugin/MortarCommand.java @@ -91,7 +91,7 @@ public abstract class MortarCommand implements ICommand { b = true; - sender.sendMessage(C.GREEN + i.getNode() + " " + C.WHITE + i.getArgsUsage() + C.GRAY + " - " + i.getDescription()); + sender.sendMessage("" + C.GREEN + i.getNode() + " " + "" + (getArgsUsage().trim().isEmpty() ? "" : (C.WHITE + i.getArgsUsage())) + C.GRAY + " - " + i.getDescription()); } if (!b) { diff --git a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java index 8a8f8da12..3c3ee4321 100644 --- a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java +++ b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java @@ -19,16 +19,12 @@ package com.volmit.iris.util.plugin; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.util.format.C; import lombok.Getter; import lombok.Setter; -import net.kyori.adventure.Adventure; -import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.platform.AudienceProvider; -import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.minimessage.transformation.inbuild.GradientTransformation; import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -187,10 +183,23 @@ public class VolmitSender implements CommandSender { @Override public void sendMessage(String message) { - String t = C.translateAlternateColorCodes('&', getTag() + message); - String a = C.aura(t, 12, 0, 0); - Component c = MiniMessage.get().parse(a); - Iris.audiences.sender(s).sendMessage(c); + if (message.contains("")) { + s.sendMessage(message.replaceAll("\\Q\\E", "")); + return; + } + + try { + String t = C.translateAlternateColorCodes('&', getTag() + message); + String a = C.aura(t, IrisSettings.get().getGeneral().getSpinh(), IrisSettings.get().getGeneral().getSpins(), IrisSettings.get().getGeneral().getSpinb()); + Component c = MiniMessage.get().parse(a); + Iris.audiences.sender(s).sendMessage(c); + } catch (Throwable e) { + String t = C.translateAlternateColorCodes('&', getTag() + message); + String a = C.aura(t, IrisSettings.get().getGeneral().getSpinh(), IrisSettings.get().getGeneral().getSpins(), IrisSettings.get().getGeneral().getSpinb()); + + Iris.debug("Failure to parse " + a); + s.sendMessage(C.translateAlternateColorCodes('&', getTag() + message)); + } } @Override diff --git a/src/main/java/com/volmit/iris/util/reflect/ShadeFix.java b/src/main/java/com/volmit/iris/util/reflect/ShadeFix.java index 2b63145f1..8b25562a3 100644 --- a/src/main/java/com/volmit/iris/util/reflect/ShadeFix.java +++ b/src/main/java/com/volmit/iris/util/reflect/ShadeFix.java @@ -19,8 +19,7 @@ package com.volmit.iris.util.reflect; public class ShadeFix { - public static void fix(Class c) - { + public static void fix(Class c) { c.getCanonicalName(); } }