mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-12-04 18:07:58 +01:00
84 lines
2.7 KiB
Java
84 lines
2.7 KiB
Java
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<Destruction> destructions = new Long2ObjectOpenHashMap<>();
|
|
|
|
private final Long2ObjectMap<SortedSet<BlockBreakingInfo>> 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<SortedSet<BlockBreakingInfo>> 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<SortedSet<BlockBreakingInfo>> getCombinedDestructions(Long2ObjectMap<SortedSet<BlockBreakingInfo>> 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();
|
|
}
|
|
}
|