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 e0f27b2d5..f77782238 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 @@ -26,17 +26,11 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDataHandler { private HashSet history; - private Function>, LinkedHashMap>> sortMapFunction; - - private Function, LinkedHashMap> sortMapSimpleFunction; - private int id; public int energyMax; public int energy; @@ -58,52 +52,6 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat this.entityType = (entityType) -> Types.valueOf(INMS.get().getMobCategory(entityType)); this.loadedChunks = new HashSet<>(); this.bukkitLimits = getBukkitLimits(); - this.sortMapFunction = - new Function<>() { - private Map> lastMap; - private LinkedHashMap> cachedSortedMap; - - @Override - public LinkedHashMap> apply(Map> inputMap) { - if (cachedSortedMap == null || !inputMap.equals(lastMap)) { - cachedSortedMap = inputMap.entrySet() - .stream() - .sorted(Map.Entry.>comparingByValue( - Comparator.comparingInt(list -> list.stream().mapToInt(Integer::intValue).sum()) - ).reversed()) - .collect(Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e1, - LinkedHashMap::new - )); - lastMap = new HashMap<>(inputMap); - } - return cachedSortedMap; - } - }; - - this.sortMapSimpleFunction = new Function<>() { - private Map lastMap; - private LinkedHashMap cachedSortedMap; - - @Override - public LinkedHashMap apply(Map inputMap) { - if (cachedSortedMap == null || !inputMap.equals(lastMap)) { - cachedSortedMap = inputMap.entrySet() - .stream() - .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) - .collect(Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e1, - LinkedHashMap::new - )); - lastMap = new HashMap<>(inputMap); - } - return cachedSortedMap; - } - }; new Ticker(); } @@ -111,8 +59,6 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat @Override public void onDisable(boolean hotload) { - - } private class Ticker extends Looper { @@ -132,7 +78,6 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat if (engine.isClosed() || engine.getCacheID() != id) { interrupt(); } - PrecisionStopwatch stopwatch = new PrecisionStopwatch(); stopwatch.begin(); @@ -140,18 +85,13 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat .collect(Collectors.toCollection(HashSet::new)); updateMaxEnergy(); - Predicate shouldTick = IrisMobPiece::shouldTick; - Function> tickCosts = piece -> piece.getTickCosts(1); - - Map> pieceTickCostsMap = pieces.stream() + Map costs = assignEnergyToPieces(pieces.stream() .collect(Collectors.toMap( - Function.identity(), - tickCosts - )); - - - Consumer tick = piece -> piece.tick(42); + piece -> piece, + piece -> piece.getTickCosts(60) + ))); + Consumer tick = piece -> piece.tick(costs.get(piece)); pieces.stream() .filter(shouldTick) @@ -172,72 +112,65 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat } /** - * @param req Data to do calculations with. List> = Requested energy + future - * @return returns the energy distribution for each piece + * Assigns energy to pieces based on current and future energy requirements. + * @param req Data to do calculations with. Map of IrisMobPiece to List representing requested energy + future + * @return Map of IrisMobPiece to Integer representing the energy distribution for each piece */ - private LinkedHashMap assignEnergyToPieces(LinkedHashMap> req) { + private Map assignEnergyToPieces(Map> req) { + final int FUTURE_VIEW = 60; + int currentEnergy = calculateNewEnergy(); - // Might need caching? - int futureView = 60; - int energy = calculateNewEnergy(); + Map finalMap = new LinkedHashMap<>(); + req.forEach((piece, value) -> finalMap.put(piece, null)); - LinkedHashMap finalMap = req.keySet().stream() - .collect(Collectors.toMap( - piece -> piece, - piece -> null, - (existing, replacement) -> existing, - LinkedHashMap::new - )); + double currentEnergyRatio = (double) currentEnergy / sumCurrentRequests(req); + double futureEnergyRatio = (double) predictEnergy(FUTURE_VIEW) / calculateFutureMedian(req, FUTURE_VIEW); - Function> viewSingleFuture = (future) -> - req.values().stream() - .mapToInt(list -> list.isEmpty() ? 0 : list.get(future)).boxed(); + if (futureEnergyRatio > 1.25 && currentEnergyRatio > 1) { + req.forEach((piece, energyList) -> finalMap.put(piece, energyList.isEmpty() ? 0 : energyList.get(0))); + } else if (currentEnergyRatio > 1) { - Function>> viewFuture = (rangeMin) -> (rangeMax) -> - IntStream.range(rangeMin, rangeMax) - .boxed() - .flatMap(viewSingleFuture); + // TODO: Implement hard part - Function viewFutureMedian = (value) -> viewFuture.apply(value).apply(futureView) - .sorted() - .collect(Collectors.collectingAndThen(Collectors.toList(), - list -> { - int size = list.size(); - if (size % 2 == 0) { - return (list.get(size / 2 - 1) + list.get(size / 2)) / 2.0; - } else { - return list.get(size / 2).doubleValue(); - } - })); - - // Logic - - if ((predictEnergy(futureView) / viewFutureMedian.apply(0)) > 1.25 && (energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() > 1)) { - - finalMap = req.entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - e -> e.getValue().isEmpty() ? 0 : e.getValue().get(0), - (v1, v2) -> v1, - LinkedHashMap::new - )); - } else if ((energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() > 1)) { - // hard part - - - } else if ((energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() < 1)) { - double scale = 1; - while ((double) energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() >= scale) { - scale -= 0.1; - } - double finalScale = scale + 0.1; - - LinkedHashMap finalMap1 = finalMap; - req.forEach((key, value) -> finalMap1.put(key, (int) (value.get(0) * finalScale))); + } else if (currentEnergyRatio < 1) { + double scale = calculateScale(currentEnergy, req); + req.forEach((piece, energyList) -> finalMap.put(piece, (int) (energyList.get(0) * scale))); } return finalMap; + } + private int sumCurrentRequests(Map> req) { + return req.values().stream() + .mapToInt(list -> list.isEmpty() ? 0 : list.get(0)) + .sum(); + } + + private double calculateFutureMedian(Map> req, int futureView) { + List allFutureValues = new ArrayList<>(); + for (int i = 0; i < futureView; i++) { + for (List energyList : req.values()) { + if (i < energyList.size()) { + allFutureValues.add(energyList.get(i)); + } + } + } + Collections.sort(allFutureValues); + int size = allFutureValues.size(); + if (size % 2 == 0) { + return (allFutureValues.get(size / 2 - 1) + allFutureValues.get(size / 2)) / 2.0; + } else { + return allFutureValues.get(size / 2); + } + } + + private double calculateScale(int currentEnergy, Map> req) { + double scale = 1.0; + double ratio = (double) currentEnergy / sumCurrentRequests(req); + while (ratio < scale) { + scale -= 0.1; + } + return Math.min(scale + 0.1, 1.0); }