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.
# [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://docs.volmit.com/iris/) **
|** [Git](https://github.com/IrisDimensions)
# [Support](https://discord.gg/3xxPTpT) **|** [Documentation](https://docs.volmit.com/iris/) **|** [Git](https://github.com/IrisDimensions)
## Iris Toolbelt
@ -17,18 +15,18 @@ package com.volmit.iris.core.tools
IrisToolbelt.access(anyWorld).getCompound().getData();
// Get Default Engine from world
IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine();
IrisToolbelt.access(anyWorld).getCompound().getDefaultEngine();
// Get the engine at the given height
IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68);
IrisToolbelt.access(anyWorld).getCompound().getEngineForHeight(68);
// IS THIS THING ON?
boolean yes=IrisToolbelt.isIrisWorld(world);
boolean yes=IrisToolbelt.isIrisWorld(world);
// GTFO for worlds (moves players to any other world, just not this one)
IrisToolbelt.evacuate(world);
IrisToolbelt.evacuate(world);
IrisAccess access=IrisToolbelt.createWorld() // If you like builders...
IrisAccess access=IrisToolbelt.createWorld() // If you like builders...
.name("myWorld") // The world name
.dimension("terrifyinghands")
.seed(69133742) // The world seed

View File

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

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.ShurikenQueue;
import io.papermc.lib.PaperLib;
import net.kyori.adventure.platform.AudienceProvider;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.serializer.ComponentSerializer;
import org.bukkit.Bukkit;
@ -74,7 +73,7 @@ import org.bukkit.plugin.Plugin;
import java.io.*;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.*;
import java.util.Date;
@SuppressWarnings("CanBeFinal")
public class Iris extends VolmitPlugin implements Listener {
@ -135,6 +134,7 @@ public class Iris extends VolmitPlugin implements Listener {
super.onEnable();
Bukkit.getPluginManager().registerEvents(this, this);
J.s(this::lateBind);
splash();
}
public static void callEvent(Event e) {
@ -166,7 +166,6 @@ public class Iris extends VolmitPlugin implements Listener {
J.a(() -> PaperLib.suggestPaper(this));
J.a(() -> IO.delete(getTemp()));
J.a(this::bstats);
J.a(this::splash, 20);
J.ar(this::checkConfigHotload, 60);
J.sr(this::tickQueue, 0);
J.s(this::setupPapi);
@ -251,7 +250,7 @@ public class Iris extends VolmitPlugin implements Listener {
@Override
public String getTag(String subTag) {
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GREEN + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
}
private void checkConfigHotload() {
@ -424,7 +423,7 @@ public class Iris extends VolmitPlugin implements Listener {
}
public void imsg(CommandSender s, String msg) {
s.sendMessage(C.GREEN + "[" + C.DARK_GRAY + "Iris" + C.GREEN + "]" + C.GRAY + ": " + msg);
s.sendMessage(C.IRIS + "[" + C.DARK_GRAY + "Iris" + C.IRIS + "]" + C.GRAY + ": " + msg);
}
@ -443,9 +442,12 @@ public class Iris extends VolmitPlugin implements Listener {
public static void msg(String string) {
try {
sender.sendMessage(string);
} catch (Throwable e) {
} catch (Throwable ignored) {
try {
System.out.println(string);
Iris.reportError(e);
} catch (Throwable ignored1) {
}
}
}
@ -523,7 +525,29 @@ public class Iris extends VolmitPlugin implements Listener {
return;
}
msg(C.LIGHT_PURPLE + string);
try {
throw new RuntimeException();
} catch (Throwable e) {
try {
String[] cc = e.getStackTrace()[1].getClassName().split("\\Q.\\E");
if (cc.length > 5) {
debug(cc[3] + "/" + cc[4] + "/" + cc[cc.length - 1], e.getStackTrace()[1].getLineNumber(), string);
} else {
debug(cc[3] + "/" + cc[4], e.getStackTrace()[1].getLineNumber(), string);
}
} catch (Throwable ex) {
debug("Origin", -1, string);
}
}
}
public static void debug(String category, int line, String string) {
if (!IrisSettings.get().getGeneral().isDebug()) {
return;
}
msg("<gradient:#095fe0:#a848db>" + category + " <#bf3b76>" + line + "<reset> " + C.LIGHT_PURPLE + string.replaceAll("\\Q<\\E", "[").replaceAll("\\Q>\\E", "]"));
}
public static void verbose(String string) {
@ -538,7 +562,7 @@ public class Iris extends VolmitPlugin implements Listener {
}
public static void success(String string) {
msg(C.GREEN + string);
msg(C.IRIS + string);
}
public static void info(String string) {
@ -558,9 +582,9 @@ public class Iris extends VolmitPlugin implements Listener {
// @NoArgsConstructor
String padd = Form.repeat(" ", 8);
String padd2 = Form.repeat(" ", 4);
String[] info = {"", "", "", "", "", padd2 + C.GREEN + " Iris", padd2 + C.GRAY + " by " + C.randomColor() + "V" + C.randomColor() + "o" + C.randomColor() + "l" + C.randomColor() + "m" + C.randomColor() + "i" + C.randomColor() + "t" + C.randomColor() + "S" + C.randomColor() + "o" + C.randomColor() + "f" + C.randomColor() + "t" + C.randomColor() + "w" + C.randomColor() + "a" + C.randomColor() + "r" + C.randomColor() + "e", padd2 + C.GRAY + " v" + getDescription().getVersion(),
String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "<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
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.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.function.Consumer2;
import com.volmit.iris.util.io.Converter;
@ -42,8 +41,6 @@ import com.volmit.iris.util.nbt.tag.IntTag;
import com.volmit.iris.util.nbt.tag.ListTag;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import net.kyori.adventure.text.minimessage.parser.Token;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Jigsaw;

View File

@ -1,6 +1,5 @@
package com.volmit.iris.core;
import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisToolbelt;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
@ -15,13 +14,13 @@ public class DolphinManager implements Listener {
* Note: This results in odd dolphin behaviour, but it's the best we can do.
*/
@EventHandler
public void on(PlayerInteractEntityEvent event){
if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())){
public void on(PlayerInteractEntityEvent event) {
if (!IrisToolbelt.isIrisWorld(event.getPlayer().getWorld())) {
return;
}
Material hand = event.getPlayer().getInventory().getItem(event.getHand()).getType();
if (event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))){
if (event.getRightClicked().getType().equals(EntityType.DOLPHIN) && (hand.equals(Material.TROPICAL_FISH) || hand.equals(Material.PUFFERFISH) || hand.equals(Material.COD) || hand.equals(Material.SALMON))) {
event.setCancelled(true);
}
}

View File

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

View File

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

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

View File

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

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

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.WandManager;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.matter.IrisMatter;
import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender;

View File

@ -23,11 +23,13 @@ import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONArray;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.plugin.MortarCommand;
import com.volmit.iris.util.plugin.VolmitSender;
import java.io.File;
import java.io.IOException;
public class CommandIrisStudioBeautify extends MortarCommand {
public CommandIrisStudioBeautify() {
@ -80,7 +82,7 @@ public class CommandIrisStudioBeautify extends MortarCommand {
}
} else if (clean.getName().endsWith(".json")) {
try {
IO.writeAll(clean, new JSONObject(IO.readAll(clean)).toString(4));
clean(clean);
} catch (Throwable e) {
Iris.reportError(e);
Iris.error("Failed to beautify " + clean.getAbsolutePath() + " You may have errors in your json!");
@ -92,6 +94,43 @@ public class CommandIrisStudioBeautify extends MortarCommand {
return c;
}
private void clean(File clean) throws IOException {
JSONObject obj = new JSONObject(IO.readAll(clean));
fixBlocks(obj, clean);
IO.writeAll(clean, obj.toString(4));
}
private void fixBlocks(JSONObject obj, File f) {
for (String i : obj.keySet()) {
Object o = obj.get(i);
if (i.equals("block") && o instanceof String && !o.toString().trim().isEmpty() && !o.toString().contains(":")) {
obj.put(i, "minecraft:" + o);
Iris.debug("Updated Block Key: " + o + " to " + obj.getString(i) + " in " + f.getPath());
}
if (o instanceof JSONObject) {
fixBlocks((JSONObject) o, f);
} else if (o instanceof JSONArray) {
fixBlocks((JSONArray) o, f);
}
}
}
private void fixBlocks(JSONArray obj, File f) {
for (int i = 0; i < obj.length(); i++) {
Object o = obj.get(i);
if (o instanceof JSONObject) {
fixBlocks((JSONObject) o, f);
} else if (o instanceof JSONArray) {
fixBlocks((JSONArray) o, f);
}
}
}
@Override
protected String getArgsUsage() {
return "[project]";

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

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

View File

@ -43,4 +43,6 @@ public interface EngineWorldManager {
void onBlockPlace(BlockPlaceEvent e);
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.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)

View File

@ -48,4 +48,8 @@ public class IrisRate {
public ChronoLatch toChronoLatch() {
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)
{
if(dat.contains(":"))
{
private String keyify(String dat) {
if (dat.contains(":")) {
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.IrisCaverns;
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
import com.volmit.iris.engine.object.villager.IrisVillagerOverride;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
import com.volmit.iris.engine.object.jigsaw.IrisJigsawStructure;
@ -47,6 +46,7 @@ import com.volmit.iris.engine.object.objects.IrisObjectPlacement;
import com.volmit.iris.engine.object.regional.IrisRegion;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.engine.object.trees.IrisTreeSettings;
import com.volmit.iris.engine.object.villager.IrisVillagerOverride;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.io.IO;

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;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.spawners.IrisSpawner;
import com.volmit.iris.util.collection.KList;
import lombok.Data;
@ -25,4 +28,43 @@ import lombok.Data;
public class IrisEngineData {
private IrisEngineStatistics statistics = new IrisEngineStatistics();
private KList<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
public class IrisEngineSpawnerCooldown {
private long lastSpawn;
private long lastSpawn = 0;
private String spawner;
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.RNG;
import com.volmit.iris.util.scheduling.IrisLock;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.bukkit.Location;
import org.bukkit.Material;
@ -56,26 +57,37 @@ import java.util.function.Consumer;
@SuppressWarnings("DefaultAnnotationParam")
@Accessors(chain = true)
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisObject extends IrisRegistrant {
private static final Vector HALF = new Vector(0.5, 0.5, 0.5);
private static final BlockData AIR = B.get("CAVE_AIR");
private static final BlockData VAIR = B.get("VOID_AIR");
private static final BlockData VAIR_DEBUG = B.get("COBWEB");
private static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")};
public static boolean shitty = false;
protected static final Vector HALF = new Vector(0.5, 0.5, 0.5);
protected static final BlockData AIR = B.get("CAVE_AIR");
protected static final BlockData VAIR = B.get("VOID_AIR");
protected static final BlockData VAIR_DEBUG = B.get("COBWEB");
protected static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")};
private KMap<BlockVector, BlockData> blocks;
private KMap<BlockVector, TileData<? extends TileState>> states;
@Getter
@Setter
private int w;
@Getter
@Setter
private int d;
@Getter
@Setter
private int h;
private transient final IrisLock readLock = new IrisLock("read-conclock");
protected transient final IrisLock readLock = new IrisLock("read-conclock");
@Getter
@Setter
private transient BlockVector center;
private transient volatile boolean smartBored = false;
private transient IrisLock lock = new IrisLock("Preloadcache");
private transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
@Getter
@Setter
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) {
blocks = new KMap<>();
@ -330,10 +342,6 @@ public class IrisObject extends IrisRegistrant {
}
public void read(File file) throws IOException {
if (shitty) {
return;
}
FileInputStream fin = new FileInputStream(file);
try {
read(fin);
@ -348,8 +356,7 @@ public class IrisObject extends IrisRegistrant {
}
public void write(File file) throws IOException {
if(file == null)
{
if (file == null) {
return;
}
@ -862,7 +869,7 @@ public class IrisObject extends IrisRegistrant {
}
}
setBlocks(b);
blocks = b;
}
public void tricubic(int rad) {
@ -891,7 +898,7 @@ public class IrisObject extends IrisRegistrant {
}
}
setBlocks(b);
blocks = b;
}
public void trihermite(int rad) {
@ -924,7 +931,7 @@ public class IrisObject extends IrisRegistrant {
}
}
setBlocks(b);
blocks = b;
}
private BlockData nearestBlockData(int x, int y, int z) {

View File

@ -48,6 +48,9 @@ public class IrisSpawner extends IrisRegistrant {
@Desc("The energy multiplier when calculating spawn energy usage")
private double energyMultiplier = 1;
@Desc("This spawner will not spawn in a given chunk if that chunk has more than the defined amount of living entities.")
private int maxEntitiesPerChunk = 1;
@Desc("The block of 24 hour time to contain this spawn in.")
private IrisTimeBlock timeBlock = new IrisTimeBlock();
@ -57,6 +60,9 @@ public class IrisSpawner extends IrisRegistrant {
@Desc("The maximum rate this spawner can fire")
private IrisRate maximumRate = new IrisRate();
@Desc("The maximum rate this spawner can fire on a specific chunk")
private IrisRate maximumRatePerChunk = new IrisRate();
@Desc("Where should these spawns be placed")
private IrisSpawnGroup group = IrisSpawnGroup.NORMAL;

View File

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

View File

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

View File

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

View File

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

View File

@ -61,6 +61,14 @@ public interface Hunk<T> {
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) {
return new FunctionalHunkView<A, B>(src, reader, null);
}
@ -1059,6 +1067,42 @@ public interface Hunk<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) {
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight() || z < 0 || z >= getDepth()) {
return;
@ -1401,4 +1445,8 @@ public interface Hunk<T> {
c[0] = x;
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();
}
public boolean isMapped() {
return true;
}
public boolean isEmpty() {
return data.isEmpty();
}
@Override
public void setRaw(int x, int y, int z, T t) {
if (t == null) {

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;
public class IrisMatter implements Matter {
private static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers();
protected static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers();
@Getter
private final MatterHeader header;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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