package com.minelittlepony.unicopia.client; import java.util.SortedSet; import com.google.common.collect.Sets; import com.minelittlepony.unicopia.server.world.BlockDestructionManager; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.client.render.BlockBreakingInfo; import net.minecraft.util.math.BlockPos; public class ClientBlockDestructionManager { private final Long2ObjectMap destructions = new Long2ObjectOpenHashMap<>(); private final Long2ObjectMap> combined = new Long2ObjectOpenHashMap<>(); private final Object locker = new Object(); public void setBlockDestruction(long pos, float amount) { synchronized (locker) { if (amount <= 0 || amount > BlockDestructionManager.MAX_DAMAGE) { destructions.remove(pos); } else { destructions.computeIfAbsent(pos, p -> new Destruction(pos)).set(amount); } } } public void tick(Long2ObjectMap> vanilla) { synchronized (locker) { destructions.long2ObjectEntrySet().removeIf(entry -> entry.getValue().tick()); combined.clear(); if (!destructions.isEmpty()) { destructions.forEach((pos, value) -> { combined.computeIfAbsent(pos.longValue(), p -> Sets.newTreeSet()).add(value.info); }); vanilla.forEach((pos, value) -> { combined.computeIfAbsent(pos.longValue(), p -> Sets.newTreeSet()).addAll(value); }); } } } public Long2ObjectMap> getCombinedDestructions(Long2ObjectMap> vanilla) { return destructions.isEmpty() ? vanilla : combined; } private class Destruction { int age = 50; BlockBreakingInfo info; Destruction(long pos) { this.info = new BlockBreakingInfo(0, BlockPos.fromLong(pos)); } boolean tick() { if (age-- > 0) { return false; } int amount = info.getStage(); if (amount >= 0) { amount--; set(amount); } return amount < 0 || age-- <= 0; } void set(float amount) { this.age = 50; info.setStage(amount >= 0 && amount < BlockDestructionManager.MAX_DAMAGE ? (int)amount : BlockDestructionManager.UNSET_DAMAGE); } } public interface Source { ClientBlockDestructionManager getDestructionManager(); int getTicks(); } }