use of com.lowdragmc.multiblocked.api.tile.ComponentTileEntity in project Multiblocked by Low-Drag-MC.
the class BlockPattern method getPreview.
public BlockInfo[][][] getPreview(int[] repetition) {
Map<SimplePredicate, Integer> cacheGlobal = new HashMap<>();
Map<BlockPos, BlockInfo> blocks = new HashMap<>();
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int minZ = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
int maxZ = Integer.MIN_VALUE;
for (int l = 0, x = 0; l < this.fingerLength; l++) {
for (int r = 0; r < repetition[l]; r++) {
// Checking single slice
for (int y = 0; y < this.thumbLength; y++) {
for (int z = 0; z < this.palmLength; z++) {
TraceabilityPredicate predicate = this.blockMatches[l][y][z];
boolean find = false;
BlockInfo[] infos = null;
// check global and previewCount
for (SimplePredicate limit : predicate.limited) {
if (limit.minCount == -1 && limit.previewCount == -1)
continue;
if (cacheGlobal.getOrDefault(limit, 0) < limit.previewCount) {
if (!cacheGlobal.containsKey(limit)) {
cacheGlobal.put(limit, 1);
} else if (cacheGlobal.get(limit) < limit.previewCount) {
cacheGlobal.put(limit, cacheGlobal.get(limit) + 1);
} else {
continue;
}
} else if (limit.minCount > 0) {
if (!cacheGlobal.containsKey(limit)) {
cacheGlobal.put(limit, 1);
} else if (cacheGlobal.get(limit) < limit.minCount) {
cacheGlobal.put(limit, cacheGlobal.get(limit) + 1);
} else {
continue;
}
} else {
continue;
}
infos = limit.candidates == null ? null : limit.candidates.get();
find = true;
break;
}
if (!find) {
// check common with previewCount
for (SimplePredicate common : predicate.common) {
if (common.previewCount > 0) {
if (!cacheGlobal.containsKey(common)) {
cacheGlobal.put(common, 1);
} else if (cacheGlobal.get(common) < common.previewCount) {
cacheGlobal.put(common, cacheGlobal.get(common) + 1);
} else {
continue;
}
} else {
continue;
}
infos = common.candidates == null ? null : common.candidates.get();
find = true;
break;
}
}
if (!find) {
// check without previewCount
for (SimplePredicate common : predicate.common) {
if (common.previewCount == -1) {
infos = common.candidates == null ? null : common.candidates.get();
find = true;
break;
}
}
}
if (!find) {
// check max
for (SimplePredicate limit : predicate.limited) {
if (limit.previewCount != -1) {
continue;
} else if (limit.maxCount != -1) {
if (cacheGlobal.getOrDefault(limit, 0) < limit.maxCount) {
if (!cacheGlobal.containsKey(limit)) {
cacheGlobal.put(limit, 1);
} else {
cacheGlobal.put(limit, cacheGlobal.get(limit) + 1);
}
} else {
continue;
}
}
infos = limit.candidates == null ? null : limit.candidates.get();
break;
}
}
BlockInfo info = infos == null || infos.length == 0 ? BlockInfo.EMPTY : infos[0];
BlockPos pos = setActualRelativeOffset(z, y, x, Direction.NORTH);
blocks.put(pos, info);
minX = Math.min(pos.getX(), minX);
minY = Math.min(pos.getY(), minY);
minZ = Math.min(pos.getZ(), minZ);
maxX = Math.max(pos.getX(), maxX);
maxY = Math.max(pos.getY(), maxY);
maxZ = Math.max(pos.getZ(), maxZ);
}
}
x++;
}
}
BlockInfo[][][] result = (BlockInfo[][][]) Array.newInstance(BlockInfo.class, maxX - minX + 1, maxY - minY + 1, maxZ - minZ + 1);
int finalMinX = minX;
int finalMinY = minY;
int finalMinZ = minZ;
blocks.forEach((pos, info) -> {
TileEntity te = blocks.get(pos).getTileEntity();
resetFacing(pos, info.getBlockState(), null, (p, f) -> {
BlockInfo blockInfo = blocks.get(p.relative(f));
if (blockInfo == null || blockInfo.getBlockState().getBlock() == Blocks.AIR) {
if (te instanceof ComponentTileEntity) {
return ((ComponentTileEntity<?>) te).isValidFrontFacing(f);
}
return true;
}
return false;
}, info::setBlockState);
result[pos.getX() - finalMinX][pos.getY() - finalMinY][pos.getZ() - finalMinZ] = info;
});
return result;
}
use of com.lowdragmc.multiblocked.api.tile.ComponentTileEntity in project Multiblocked by Low-Drag-MC.
the class WorldMixin method afterUpdatingEntities.
@Inject(method = "tickBlockEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;pop()V", ordinal = 1), locals = LocalCapture.CAPTURE_FAILHARD)
private void afterUpdatingEntities(CallbackInfo ci, IProfiler iprofiler) {
iprofiler.popPush("multiblocked_update");
if (!((World) (Object) this).isClientSide) {
List<ComponentTileEntity<?>> isRemoved = null;
MultiblockWorldSavedData mbds = MultiblockWorldSavedData.getOrCreate((World) (Object) this);
for (ComponentTileEntity<?> loading : mbds.getLoadings()) {
if (loading.isRemoved()) {
if (isRemoved == null) {
isRemoved = new ArrayList<>();
}
isRemoved.add(loading);
} else {
loading.update();
}
}
if (isRemoved != null) {
for (ComponentTileEntity<?> inValid : isRemoved) {
mbds.removeLoading(inValid.getBlockPos());
}
}
}
}
use of com.lowdragmc.multiblocked.api.tile.ComponentTileEntity in project Multiblocked by Low-Drag-MC.
the class BlockPattern method autoBuild.
public void autoBuild(PlayerEntity player, MultiblockState worldState) {
World world = player.level;
int minZ = -centerOffset[4];
worldState.clean();
ControllerTileEntity controller = worldState.getController();
BlockPos centerPos = controller.getBlockPos();
Direction facing = controller.getFrontFacing();
Map<SimplePredicate, Integer> cacheGlobal = worldState.globalCount;
Map<BlockPos, Object> blocks = new HashMap<>();
blocks.put(centerPos, controller);
for (int c = 0, z = minZ++, r; c < this.fingerLength; c++) {
for (r = 0; r < aisleRepetitions[c][0]; r++) {
for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) {
for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) {
TraceabilityPredicate predicate = this.blockMatches[c][b][a];
BlockPos pos = setActualRelativeOffset(x, y, z, facing).offset(centerPos.getX(), centerPos.getY(), centerPos.getZ());
worldState.update(pos, predicate);
if (!world.isEmptyBlock(pos)) {
blocks.put(pos, world.getBlockState(pos));
for (SimplePredicate limit : predicate.limited) {
limit.testLimited(worldState);
}
} else {
boolean find = false;
BlockInfo[] infos = new BlockInfo[0];
for (SimplePredicate limit : predicate.limited) {
if (limit.minCount > 0) {
if (!cacheGlobal.containsKey(limit)) {
cacheGlobal.put(limit, 1);
} else if (cacheGlobal.get(limit) < limit.minCount && (limit.maxCount == -1 || cacheGlobal.get(limit) < limit.maxCount)) {
cacheGlobal.put(limit, cacheGlobal.get(limit) + 1);
} else {
continue;
}
} else {
continue;
}
infos = limit.candidates == null ? null : limit.candidates.get();
find = true;
break;
}
if (!find) {
// no limited
for (SimplePredicate limit : predicate.limited) {
if (limit.maxCount != -1 && cacheGlobal.getOrDefault(limit, Integer.MAX_VALUE) == limit.maxCount)
continue;
if (cacheGlobal.containsKey(limit)) {
cacheGlobal.put(limit, cacheGlobal.get(limit) + 1);
} else {
cacheGlobal.put(limit, 1);
}
infos = ArrayUtils.addAll(infos, limit.candidates == null ? null : limit.candidates.get());
}
for (SimplePredicate common : predicate.common) {
infos = ArrayUtils.addAll(infos, common.candidates == null ? null : common.candidates.get());
}
}
List<ItemStack> candidates = new ArrayList<>();
if (infos != null) {
for (BlockInfo info : infos) {
if (info.getBlockState().getBlock() != Blocks.AIR) {
BlockState blockState = info.getBlockState();
if (blockState.getBlock() instanceof BlockComponent && ((BlockComponent) blockState.getBlock()).definition != null) {
if (((BlockComponent) blockState.getBlock()).definition.baseRenderer instanceof CycleBlockStateRenderer) {
CycleBlockStateRenderer renderer = (CycleBlockStateRenderer) ((BlockComponent) blockState.getBlock()).definition.baseRenderer;
for (BlockInfo blockInfo : renderer.blockInfos) {
candidates.add(blockInfo.getItemStackForm());
}
} else {
candidates.add(info.getItemStackForm());
}
} else {
candidates.add(info.getItemStackForm());
}
}
}
}
// check inventory
ItemStack found = null;
if (!player.isCreative()) {
for (ItemStack itemStack : player.inventory.items) {
if (candidates.stream().anyMatch(candidate -> candidate.equals(itemStack, false)) && !itemStack.isEmpty() && itemStack.getItem() instanceof BlockItem) {
found = itemStack.copy();
itemStack.setCount(itemStack.getCount() - 1);
break;
}
}
} else {
for (ItemStack candidate : candidates) {
found = candidate.copy();
if (!found.isEmpty() && found.getItem() instanceof BlockItem) {
break;
}
found = null;
}
}
if (found == null)
continue;
BlockItem itemBlock = (BlockItem) found.getItem();
BlockItemUseContext context = new BlockItemUseContext(world, player, Hand.MAIN_HAND, found, BlockRayTraceResult.miss(player.getEyePosition(0), Direction.UP, pos));
itemBlock.place(context);
TileEntity tileEntity = world.getBlockEntity(pos);
if (tileEntity instanceof ComponentTileEntity) {
blocks.put(pos, tileEntity);
} else {
blocks.put(pos, world.getBlockState(pos));
}
}
}
}
z++;
}
}
Direction frontFacing = controller.getFrontFacing();
blocks.forEach((pos, block) -> {
// adjust facing
if (block instanceof BlockState) {
resetFacing(pos, (BlockState) block, frontFacing, (p, f) -> {
Object object = blocks.get(p.relative(f));
return object == null || (object instanceof BlockState && ((BlockState) object).getBlock() == Blocks.AIR);
}, state -> world.setBlock(pos, state, 3));
} else if (block instanceof ComponentTileEntity) {
resetFacing(pos, ((ComponentTileEntity<?>) block).getBlockState(), frontFacing, (p, f) -> {
Object object = blocks.get(p.relative(f));
if (object == null || (object instanceof BlockState && ((BlockState) object).getBlock() == Blocks.AIR)) {
return ((ComponentTileEntity<?>) block).isValidFrontFacing(f);
}
return false;
}, state -> world.setBlock(pos, state, 3));
}
});
}
Aggregations