mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-18 16:02:19 +01:00
cleanup and style
This commit is contained in:
parent
2ad8ffe0ed
commit
b088843aa1
9 changed files with 42 additions and 761 deletions
|
@ -35,14 +35,14 @@ import java.util.Set;
|
||||||
|
|
||||||
public class ConnectivityHandler {
|
public class ConnectivityHandler {
|
||||||
|
|
||||||
public static <T extends BlockEntity & IMultiTileContainer> void formMulti (T be) {
|
public static <T extends BlockEntity & IMultiTileContainer> void formMulti(T be) {
|
||||||
SearchCache<T> cache = new SearchCache<>();
|
SearchCache<T> cache = new SearchCache<>();
|
||||||
List<T> frontier = new ArrayList<>();
|
List<T> frontier = new ArrayList<>();
|
||||||
frontier.add(be);
|
frontier.add(be);
|
||||||
formMulti(be.getType(), be.getLevel(), cache, frontier);
|
formMulti(be.getType(), be.getLevel(), cache, frontier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends BlockEntity & IMultiTileContainer> void formMulti (BlockEntityType<?> type, BlockGetter level, SearchCache<T> cache, List<T> frontier) {
|
private static <T extends BlockEntity & IMultiTileContainer> void formMulti(BlockEntityType<?> type, BlockGetter level, SearchCache<T> cache, List<T> frontier) {
|
||||||
PriorityQueue<Pair<Integer, T>> creationQueue = makeCreationQueue();
|
PriorityQueue<Pair<Integer, T>> creationQueue = makeCreationQueue();
|
||||||
Set<BlockPos> visited = new HashSet<>();
|
Set<BlockPos> visited = new HashSet<>();
|
||||||
Direction.Axis mainAxis = frontier.get(0).getMainConnectionAxis();
|
Direction.Axis mainAxis = frontier.get(0).getMainConnectionAxis();
|
||||||
|
@ -99,7 +99,7 @@ public class ConnectivityHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends BlockEntity & IMultiTileContainer> int tryToFormNewMulti (T be, SearchCache<T> cache, boolean simulate) {
|
private static <T extends BlockEntity & IMultiTileContainer> int tryToFormNewMulti(T be, SearchCache<T> cache, boolean simulate) {
|
||||||
int bestWidth = 1;
|
int bestWidth = 1;
|
||||||
int bestAmount = -1;
|
int bestAmount = -1;
|
||||||
if (!be.isController()) return 0;
|
if (!be.isController()) return 0;
|
||||||
|
@ -129,7 +129,7 @@ public class ConnectivityHandler {
|
||||||
return bestAmount;
|
return bestAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends BlockEntity & IMultiTileContainer> int tryToFormNewMultiOfWidth (T be, int width, SearchCache<T> cache, boolean simulate) {
|
private static <T extends BlockEntity & IMultiTileContainer> int tryToFormNewMultiOfWidth(T be, int width, SearchCache<T> cache, boolean simulate) {
|
||||||
int amount = 0;
|
int amount = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
BlockEntityType<?> type = be.getType();
|
BlockEntityType<?> type = be.getType();
|
||||||
|
@ -236,12 +236,12 @@ public class ConnectivityHandler {
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends BlockEntity & IMultiTileContainer> void splitMulti (T be) {
|
public static <T extends BlockEntity & IMultiTileContainer> void splitMulti(T be) {
|
||||||
splitMultiAndInvalidate(be, null, false);
|
splitMultiAndInvalidate(be, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryReconnect helps whenever only a few tanks have been removed
|
// tryReconnect helps whenever only a few tanks have been removed
|
||||||
private static <T extends BlockEntity & IMultiTileContainer> void splitMultiAndInvalidate (T be, @Nullable SearchCache<T> cache, boolean tryReconnect) {
|
private static <T extends BlockEntity & IMultiTileContainer> void splitMultiAndInvalidate(T be, @Nullable SearchCache<T> cache, boolean tryReconnect) {
|
||||||
Level level = be.getLevel();
|
Level level = be.getLevel();
|
||||||
if (level == null) return;
|
if (level == null) return;
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ public class ConnectivityHandler {
|
||||||
if (!partAt.getController().equals(origin)) continue;
|
if (!partAt.getController().equals(origin)) continue;
|
||||||
|
|
||||||
T controllerBE = partAt.getControllerTE();
|
T controllerBE = partAt.getControllerTE();
|
||||||
partAt.setExtraData ( (controllerBE == null ? null : controllerBE.getExtraData()));
|
partAt.setExtraData((controllerBE == null ? null : controllerBE.getExtraData()));
|
||||||
partAt.removeController(true);
|
partAt.removeController(true);
|
||||||
|
|
||||||
if (!toDistribute.isEmpty() && partAt != be) {
|
if (!toDistribute.isEmpty() && partAt != be) {
|
||||||
|
@ -317,19 +317,19 @@ public class ConnectivityHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends BlockEntity & IMultiTileContainer> PriorityQueue<Pair<Integer, T>> makeCreationQueue () {
|
private static <T extends BlockEntity & IMultiTileContainer> PriorityQueue<Pair<Integer, T>> makeCreationQueue() {
|
||||||
return new PriorityQueue<>((one, two) -> two.getKey() - one.getKey());
|
return new PriorityQueue<>((one, two) -> two.getKey() - one.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends BlockEntity & IMultiTileContainer> T partAt (BlockEntityType<?> type, BlockGetter level, BlockPos pos) {
|
public static <T extends BlockEntity & IMultiTileContainer> T partAt(BlockEntityType<?> type, BlockGetter level, BlockPos pos) {
|
||||||
BlockEntity be = level.getBlockEntity(pos);
|
BlockEntity be = level.getBlockEntity(pos);
|
||||||
if (be != null && be.getType() == type) return checked(be);
|
if (be != null && be.getType() == type) return checked(be);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends BlockEntity & IMultiTileContainer> boolean isConnected (BlockGetter level, BlockPos pos, BlockPos other) {
|
public static <T extends BlockEntity & IMultiTileContainer> boolean isConnected(BlockGetter level, BlockPos pos, BlockPos other) {
|
||||||
T one = checked(level.getBlockEntity(pos));
|
T one = checked(level.getBlockEntity(pos));
|
||||||
T two = checked(level.getBlockEntity(other));
|
T two = checked(level.getBlockEntity(other));
|
||||||
if (one == null || two == null) return false;
|
if (one == null || two == null) return false;
|
||||||
|
@ -338,7 +338,7 @@ public class ConnectivityHandler {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static <T extends BlockEntity & IMultiTileContainer> T checked (BlockEntity be) {
|
private static <T extends BlockEntity & IMultiTileContainer> T checked(BlockEntity be) {
|
||||||
if (be instanceof IMultiTileContainer) return (T)be;
|
if (be instanceof IMultiTileContainer) return (T)be;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -346,15 +346,15 @@ public class ConnectivityHandler {
|
||||||
private static class SearchCache<T extends BlockEntity & IMultiTileContainer> {
|
private static class SearchCache<T extends BlockEntity & IMultiTileContainer> {
|
||||||
Map<BlockPos, Optional<T>> controllerMap;
|
Map<BlockPos, Optional<T>> controllerMap;
|
||||||
|
|
||||||
public SearchCache () { controllerMap = new HashMap<>(); }
|
public SearchCache() { controllerMap = new HashMap<>(); }
|
||||||
|
|
||||||
void put (BlockPos pos, T target) { controllerMap.put(pos, Optional.of(target)); }
|
void put(BlockPos pos, T target) { controllerMap.put(pos, Optional.of(target)); }
|
||||||
|
|
||||||
void putEmpty (BlockPos pos) { controllerMap.put(pos, Optional.empty()); }
|
void putEmpty(BlockPos pos) { controllerMap.put(pos, Optional.empty()); }
|
||||||
|
|
||||||
boolean hasVisited (BlockPos pos) { return controllerMap.containsKey(pos); }
|
boolean hasVisited(BlockPos pos) { return controllerMap.containsKey(pos); }
|
||||||
|
|
||||||
Optional<T> getOrCache (BlockEntityType<?> type, BlockGetter level, BlockPos pos) {
|
Optional<T> getOrCache(BlockEntityType<?> type, BlockGetter level, BlockPos pos) {
|
||||||
if (hasVisited(pos)) return controllerMap.get(pos);
|
if (hasVisited(pos)) return controllerMap.get(pos);
|
||||||
|
|
||||||
T partAt = partAt(type, level, pos);
|
T partAt = partAt(type, level, pos);
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) {
|
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) {
|
||||||
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(getTileEntityType(), world, pos); //FluidTankConnectivityHandler.anyTankAt(world, pos);
|
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(getTileEntityType(), world, pos);
|
||||||
if (tankAt == null)
|
if (tankAt == null)
|
||||||
return 0;
|
return 0;
|
||||||
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
||||||
|
@ -121,7 +121,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
|
||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
|
|
||||||
FluidExchange exchange = null;
|
FluidExchange exchange = null;
|
||||||
FluidTankTileEntity te = ConnectivityHandler.partAt(getTileEntityType(), world, pos); //FluidTankConnectivityHandler.anyTankAt(world, pos);
|
FluidTankTileEntity te = ConnectivityHandler.partAt(getTileEntityType(), world, pos);
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return InteractionResult.FAIL;
|
return InteractionResult.FAIL;
|
||||||
|
|
||||||
|
@ -232,7 +232,6 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
|
||||||
return;
|
return;
|
||||||
FluidTankTileEntity tankTE = (FluidTankTileEntity) te;
|
FluidTankTileEntity tankTE = (FluidTankTileEntity) te;
|
||||||
world.removeBlockEntity(pos);
|
world.removeBlockEntity(pos);
|
||||||
//FluidTankConnectivityHandler.splitTank(tankTE);
|
|
||||||
ConnectivityHandler.splitMulti(tankTE);
|
ConnectivityHandler.splitMulti(tankTE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,381 +0,0 @@
|
||||||
package com.simibubi.create.content.contraptions.fluids.tank;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.PriorityQueue;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank;
|
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.Direction.Axis;
|
|
||||||
import net.minecraft.core.Direction.AxisDirection;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
|
||||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
|
||||||
|
|
||||||
public class FluidTankConnectivityHandler {
|
|
||||||
|
|
||||||
public static void formTanks(FluidTankTileEntity te) {
|
|
||||||
TankSearchCache cache = new TankSearchCache();
|
|
||||||
List<FluidTankTileEntity> frontier = new ArrayList<>();
|
|
||||||
frontier.add(te);
|
|
||||||
formTanks(te.getType(), te.getLevel(), cache, frontier);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void formTanks(BlockEntityType<?> type, BlockGetter world, TankSearchCache cache,
|
|
||||||
List<FluidTankTileEntity> frontier) {
|
|
||||||
PriorityQueue<Pair<Integer, FluidTankTileEntity>> creationQueue = makeCreationQueue();
|
|
||||||
Set<BlockPos> visited = new HashSet<>();
|
|
||||||
|
|
||||||
int minX = Integer.MAX_VALUE;
|
|
||||||
int minZ = Integer.MAX_VALUE;
|
|
||||||
for (FluidTankTileEntity fluidTankTileEntity : frontier) {
|
|
||||||
BlockPos pos = fluidTankTileEntity.getBlockPos();
|
|
||||||
minX = Math.min(pos.getX(), minX);
|
|
||||||
minZ = Math.min(pos.getZ(), minZ);
|
|
||||||
}
|
|
||||||
minX -= FluidTankTileEntity.getMaxSize();
|
|
||||||
minZ -= FluidTankTileEntity.getMaxSize();
|
|
||||||
|
|
||||||
while (!frontier.isEmpty()) {
|
|
||||||
FluidTankTileEntity tank = frontier.remove(0);
|
|
||||||
BlockPos tankPos = tank.getBlockPos();
|
|
||||||
if (visited.contains(tankPos))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
visited.add(tankPos);
|
|
||||||
|
|
||||||
int amount = tryToFormNewTank(tank, cache, true);
|
|
||||||
if (amount > 1)
|
|
||||||
creationQueue.add(Pair.of(amount, tank));
|
|
||||||
|
|
||||||
for (Axis axis : Iterate.axes) {
|
|
||||||
Direction d = Direction.get(AxisDirection.NEGATIVE, axis);
|
|
||||||
BlockPos next = tankPos.relative(d);
|
|
||||||
|
|
||||||
if (next.getX() <= minX || next.getZ() <= minZ)
|
|
||||||
continue;
|
|
||||||
if (visited.contains(next))
|
|
||||||
continue;
|
|
||||||
FluidTankTileEntity nextTank = tankAt(type, world, next);
|
|
||||||
if (nextTank == null)
|
|
||||||
continue;
|
|
||||||
if (nextTank.isRemoved())
|
|
||||||
continue;
|
|
||||||
frontier.add(nextTank);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.clear();
|
|
||||||
|
|
||||||
while (!creationQueue.isEmpty()) {
|
|
||||||
Pair<Integer, FluidTankTileEntity> next = creationQueue.poll();
|
|
||||||
FluidTankTileEntity toCreate = next.getValue();
|
|
||||||
if (visited.contains(toCreate.getBlockPos()))
|
|
||||||
continue;
|
|
||||||
visited.add(toCreate.getBlockPos());
|
|
||||||
tryToFormNewTank(toCreate, cache, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void splitTank(FluidTankTileEntity te) {
|
|
||||||
splitTankAndInvalidate(te, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int tryToFormNewTank(FluidTankTileEntity te, TankSearchCache cache, boolean simulate) {
|
|
||||||
int bestWidth = 1;
|
|
||||||
int bestAmount = -1;
|
|
||||||
|
|
||||||
if (!te.isController())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (int w = 1; w <= FluidTankTileEntity.getMaxSize(); w++) {
|
|
||||||
int amount = tryToFormNewTankOfWidth(te, w, cache, true);
|
|
||||||
if (amount < bestAmount)
|
|
||||||
continue;
|
|
||||||
bestWidth = w;
|
|
||||||
bestAmount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!simulate) {
|
|
||||||
if (te.width == bestWidth && te.width * te.width * te.height == bestAmount)
|
|
||||||
return bestAmount;
|
|
||||||
|
|
||||||
splitTankAndInvalidate(te, cache, false);
|
|
||||||
te.applyFluidTankSize(bestAmount);
|
|
||||||
tryToFormNewTankOfWidth(te, bestWidth, cache, simulate);
|
|
||||||
te.updateConnectivity = false;
|
|
||||||
te.width = bestWidth;
|
|
||||||
te.height = bestAmount / bestWidth / bestWidth;
|
|
||||||
|
|
||||||
BlockState state = te.getBlockState();
|
|
||||||
if (FluidTankBlock.isTank(state)) {
|
|
||||||
state = state.setValue(FluidTankBlock.BOTTOM, true);
|
|
||||||
state = state.setValue(FluidTankBlock.TOP, te.height == 1);
|
|
||||||
te.getLevel()
|
|
||||||
.setBlock(te.getBlockPos(), state, 22);
|
|
||||||
}
|
|
||||||
|
|
||||||
te.setWindows(te.window);
|
|
||||||
te.onFluidStackChanged(te.tankInventory.getFluid());
|
|
||||||
te.setChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
return bestAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int tryToFormNewTankOfWidth(FluidTankTileEntity te, int width, TankSearchCache cache,
|
|
||||||
boolean simulate) {
|
|
||||||
int amount = 0;
|
|
||||||
int height = 0;
|
|
||||||
BlockEntityType<?> type = te.getType();
|
|
||||||
Level world = te.getLevel();
|
|
||||||
BlockPos origin = te.getBlockPos();
|
|
||||||
LazyOptional<IFluidHandler> capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY);
|
|
||||||
FluidTank teTank = (FluidTank) capability.orElse(null);
|
|
||||||
FluidStack fluid = capability.map(ifh -> ifh.getFluidInTank(0))
|
|
||||||
.orElse(FluidStack.EMPTY);
|
|
||||||
|
|
||||||
Search:
|
|
||||||
|
|
||||||
for (int yOffset = 0; yOffset < FluidTankTileEntity.getMaxHeight(); yOffset++) {
|
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
|
||||||
|
|
||||||
BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
|
|
||||||
Optional<FluidTankTileEntity> tank = cache.getOrCache(type, world, pos);
|
|
||||||
if (!tank.isPresent())
|
|
||||||
break Search;
|
|
||||||
|
|
||||||
FluidTankTileEntity controller = tank.get();
|
|
||||||
int otherWidth = controller.width;
|
|
||||||
if (otherWidth > width)
|
|
||||||
break Search;
|
|
||||||
|
|
||||||
BlockPos controllerPos = controller.getBlockPos();
|
|
||||||
if (!controllerPos.equals(origin)) {
|
|
||||||
if (controllerPos.getX() < origin.getX())
|
|
||||||
break Search;
|
|
||||||
if (controllerPos.getZ() < origin.getZ())
|
|
||||||
break Search;
|
|
||||||
if (controllerPos.getX() + otherWidth > origin.getX() + width)
|
|
||||||
break Search;
|
|
||||||
if (controllerPos.getZ() + otherWidth > origin.getZ() + width)
|
|
||||||
break Search;
|
|
||||||
}
|
|
||||||
|
|
||||||
FluidStack otherFluid = controller.getTankInventory()
|
|
||||||
.getFluid();
|
|
||||||
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
|
|
||||||
break Search;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
amount += width * width;
|
|
||||||
height++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simulate)
|
|
||||||
return amount;
|
|
||||||
|
|
||||||
boolean opaque = false;
|
|
||||||
|
|
||||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
|
||||||
BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
|
|
||||||
FluidTankTileEntity tank = tankAt(type, world, pos);
|
|
||||||
if (tank == te)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
opaque |= !tank.window;
|
|
||||||
FluidTank tankTank = tank.tankInventory;
|
|
||||||
FluidStack fluidInTank = tankTank.getFluid();
|
|
||||||
if (!fluidInTank.isEmpty()) {
|
|
||||||
if (teTank.isEmpty() && teTank instanceof CreativeSmartFluidTank)
|
|
||||||
((CreativeSmartFluidTank) teTank).setContainedFluid(fluidInTank);
|
|
||||||
teTank.fill(fluidInTank, FluidAction.EXECUTE);
|
|
||||||
}
|
|
||||||
tankTank.setFluid(FluidStack.EMPTY);
|
|
||||||
|
|
||||||
splitTankAndInvalidate(tank, cache, false);
|
|
||||||
tank.setController(origin);
|
|
||||||
tank.updateConnectivity = false;
|
|
||||||
cache.put(pos, te);
|
|
||||||
|
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
if (!FluidTankBlock.isTank(state))
|
|
||||||
continue;
|
|
||||||
state = state.setValue(FluidTankBlock.BOTTOM, yOffset == 0);
|
|
||||||
state = state.setValue(FluidTankBlock.TOP, yOffset == height - 1);
|
|
||||||
world.setBlock(pos, state, 22);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
te.setWindows(!opaque);
|
|
||||||
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void splitTankAndInvalidate(FluidTankTileEntity te, @Nullable TankSearchCache cache,
|
|
||||||
boolean tryReconnect) {
|
|
||||||
// tryReconnect helps whenever only few tanks have been removed
|
|
||||||
|
|
||||||
te = te.getControllerTE();
|
|
||||||
if (te == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int height = te.height;
|
|
||||||
int width = te.width;
|
|
||||||
if (width == 1 && height == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Level world = te.getLevel();
|
|
||||||
BlockPos origin = te.getBlockPos();
|
|
||||||
List<FluidTankTileEntity> frontier = new ArrayList<>();
|
|
||||||
FluidStack toDistribute = te.tankInventory.getFluid()
|
|
||||||
.copy();
|
|
||||||
int maxCapacity = FluidTankTileEntity.getCapacityMultiplier();
|
|
||||||
if (!toDistribute.isEmpty() && !te.isRemoved())
|
|
||||||
toDistribute.shrink(maxCapacity);
|
|
||||||
te.applyFluidTankSize(1);
|
|
||||||
|
|
||||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
|
||||||
|
|
||||||
BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
|
|
||||||
FluidTankTileEntity tankAt = tankAt(te.getType(), world, pos);
|
|
||||||
if (tankAt == null)
|
|
||||||
continue;
|
|
||||||
if (!tankAt.getController()
|
|
||||||
.equals(origin))
|
|
||||||
continue;
|
|
||||||
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
|
||||||
tankAt.window = controllerTE == null || controllerTE.window;
|
|
||||||
tankAt.removeController(true);
|
|
||||||
|
|
||||||
if (!toDistribute.isEmpty() && tankAt != te) {
|
|
||||||
FluidStack copy = toDistribute.copy();
|
|
||||||
FluidTank tankInventory = tankAt.tankInventory;
|
|
||||||
if (tankInventory.isEmpty() && tankInventory instanceof CreativeSmartFluidTank)
|
|
||||||
((CreativeSmartFluidTank) tankInventory).setContainedFluid(toDistribute);
|
|
||||||
else {
|
|
||||||
int split = Math.min(maxCapacity, toDistribute.getAmount());
|
|
||||||
copy.setAmount(split);
|
|
||||||
toDistribute.shrink(split);
|
|
||||||
tankInventory.fill(copy, FluidAction.EXECUTE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tryReconnect) {
|
|
||||||
frontier.add(tankAt);
|
|
||||||
tankAt.updateConnectivity = false;
|
|
||||||
}
|
|
||||||
if (cache != null)
|
|
||||||
cache.put(pos, tankAt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
te.fluidCapability.invalidate();
|
|
||||||
if (tryReconnect)
|
|
||||||
formTanks(te.getType(), world, cache == null ? new TankSearchCache() : cache, frontier);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PriorityQueue<Pair<Integer, FluidTankTileEntity>> makeCreationQueue() {
|
|
||||||
return new PriorityQueue<>(new Comparator<Pair<Integer, FluidTankTileEntity>>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Pair<Integer, FluidTankTileEntity> o1, Pair<Integer, FluidTankTileEntity> o2) {
|
|
||||||
return o2.getKey() - o1.getKey();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static FluidTankTileEntity tankAt(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
|
||||||
BlockEntity te = world.getBlockEntity(pos);
|
|
||||||
if (te instanceof FluidTankTileEntity && te.getType() == type)
|
|
||||||
return (FluidTankTileEntity) te;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static FluidTankTileEntity anyTankAt(BlockGetter world, BlockPos pos) {
|
|
||||||
BlockEntity te = world.getBlockEntity(pos);
|
|
||||||
if (te instanceof FluidTankTileEntity)
|
|
||||||
return (FluidTankTileEntity) te;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TankSearchCache {
|
|
||||||
Map<BlockPos, Optional<FluidTankTileEntity>> controllerMap;
|
|
||||||
|
|
||||||
public TankSearchCache() {
|
|
||||||
controllerMap = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void put(BlockPos pos, FluidTankTileEntity target) {
|
|
||||||
controllerMap.put(pos, Optional.of(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
void putEmpty(BlockPos pos) {
|
|
||||||
controllerMap.put(pos, Optional.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasVisited(BlockPos pos) {
|
|
||||||
return controllerMap.containsKey(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<FluidTankTileEntity> getOrCache(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
|
||||||
if (hasVisited(pos))
|
|
||||||
return controllerMap.get(pos);
|
|
||||||
FluidTankTileEntity tankAt = tankAt(type, world, pos);
|
|
||||||
if (tankAt == null) {
|
|
||||||
putEmpty(pos);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
FluidTankTileEntity controller = tankAt.getControllerTE();
|
|
||||||
if (controller == null) {
|
|
||||||
putEmpty(pos);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
put(pos, controller);
|
|
||||||
return Optional.of(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isConnected(BlockGetter world, BlockPos tankPos, BlockPos otherTankPos) {
|
|
||||||
BlockEntity te1 = world.getBlockEntity(tankPos);
|
|
||||||
BlockEntity te2 = world.getBlockEntity(otherTankPos);
|
|
||||||
if (!(te1 instanceof FluidTankTileEntity) || !(te2 instanceof FluidTankTileEntity))
|
|
||||||
return false;
|
|
||||||
return ((FluidTankTileEntity) te1).getController()
|
|
||||||
.equals(((FluidTankTileEntity) te2).getController());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -79,7 +79,6 @@ public class FluidTankItem extends BlockItem {
|
||||||
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(
|
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(
|
||||||
creative ? AllTileEntities.CREATIVE_FLUID_TANK.get() : AllTileEntities.FLUID_TANK.get(), world, placedOnPos
|
creative ? AllTileEntities.CREATIVE_FLUID_TANK.get() : AllTileEntities.FLUID_TANK.get(), world, placedOnPos
|
||||||
);
|
);
|
||||||
//FluidTankConnectivityHandler.anyTankAt(world, placedOnPos);
|
|
||||||
if (tankAt == null)
|
if (tankAt == null)
|
||||||
return;
|
return;
|
||||||
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.List;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
||||||
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock.Shape;
|
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock.Shape;
|
||||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||||
|
@ -81,7 +80,6 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
||||||
return;
|
return;
|
||||||
if (!isController())
|
if (!isController())
|
||||||
return;
|
return;
|
||||||
//FluidTankConnectivityHandler.formTanks(this);
|
|
||||||
ConnectivityHandler.formMulti(this);
|
ConnectivityHandler.formMulti(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +146,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||||
BlockPos pos = this.worldPosition.offset(xOffset, yOffset, zOffset);
|
BlockPos pos = this.worldPosition.offset(xOffset, yOffset, zOffset);
|
||||||
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(getType(), level, pos); //FluidTankConnectivityHandler.anyTankAt(level, pos);
|
FluidTankTileEntity tankAt = ConnectivityHandler.partAt(getType(), level, pos);
|
||||||
if (tankAt == null)
|
if (tankAt == null)
|
||||||
continue;
|
continue;
|
||||||
level.updateNeighbourForOutputSignal(pos, tankAt.getBlockState()
|
level.updateNeighbourForOutputSignal(pos, tankAt.getBlockState()
|
||||||
|
@ -469,7 +467,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
||||||
public void preventConnectivityUpdate() { updateConnectivity = false; }
|
public void preventConnectivityUpdate() { updateConnectivity = false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyMultiUpdated () {
|
public void notifyMultiUpdated() {
|
||||||
BlockState state = this.getBlockState();
|
BlockState state = this.getBlockState();
|
||||||
if (FluidTankBlock.isTank(state)) { // safety
|
if (FluidTankBlock.isTank(state)) { // safety
|
||||||
state = state.setValue(FluidTankBlock.BOTTOM, getController().getY() == getBlockPos().getY());
|
state = state.setValue(FluidTankBlock.BOTTOM, getController().getY() == getBlockPos().getY());
|
||||||
|
@ -482,16 +480,16 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setExtraData (@Nullable Object data) {
|
public void setExtraData(@Nullable Object data) {
|
||||||
if (data instanceof Boolean) window = (boolean)data;
|
if (data instanceof Boolean) window = (boolean)data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Object getExtraData () { return window; }
|
public Object getExtraData() { return window; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object modifyExtraData (Object data) {
|
public Object modifyExtraData(Object data) {
|
||||||
if (data instanceof Boolean windows) {
|
if (data instanceof Boolean windows) {
|
||||||
windows |= window;
|
windows |= window;
|
||||||
return windows;
|
return windows;
|
||||||
|
@ -503,44 +501,44 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
|
||||||
public Direction.Axis getMainConnectionAxis() { return Direction.Axis.Y; }
|
public Direction.Axis getMainConnectionAxis() { return Direction.Axis.Y; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxLength (Direction.Axis longAxis, int width) {
|
public int getMaxLength(Direction.Axis longAxis, int width) {
|
||||||
if (longAxis == Direction.Axis.Y) return getMaxHeight();
|
if (longAxis == Direction.Axis.Y) return getMaxHeight();
|
||||||
return getMaxWidth();
|
return getMaxWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxWidth () { return MAX_SIZE; }
|
public int getMaxWidth() { return MAX_SIZE; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight () { return height; }
|
public int getHeight() { return height; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHeight (int height) { this.height = height; }
|
public void setHeight(int height) { this.height = height; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWidth () { return width; }
|
public int getWidth() { return width; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWidth (int width) { this.width = width; }
|
public void setWidth(int width) { this.width = width; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasFluid () { return true; }
|
public boolean hasFluid() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTankSize (int tank) { return getCapacityMultiplier(); }
|
public int getTankSize(int tank) { return getCapacityMultiplier(); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTankSize (int tank, int blocks) {
|
public void setTankSize(int tank, int blocks) {
|
||||||
applyFluidTankSize(blocks);
|
applyFluidTankSize(blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IFluidTank getTank (int tank) {
|
public IFluidTank getTank(int tank) {
|
||||||
return tankInventory;
|
return tankInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FluidStack getFluid (int tank) {
|
public FluidStack getFluid(int tank) {
|
||||||
return tankInventory.getFluid().copy();
|
return tankInventory.getFluid().copy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,6 @@ public class ItemVaultBlock extends Block implements IWrenchable, ITE<ItemVaultT
|
||||||
if (te instanceof ItemVaultTileEntity) {
|
if (te instanceof ItemVaultTileEntity) {
|
||||||
ItemVaultTileEntity vault = (ItemVaultTileEntity) te;
|
ItemVaultTileEntity vault = (ItemVaultTileEntity) te;
|
||||||
ConnectivityHandler.splitMulti(vault);
|
ConnectivityHandler.splitMulti(vault);
|
||||||
//ItemVaultConnectivityHandler.splitVault(vault);
|
|
||||||
vault.removeController(true);
|
vault.removeController(true);
|
||||||
}
|
}
|
||||||
state = state.setValue(LARGE, false);
|
state = state.setValue(LARGE, false);
|
||||||
|
@ -105,7 +104,6 @@ public class ItemVaultBlock extends Block implements IWrenchable, ITE<ItemVaultT
|
||||||
ItemVaultTileEntity vaultTE = (ItemVaultTileEntity) te;
|
ItemVaultTileEntity vaultTE = (ItemVaultTileEntity) te;
|
||||||
ItemHelper.dropContents(world, pos, vaultTE.inventory);
|
ItemHelper.dropContents(world, pos, vaultTE.inventory);
|
||||||
world.removeBlockEntity(pos);
|
world.removeBlockEntity(pos);
|
||||||
//ItemVaultConnectivityHandler.splitVault(tankTE);
|
|
||||||
ConnectivityHandler.splitMulti(vaultTE);
|
ConnectivityHandler.splitMulti(vaultTE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,329 +0,0 @@
|
||||||
package com.simibubi.create.content.logistics.block.vault;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.PriorityQueue;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.Direction.Axis;
|
|
||||||
import net.minecraft.core.Direction.AxisDirection;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
public class ItemVaultConnectivityHandler {
|
|
||||||
|
|
||||||
public static void formVaults(ItemVaultTileEntity te) {
|
|
||||||
VaultSearchCache cache = new VaultSearchCache();
|
|
||||||
List<ItemVaultTileEntity> frontier = new ArrayList<>();
|
|
||||||
frontier.add(te);
|
|
||||||
formVaults(te.getType(), te.getLevel(), cache, frontier);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void formVaults(BlockEntityType<?> type, BlockGetter world, VaultSearchCache cache,
|
|
||||||
List<ItemVaultTileEntity> frontier) {
|
|
||||||
PriorityQueue<Pair<Integer, ItemVaultTileEntity>> creationQueue = makeCreationQueue();
|
|
||||||
Set<BlockPos> visited = new HashSet<>();
|
|
||||||
|
|
||||||
int minY = Integer.MAX_VALUE;
|
|
||||||
for (ItemVaultTileEntity fluidTankTileEntity : frontier) {
|
|
||||||
BlockPos pos = fluidTankTileEntity.getBlockPos();
|
|
||||||
minY = Math.min(pos.getY(), minY);
|
|
||||||
}
|
|
||||||
|
|
||||||
minY -= 3;
|
|
||||||
|
|
||||||
while (!frontier.isEmpty()) {
|
|
||||||
ItemVaultTileEntity tank = frontier.remove(0);
|
|
||||||
BlockPos tankPos = tank.getBlockPos();
|
|
||||||
if (visited.contains(tankPos))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
visited.add(tankPos);
|
|
||||||
|
|
||||||
int amount = tryToFormNewVault(tank, cache, true);
|
|
||||||
if (amount > 1)
|
|
||||||
creationQueue.add(Pair.of(amount, tank));
|
|
||||||
|
|
||||||
for (Axis axis : Iterate.axes) {
|
|
||||||
Direction d = Direction.fromAxisAndDirection(axis, AxisDirection.NEGATIVE);
|
|
||||||
BlockPos next = tankPos.relative(d);
|
|
||||||
|
|
||||||
if (next.getY() <= minY)
|
|
||||||
continue;
|
|
||||||
if (visited.contains(next))
|
|
||||||
continue;
|
|
||||||
ItemVaultTileEntity nextTank = vaultAt(type, world, next);
|
|
||||||
if (nextTank == null)
|
|
||||||
continue;
|
|
||||||
if (nextTank.isRemoved())
|
|
||||||
continue;
|
|
||||||
frontier.add(nextTank);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visited.clear();
|
|
||||||
|
|
||||||
while (!creationQueue.isEmpty()) {
|
|
||||||
Pair<Integer, ItemVaultTileEntity> next = creationQueue.poll();
|
|
||||||
ItemVaultTileEntity toCreate = next.getValue();
|
|
||||||
if (visited.contains(toCreate.getBlockPos()))
|
|
||||||
continue;
|
|
||||||
visited.add(toCreate.getBlockPos());
|
|
||||||
tryToFormNewVault(toCreate, cache, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void splitVault(ItemVaultTileEntity te) {
|
|
||||||
splitVaultAndInvalidate(te, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int tryToFormNewVault(ItemVaultTileEntity te, VaultSearchCache cache, boolean simulate) {
|
|
||||||
int bestWidth = 1;
|
|
||||||
int bestAmount = -1;
|
|
||||||
|
|
||||||
if (!te.isController())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (int w = 1; w <= 3; w++) {
|
|
||||||
int amount = tryToFormNewVaultOfRadius(te, w, cache, true);
|
|
||||||
if (amount < bestAmount)
|
|
||||||
continue;
|
|
||||||
bestWidth = w;
|
|
||||||
bestAmount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!simulate) {
|
|
||||||
if (te.radius == bestWidth && te.radius * te.radius * te.length == bestAmount)
|
|
||||||
return bestAmount;
|
|
||||||
|
|
||||||
splitVaultAndInvalidate(te, cache, false);
|
|
||||||
tryToFormNewVaultOfRadius(te, bestWidth, cache, simulate);
|
|
||||||
te.updateConnectivity = false;
|
|
||||||
te.radius = bestWidth;
|
|
||||||
te.length = bestAmount / bestWidth / bestWidth;
|
|
||||||
|
|
||||||
BlockState state = te.getBlockState();
|
|
||||||
if (ItemVaultBlock.isVault(state))
|
|
||||||
te.getLevel()
|
|
||||||
.setBlock(te.getBlockPos(), state.setValue(ItemVaultBlock.LARGE, te.radius > 2), 22);
|
|
||||||
|
|
||||||
te.itemCapability.invalidate();
|
|
||||||
te.setChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
return bestAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int tryToFormNewVaultOfRadius(ItemVaultTileEntity te, int width, VaultSearchCache cache,
|
|
||||||
boolean simulate) {
|
|
||||||
int amount = 0;
|
|
||||||
int height = 0;
|
|
||||||
BlockEntityType<?> type = te.getType();
|
|
||||||
Level world = te.getLevel();
|
|
||||||
BlockPos origin = te.getBlockPos();
|
|
||||||
boolean alongZ = ItemVaultBlock.getVaultBlockAxis(te.getBlockState()) == Axis.Z;
|
|
||||||
|
|
||||||
Search:
|
|
||||||
|
|
||||||
for (int yOffset = 0; yOffset < ItemVaultTileEntity.getMaxLength(width); yOffset++) {
|
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
|
||||||
|
|
||||||
BlockPos pos =
|
|
||||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
|
||||||
Optional<ItemVaultTileEntity> tank = cache.getOrCache(type, world, pos);
|
|
||||||
if (!tank.isPresent())
|
|
||||||
break Search;
|
|
||||||
|
|
||||||
ItemVaultTileEntity controller = tank.get();
|
|
||||||
int otherWidth = controller.radius;
|
|
||||||
if (otherWidth > width)
|
|
||||||
break Search;
|
|
||||||
if (otherWidth == width && controller.length == ItemVaultTileEntity.getMaxLength(width))
|
|
||||||
break Search;
|
|
||||||
if ((ItemVaultBlock.getVaultBlockAxis(controller.getBlockState()) == Axis.Z) != alongZ)
|
|
||||||
break Search;
|
|
||||||
|
|
||||||
BlockPos controllerPos = controller.getBlockPos();
|
|
||||||
if (!controllerPos.equals(origin)) {
|
|
||||||
if (alongZ && controllerPos.getX() < origin.getX())
|
|
||||||
break Search;
|
|
||||||
if (controllerPos.getY() < origin.getY())
|
|
||||||
break Search;
|
|
||||||
if (!alongZ && controllerPos.getZ() < origin.getZ())
|
|
||||||
break Search;
|
|
||||||
if (alongZ && controllerPos.getX() + otherWidth > origin.getX() + width)
|
|
||||||
break Search;
|
|
||||||
if (controllerPos.getY() + otherWidth > origin.getY() + width)
|
|
||||||
break Search;
|
|
||||||
if (!alongZ && controllerPos.getZ() + otherWidth > origin.getZ() + width)
|
|
||||||
break Search;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
amount += width * width;
|
|
||||||
height++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simulate)
|
|
||||||
return amount;
|
|
||||||
|
|
||||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
|
||||||
BlockPos pos =
|
|
||||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
|
||||||
ItemVaultTileEntity tank = vaultAt(type, world, pos);
|
|
||||||
if (tank == te)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
splitVaultAndInvalidate(tank, cache, false);
|
|
||||||
tank.setController(origin);
|
|
||||||
tank.updateConnectivity = false;
|
|
||||||
cache.put(pos, te);
|
|
||||||
|
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
if (!ItemVaultBlock.isVault(state))
|
|
||||||
continue;
|
|
||||||
state = state.setValue(ItemVaultBlock.LARGE, width > 2);
|
|
||||||
world.setBlock(pos, state, 22);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void splitVaultAndInvalidate(ItemVaultTileEntity te, @Nullable VaultSearchCache cache,
|
|
||||||
boolean tryReconnect) {
|
|
||||||
// tryReconnect helps whenever only few tanks have been removed
|
|
||||||
|
|
||||||
te = te.getControllerTE();
|
|
||||||
if (te == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int height = te.length;
|
|
||||||
int width = te.radius;
|
|
||||||
BlockState state = te.getBlockState();
|
|
||||||
boolean alongZ = ItemVaultBlock.getVaultBlockAxis(state) == Axis.Z;
|
|
||||||
if (width == 1 && height == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Level world = te.getLevel();
|
|
||||||
BlockPos origin = te.getBlockPos();
|
|
||||||
List<ItemVaultTileEntity> frontier = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
|
||||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
|
||||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
|
||||||
|
|
||||||
BlockPos pos =
|
|
||||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
|
||||||
ItemVaultTileEntity tankAt = vaultAt(te.getType(), world, pos);
|
|
||||||
if (tankAt == null)
|
|
||||||
continue;
|
|
||||||
if (!tankAt.getController()
|
|
||||||
.equals(origin))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
tankAt.removeController(true);
|
|
||||||
|
|
||||||
if (tryReconnect) {
|
|
||||||
frontier.add(tankAt);
|
|
||||||
tankAt.updateConnectivity = false;
|
|
||||||
}
|
|
||||||
if (cache != null)
|
|
||||||
cache.put(pos, tankAt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
te.itemCapability.invalidate();
|
|
||||||
if (tryReconnect)
|
|
||||||
formVaults(te.getType(), world, cache == null ? new VaultSearchCache() : cache, frontier);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PriorityQueue<Pair<Integer, ItemVaultTileEntity>> makeCreationQueue() {
|
|
||||||
return new PriorityQueue<>(new Comparator<Pair<Integer, ItemVaultTileEntity>>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Pair<Integer, ItemVaultTileEntity> o1, Pair<Integer, ItemVaultTileEntity> o2) {
|
|
||||||
return o2.getKey() - o1.getKey();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static ItemVaultTileEntity vaultAt(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
|
||||||
BlockEntity te = world.getBlockEntity(pos);
|
|
||||||
if (te instanceof ItemVaultTileEntity && te.getType() == type)
|
|
||||||
return (ItemVaultTileEntity) te;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class VaultSearchCache {
|
|
||||||
Map<BlockPos, Optional<ItemVaultTileEntity>> controllerMap;
|
|
||||||
|
|
||||||
public VaultSearchCache() {
|
|
||||||
controllerMap = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void put(BlockPos pos, ItemVaultTileEntity target) {
|
|
||||||
controllerMap.put(pos, Optional.of(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
void putEmpty(BlockPos pos) {
|
|
||||||
controllerMap.put(pos, Optional.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasVisited(BlockPos pos) {
|
|
||||||
return controllerMap.containsKey(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<ItemVaultTileEntity> getOrCache(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
|
||||||
if (hasVisited(pos))
|
|
||||||
return controllerMap.get(pos);
|
|
||||||
ItemVaultTileEntity tankAt = vaultAt(type, world, pos);
|
|
||||||
if (tankAt == null) {
|
|
||||||
putEmpty(pos);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
ItemVaultTileEntity controller = tankAt.getControllerTE();
|
|
||||||
if (controller == null) {
|
|
||||||
putEmpty(pos);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
put(pos, controller);
|
|
||||||
return Optional.of(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isConnected(BlockGetter world, BlockPos tankPos, BlockPos otherTankPos) {
|
|
||||||
BlockEntity te1 = world.getBlockEntity(tankPos);
|
|
||||||
BlockEntity te2 = world.getBlockEntity(otherTankPos);
|
|
||||||
if (!(te1 instanceof ItemVaultTileEntity) || !(te2 instanceof ItemVaultTileEntity))
|
|
||||||
return false;
|
|
||||||
return ((ItemVaultTileEntity) te1).getController()
|
|
||||||
.equals(((ItemVaultTileEntity) te2).getController());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -66,7 +66,6 @@ public class ItemVaultItem extends BlockItem {
|
||||||
if (!ItemVaultBlock.isVault(placedOnState))
|
if (!ItemVaultBlock.isVault(placedOnState))
|
||||||
return;
|
return;
|
||||||
ItemVaultTileEntity tankAt = ConnectivityHandler.partAt(AllTileEntities.ITEM_VAULT.get(), world, placedOnPos);
|
ItemVaultTileEntity tankAt = ConnectivityHandler.partAt(AllTileEntities.ITEM_VAULT.get(), world, placedOnPos);
|
||||||
//ItemVaultConnectivityHandler.vaultAt(AllTileEntities.ITEM_VAULT.get(), world, placedOnPos);
|
|
||||||
if (tankAt == null)
|
if (tankAt == null)
|
||||||
return;
|
return;
|
||||||
ItemVaultTileEntity controllerTE = tankAt.getControllerTE();
|
ItemVaultTileEntity controllerTE = tankAt.getControllerTE();
|
||||||
|
|
|
@ -63,7 +63,6 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
||||||
return;
|
return;
|
||||||
if (!isController())
|
if (!isController())
|
||||||
return;
|
return;
|
||||||
//ItemVaultConnectivityHandler.formVaults(this);
|
|
||||||
ConnectivityHandler.formMulti(this);
|
ConnectivityHandler.formMulti(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +249,6 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
||||||
BlockPos vaultPos = alongZ ? worldPosition.offset(xOffset, zOffset, yOffset)
|
BlockPos vaultPos = alongZ ? worldPosition.offset(xOffset, zOffset, yOffset)
|
||||||
: worldPosition.offset(yOffset, xOffset, zOffset);
|
: worldPosition.offset(yOffset, xOffset, zOffset);
|
||||||
ItemVaultTileEntity vaultAt =
|
ItemVaultTileEntity vaultAt =
|
||||||
//ItemVaultConnectivityHandler.vaultAt(AllTileEntities.ITEM_VAULT.get(), level, vaultPos);
|
|
||||||
ConnectivityHandler.partAt(AllTileEntities.ITEM_VAULT.get(), level, vaultPos);
|
ConnectivityHandler.partAt(AllTileEntities.ITEM_VAULT.get(), level, vaultPos);
|
||||||
invs[yOffset * radius * radius + xOffset * radius + zOffset] =
|
invs[yOffset * radius * radius + xOffset * radius + zOffset] =
|
||||||
vaultAt != null ? vaultAt.inventory : new ItemStackHandler();
|
vaultAt != null ? vaultAt.inventory : new ItemStackHandler();
|
||||||
|
@ -270,7 +268,7 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
||||||
public void preventConnectivityUpdate() { updateConnectivity = false; }
|
public void preventConnectivityUpdate() { updateConnectivity = false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyMultiUpdated () {
|
public void notifyMultiUpdated() {
|
||||||
BlockState state = this.getBlockState();
|
BlockState state = this.getBlockState();
|
||||||
if (ItemVaultBlock.isVault(state)) { // safety
|
if (ItemVaultBlock.isVault(state)) { // safety
|
||||||
level.setBlock(getBlockPos(), state.setValue(ItemVaultBlock.LARGE, radius > 2), 22);
|
level.setBlock(getBlockPos(), state.setValue(ItemVaultBlock.LARGE, radius > 2), 22);
|
||||||
|
@ -283,28 +281,28 @@ public class ItemVaultTileEntity extends SmartTileEntity implements IMultiTileCo
|
||||||
public Direction.Axis getMainConnectionAxis() { return getMainAxisOf(this); }
|
public Direction.Axis getMainConnectionAxis() { return getMainAxisOf(this); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxLength (Direction.Axis longAxis, int width) {
|
public int getMaxLength(Direction.Axis longAxis, int width) {
|
||||||
if (longAxis == Direction.Axis.Y) return getMaxWidth();
|
if (longAxis == Direction.Axis.Y) return getMaxWidth();
|
||||||
return getMaxLength(width);
|
return getMaxLength(width);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxWidth () {
|
public int getMaxWidth() {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight () { return length; }
|
public int getHeight() { return length; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWidth () { return radius; }
|
public int getWidth() { return radius; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setHeight (int height) { this.length = height; }
|
public void setHeight(int height) { this.length = height; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setWidth (int width) { this.radius = width; }
|
public void setWidth(int width) { this.radius = width; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasItems () { return true; }
|
public boolean hasItems() { return true; }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue