Merge remote-tracking branch 'upstream/master' into UseToolbelt

This commit is contained in:
CocoTheOwner 2021-08-07 20:04:48 +02:00
commit 603f032e28
60 changed files with 1597 additions and 387 deletions

View File

@ -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. 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/) ** # [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://docs.volmit.com/iris/) **|** [Git](https://github.com/IrisDimensions)
|** [Git](https://github.com/IrisDimensions)
## Iris Toolbelt ## Iris Toolbelt
@ -17,26 +15,26 @@ package com.volmit.iris.core.tools
IrisToolbelt.access(anyWorld).getCompound().getData(); IrisToolbelt.access(anyWorld).getCompound().getData();
// Get Default Engine from world // Get Default Engine from world
IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine(); IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine();
// Get the engine at the given height // Get the engine at the given height
IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68); IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68);
// IS THIS THING ON? // 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) // 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... IrisAccess access=IrisToolbelt.createWorld() // If you like builders...
.name("myWorld") // The world name .name("myWorld") // The world name
.dimension("terrifyinghands") .dimension("terrifyinghands")
.seed(69133742) // The world seed .seed(69133742) // The world seed
.headless(true) // Headless make gen go fast .headless(true) // Headless make gen go fast
.pregen(PregenTask // Define a pregen job to run .pregen(PregenTask // Define a pregen job to run
.builder() .builder()
.center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks) .center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks)
.radius(4) // Radius in REGIONS. Rad of 4 means a 9x9 Region map. .radius(4) // Radius in REGIONS. Rad of 4 means a 9x9 Region map.
.build()) .build())
.create(); .create();
``` ```

View File

@ -32,7 +32,7 @@ plugins {
} }
group 'com.volmit.iris' group 'com.volmit.iris'
version '1.6.2' version '1.6.5'
def apiVersion = '1.17' def apiVersion = '1.17'
def name = 'Iris' def name = 'Iris'
def main = 'com.volmit.iris.Iris' def main = 'com.volmit.iris.Iris'

View File

@ -57,7 +57,6 @@ import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Queue; import com.volmit.iris.util.scheduling.Queue;
import com.volmit.iris.util.scheduling.ShurikenQueue; import com.volmit.iris.util.scheduling.ShurikenQueue;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import net.kyori.adventure.platform.AudienceProvider;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.serializer.ComponentSerializer; import net.kyori.adventure.text.serializer.ComponentSerializer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -74,7 +73,7 @@ import org.bukkit.plugin.Plugin;
import java.io.*; import java.io.*;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.Date;
@SuppressWarnings("CanBeFinal") @SuppressWarnings("CanBeFinal")
public class Iris extends VolmitPlugin implements Listener { public class Iris extends VolmitPlugin implements Listener {
@ -135,6 +134,7 @@ public class Iris extends VolmitPlugin implements Listener {
super.onEnable(); super.onEnable();
Bukkit.getPluginManager().registerEvents(this, this); Bukkit.getPluginManager().registerEvents(this, this);
J.s(this::lateBind); J.s(this::lateBind);
splash();
} }
public static void callEvent(Event e) { public static void callEvent(Event e) {
@ -166,7 +166,6 @@ public class Iris extends VolmitPlugin implements Listener {
J.a(() -> PaperLib.suggestPaper(this)); J.a(() -> PaperLib.suggestPaper(this));
J.a(() -> IO.delete(getTemp())); J.a(() -> IO.delete(getTemp()));
J.a(this::bstats); J.a(this::bstats);
J.a(this::splash, 20);
J.ar(this::checkConfigHotload, 60); J.ar(this::checkConfigHotload, 60);
J.sr(this::tickQueue, 0); J.sr(this::tickQueue, 0);
J.s(this::setupPapi); J.s(this::setupPapi);
@ -251,7 +250,7 @@ public class Iris extends VolmitPlugin implements Listener {
@Override @Override
public String getTag(String subTag) { 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() { private void checkConfigHotload() {
@ -424,7 +423,7 @@ public class Iris extends VolmitPlugin implements Listener {
} }
public void imsg(CommandSender s, String msg) { 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) { public static void msg(String string) {
try { try {
sender.sendMessage(string); sender.sendMessage(string);
} catch (Throwable e) { } catch (Throwable ignored) {
System.out.println(string); try {
Iris.reportError(e); System.out.println(string);
} catch (Throwable ignored1) {
}
} }
} }
@ -523,7 +525,29 @@ public class Iris extends VolmitPlugin implements Listener {
return; 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("<gradient:#095fe0:#a848db>" + category + " <#bf3b76>" + line + "<reset> " + C.LIGHT_PURPLE + string.replaceAll("\\Q<\\E", "[").replaceAll("\\Q>\\E", "]"));
} }
public static void verbose(String string) { public static void verbose(String string) {
@ -538,7 +562,7 @@ public class Iris extends VolmitPlugin implements Listener {
} }
public static void success(String string) { public static void success(String string) {
msg(C.GREEN + string); msg(C.IRIS + string);
} }
public static void info(String string) { public static void info(String string) {
@ -558,9 +582,9 @@ public class Iris extends VolmitPlugin implements Listener {
// @NoArgsConstructor // @NoArgsConstructor
String padd = Form.repeat(" ", 8); String padd = Form.repeat(" ", 8);
String padd2 = Form.repeat(" ", 4); 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 " + "<rainbow>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 //@done
Iris.info("Server type & version: " + Bukkit.getVersion()); Iris.info("Server type & version: " + Bukkit.getVersion());

View File

@ -28,7 +28,6 @@ import com.volmit.iris.engine.object.objects.IrisDirection;
import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.objects.IrisObject;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; 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.format.Form;
import com.volmit.iris.util.function.Consumer2; import com.volmit.iris.util.function.Consumer2;
import com.volmit.iris.util.io.Converter; 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.nbt.tag.ListTag;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J; 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.Material;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Jigsaw; import org.bukkit.block.data.type.Jigsaw;

View File

@ -1,6 +1,5 @@
package com.volmit.iris.core; package com.volmit.iris.core;
import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.EntityType; 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. * Note: This results in odd dolphin behaviour, but it's the best we can do.
*/ */
@EventHandler @EventHandler
public void on(PlayerInteractEntityEvent event){ public void on(PlayerInteractEntityEvent event) {
if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())){ if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())) {
return; return;
} }
Material hand = event.getPlayer().getInventory().getItem(event.getHand()).getType(); 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); event.setCancelled(true);
} }
} }

View File

@ -107,6 +107,9 @@ public class IrisSettings {
public boolean pluginMetrics = true; public boolean pluginMetrics = true;
public boolean splashLogoStartup = true; public boolean splashLogoStartup = true;
public String forceMainWorld = ""; public String forceMainWorld = "";
public int spinh = -20;
public int spins = 7;
public int spinb = 8;
} }
@Data @Data

View File

@ -14,8 +14,8 @@ public class VillagerManager implements Listener {
* Replace or disable villager trade add event to prevent explorer map * Replace or disable villager trade add event to prevent explorer map
*/ */
@EventHandler @EventHandler
public void on(VillagerAcquireTradeEvent event){ public void on(VillagerAcquireTradeEvent event) {
if (!IrisToolbelt.isIrisWorld((event.getEntity().getWorld()))){ if (!IrisToolbelt.isIrisWorld((event.getEntity().getWorld()))) {
return; return;
} }
@ -26,13 +26,13 @@ public class VillagerManager implements Listener {
IrisVillagerOverride override = IrisToolbelt.access(event.getEntity().getWorld()).getCompound().getRootDimension().getPatchCartographers(); IrisVillagerOverride override = IrisToolbelt.access(event.getEntity().getWorld()).getCompound().getRootDimension().getPatchCartographers();
if (override.isDisableTrade()){ if (override.isDisableTrade()) {
event.setCancelled(true); event.setCancelled(true);
Iris.debug("Cancelled cartographer trade @ " + event.getEntity().getLocation()); Iris.debug("Cancelled cartographer trade @ " + event.getEntity().getLocation());
return; return;
} }
if (override.getValidItems() == null){ if (override.getValidItems() == null) {
event.setCancelled(true); event.setCancelled(true);
Iris.debug("Cancelled cartographer trade because no override items are valid @ " + event.getEntity().getLocation()); Iris.debug("Cancelled cartographer trade because no override items are valid @ " + event.getEntity().getLocation());
return; return;

View File

@ -26,14 +26,12 @@ import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.Cuboid; import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.M; 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.Matter;
import com.volmit.iris.util.matter.WorldMatter; import com.volmit.iris.util.matter.WorldMatter;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -68,8 +66,7 @@ public class WandManager implements Listener {
} }
public void tick(Player p) { public void tick(Player p) {
try try {
{
try { try {
if (isWand(p.getInventory().getItemInMainHand())) { if (isWand(p.getInventory().getItemInMainHand())) {
Location[] d = getCuboid(p.getInventory().getItemInMainHand()); Location[] d = getCuboid(p.getInventory().getItemInMainHand());
@ -78,10 +75,7 @@ public class WandManager implements Listener {
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
} }
} } catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -76,6 +76,9 @@ public class CommandIris extends MortarCommand {
@Command @Command
private CommandIrisReload reload; private CommandIrisReload reload;
@Command
private CommandIrisAura aura;
public CommandIris() { public CommandIris() {
super("iris", "ir", "irs"); super("iris", "ir", "irs");
requiresPermission(Iris.perm); requiresPermission(Iris.perm);

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<String> 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("<rainbow>Aura Spins updated to " + h + " " + s + " " + b);
} catch (Throwable b) {
sender.sendMessage(getArgsUsage());
}
return true;
}
@Override
protected String getArgsUsage() {
return "<spinH> <spinS> <spinB>";
}
}

View File

@ -21,10 +21,14 @@ package com.volmit.iris.core.command;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.util.collection.KList; 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.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
public class CommandIrisDebug extends MortarCommand { public class CommandIrisDebug extends MortarCommand {
@Command
private CommandIrisDebugSpawnerBoost boost;
public CommandIrisDebug() { public CommandIrisDebug() {
super("debug", "dbg"); super("debug", "dbg");
requiresPermission(Iris.perm.studio); requiresPermission(Iris.perm.studio);

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<String> 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 "<number> [|,&,^,>>,<<,%] <other>";
}
}

View File

@ -22,7 +22,6 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.WandManager; import com.volmit.iris.core.WandManager;
import com.volmit.iris.util.collection.KList; 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.matter.Matter;
import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;

View File

@ -23,11 +23,13 @@ import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO; 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.json.JSONObject;
import com.volmit.iris.util.plugin.MortarCommand; import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.plugin.VolmitSender;
import java.io.File; import java.io.File;
import java.io.IOException;
public class CommandIrisStudioBeautify extends MortarCommand { public class CommandIrisStudioBeautify extends MortarCommand {
public CommandIrisStudioBeautify() { public CommandIrisStudioBeautify() {
@ -80,7 +82,7 @@ public class CommandIrisStudioBeautify extends MortarCommand {
} }
} else if (clean.getName().endsWith(".json")) { } else if (clean.getName().endsWith(".json")) {
try { try {
IO.writeAll(clean, new JSONObject(IO.readAll(clean)).toString(4)); clean(clean);
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
Iris.error("Failed to beautify " + clean.getAbsolutePath() + " You may have errors in your json!"); 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; 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 @Override
protected String getArgsUsage() { protected String getArgsUsage() {
return "[project]"; return "[project]";

View File

@ -20,6 +20,7 @@ package com.volmit.iris.core.command.studio;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; 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.core.tools.IrisWorlds;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.IrisAccess; import com.volmit.iris.engine.framework.IrisAccess;
@ -41,7 +42,16 @@ public class CommandIrisStudioSummon extends MortarCommand {
@Override @Override
public void addTabOptions(VolmitSender sender, String[] args, KList<String> list) { public void addTabOptions(VolmitSender sender, String[] args, KList<String> 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 @Override

View File

@ -60,27 +60,23 @@ public class CommandIrisStudioUpdate extends MortarCommand {
return true; return true;
} }
for(String i : args) for (String i : args) {
{ if (i.equals("--rewrite-objects")) {
if(i.equals("--rewrite-objects"))
{
IrisData data = new IrisData(Iris.proj.getWorkspaceFolder(args[0])); IrisData data = new IrisData(Iris.proj.getWorkspaceFolder(args[0]));
int t = data.getObjectLoader().getPossibleKeys().length; int t = data.getObjectLoader().getPossibleKeys().length;
ChronoLatch cl = new ChronoLatch(250, false); 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(); BurstExecutor b = bx.burst();
int g = 0; int g = 0;
for(String f : data.getObjectLoader().getPossibleKeys()) for (String f : data.getObjectLoader().getPossibleKeys()) {
{
int finalG1 = g; int finalG1 = g;
b.queue(() -> { b.queue(() -> {
if(cl.flip()) if (cl.flip()) {
{
Iris.info("Rewriting: " + Form.f(t - finalG1) + " Objects Left"); Iris.info("Rewriting: " + Form.f(t - finalG1) + " Objects Left");
} }
File ff = data.getObjectLoader().findFile(f); File ff = data.getObjectLoader().findFile(f);
IrisObject oo = new IrisObject(0,0,0); IrisObject oo = new IrisObject(0, 0, 0);
try { try {
oo.read(ff); oo.read(ff);
} catch (Throwable e) { } catch (Throwable e) {
@ -88,8 +84,7 @@ public class CommandIrisStudioUpdate extends MortarCommand {
return; return;
} }
if(oo == null) if (oo == null) {
{
Iris.error("FAILER TO READ: " + f); Iris.error("FAILER TO READ: " + f);
return; return;
} }

View File

@ -31,11 +31,13 @@ public class MythicMobsLink {
/** /**
* Spawn a mythic mob at this location * Spawn a mythic mob at this location
* @param mob The mob *
* @param mob The mob
* @param location The location * @param location The location
* @return The mob, or null if it can't be spawned * @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 (!isEnabled()) return null;
if (spawnMobFunction != null) { if (spawnMobFunction != null) {
@ -72,7 +74,7 @@ public class MythicMobsLink {
return mobs; return mobs;
} }
if(isEnabled()) { if (isEnabled()) {
try { try {
Class<?> mythicMobClass = Class.forName("io.lumine.xikage.mythicmobs.MythicMobs"); Class<?> mythicMobClass = Class.forName("io.lumine.xikage.mythicmobs.MythicMobs");

View File

@ -18,11 +18,7 @@
package com.volmit.iris.core.link; package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList; 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.items.OraxenItems;
import io.th0rgal.oraxen.mechanics.Mechanic; import io.th0rgal.oraxen.mechanics.Mechanic;
import io.th0rgal.oraxen.mechanics.MechanicFactory; 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 io.th0rgal.oraxen.utils.Utils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.MultipleFacing; import org.bukkit.block.data.MultipleFacing;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -49,40 +44,32 @@ public class OraxenLink {
} }
public BlockData getBlockDataFor(String id) { public BlockData getBlockDataFor(String id) {
if(!supported()) if (!supported()) {
{
return null; return null;
} }
MechanicFactory f = getFactory(id); MechanicFactory f = getFactory(id);
if(f == null) if (f == null) {
{
return null; return null;
} }
Mechanic m = f.getMechanic(id); Mechanic m = f.getMechanic(id);
// TODO: Why isnt there a simple getBlockData() function? // TODO: Why isnt there a simple getBlockData() function?
if(m.getFactory() instanceof NoteBlockMechanicFactory) if (m.getFactory() instanceof NoteBlockMechanicFactory) {
{
return ((NoteBlockMechanicFactory) m.getFactory()).createNoteBlockData(id); return ((NoteBlockMechanicFactory) m.getFactory()).createNoteBlockData(id);
} } else if (m.getFactory() instanceof BlockMechanicFactory) {
MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM);
else if(m.getFactory() instanceof BlockMechanicFactory) Utils.setBlockFacing(newBlockData, ((BlockMechanic) m).getCustomVariation());
{
MultipleFacing newBlockData = (MultipleFacing)Bukkit.createBlockData(Material.MUSHROOM_STEM);
Utils.setBlockFacing(newBlockData, ((BlockMechanic)m).getCustomVariation());
return newBlockData; return newBlockData;
} }
return null; return null;
} }
public MechanicFactory getFactory(String id) public MechanicFactory getFactory(String id) {
{ if (!supported()) {
if(!supported())
{
return null; return null;
} }
@ -91,10 +78,8 @@ public class OraxenLink {
f.setAccessible(true); f.setAccessible(true);
Map<String, MechanicFactory> map = (Map<String, MechanicFactory>) f.get(null); Map<String, MechanicFactory> map = (Map<String, MechanicFactory>) f.get(null);
for(MechanicFactory i : map.values()) for (MechanicFactory i : map.values()) {
{ if (i.getItems().contains(id)) {
if(i.getItems().contains(id))
{
return i; return i;
} }
} }
@ -106,17 +91,14 @@ public class OraxenLink {
} }
public String[] getItemTypes() { public String[] getItemTypes() {
if(!supported()) if (!supported()) {
{
return EMPTY; return EMPTY;
} }
KList<String> v = new KList<>(); KList<String> v = new KList<>();
for(String i : OraxenItems.getItemNames()) for (String i : OraxenItems.getItemNames()) {
{ if (getBlockDataFor(i) != null) {
if(getBlockDataFor(i) != null)
{
v.add(i); v.add(i);
} }
} }

View File

@ -23,7 +23,6 @@ import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.TileState;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;

View File

@ -23,14 +23,17 @@ import com.volmit.iris.core.nms.INMSBinding;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.io.NBTUtil;
import com.volmit.iris.util.nbt.tag.CompoundTag; 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.BlockPosition;
import net.minecraft.core.IRegistry; import net.minecraft.core.IRegistry;
import net.minecraft.core.IRegistryWritable; 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.MinecraftKey;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer; import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.biome.BiomeBase; import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.block.entity.TileEntity; import net.minecraft.world.level.block.entity.TileEntity;
import net.minecraft.world.level.block.state.IBlockData; 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.CraftServer;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity;
import net.minecraft.world.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
@ -74,15 +76,14 @@ public class NMSBinding17_1 implements INMSBinding {
@Override @Override
public boolean hasTile(Location l) { 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 @Override
public CompoundTag serializeTile(Location location) { 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; return null;
} }
@ -95,12 +96,11 @@ public class NMSBinding17_1 implements INMSBinding {
public void deserializeTile(CompoundTag s, Location newPosition) { public void deserializeTile(CompoundTag s, Location newPosition) {
NBTTagCompound c = convert(s); NBTTagCompound c = convert(s);
if(c != null) if (c != null) {
{
int x = newPosition.getBlockX(); int x = newPosition.getBlockX();
int y = newPosition.getBlockY(); int y = newPosition.getBlockY();
int z = newPosition.getBlockZ(); int z = newPosition.getBlockZ();
WorldServer w = ((CraftWorld)newPosition.getWorld()).getHandle(); WorldServer w = ((CraftWorld) newPosition.getWorld()).getHandle();
Chunk ch = w.getChunkAt(x >> 4, z >> 4); Chunk ch = w.getChunkAt(x >> 4, z >> 4);
ChunkSection sect = ch.getSections()[y >> 4]; ChunkSection sect = ch.getSections()[y >> 4];
IBlockData block = sect.getBlocks().a(x & 15, y & 15, z & 15); 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 { try {
ByteArrayOutputStream boas = new ByteArrayOutputStream(); ByteArrayOutputStream boas = new ByteArrayOutputStream();
NBTUtil.write(tag, boas, false); NBTUtil.write(tag, boas, false);
@ -118,18 +117,14 @@ public class NMSBinding17_1 implements INMSBinding {
NBTTagCompound c = NBTCompressedStreamTools.a((DataInput) din); NBTTagCompound c = NBTCompressedStreamTools.a((DataInput) din);
din.close(); din.close();
return c; return c;
} } catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
private CompoundTag convert(NBTTagCompound tag) private CompoundTag convert(NBTTagCompound tag) {
{
try { try {
ByteArrayOutputStream boas = new ByteArrayOutputStream(); ByteArrayOutputStream boas = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(boas); DataOutputStream dos = new DataOutputStream(boas);
@ -145,7 +140,7 @@ public class NMSBinding17_1 implements INMSBinding {
@Override @Override
public CompoundTag serializeEntity(org.bukkit.entity.Entity be) { public CompoundTag serializeEntity(org.bukkit.entity.Entity be) {
Entity entity = ((CraftEntity)be).getHandle(); Entity entity = ((CraftEntity) be).getHandle();
NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound tag = new NBTTagCompound();
entity.save(tag); entity.save(tag);
CompoundTag t = convert(tag); CompoundTag t = convert(tag);
@ -165,7 +160,7 @@ public class NMSBinding17_1 implements INMSBinding {
pos.a(2, NBTTagDouble.a(newPosition.getZ())); pos.a(2, NBTTagDouble.a(newPosition.getZ()));
tag.set("Pos", pos); tag.set("Pos", pos);
org.bukkit.entity.Entity be = newPosition.getWorld().spawnEntity(newPosition, type); org.bukkit.entity.Entity be = newPosition.getWorld().spawnEntity(newPosition, type);
((CraftEntity)be).getHandle().load(tag); ((CraftEntity) be).getHandle().load(tag);
return be; return be;
} }

View File

@ -28,9 +28,6 @@ import com.volmit.iris.util.data.B;
import com.volmit.iris.util.json.JSONArray; import com.volmit.iris.util.json.JSONArray;
import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.json.JSONObject;
import org.bukkit.enchantments.Enchantment; 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 org.bukkit.potion.PotionEffectType;
import java.awt.*; import java.awt.*;
@ -225,11 +222,10 @@ public class SchemaBuilder {
prop.put("$ref", "#/definitions/" + key); prop.put("$ref", "#/definitions/" + key);
description.add(SYMBOL_TYPE__N + " Must be a valid Item Type (use ctrl+space for auto complete!)"); 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"; String key = "enum-reg-specialentity";
if(!definitions.containsKey(key)) if (!definitions.containsKey(key)) {
{
JSONObject j = new JSONObject(); JSONObject j = new JSONObject();
KList<String> list = new KList<>(); KList<String> list = new KList<>();
list.addAll(Iris.linkMythicMobs.getMythicMobTypes().stream().map(s -> "MythicMobs:" + s).collect(Collectors.toList())); list.addAll(Iris.linkMythicMobs.getMythicMobTypes().stream().map(s -> "MythicMobs:" + s).collect(Collectors.toList()));
@ -540,7 +536,7 @@ public class SchemaBuilder {
return "number"; return "number";
} }
if (c.equals(boolean.class)||c.equals(Boolean.class)) { if (c.equals(boolean.class) || c.equals(Boolean.class)) {
return "boolean"; return "boolean";
} }
@ -570,7 +566,7 @@ public class SchemaBuilder {
} }
// suppress warnings on bukkit classes // 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"; return "Bukkit package classes and enums have no descriptions";
} }

View File

@ -18,7 +18,6 @@
package com.volmit.iris.core.wand; package com.volmit.iris.core.wand;
import com.volmit.iris.Iris;
import com.volmit.iris.util.data.Cuboid; import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
@ -33,23 +32,18 @@ public class WandSelection {
private final Cuboid c; private final Cuboid c;
private final Player p; private final Player p;
public WandSelection(Cuboid c, Player p) public WandSelection(Cuboid c, Player p) {
{
this.c = c; this.c = c;
this.p = p; this.p = p;
} }
public void draw() public void draw() {
{
double accuracy = M.lerpInverse(0, 64 * 64, p.getLocation().distanceSquared(c.getCenter())); double accuracy = M.lerpInverse(0, 64 * 64, p.getLocation().distanceSquared(c.getCenter()));
double dist = M.lerp(0.125, 3.5, accuracy); double dist = M.lerp(0.125, 3.5, accuracy);
for(double i = c.getLowerX()-1; i < c.getUpperX()+1; i+=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 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 k = c.getLowerZ()-1; k < c.getUpperZ()+1; k+=0.25)
{
boolean ii = i == c.getLowerX() || i == c.getUpperX(); boolean ii = i == c.getLowerX() || i == c.getUpperX();
boolean jj = j == c.getLowerY() || j == c.getUpperY(); boolean jj = j == c.getLowerY() || j == c.getUpperY();
boolean kk = k == c.getLowerZ() || k == c.getUpperZ(); 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)); accuracy = M.lerpInverse(0, 64 * 64, p.getLocation().distanceSquared(a));
dist = M.lerp(0.125, 3.5, accuracy); 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; continue;
} }
if(ii && jj) if (ii && jj) {
{
a.add(0, 0, RNG.r.d(-0.3, 0.3)); 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); 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); 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); Color color = Color.getHSBColor((float) (0.5f + (Math.sin((i + j + k + (p.getTicksLived() / 2f)) / (20f)) / 2)), 1, 1);
int r = color.getRed(); int r = color.getRed();
int g = color.getGreen(); int g = color.getGreen();
@ -115,7 +104,7 @@ public class WandSelection {
p.spawnParticle(Particle.REDSTONE, a.getX(), a.getY(), a.getZ(), p.spawnParticle(Particle.REDSTONE, a.getX(), a.getY(), a.getZ(),
1, 0, 0, 0, 0, 1, 0, 0, 0, 0,
new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b), new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b),
(float) dist*2f)); (float) dist * 3f));
} }
} }
} }

View File

@ -20,7 +20,6 @@ package com.volmit.iris.engine;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.events.IrisEngineHotloadEvent; import com.volmit.iris.core.events.IrisEngineHotloadEvent;
import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.*; 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.decoration.IrisDecorator;
import com.volmit.iris.engine.object.engine.IrisEngineData; import com.volmit.iris.engine.object.engine.IrisEngineData;
import com.volmit.iris.engine.object.objects.IrisObjectPlacement; 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.context.IrisContext;
import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates; 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.hunk.Hunk;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
@ -228,24 +223,10 @@ public class IrisEngine extends BlockPopulator implements Engine {
} }
case ISLANDS -> { case ISLANDS -> {
getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore); getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore);
} }
} }
getMetrics().getTotal().put(p.getMilliseconds()); getMetrics().getTotal().put(p.getMilliseconds());
if (IrisSettings.get().getGeneral().isDebug()) {
KList<String> v = new KList<>();
KMap<String, Double> 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) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
fail("Failed to generate " + x + ", " + z, e); fail("Failed to generate " + x + ", " + z, e);
@ -258,7 +239,9 @@ public class IrisEngine extends BlockPopulator implements Engine {
f.getParentFile().mkdirs(); f.getParentFile().mkdirs();
try { try {
IO.writeAll(f, new Gson().toJson(getEngineData())); IO.writeAll(f, new Gson().toJson(getEngineData()));
Iris.debug("Saved Engine Data");
} catch (IOException e) { } catch (IOException e) {
Iris.error("Failed to save Engine Data");
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View File

@ -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.biome.IrisBiome;
import com.volmit.iris.engine.object.block.IrisBlockDrops; import com.volmit.iris.engine.object.block.IrisBlockDrops;
import com.volmit.iris.engine.object.common.IRare; 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.IrisEngineData;
import com.volmit.iris.engine.object.engine.IrisEngineSpawnerCooldown; import com.volmit.iris.engine.object.engine.IrisEngineSpawnerCooldown;
import com.volmit.iris.engine.object.entity.IrisEntitySpawn; import com.volmit.iris.engine.object.entity.IrisEntitySpawn;
@ -61,6 +62,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
private int entityCount = 0; private int entityCount = 0;
private final ChronoLatch cl; private final ChronoLatch cl;
private final ChronoLatch ecl; private final ChronoLatch ecl;
private final ChronoLatch cln;
private long charge = 0;
private int actuallySpawned = 0; private int actuallySpawned = 0;
private int cooldown = 0; private int cooldown = 0;
private List<Entity> precount = new KList<>(); private List<Entity> precount = new KList<>();
@ -69,12 +72,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
super(null); super(null);
cl = null; cl = null;
ecl = null; ecl = null;
cln = null;
chunkCooldowns = null; chunkCooldowns = null;
looper = null; looper = null;
} }
public IrisWorldManager(Engine engine) { public IrisWorldManager(Engine engine) {
super(engine); super(engine);
cln = new ChronoLatch(60000);
cl = new ChronoLatch(3000); cl = new ChronoLatch(3000);
ecl = new ChronoLatch(250); ecl = new ChronoLatch(250);
chunkCooldowns = new KMap<>(); chunkCooldowns = new KMap<>();
@ -82,6 +87,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
looper = new Looper() { looper = new Looper() {
@Override @Override
protected long loop() { protected long loop() {
if (M.ms() < charge) {
energy += 70;
}
if (cln.flip()) {
engine.getEngineData().cleanup(getEngine());
}
if (precount != null) { if (precount != null) {
entityCount = 0; entityCount = 0;
for (Entity i : precount) { for (Entity i : precount) {
@ -137,7 +150,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
J.s(() -> precount = getEngine().getWorld().realWorld().getEntities()); J.s(() -> precount = getEngine().getWorld().realWorld().getEntities());
} }
int maxGroups = 1;
int chunkCooldownSeconds = 60; int chunkCooldownSeconds = 60;
for (Long i : chunkCooldowns.k()) { for (Long i : chunkCooldowns.k()) {
@ -158,7 +170,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
Chunk c = cc[RNG.r.nextInt(cc.length)]; Chunk c = cc[RNG.r.nextInt(cc.length)];
IrisBiome biome = getEngine().getSurfaceBiome(c); IrisBiome biome = getEngine().getSurfaceBiome(c);
IrisRegion region = getEngine().getRegion(c); IrisRegion region = getEngine().getRegion(c);
spawnIn(c, biome, region, maxGroups); spawnIn(c, biome, region);
chunkCooldowns.put(Cache.key(c), M.ms()); chunkCooldowns.put(Cache.key(c), M.ms());
} }
@ -170,15 +182,9 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
energy = M.clip(energy, 1D, 1000D); energy = M.clip(energy, 1D, 1000D);
} }
private void spawnIn(Chunk c, IrisBiome biome, IrisRegion region, int max) { private void spawnIn(Chunk c, IrisBiome biome, IrisRegion region) {
for (Entity i : c.getEntities()) {
if (i instanceof LivingEntity) {
return;
}
}
//@builder //@builder
spawnRandomly(Stream.concat(Stream.concat( IrisEntitySpawn v = spawnRandomly(Stream.concat(Stream.concat(
getData().getSpawnerLoader() getData().getSpawnerLoader()
.loadAll(getDimension().getEntitySpawners()) .loadAll(getDimension().getEntitySpawners())
.shuffleCopy(RNG.r).stream().filter(this::canSpawn), .shuffleCopy(RNG.r).stream().filter(this::canSpawn),
@ -197,16 +203,57 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
.shuffleCopy(RNG.r).stream().filter(this::canSpawn) .shuffleCopy(RNG.r).stream().filter(this::canSpawn)
.flatMap(this::stream))) .flatMap(this::stream)))
.collect(Collectors.toList())) .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 //@done
} }
private void spawn(Chunk c, IrisEntitySpawn i) { private void spawn(Chunk c, IrisEntitySpawn i) {
int s = i.spawn(getEngine(), c, RNG.r); boolean allow = true;
actuallySpawned += s;
if (s > 0) { if (!i.getReferenceSpawner().getMaximumRatePerChunk().isInfinite()) {
getCooldown(i.getReferenceSpawner()).spawn(getEngine()); allow = false;
energy -= s * ((i.getEnergyMultiplier() * i.getReferenceSpawner().getEnergyMultiplier() * 1)); 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(); fixEnergy();
} }
@Override
public void chargeEnergy() {
charge = M.ms() + 3000;
}
@Override @Override
public void onBlockBreak(BlockBreakEvent e) { public void onBlockBreak(BlockBreakEvent e) {
if (e.getBlock().getWorld().equals(getTarget().getWorld().realWorld()) && getEngine().contains(e.getBlock().getLocation())) { if (e.getBlock().getWorld().equals(getTarget().getWorld().realWorld()) && getEngine().contains(e.getBlock().getLocation())) {

View File

@ -43,4 +43,6 @@ public interface EngineWorldManager {
void onBlockPlace(BlockPlaceEvent e); void onBlockPlace(BlockPlaceEvent e);
void onChunkLoad(Chunk e, boolean generated); void onChunkLoad(Chunk e, boolean generated);
void chargeEnergy();
} }

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<? extends TileState> 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();
}
}

View File

@ -21,9 +21,7 @@ package com.volmit.iris.engine.object.annotations;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME) @Retention(RUNTIME)

View File

@ -48,4 +48,8 @@ public class IrisRate {
public ChronoLatch toChronoLatch() { public ChronoLatch toChronoLatch() {
return new ChronoLatch(getInterval()); return new ChronoLatch(getInterval());
} }
public boolean isInfinite() {
return per.toMilliseconds() == 0;
}
} }

View File

@ -149,10 +149,8 @@ public class IrisBlockData extends IrisRegistrant {
}); });
} }
private String keyify(String dat) private String keyify(String dat) {
{ if (dat.contains(":")) {
if(dat.contains(":"))
{
return dat; return dat;
} }

View File

@ -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.IrisCaveLayer;
import com.volmit.iris.engine.object.carve.IrisCaverns; import com.volmit.iris.engine.object.carve.IrisCaverns;
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; 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.IrisFeaturePositional;
import com.volmit.iris.engine.object.feature.IrisFeaturePotential; import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure; 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.regional.IrisRegion;
import com.volmit.iris.engine.object.spawners.IrisSpawner; import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.engine.object.trees.IrisTreeSettings; 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.collection.KList;
import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<IrisEngineSpawnerCooldown> 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();
}
}

View File

@ -18,6 +18,9 @@
package com.volmit.iris.engine.object.engine; 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 com.volmit.iris.util.collection.KList;
import lombok.Data; import lombok.Data;
@ -25,4 +28,43 @@ import lombok.Data;
public class IrisEngineData { public class IrisEngineData {
private IrisEngineStatistics statistics = new IrisEngineStatistics(); private IrisEngineStatistics statistics = new IrisEngineStatistics();
private KList<IrisEngineSpawnerCooldown> spawnerCooldowns = new KList<>(); private KList<IrisEngineSpawnerCooldown> spawnerCooldowns = new KList<>();
private KList<IrisEngineChunkData> 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);
}
}
}
} }

View File

@ -25,7 +25,7 @@ import lombok.Data;
@Data @Data
public class IrisEngineSpawnerCooldown { public class IrisEngineSpawnerCooldown {
private long lastSpawn; private long lastSpawn = 0;
private String spawner; private String spawner;
public void spawn(Engine engine) { public void spawn(Engine engine) {

View File

@ -36,8 +36,9 @@ import com.volmit.iris.util.math.BlockPosition;
import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.IrisLock; import com.volmit.iris.util.scheduling.IrisLock;
import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -56,26 +57,37 @@ import java.util.function.Consumer;
@SuppressWarnings("DefaultAnnotationParam") @SuppressWarnings("DefaultAnnotationParam")
@Accessors(chain = true) @Accessors(chain = true)
@Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisObject extends IrisRegistrant { public class IrisObject extends IrisRegistrant {
private static final Vector HALF = new Vector(0.5, 0.5, 0.5); protected static final Vector HALF = new Vector(0.5, 0.5, 0.5);
private static final BlockData AIR = B.get("CAVE_AIR"); protected static final BlockData AIR = B.get("CAVE_AIR");
private static final BlockData VAIR = B.get("VOID_AIR"); protected static final BlockData VAIR = B.get("VOID_AIR");
private static final BlockData VAIR_DEBUG = B.get("COBWEB"); protected 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]")}; 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]")};
public static boolean shitty = false;
private KMap<BlockVector, BlockData> blocks; private KMap<BlockVector, BlockData> blocks;
private KMap<BlockVector, TileData<? extends TileState>> states; private KMap<BlockVector, TileData<? extends TileState>> states;
@Getter
@Setter
private int w; private int w;
@Getter
@Setter
private int d; private int d;
@Getter
@Setter
private int h; 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 BlockVector center;
private transient volatile boolean smartBored = false; @Getter
private transient IrisLock lock = new IrisLock("Preloadcache"); @Setter
private transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>(); protected transient volatile boolean smartBored = false;
@Getter
@Setter
protected transient IrisLock lock = new IrisLock("Preloadcache");
@Setter
protected transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
public IrisObject(int w, int h, int d) { public IrisObject(int w, int h, int d) {
blocks = new KMap<>(); blocks = new KMap<>();
@ -330,10 +342,6 @@ public class IrisObject extends IrisRegistrant {
} }
public void read(File file) throws IOException { public void read(File file) throws IOException {
if (shitty) {
return;
}
FileInputStream fin = new FileInputStream(file); FileInputStream fin = new FileInputStream(file);
try { try {
read(fin); read(fin);
@ -348,8 +356,7 @@ public class IrisObject extends IrisRegistrant {
} }
public void write(File file) throws IOException { public void write(File file) throws IOException {
if(file == null) if (file == null) {
{
return; return;
} }
@ -862,7 +869,7 @@ public class IrisObject extends IrisRegistrant {
} }
} }
setBlocks(b); blocks = b;
} }
public void tricubic(int rad) { public void tricubic(int rad) {
@ -891,7 +898,7 @@ public class IrisObject extends IrisRegistrant {
} }
} }
setBlocks(b); blocks = b;
} }
public void trihermite(int rad) { 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) { private BlockData nearestBlockData(int x, int y, int z) {

View File

@ -48,6 +48,9 @@ public class IrisSpawner extends IrisRegistrant {
@Desc("The energy multiplier when calculating spawn energy usage") @Desc("The energy multiplier when calculating spawn energy usage")
private double energyMultiplier = 1; 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.") @Desc("The block of 24 hour time to contain this spawn in.")
private IrisTimeBlock timeBlock = new IrisTimeBlock(); private IrisTimeBlock timeBlock = new IrisTimeBlock();
@ -57,6 +60,9 @@ public class IrisSpawner extends IrisRegistrant {
@Desc("The maximum rate this spawner can fire") @Desc("The maximum rate this spawner can fire")
private IrisRate maximumRate = new IrisRate(); 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") @Desc("Where should these spawns be placed")
private IrisSpawnGroup group = IrisSpawnGroup.NORMAL; private IrisSpawnGroup group = IrisSpawnGroup.NORMAL;

View File

@ -22,11 +22,11 @@ import org.bukkit.inventory.ItemStack;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class IrisVillagerOverride { public class IrisVillagerOverride {
@Desc(""" @Desc("""
Disable the trade altogether. Disable the trade altogether.
If a cartographer villager gets a new explorer map trade: If a cartographer villager gets a new explorer map trade:
If this is enabled -> the trade is removed If this is enabled -> the trade is removed
If this is disabled -> the trade is replaced with the "override" setting below 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.""") Default is true, so if you omit this, trades will be removed.""")
private boolean disableTrade = true; private boolean disableTrade = true;
@DependsOn("disableTrade") @DependsOn("disableTrade")
@ -44,7 +44,7 @@ public class IrisVillagerOverride {
.setMinTrades(3) .setMinTrades(3)
.setMaxTrades(5)); .setMaxTrades(5));
public KList<IrisVillagerTrade> getValidItems(){ public KList<IrisVillagerTrade> getValidItems() {
KList<IrisVillagerTrade> valid = new KList<>(); KList<IrisVillagerTrade> valid = new KList<>();
getItems().stream().filter(IrisVillagerTrade::isValidItems).forEach(valid::add); getItems().stream().filter(IrisVillagerTrade::isValidItems).forEach(valid::add);
return valid.size() == 0 ? null : valid; return valid.size() == 0 ? null : valid;

View File

@ -4,9 +4,7 @@ package com.volmit.iris.engine.object.villager;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList; 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.math.RNG;
import com.volmit.iris.util.scheduling.S;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -58,7 +56,7 @@ public class IrisVillagerTrade {
* mintrades > 0, maxtrades > 0, maxtrades > mintrades, and<br> * mintrades > 0, maxtrades > 0, maxtrades > mintrades, and<br>
* ingredient 1, (if defined ingredient 2) and the result are valid items * ingredient 1, (if defined ingredient 2) and the result are valid items
*/ */
public boolean isValidItems(){ public boolean isValidItems() {
KList<String> warnings = new KList<>(); KList<String> warnings = new KList<>();
if (ingredient1 == null) { if (ingredient1 == null) {
warnings.add("Ingredient 1 is null"); warnings.add("Ingredient 1 is null");
@ -80,15 +78,15 @@ public class IrisVillagerTrade {
warnings.add("More minimal than maximal trades"); 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"); 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"); 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"); warnings.add("Result is not an item");
} }
@ -103,10 +101,11 @@ public class IrisVillagerTrade {
/** /**
* Get the ingredients * Get the ingredients
*
* @return The list of 1 or 2 ingredients (depending on if ing2 is null) * @return The list of 1 or 2 ingredients (depending on if ing2 is null)
*/ */
public List<ItemStack> getIngredients() { public List<ItemStack> getIngredients() {
if (!isValidItems()){ if (!isValidItems()) {
return null; return null;
} }
return ingredient2 == null ? new KList<>(ingredient1) : new KList<>(ingredient1, ingredient2); return ingredient2 == null ? new KList<>(ingredient1) : new KList<>(ingredient1, ingredient2);
@ -122,7 +121,7 @@ public class IrisVillagerTrade {
/** /**
* @return the trade as a merchant recipe * @return the trade as a merchant recipe
*/ */
public MerchantRecipe convert(){ public MerchantRecipe convert() {
MerchantRecipe recipe = new MerchantRecipe(getResult(), getAmount()); MerchantRecipe recipe = new MerchantRecipe(getResult(), getAmount());
recipe.setIngredients(getIngredients()); recipe.setIngredients(getIngredients());
return recipe; return recipe;

View File

@ -114,6 +114,7 @@ public class ParallaxWorld implements ParallaxAccess {
if (lr != null) { if (lr != null) {
v += lr.unload(); 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); ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z);
loadedRegions.put(key(x, z), v); loadedRegions.put(key(x, z), v);
Iris.debug("Loaded Parallax Region " + C.RED + x + " " + z);
return v; return v;
} }

View File

@ -572,15 +572,11 @@ public class B {
} }
} }
try try {
{
for (String i : Iris.linkOraxen.getItemTypes()) { for (String i : Iris.linkOraxen.getItemTypes()) {
bt.add("oraxen:" + i); bt.add("oraxen:" + i);
} }
} } catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -19,16 +19,13 @@
package com.volmit.iris.util.format; package com.volmit.iris.util.format;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS; import net.md_5.bungee.api.chat.BaseComponent;
import com.volmit.iris.engine.object.biome.IrisBiomeCustom; import net.md_5.bungee.api.chat.TextComponent;
import com.volmit.iris.util.plugin.VolmitSender;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import java.awt.color.ColorSpace;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -139,6 +136,14 @@ public enum C {
return net.md_5.bungee.api.ChatColor.GREEN; 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 * Represents aqua
*/ */
@ -238,8 +243,10 @@ public enum C {
public net.md_5.bungee.api.ChatColor asBungee() { public net.md_5.bungee.api.ChatColor asBungee() {
return net.md_5.bungee.api.ChatColor.RESET; return net.md_5.bungee.api.ChatColor.RESET;
} }
}; },
;
/** /**
* The special character which prefixes all chat colour codes. Use this if you * The special character which prefixes all chat colour codes. Use this if you
* need to dynamically convert colour codes from your custom format. * need to dynamically convert colour codes from your custom format.
@ -263,6 +270,7 @@ public enum C {
static { static {
chatHexMap.put(C.BLACK, "#000000"); chatHexMap.put(C.BLACK, "#000000");
chatHexMap.put(C.DARK_BLUE, "#0000AA"); chatHexMap.put(C.DARK_BLUE, "#0000AA");
chatHexMap.put(C.IRIS, "#1bb19e");
chatHexMap.put(C.DARK_GREEN, "#00AA00"); chatHexMap.put(C.DARK_GREEN, "#00AA00");
chatHexMap.put(C.DARK_AQUA, "#00AAAA"); chatHexMap.put(C.DARK_AQUA, "#00AAAA");
chatHexMap.put(C.DARK_RED, "#AA0000"); chatHexMap.put(C.DARK_RED, "#AA0000");
@ -319,9 +327,10 @@ public enum C {
this(token, code, intCode, false); this(token, code, intCode, false);
} }
C( char code, int intCode, boolean isFormat) { C(char code, int intCode, boolean isFormat) {
this("^", code, intCode, false); this("^", code, intCode, false);
} }
C(String token, char code, int intCode, boolean isFormat) { C(String token, char code, int intCode, boolean isFormat) {
this.code = code; this.code = code;
this.token = token.equalsIgnoreCase("^") ? "<" + name().toLowerCase(Locale.ROOT) + ">" : token; 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}); this.toString = new String(new char[]{COLOR_CHAR, code});
} }
public static float[] spin(float[] c, int shift) public static float[] spin(float[] c, int shift) {
{ return new float[]{spin(c[0], shift), spinc(c[1], shift), spinc(c[2], shift)};
return new float[]{spin(c[0], shift),spin(c[1], shift),spin(c[2], shift)};
} }
public static float[] spin(float[] c, int a,int b, int 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)};
return new float[]{spin(c[0], a),spin(c[1], b),spin(c[2], d)};
} }
public static float spin(float c, int shift) public static float spin(float c, int shift) {
{ float g = ((((int) Math.floor(c * 360)) + shift) % 360) / 360F;
float g = ((((int)Math.floor(c * 360)) + shift) % 360) / 360F;
return g < 0 ? 1f - g : g; 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(); StringBuilder b = new StringBuilder();
boolean c = false; boolean c = false;
for(char i : msg.toCharArray()) for (char i : msg.toCharArray()) {
{ if (c) {
if(c)
{
c = false; c = false;
C o = C.getByChar(i); C o = C.getByChar(i);
if(hrad != 0 || srad != 0 || vrad != 0) if (hrad != 0 || srad != 0 || vrad != 0) {
{ b.append("<gradient:")
//TODO: Spin to win .append(spinToHex(o, hrad, srad, vrad))
b.append(C.getByChar(i).token); .append(":")
} .append(spinToHex(o, -hrad, -srad, -vrad))
.append(">");
else } else {
{
b.append(C.getByChar(i).token); b.append(C.getByChar(i).token);
} }
continue; continue;
} }
if(i == C.COLOR_CHAR) if (i == C.COLOR_CHAR) {
{
c = true; c = true;
continue; continue;
} }
@ -384,6 +402,10 @@ public enum C {
return b.toString(); return b.toString();
} }
public static String compress(String c) {
return BaseComponent.toLegacyText(TextComponent.fromLegacyText(c));
}
public net.md_5.bungee.api.ChatColor asBungee() { public net.md_5.bungee.api.ChatColor asBungee() {
return net.md_5.bungee.api.ChatColor.RESET; return net.md_5.bungee.api.ChatColor.RESET;
} }
@ -399,7 +421,7 @@ public enum C {
@Override @Override
public String toString() { public String toString() {
return toString; return intCode == -1 ? token : toString;
} }
/** /**
@ -413,6 +435,10 @@ public enum C {
return chatToHex(this); 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. * 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 RED -> (byte) 12;
case WHITE -> (byte) 15; case WHITE -> (byte) 15;
case YELLOW -> (byte) 14; case YELLOW -> (byte) 14;
default -> (byte) 15;
}; };
} }
@ -657,6 +684,7 @@ public enum C {
case GREEN -> (byte) 5; case GREEN -> (byte) 5;
case LIGHT_PURPLE -> (byte) 2; case LIGHT_PURPLE -> (byte) 2;
case WHITE -> (byte) 0; case WHITE -> (byte) 0;
default -> (byte) 15;
}; };
} }

View File

@ -61,6 +61,14 @@ public interface Hunk<T> {
return new HunkView<T>(src); return new HunkView<T>(src);
} }
default boolean isMapped() {
return false;
}
default int getEntryCount() {
return getWidth() * getHeight() * getDepth();
}
static <A, B> Hunk<B> convertedReadView(Hunk<A> src, Function<A, B> reader) { static <A, B> Hunk<B> convertedReadView(Hunk<A> src, Function<A, B> reader) {
return new FunctionalHunkView<A, B>(src, reader, null); return new FunctionalHunkView<A, B>(src, reader, null);
} }
@ -1059,6 +1067,42 @@ public interface Hunk<T> {
setRaw(x, y, z, t); 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 <T> the type
* @return the hunk
*/
static <T> Hunk<T> newHunk(int w, int h, int d, Class<T> type, boolean packed, boolean concurrent) {
if (type.equals(Double.class)) {
return concurrent ?
packed ? (Hunk<T>) 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<T>) 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<T>) 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) { default void setIfExists(int x, int y, int z, T t) {
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) { if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) {
return; return;
@ -1401,4 +1445,8 @@ public interface Hunk<T> {
c[0] = x; c[0] = x;
c[1] = y; c[1] = y;
} }
default boolean isEmpty() {
return false;
}
} }

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.hunk;
@FunctionalInterface
public interface HunkFactory {
<T> Hunk<T> create(int w, int h, int d);
}

View File

@ -43,6 +43,14 @@ public class MappedHunk<T> extends StorageHunk<T> implements Hunk<T> {
return data.size(); return data.size();
} }
public boolean isMapped() {
return true;
}
public boolean isEmpty() {
return data.isEmpty();
}
@Override @Override
public void setRaw(int x, int y, int z, T t) { public void setRaw(int x, int y, int z, T t) {
if (t == null) { if (t == null) {

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<Long, Long> lastUse;
private final Map<Long, TectonicPlate> loadedRegions;
private final HyperLock hyperLock;
private final KSet<Long> 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 <T> the type of data (generic method)
*/
@BlockCoordinates
public <T> 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 <T> the type assumed from the provided class
* @return the returned result (or null) if it doesnt exist
*/
@SuppressWarnings("unchecked")
@BlockCoordinates
public <T> T get(int x, int y, int z, Class<T> 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<TectonicPlate> 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);
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<Matter> 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);
}
}
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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<MantleChunk> 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);
}
}
}
}

View File

@ -23,7 +23,7 @@ import com.volmit.iris.util.collection.KMap;
import lombok.Getter; import lombok.Getter;
public class IrisMatter implements Matter { public class IrisMatter implements Matter {
private static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers(); protected static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers();
@Getter @Getter
private final MatterHeader header; private final MatterHeader header;

View File

@ -18,11 +18,16 @@
package com.volmit.iris.util.matter; package com.volmit.iris.util.matter;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.data.Varint; 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.hunk.Hunk;
import com.volmit.iris.util.math.BlockPosition; 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.io.*;
import java.util.Map; 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 type the type class
* @param matter the matter this slice will go into (size provider) * @param matter the matter this slice will go into (size provider)
@ -166,11 +171,26 @@ public interface Matter {
return (MatterSlice<T>) getSliceMap().put(c, slice); return (MatterSlice<T>) 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 <T> MatterSlice<T> slice(Class<?> c) { default <T> MatterSlice<T> slice(Class<?> c) {
if (!hasSlice(c)) { if (!hasSlice(c)) {
MatterSlice<?> s = createSlice(c, this); MatterSlice<?> s = createSlice(c, this);
if (s == null) { if (s == null) {
Iris.error("Unable to find a slice for class " + C.DARK_RED + c.getCanonicalName());
return null; return null;
} }
@ -244,16 +264,12 @@ public interface Matter {
/** /**
* Remove any slices that are empty * Remove any slices that are empty
*/ */
default void trimSlices() default void trimSlices() {
{
Set<Class<?>> drop = null; Set<Class<?>> drop = null;
for(Class<?> i : getSliceTypes()) for (Class<?> i : getSliceTypes()) {
{ if (getSlice(i).getEntryCount() == 0) {
if(getSlice(i).getCount() == 0) if (drop == null) {
{
if(drop == null)
{
drop = new KSet<>(); drop = new KSet<>();
} }
@ -261,10 +277,8 @@ public interface Matter {
} }
} }
if(drop != null) if (drop != null) {
{ for (Class<?> i : drop) {
for(Class<?> i : drop)
{
deleteSlice(i); deleteSlice(i);
} }
} }
@ -278,8 +292,11 @@ public interface Matter {
* @throws IOException shit happens yo * @throws IOException shit happens yo
*/ */
default void write(OutputStream out) throws IOException { default void write(OutputStream out) throws IOException {
writeDos(new DataOutputStream(out));
}
default void writeDos(DataOutputStream dos) throws IOException {
trimSlices(); trimSlices();
DataOutputStream dos = new DataOutputStream(out);
Varint.writeUnsignedVarInt(getWidth(), dos); Varint.writeUnsignedVarInt(getWidth(), dos);
Varint.writeUnsignedVarInt(getHeight(), dos); Varint.writeUnsignedVarInt(getHeight(), dos);
Varint.writeUnsignedVarInt(getDepth(), dos); Varint.writeUnsignedVarInt(getDepth(), dos);
@ -289,8 +306,6 @@ public interface Matter {
for (Class<?> i : getSliceTypes()) { for (Class<?> i : getSliceTypes()) {
getSlice(i).write(dos); getSlice(i).write(dos);
} }
dos.flush();
} }
static Matter read(File f) throws IOException, ClassNotFoundException { static Matter read(File f) throws IOException, ClassNotFoundException {
@ -325,16 +340,12 @@ public interface Matter {
while (sliceCount-- > 0) { while (sliceCount-- > 0) {
String cn = din.readUTF(); String cn = din.readUTF();
try try {
{
Class<?> type = Class.forName(cn); Class<?> type = Class.forName(cn);
MatterSlice<?> slice = matter.createSlice(type, matter); MatterSlice<?> slice = matter.createSlice(type, matter);
slice.read(din); slice.read(din);
matter.putSlice(type, slice); matter.putSlice(type, slice);
} } catch (Throwable e) {
catch(Throwable e)
{
e.printStackTrace(); e.printStackTrace();
throw new IOException("Can't read class '" + cn + "' (slice count reverse at " + sliceCount + ")"); throw new IOException("Can't read class '" + cn + "' (slice count reverse at " + sliceCount + ")");
} }
@ -342,4 +353,14 @@ public interface Matter {
return matter; return matter;
} }
default int getTotalCount() {
int m = 0;
for (MatterSlice<?> i : getSliceMap().values()) {
m += i.getEntryCount();
}
return m;
}
} }

View File

@ -19,8 +19,6 @@
package com.volmit.iris.util.matter; package com.volmit.iris.util.matter;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@Data @Data

View File

@ -18,15 +18,14 @@
package com.volmit.iris.util.matter; package com.volmit.iris.util.matter;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.util.data.Varint; import com.volmit.iris.util.data.Varint;
import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.storage.MappedHunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.util.BlockVector;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -68,7 +67,7 @@ public interface MatterSlice<T> extends Hunk<T> {
return false; 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; return true;
} }
@ -89,8 +88,7 @@ public interface MatterSlice<T> extends Hunk<T> {
for (int k = z; k < z + getDepth(); k++) { for (int k = z; k < z + getDepth(); k++) {
T v = ejector.readMatter(w, i, j, k); T v = ejector.readMatter(w, i, j, k);
if(v != null) if (v != null) {
{
set(i - x, j - y, k - z, v); set(i - x, j - y, k - z, v);
} }
} }
@ -100,14 +98,6 @@ public interface MatterSlice<T> extends Hunk<T> {
return true; return true;
} }
// BlockMatter<T>
// RawMatter<T> ex MappedHunk<T>
// IMatterSlice<T> ex Hunk<T>
default int getCount() {
return ((MappedHunk<?>) this).getEntryCount();
}
default boolean canWrite(Class<?> mediumType) { default boolean canWrite(Class<?> mediumType) {
return writeInto(mediumType) != null; return writeInto(mediumType) != null;
} }
@ -123,28 +113,49 @@ public interface MatterSlice<T> extends Hunk<T> {
MatterPalette<T> palette = new MatterPalette<T>(this); MatterPalette<T> palette = new MatterPalette<T>(this);
iterateSync((x, y, z, b) -> palette.assign(b)); iterateSync((x, y, z, b) -> palette.assign(b));
palette.writePalette(dos); palette.writePalette(dos);
Varint.writeUnsignedVarInt(getCount(), dos); dos.writeBoolean(isMapped());
iterateSyncIO((x, y, z, b) -> {
Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos); if (isMapped()) {
palette.writeNode(b, dos); 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 { default void read(DataInputStream din) throws IOException {
int w = getWidth(); int w = getWidth();
int h = getHeight(); int h = getHeight();
MatterPalette<T> palette = new MatterPalette<T>(this, din); MatterPalette<T> palette = new MatterPalette<T>(this, din);
int nodes = Varint.readUnsignedVarInt(din); if (din.readBoolean()) {
int[] pos; int nodes = Varint.readUnsignedVarInt(din);
int[] pos;
while (nodes-- > 0) { while (nodes-- > 0) {
pos = Cache.to3D(Varint.readUnsignedVarInt(din), w, h); pos = Cache.to3D(Varint.readUnsignedVarInt(din), w, h);
setRaw(pos[0], pos[1], pos[2], palette.readNode(din)); 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) { default void rotateSliceInto(Matter n, double x, double y, double z) {
rotate(x, y, z, (_x, _y, _z) -> n.slice(getType())); 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());
}
} }

View File

@ -24,26 +24,21 @@ import org.bukkit.Location;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
public class WorldMatter { public class WorldMatter {
public static void placeMatter(Matter matter, Location at) public static void placeMatter(Matter matter, Location at) {
{ if (matter.hasSlice(BlockData.class)) {
if(matter.hasSlice(BlockData.class))
{
matter.slice(BlockData.class).writeInto(at); matter.slice(BlockData.class).writeInto(at);
} }
if(matter.hasSlice(MatterEntityGroup.class)) if (matter.hasSlice(MatterEntityGroup.class)) {
{
matter.slice(MatterEntityGroup.class).writeInto(at); matter.slice(MatterEntityGroup.class).writeInto(at);
} }
if(matter.hasSlice(MatterTile.class)) if (matter.hasSlice(MatterTile.class)) {
{
matter.slice(MatterTile.class).writeInto(at); 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); Cuboid c = new Cuboid(a, b);
Matter s = new IrisMatter(c.getSizeX(), c.getSizeY(), c.getSizeZ()); Matter s = new IrisMatter(c.getSizeX(), c.getSizeY(), c.getSizeZ());
Iris.info(s.getWidth() + " " + s.getHeight() + " " + s.getDepth()); Iris.info(s.getWidth() + " " + s.getHeight() + " " + s.getDepth());

View File

@ -18,8 +18,6 @@
package com.volmit.iris.util.matter.slices; 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.data.B;
import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.matter.Sliced;
import org.bukkit.World; import org.bukkit.World;
@ -38,12 +36,10 @@ public class BlockMatter extends RawMatter<BlockData> {
public BlockMatter(int width, int height, int depth) { public BlockMatter(int width, int height, int depth) {
super(width, height, depth, BlockData.class); super(width, height, depth, BlockData.class);
registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d))); 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) -> { registerReader(World.class, (w, x, y, z) -> {
BlockData d = w.getBlockAt(x, y, z).getBlockData(); BlockData d = w.getBlockAt(x, y, z).getBlockData();
return d.getMaterial().isAir() ? null : d; return d.getMaterial().isAir() ? null : d;
}); });
registerReader(ParallaxWorld.class, ParallaxAccess::getBlock);
} }
@Override @Override

View File

@ -18,13 +18,15 @@
package com.volmit.iris.util.matter.slices; package com.volmit.iris.util.matter.slices;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.engine.object.basic.IrisPosition; import com.volmit.iris.engine.object.basic.IrisPosition;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.Varint; 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.io.NBTUtil;
import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.nbt.tag.CompoundTag;
import org.bukkit.Location; import org.bukkit.Location;
@ -47,20 +49,17 @@ public class EntityMatter extends RawMatter<MatterEntityGroup> {
public EntityMatter(int width, int height, int depth) { public EntityMatter(int width, int height, int depth) {
super(width, height, depth, MatterEntityGroup.class); super(width, height, depth, MatterEntityGroup.class);
registerWriter(World.class, ((w, d, x, y, z) -> { registerWriter(World.class, ((w, d, x, y, z) -> {
for(MatterEntity i : d.getEntities()) for (MatterEntity i : d.getEntities()) {
{ Location realPosition = new Location(w, x + i.getXOff(), y + i.getYOff(), z + i.getZOff());
Location realPosition = new Location(w, x+i.getXOff(), y+i.getYOff(), z+i.getZOff());
INMS.get().deserializeEntity(i.getEntityData(), realPosition); INMS.get().deserializeEntity(i.getEntityData(), realPosition);
} }
})); }));
registerReader(World.class, (w, x, y, z) -> { registerReader(World.class, (w, x, y, z) -> {
IrisPosition pos = new IrisPosition(x,y,z); IrisPosition pos = new IrisPosition(x, y, z);
KList<Entity> entities = entityCache.get(pos); KList<Entity> entities = entityCache.get(pos);
MatterEntityGroup g = new MatterEntityGroup(); MatterEntityGroup g = new MatterEntityGroup();
if(entities != null) if (entities != null) {
{ for (Entity i : entities) {
for(Entity i : entities)
{
g.getEntities().add(new MatterEntity( g.getEntities().add(new MatterEntity(
Math.abs(i.getLocation().getX()) - Math.abs(i.getLocation().getBlockX()), Math.abs(i.getLocation().getX()) - Math.abs(i.getLocation().getBlockX()),
Math.abs(i.getLocation().getY()) - Math.abs(i.getLocation().getBlockY()), Math.abs(i.getLocation().getY()) - Math.abs(i.getLocation().getBlockY()),
@ -81,17 +80,17 @@ public class EntityMatter extends RawMatter<MatterEntityGroup> {
* across every block position, we simply use getNearbyEntities and cache each * across every block position, we simply use getNearbyEntities and cache each
* block position with a list of entities within that block, and directly feed * block position with a list of entities within that block, and directly feed
* the reader with the entities we capture. * the reader with the entities we capture.
* @param w the world *
* @param x the x offset * @param w the world
* @param y the y offset * @param x the x offset
* @param z the z offset * @param y the y offset
* @param z the z offset
* @param <W> the type * @param <W> the type
* @return true if we read * @return true if we read
*/ */
@Override @Override
public synchronized <W> boolean readFrom(W w, int x, int y, int z) { public synchronized <W> 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); return super.readFrom(w, x, y, z);
} }
@ -103,18 +102,15 @@ public class EntityMatter extends RawMatter<MatterEntityGroup> {
entityCache = new KMap<>(); 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()), entityCache.compute(new IrisPosition(i.getLocation()),
(k, v) -> v == null ? new KList<>() : v).add(i); (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()); 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); set(i.getX() - x, i.getY() - y, i.getZ() - z, g);
} }
} }
@ -127,11 +123,10 @@ public class EntityMatter extends RawMatter<MatterEntityGroup> {
@Override @Override
public void writeNode(MatterEntityGroup b, DataOutputStream dos) throws IOException { public void writeNode(MatterEntityGroup b, DataOutputStream dos) throws IOException {
Varint.writeUnsignedVarInt(b.getEntities().size(), dos); Varint.writeUnsignedVarInt(b.getEntities().size(), dos);
for(MatterEntity i : b.getEntities()) for (MatterEntity i : b.getEntities()) {
{ dos.writeByte((int) (i.getXOff() * 255) + Byte.MIN_VALUE);
dos.writeByte((int)(i.getXOff() * 255) + Byte.MIN_VALUE); dos.writeByte((int) (i.getYOff() * 255) + Byte.MIN_VALUE);
dos.writeByte((int)(i.getYOff() * 255) + Byte.MIN_VALUE); dos.writeByte((int) (i.getZOff() * 255) + Byte.MIN_VALUE);
dos.writeByte((int)(i.getZOff() * 255) + Byte.MIN_VALUE);
NBTUtil.write(i.getEntityData(), dos, false); NBTUtil.write(i.getEntityData(), dos, false);
} }
} }
@ -141,12 +136,11 @@ public class EntityMatter extends RawMatter<MatterEntityGroup> {
MatterEntityGroup g = new MatterEntityGroup(); MatterEntityGroup g = new MatterEntityGroup();
int c = Varint.readUnsignedVarInt(din); int c = Varint.readUnsignedVarInt(din);
while(c-- > 0) while (c-- > 0) {
{
g.getEntities().add(new MatterEntity( 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())); (CompoundTag) NBTUtil.read(din, false).getTag()));
} }

View File

@ -19,8 +19,6 @@
package com.volmit.iris.util.matter.slices; package com.volmit.iris.util.matter.slices;
import com.volmit.iris.core.nms.INMS; 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.MatterTile;
import com.volmit.iris.util.matter.Sliced; import com.volmit.iris.util.matter.Sliced;
import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.io.NBTUtil;
@ -43,12 +41,10 @@ public class TileMatter extends RawMatter<MatterTile> {
registerWriter(World.class, ((w, d, x, y, z) -> INMS.get().deserializeTile(d.getTileData(), new Location(w, x, y, z)))); 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) -> { registerReader(World.class, (w, x, y, z) -> {
Location l = new Location(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); CompoundTag tag = INMS.get().serializeTile(l);
if(tag != null) if (tag != null) {
{
return new MatterTile(tag); return new MatterTile(tag);
} }
} }

View File

@ -64,14 +64,34 @@ public class HyperLock {
public void withNasty(int x, int z, NastyRunnable r) throws Throwable { public void withNasty(int x, int z, NastyRunnable r) throws Throwable {
lock(x, z); lock(x, z);
r.run(); Throwable ee = null;
unlock(x, z); 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 { public void withIO(int x, int z, IORunnable r) throws IOException {
lock(x, z); lock(x, z);
r.run(); IOException ee = null;
unlock(x, z); try {
r.run();
} catch (IOException e) {
ee = e;
} finally {
unlock(x, z);
if (ee != null) {
throw ee;
}
}
} }
public <T> T withResult(int x, int z, Supplier<T> r) { public <T> T withResult(int x, int z, Supplier<T> r) {

View File

@ -27,6 +27,7 @@ import com.volmit.iris.util.scheduling.Looper;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
public class MultiBurst { public class MultiBurst {
public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); 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) { if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) {
service.shutdown(); service.shutdown();
service = null; service = null;
Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resource."); Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources.");
} }
return 60000; return 60000;
} }
}; };
heartbeat.setName(name); heartbeat.setName(name + " Monitor");
heartbeat.start(); heartbeat.start();
} }
@ -123,6 +124,10 @@ public class MultiBurst {
return CompletableFuture.runAsync(o, getService()); return CompletableFuture.runAsync(o, getService());
} }
public <T> CompletableFuture<T> completeValue(Supplier<T> o) {
return CompletableFuture.supplyAsync(o, getService());
}
public void shutdownNow() { public void shutdownNow() {
Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + ".");
heartbeat.interrupt(); heartbeat.interrupt();

View File

@ -91,7 +91,7 @@ public abstract class MortarCommand implements ICommand {
b = true; b = true;
sender.sendMessage(C.GREEN + i.getNode() + " " + C.WHITE + i.getArgsUsage() + C.GRAY + " - " + i.getDescription()); sender.sendMessage("" + C.GREEN + i.getNode() + " " + "<font:minecraft:uniform>" + (getArgsUsage().trim().isEmpty() ? "" : (C.WHITE + i.getArgsUsage())) + C.GRAY + " - " + i.getDescription());
} }
if (!b) { if (!b) {

View File

@ -19,16 +19,12 @@
package com.volmit.iris.util.plugin; package com.volmit.iris.util.plugin;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; 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.Component;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.transformation.inbuild.GradientTransformation;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -187,10 +183,23 @@ public class VolmitSender implements CommandSender {
@Override @Override
public void sendMessage(String message) { public void sendMessage(String message) {
String t = C.translateAlternateColorCodes('&', getTag() + message); if (message.contains("<NOMINI>")) {
String a = C.aura(t, 12, 0, 0); s.sendMessage(message.replaceAll("\\Q<NOMINI>\\E", ""));
Component c = MiniMessage.get().parse(a); return;
Iris.audiences.sender(s).sendMessage(c); }
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("<NOMINI>Failure to parse " + a);
s.sendMessage(C.translateAlternateColorCodes('&', getTag() + message));
}
} }
@Override @Override

View File

@ -19,8 +19,7 @@
package com.volmit.iris.util.reflect; package com.volmit.iris.util.reflect;
public class ShadeFix { public class ShadeFix {
public static void fix(Class<?> c) public static void fix(Class<?> c) {
{
c.getCanonicalName(); c.getCanonicalName();
} }
} }