use of com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank in project Create by Creators-of-Create.
the class FluidTankConnectivityHandler method splitTankAndInvalidate.
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);
}
use of com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank in project Create by Creators-of-Create.
the class MountedFluidStorage method serialize.
public CompoundTag serialize() {
if (!valid)
return null;
CompoundTag tag = tank.writeToNBT(new CompoundTag());
tag.putInt("Capacity", tank.getCapacity());
if (tank instanceof CreativeSmartFluidTank) {
NBTHelper.putMarker(tag, "Bottomless");
tag.put("ProvidedStack", tank.getFluid().writeToNBT(new CompoundTag()));
}
return tag;
}
use of com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank in project Create by Creators-of-Create.
the class MountedFluidStorage method deserialize.
public static MountedFluidStorage deserialize(CompoundTag nbt) {
MountedFluidStorage storage = new MountedFluidStorage(null);
if (nbt == null)
return storage;
int capacity = nbt.getInt("Capacity");
storage.tank = new SmartFluidTank(capacity, storage::onFluidStackChanged);
storage.valid = true;
if (nbt.contains("Bottomless")) {
FluidStack providedStack = FluidStack.loadFluidStackFromNBT(nbt.getCompound("ProvidedStack"));
CreativeSmartFluidTank creativeSmartFluidTank = new CreativeSmartFluidTank(capacity, $ -> {
});
creativeSmartFluidTank.setContainedFluid(providedStack);
storage.tank = creativeSmartFluidTank;
return storage;
}
storage.tank.readFromNBT(nbt);
return storage;
}
use of com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank in project Create by Creators-of-Create.
the class FluidTankBlock method use.
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult ray) {
ItemStack heldItem = player.getItemInHand(hand);
boolean onClient = world.isClientSide;
if (heldItem.isEmpty())
return InteractionResult.PASS;
if (!player.isCreative() && !creative)
return InteractionResult.PASS;
FluidExchange exchange = null;
FluidTankTileEntity te = FluidTankConnectivityHandler.anyTankAt(world, pos);
if (te == null)
return InteractionResult.FAIL;
LazyOptional<IFluidHandler> tankCapability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY);
if (!tankCapability.isPresent())
return InteractionResult.PASS;
IFluidHandler fluidTank = tankCapability.orElse(null);
FluidStack prevFluidInTank = fluidTank.getFluidInTank(0).copy();
if (FluidHelper.tryEmptyItemIntoTE(world, player, hand, heldItem, te))
exchange = FluidExchange.ITEM_TO_TANK;
else if (FluidHelper.tryFillItemFromTE(world, player, hand, heldItem, te))
exchange = FluidExchange.TANK_TO_ITEM;
if (exchange == null) {
if (EmptyingByBasin.canItemBeEmptied(world, heldItem) || GenericItemFilling.canItemBeFilled(world, heldItem))
return InteractionResult.SUCCESS;
return InteractionResult.PASS;
}
SoundEvent soundevent = null;
BlockState fluidState = null;
FluidStack fluidInTank = tankCapability.map(fh -> fh.getFluidInTank(0)).orElse(FluidStack.EMPTY);
if (exchange == FluidExchange.ITEM_TO_TANK) {
if (creative && !onClient) {
FluidStack fluidInItem = EmptyingByBasin.emptyItem(world, heldItem, true).getFirst();
if (!fluidInItem.isEmpty() && fluidTank instanceof CreativeSmartFluidTank)
((CreativeSmartFluidTank) fluidTank).setContainedFluid(fluidInItem);
}
Fluid fluid = fluidInTank.getFluid();
fluidState = fluid.defaultFluidState().createLegacyBlock();
FluidAttributes attributes = fluid.getAttributes();
soundevent = attributes.getEmptySound();
if (soundevent == null)
soundevent = fluid.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
}
if (exchange == FluidExchange.TANK_TO_ITEM) {
if (creative && !onClient)
if (fluidTank instanceof CreativeSmartFluidTank)
((CreativeSmartFluidTank) fluidTank).setContainedFluid(FluidStack.EMPTY);
Fluid fluid = prevFluidInTank.getFluid();
fluidState = fluid.defaultFluidState().createLegacyBlock();
soundevent = fluid.getAttributes().getFillSound();
if (soundevent == null)
soundevent = fluid.is(FluidTags.LAVA) ? SoundEvents.BUCKET_FILL_LAVA : SoundEvents.BUCKET_FILL;
}
if (soundevent != null && !onClient) {
float pitch = Mth.clamp(1 - (1f * fluidInTank.getAmount() / (FluidTankTileEntity.getCapacityMultiplier() * 16)), 0, 1);
pitch /= 1.5f;
pitch += .5f;
pitch += (world.random.nextFloat() - .5f) / 4f;
world.playSound(null, pos, soundevent, SoundSource.BLOCKS, .5f, pitch);
}
if (!fluidInTank.isFluidStackIdentical(prevFluidInTank)) {
if (te instanceof FluidTankTileEntity) {
FluidTankTileEntity controllerTE = ((FluidTankTileEntity) te).getControllerTE();
if (controllerTE != null) {
if (fluidState != null && onClient) {
BlockParticleOption blockParticleData = new BlockParticleOption(ParticleTypes.BLOCK, fluidState);
float level = (float) fluidInTank.getAmount() / fluidTank.getTankCapacity(0);
boolean reversed = fluidInTank.getFluid().getAttributes().isLighterThanAir();
if (reversed)
level = 1 - level;
Vec3 vec = ray.getLocation();
vec = new Vec3(vec.x, controllerTE.getBlockPos().getY() + level * (controllerTE.height - .5f) + .25f, vec.z);
Vec3 motion = player.position().subtract(vec).scale(1 / 20f);
vec = vec.add(motion);
world.addParticle(blockParticleData, vec.x, vec.y, vec.z, motion.x, motion.y, motion.z);
return InteractionResult.SUCCESS;
}
controllerTE.sendDataImmediately();
controllerTE.setChanged();
}
}
}
return InteractionResult.SUCCESS;
}
use of com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank in project Create by Creators-of-Create.
the class FluidTankConnectivityHandler method tryToFormNewTankOfWidth.
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;
}
Aggregations