diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 2acdb735f..ce32385aa 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -833,7 +833,7 @@ public class Iris extends VolmitPlugin implements Listener { throw new IllegalStateException("Unable to register dimension " + dim.getName()); } - return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false); + return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey()); } public void splash() { diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index d0d15cffe..ffe8409c3 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -72,7 +72,6 @@ public class CommandIris implements DecreeExecutor { VolmitSender sender = Iris.getSender(); private CommandStudio studio; private CommandPregen pregen; - private CommandLazyPregen lazyPregen; private CommandSettings settings; private CommandObject object; private CommandJigsaw jigsaw; @@ -133,7 +132,6 @@ public class CommandIris implements DecreeExecutor { .seed(seed) .sender(sender()) .studio(false) - .smartVanillaHeight(vanillaheight) .headlessRadius(headlessRadius) .create(); } catch (Throwable e) { @@ -647,6 +645,6 @@ public class CommandIris implements DecreeExecutor { ff.mkdirs(); service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile()); } - return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false); + return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey()); } } diff --git a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index e8a459cb9..b7e961e52 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -34,6 +34,8 @@ import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import javax.swing.*; import java.awt.*; @@ -93,6 +95,7 @@ public class PregeneratorJob implements PregenListener { J.a(this.pregenerator::start, 20); } + public static boolean shutdownInstance() { if (instance == null) { return false; @@ -234,11 +237,6 @@ public class PregeneratorJob implements PregenListener { draw(x, z, COLOR_GENERATING); } - @Override - public void onServerShutdown() { - - } - @Override public void onChunkGenerated(int x, int z) { if (engine != null) { diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/EmptyListener.java b/core/src/main/java/com/volmit/iris/core/pregenerator/EmptyListener.java index 13d4f696a..25b2c1208 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/EmptyListener.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/EmptyListener.java @@ -15,11 +15,6 @@ public final class EmptyListener implements PregenListener { } - @Override - public void onServerShutdown() { - - } - @Override public void onChunkGenerated(int x, int z) { diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index eda3029c2..c989aefa9 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -40,6 +40,8 @@ import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import java.io.*; import java.lang.reflect.Type; @@ -351,11 +353,6 @@ public class IrisPregenerator { listener.onChunkGenerating(x, z); } - @Override - public void onServerShutdown() { - - } - @Override public void onChunkGenerated(int x, int z) { listener.onChunkGenerated(x, z); diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java index 3c8815222..d9a555922 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenListener.java @@ -23,8 +23,6 @@ public interface PregenListener { void onChunkGenerating(int x, int z); - void onServerShutdown(); - void onChunkGenerated(int x, int z); void onRegionGenerated(int x, int z); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 11876c6ed..9282a1c46 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -82,7 +82,6 @@ public class IrisCreator { * Benchmark mode */ private boolean benchmark = false; - private boolean smartVanillaHeight = false; /** * Radius of chunks to pregenerate in the headless mode * if set to -1, headless mode is disabled @@ -144,7 +143,6 @@ public class IrisCreator { .name(name) .seed(seed) .studio(studio) - .smartVanillaHeight(smartVanillaHeight) .create(); PlatformChunkGenerator access = (PlatformChunkGenerator) wc.generator(); if (access == null) { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java index 2b71576d3..b21c00237 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java @@ -34,7 +34,6 @@ public class IrisWorldCreator { private String name; private boolean studio = false; private String dimensionName = null; - private boolean smartVanillaHeight = false; private long seed = 1337; public IrisWorldCreator() { @@ -66,11 +65,6 @@ public class IrisWorldCreator { return this; } - public IrisWorldCreator smartVanillaHeight(boolean smartVanillaHeight) { - this.smartVanillaHeight = smartVanillaHeight; - return this; - } - public WorldCreator create() { IrisDimension dim = IrisData.loadAnyDimension(dimensionName); @@ -84,7 +78,7 @@ public class IrisWorldCreator { .build(); ChunkGenerator g = new BukkitChunkGenerator(w, studio, studio ? dim.getLoader().getDataFolder() : - new File(w.worldFolder(), "iris/pack"), dimensionName, smartVanillaHeight); + new File(w.worldFolder(), "iris/pack"), dimensionName); if (!INMS.get().registerDimension(name, dim)) { throw new IllegalStateException("Unable to register dimension " + dim.getName()); diff --git a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 41a3deb60..3482a3456 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -287,7 +287,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } private void fixEnergy() { - energy = M.clip(energy, 1D, getDimension().getEnergy().evaluate(null, getData(), energy)); + //energy = M.clip(energy, 1D, getDimension().getEnergy().evaluateMax(null, getData(), energy)); + energy = 1000; // Temp fix to prevent crash } private void spawnIn(Chunk c, boolean initial) { diff --git a/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java b/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java index 6830222e0..77938e421 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java @@ -28,6 +28,7 @@ import org.bukkit.*; import org.bukkit.entity.EnderSignal; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEnergy.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEnergy.java index 82caa59fd..52c1496ad 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEnergy.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEnergy.java @@ -47,45 +47,59 @@ public class IrisEnergy { @MaxNumber(10000) // @Desc("This is the maximum energy you can have in a dimension") // private double maximumEnergy = 1000; - @Desc("The expression. For your energy scaling, Inherited variables are me ( maximum energy ), ce ( current energy ). Avoid using those variable names. ") - private String expression = null; + @Desc("The expression. For your energy scaling, Inherited variables are ce ( current energy ). Avoid using those variable names. ") + private String expressionMax = null; + @Desc("The expression. For your energy scaling, Inherited variables are ce ( current energy ). Avoid using those variable names. ") + private String expressionCur = null; @ArrayType(type = IrisEnergyExpressionLoad.class, min = 1) @Desc("Variables to use in this expression") private KList variables = new KList<>(); private static final Parser parser = new Parser(); - private transient AtomicCache expressionCache = new AtomicCache<>(); + private transient AtomicCache expressionMaxCache = new AtomicCache<>(); + private transient AtomicCache expressionCurCache = new AtomicCache<>(); - private Expression expression() { - return expressionCache.aquire(() -> { - Scope scope = new Scope(); // Create variable scope. This scope can hold both constants and invocation variables. - - try { - for (IrisEnergyExpressionLoad i : variables) { - scope.addInvocationVariable(i.getName()); - } - - scope.addInvocationVariable("ce"); - } catch (Throwable e) { - e.printStackTrace(); - Iris.error("Script Variable load error in Energy Expression"); - } - - try { - if (expression != null) { - return parser.parse(getExpression(), scope); - } - return parser.parse("1000", scope); - } catch (Throwable e) { - e.printStackTrace(); - Iris.error("Script load error in Energy Expression"); - } - - return null; - }); + private Expression getExpression(String type) { + switch (type) { + case "max": + return expressionMaxCache.aquire(() -> parseExpression(expressionMax, "1000")); + case "cur": + return expressionCurCache.aquire(() -> parseExpression(expressionCur, "1000")); + default: + throw new IllegalArgumentException("Unknown expression type: " + type); + } } - public double evaluate(RNG rng, IrisData data, Double ce) { + private Expression parseExpression(String expression, String defaultValue) { + Scope scope = new Scope(); + + try { + for (IrisEnergyExpressionLoad i : variables) { + scope.addInvocationVariable(i.getName()); + } + + scope.addInvocationVariable("ce"); + } catch (Throwable e) { + e.printStackTrace(); + Iris.error("Script Variable load error in Energy Expression"); + } + + try { + if (expression != null) { + return parser.parse(expression, scope); + } + return parser.parse(defaultValue, scope); + } catch (Throwable e) { + e.printStackTrace(); + Iris.error("Script load error in Energy Expression"); + } + + return null; + } + + public double evaluateMax(String type, RNG rng, IrisData data, Double ce) { + Expression expression = getExpression(type); + double[] g = new double[3 + getVariables().size()]; int m = 0; for (IrisEnergyExpressionLoad i : getVariables()) { @@ -95,7 +109,7 @@ public class IrisEnergy { g[m++] = ce; g[m] = -1; - return expression().evaluate(g); + return expression.evaluate(g); } } diff --git a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index 8919a7d16..ca5f3ef17 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -88,7 +88,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private final boolean studio; private final AtomicInteger a = new AtomicInteger(0); private final CompletableFuture spawnChunks = new CompletableFuture<>(); - private final boolean smartVanillaHeight; private Engine engine; private Looper hotloader; private StudioMode lastMode; @@ -98,7 +97,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private boolean initialized = false; - public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey, boolean smartVanillaHeight) { + public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { setup = new AtomicBoolean(false); studioGenerator = null; dummyBiomeProvider = new DummyBiomeProvider(); @@ -110,7 +109,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun this.dataLocation = dataLocation; this.dimensionKey = dimensionKey; this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload()); - this.smartVanillaHeight = smartVanillaHeight; Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance); } @@ -188,14 +186,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun throw new RuntimeException("Missing Dimension: " + dimensionKey); } } - if (smartVanillaHeight) { - dimension.setSmartVanillaHeight(true); - try (FileWriter writer = new FileWriter(data.getDimensionLoader().fileFor(dimension))) { - writer.write(data.getGson().toJson(dimension)); - } catch (IOException e) { - e.printStackTrace(); - } - } lastMode = StudioMode.NORMAL; engine = new IrisEngine(new EngineTarget(world, dimension, data), studio); diff --git a/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java b/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java index d1775b036..ce101278e 100644 --- a/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java +++ b/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java @@ -4,12 +4,13 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisEngineService; +import com.volmit.iris.util.data.KCache; import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.mobs.HistoryManager; import com.volmit.iris.util.mobs.IrisMobDataHandler; import com.volmit.iris.util.mobs.IrisMobPiece; import com.volmit.iris.util.scheduling.Looper; import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import io.lumine.mythic.bukkit.utils.lib.jooq.impl.QOM; import org.bukkit.Chunk; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -18,6 +19,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerChangedWorldEvent; +import javax.xml.crypto.Data; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; @@ -29,9 +31,12 @@ import java.util.stream.Collectors; public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDataHandler { + private HistoryManager history; + private int id; - public double energyMax; - public double energy; + public int energyMax; + public int energy; + private long irritation = 0; private HashSet loadedChunks; private HashMap bukkitLimits; private Function entityType; @@ -45,6 +50,7 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat public void onEnable(boolean hotload) { this.id = engine.getCacheID(); + this.history = new HistoryManager<>(Long.MAX_VALUE); this.pieces = new ConcurrentLinkedQueue<>(); this.entityType = (entityType) -> Types.valueOf(INMS.get().getMobCategory(entityType)); this.loadedChunks = new HashSet<>(); @@ -71,6 +77,7 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat protected long loop() { long wait = -1; try { + irritation++; if (engine.isClosed() || engine.getCacheID() != id) { interrupt(); } @@ -81,7 +88,7 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat loadedChunks = Arrays.stream(getEngine().getWorld().realWorld().getLoadedChunks()) .collect(Collectors.toCollection(HashSet::new)); - fixEnergy(); + updateMaxEnergy(); Predicate shouldTick = IrisMobPiece::shouldTick; Function> tickCosts = piece -> piece.getTickCosts(1); @@ -92,12 +99,14 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat tickCosts )); + Consumer tick = piece -> piece.tick(42); pieces.stream() .filter(shouldTick) .forEach(tick); + stopwatch.end(); Iris.info("Took: " + Form.f(stopwatch.getMilliseconds())); double millis = stopwatch.getMilliseconds(); @@ -111,7 +120,11 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat } } - private void assignEnergyToPieces(LinkedHashMap> map) { + /** + * @param map Data to do calculations with + * @return returns the energy distribution for each piece + */ + private LinkedHashMap assignEnergyToPieces(LinkedHashMap> map) { Supplier>> sortedMapSupplier = new Supplier<>() { private LinkedHashMap> cachedMap; @@ -134,13 +147,21 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat } }; - Function viewHistory = (history) -> map.values().stream() - .mapToInt(list -> list.isEmpty() ? 0 : list.get(history)) - .sum(); + // Might need caching? + Function viewHistory = (history) -> + map.values().stream() + .mapToInt(list -> list.isEmpty() ? 0 : list.get(history)) + .sum(); + int i = calculateNewEnergy(); + + + return null; + } + @EventHandler(priority = EventPriority.NORMAL) public void on(PlayerChangedWorldEvent event) { if (!engine.getWorld().tryGetRealWorld()) { @@ -177,8 +198,19 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat return temp; } - private void fixEnergy() { - energyMax = engine.getDimension().getEnergy().evaluate(null, engine.getData(), energy); + private void updateMaxEnergy() { + var e = (int) engine.getDimension().getEnergy().evaluateMax("max", null, engine.getData(), (double) energy); + history.addEntry(DataType.ENERGY_MAX, e, irritation); + energyMax = e; + } + + private int calculateNewEnergy() { + return (int) engine.getDimension().getEnergy().evaluateMax("cur",null, engine.getData(), (double) energy); + } + + @Override + public long getIrritation() { + return irritation; } @Override @@ -203,7 +235,7 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat @Override public double getEnergy() { - fixEnergy(); + updateMaxEnergy(); return energy; } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java b/core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java new file mode 100644 index 000000000..24fb00e99 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java @@ -0,0 +1,47 @@ +package com.volmit.iris.util.mobs; + +import lombok.Data; + +import java.util.Deque; +import java.util.concurrent.ConcurrentLinkedDeque; + +public class HistoryManager { + private final Deque> history = new ConcurrentLinkedDeque<>(); + private final long maxSize; + + public HistoryManager(long maxSize) { + this.maxSize = maxSize; + } + + public void addEntry(K key, V value, I irritation) { + history.addFirst(new HistoryEntry<>(key, value, irritation)); + if (history.size() > maxSize) { + history.removeLast(); + } + } + + public HistoryEntry getEntry(int index) { + return history.stream().skip(index).findFirst().orElse(null); + } + + public I get3rd() { + return history.stream() + .skip(2) + .findFirst() + .map(HistoryEntry::getExtra) + .orElse(null); + } + + @Data + public static class HistoryEntry { + private final K key; + private final V value; + private final I extra; + + public HistoryEntry(K key, V value, I extra) { + this.key = key; + this.value = value; + this.extra = extra; + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java b/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java index d8ad44b07..edce0ade1 100644 --- a/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java +++ b/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java @@ -24,6 +24,14 @@ public interface IrisMobDataHandler { ambient } + enum DataType { + ENERGY_MAX, + ENERGY_CONSUMPTION + + } + + long getIrritation(); + Function getMobType(); Engine getEngine(); diff --git a/core/src/main/java/com/volmit/iris/util/mobs/IrisMobPiece.java b/core/src/main/java/com/volmit/iris/util/mobs/IrisMobPiece.java index 30e6470b6..42a5735a8 100644 --- a/core/src/main/java/com/volmit/iris/util/mobs/IrisMobPiece.java +++ b/core/src/main/java/com/volmit/iris/util/mobs/IrisMobPiece.java @@ -44,7 +44,7 @@ public class IrisMobPiece { /** * Returns the estimated Energy cost to run this tick. * Handy for if you are on a resource limit and need to prioritize who gets ticked and who not and what to expect. - * @param predict > The Prediction size on how far it should predict + * @param predict > The Prediction size on how far it should predict, return 0 if shouldTick return false on the Irritation. * @return The Predictions it made. */ public List getTickCosts(int predict) {