Tanks of Jank

- Fluid tanks now attach the full multiblock when a part of them is moved by a contraption
- Fluid tanks now rotate and mirror properly
- Fluid tanks now react to movement properly
- Creative fluid tanks no longer lose configured fluid when more tanks are added to it
- Fluid tanks no longer render ghost fluids when placed with nbt
- Fixed some inconsistencies with tanks distributing fluids when connecting/disconnecting in multiblocks
- TileEntities are now being considered when rendering static blocks in a moving structure. Fixed brackets and tank blocks not rendering properly
- Poles no longer display their length when used for decoration
- Increased scope of caught exceptions when rendering modded tes in schematics and on contraptions
This commit is contained in:
simibubi 2020-11-24 16:56:02 +01:00
parent c5163f0953
commit 0d9a6cc8c3
11 changed files with 226 additions and 64 deletions

View file

@ -19,6 +19,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pis
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState;
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity;
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock;
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler;
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock; import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock;
import net.minecraft.block.AbstractPressurePlateBlock; import net.minecraft.block.AbstractPressurePlateBlock;
@ -45,6 +47,7 @@ import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockMovementTraits { public class BlockMovementTraits {
@ -55,9 +58,11 @@ public class BlockMovementTraits {
return true; return true;
if (state.getBlock() instanceof FenceGateBlock) if (state.getBlock() instanceof FenceGateBlock)
return true; return true;
if (state.getMaterial().isReplaceable()) if (state.getMaterial()
.isReplaceable())
return false; return false;
if (state.getCollisionShape(world, pos).isEmpty()) if (state.getCollisionShape(world, pos)
.isEmpty())
return false; return false;
return true; return true;
} }
@ -104,7 +109,7 @@ public class BlockMovementTraits {
Block block = state.getBlock(); Block block = state.getBlock();
if (state.has(BlockStateProperties.HANGING)) if (state.has(BlockStateProperties.HANGING))
return true; return true;
if (block instanceof LadderBlock) if (block instanceof LadderBlock)
return true; return true;
if (block instanceof TorchBlock) if (block instanceof TorchBlock)
@ -129,7 +134,8 @@ public class BlockMovementTraits {
/** /**
* Attached blocks will move if blocks they are attached to are moved * Attached blocks will move if blocks they are attached to are moved
*/ */
public static boolean isBlockAttachedTowards(BlockState state, Direction direction) { public static boolean isBlockAttachedTowards(IBlockReader world, BlockPos pos, BlockState state,
Direction direction) {
Block block = state.getBlock(); Block block = state.getBlock();
if (block instanceof LadderBlock) if (block instanceof LadderBlock)
return state.get(LadderBlock.FACING) == direction.getOpposite(); return state.get(LadderBlock.FACING) == direction.getOpposite();
@ -167,23 +173,30 @@ public class BlockMovementTraits {
if (block instanceof AbstractRailBlock) if (block instanceof AbstractRailBlock)
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (block instanceof AttachedActorBlock) if (block instanceof AttachedActorBlock)
return direction == state.get(HarvesterBlock.HORIZONTAL_FACING).getOpposite(); return direction == state.get(HarvesterBlock.HORIZONTAL_FACING)
.getOpposite();
if (block instanceof HandCrankBlock) if (block instanceof HandCrankBlock)
return direction == state.get(HandCrankBlock.FACING).getOpposite(); return direction == state.get(HandCrankBlock.FACING)
.getOpposite();
if (block instanceof NozzleBlock) if (block instanceof NozzleBlock)
return direction == state.get(NozzleBlock.FACING).getOpposite(); return direction == state.get(NozzleBlock.FACING)
.getOpposite();
if (block instanceof EngineBlock) if (block instanceof EngineBlock)
return direction == state.get(EngineBlock.HORIZONTAL_FACING).getOpposite(); return direction == state.get(EngineBlock.HORIZONTAL_FACING)
.getOpposite();
if (block instanceof BellBlock) { if (block instanceof BellBlock) {
BellAttachment attachment = state.get(BlockStateProperties.BELL_ATTACHMENT); BellAttachment attachment = state.get(BlockStateProperties.BELL_ATTACHMENT);
if (attachment == BellAttachment.FLOOR) if (attachment == BellAttachment.FLOOR)
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (attachment == BellAttachment.CEILING) if (attachment == BellAttachment.CEILING)
return direction == Direction.UP; return direction == Direction.UP;
return direction == state.get(HorizontalBlock.HORIZONTAL_FACING); return direction == state.get(HorizontalBlock.HORIZONTAL_FACING);
} }
if (state.getBlock() instanceof SailBlock) if (state.getBlock() instanceof SailBlock)
return direction.getAxis() != state.get(SailBlock.FACING).getAxis(); return direction.getAxis() != state.get(SailBlock.FACING)
.getAxis();
if (state.getBlock() instanceof FluidTankBlock)
return FluidTankConnectivityHandler.isConnected(world, pos, pos.offset(direction));
return false; return false;
} }
@ -209,8 +222,9 @@ public class BlockMovementTraits {
if (state.getBlock() instanceof CarpetBlock) if (state.getBlock() instanceof CarpetBlock)
return facing == Direction.UP; return facing == Direction.UP;
if (state.getBlock() instanceof SailBlock) if (state.getBlock() instanceof SailBlock)
return facing.getAxis() == state.get(SailBlock.FACING).getAxis(); return facing.getAxis() == state.get(SailBlock.FACING)
.getAxis();
return isBrittle(state); return isBrittle(state);
} }
} }

View file

@ -39,6 +39,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.MagnetBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.MagnetBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.RopeBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.RopeBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity;
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock;
import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock; import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock;
@ -288,7 +289,7 @@ public abstract class Contraption {
boolean wasVisited = visited.contains(offsetPos); boolean wasVisited = visited.contains(offsetPos);
boolean faceHasGlue = superglue.containsKey(offset); boolean faceHasGlue = superglue.containsKey(offset);
boolean blockAttachedTowardsFace = boolean blockAttachedTowardsFace =
BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()); BlockMovementTraits.isBlockAttachedTowards(world, offsetPos, blockState, offset.getOpposite());
boolean brittle = BlockMovementTraits.isBrittle(blockState); boolean brittle = BlockMovementTraits.isBrittle(blockState);
if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue)) if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue))
@ -461,6 +462,11 @@ public abstract class Contraption {
nbt.remove("x"); nbt.remove("x");
nbt.remove("y"); nbt.remove("y");
nbt.remove("z"); nbt.remove("z");
if (tileentity instanceof FluidTankTileEntity && nbt.contains("Controller"))
nbt.put("Controller",
NBTUtil.writeBlockPos(toLocalPos(NBTUtil.readBlockPos(nbt.getCompound("Controller")))));
return nbt; return nbt;
} }
@ -734,6 +740,9 @@ public abstract class Contraption {
tag.remove("InitialOffset"); tag.remove("InitialOffset");
} }
if (tileEntity instanceof FluidTankTileEntity && tag.contains("LastKnownPos"))
tag.put("LastKnownPos", NBTUtil.writeBlockPos(BlockPos.ZERO.down()));
tileEntity.read(tag); tileEntity.read(tag);
if (storage.containsKey(block.pos)) { if (storage.containsKey(block.pos)) {

View file

@ -86,6 +86,7 @@ public class ContraptionRenderer {
Random random = new Random(); Random random = new Random();
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize()); BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
renderWorld.setTileEntities(c.renderedTileEntities);
for (BlockInfo info : c.getBlocks().values()) for (BlockInfo info : c.getBlocks().values())
renderWorld.setBlockState(info.pos, info.state); renderWorld.setBlockState(info.pos, info.state);

View file

@ -176,7 +176,7 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
public static boolean isValidFace(World world, BlockPos pos, Direction direction) { public static boolean isValidFace(World world, BlockPos pos, Direction direction) {
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (BlockMovementTraits.isBlockAttachedTowards(state, direction)) if (BlockMovementTraits.isBlockAttachedTowards(world, pos, state, direction))
return true; return true;
if (!BlockMovementTraits.movementNecessary(world, pos)) if (!BlockMovementTraits.movementNecessary(world, pos))
return false; return false;

View file

@ -28,6 +28,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.IStringSerializable; import net.minecraft.util.IStringSerializable;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents; import net.minecraft.util.SoundEvents;
@ -41,6 +43,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankTileEntity> { public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankTileEntity> {
@ -72,9 +75,11 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
} }
@Override @Override
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean p_220082_5_) { public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean moved) {
if (oldState.getBlock() == state.getBlock()) if (oldState.getBlock() == state.getBlock())
return; return;
if (moved)
return;
withTileEntityDo(world, pos, FluidTankTileEntity::updateConnectivity); withTileEntityDo(world, pos, FluidTankTileEntity::updateConnectivity);
} }
@ -116,7 +121,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
if (te == null) if (te == null)
return ActionResultType.FAIL; return ActionResultType.FAIL;
LazyOptional<IFluidHandler> tankCapability = te.fluidCapability; LazyOptional<IFluidHandler> tankCapability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY);
if (!tankCapability.isPresent()) if (!tankCapability.isPresent())
return ActionResultType.PASS; return ActionResultType.PASS;
IFluidHandler fluidTank = tankCapability.orElse(null); IFluidHandler fluidTank = tankCapability.orElse(null);
@ -142,7 +147,8 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
if (exchange == FluidExchange.ITEM_TO_TANK) { if (exchange == FluidExchange.ITEM_TO_TANK) {
if (creative && !onClient) { if (creative && !onClient) {
FluidStack fluidInItem = EmptyingByBasin.emptyItem(world, heldItem, true).getFirst(); FluidStack fluidInItem = EmptyingByBasin.emptyItem(world, heldItem, true)
.getFirst();
if (!fluidInItem.isEmpty() && fluidTank instanceof CreativeSmartFluidTank) if (!fluidInItem.isEmpty() && fluidTank instanceof CreativeSmartFluidTank)
((CreativeSmartFluidTank) fluidTank).setContainedFluid(fluidInItem); ((CreativeSmartFluidTank) fluidTank).setContainedFluid(fluidInItem);
} }
@ -241,6 +247,47 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
return FluidTankTileEntity.class; return FluidTankTileEntity.class;
} }
@Override
public BlockState mirror(BlockState state, Mirror mirror) {
if (mirror == Mirror.NONE)
return state;
boolean x = mirror == Mirror.FRONT_BACK;
switch (state.get(SHAPE)) {
case WINDOW_NE:
return state.with(SHAPE, x ? Shape.WINDOW_NW : Shape.WINDOW_SE);
case WINDOW_NW:
return state.with(SHAPE, x ? Shape.WINDOW_NE : Shape.WINDOW_SW);
case WINDOW_SE:
return state.with(SHAPE, x ? Shape.WINDOW_SW : Shape.WINDOW_NE);
case WINDOW_SW:
return state.with(SHAPE, x ? Shape.WINDOW_SE : Shape.WINDOW_NW);
default:
return state;
}
}
@Override
public BlockState rotate(BlockState state, Rotation rotation) {
for (int i = 0; i < rotation.ordinal(); i++)
state = rotateOnce(state);
return state;
}
private BlockState rotateOnce(BlockState state) {
switch (state.get(SHAPE)) {
case WINDOW_NE:
return state.with(SHAPE, Shape.WINDOW_SE);
case WINDOW_NW:
return state.with(SHAPE, Shape.WINDOW_NE);
case WINDOW_SE:
return state.with(SHAPE, Shape.WINDOW_SW);
case WINDOW_SW:
return state.with(SHAPE, Shape.WINDOW_NW);
default:
return state;
}
}
public enum Shape implements IStringSerializable { public enum Shape implements IStringSerializable {
PLAIN, WINDOW, WINDOW_NW, WINDOW_SW, WINDOW_NE, WINDOW_SE; PLAIN, WINDOW, WINDOW_NW, WINDOW_SW, WINDOW_NE, WINDOW_SE;

View file

@ -14,6 +14,7 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair; 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 com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -25,8 +26,12 @@ import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack; 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.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.templates.FluidTank;
public class FluidTankConnectivityHandler { public class FluidTankConnectivityHandler {
@ -147,8 +152,10 @@ public class FluidTankConnectivityHandler {
TileEntityType<?> type = te.getType(); TileEntityType<?> type = te.getType();
World world = te.getWorld(); World world = te.getWorld();
BlockPos origin = te.getPos(); BlockPos origin = te.getPos();
FluidStack fluid = te.getTankInventory() LazyOptional<IFluidHandler> capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY);
.getFluid(); FluidTank teTank = (FluidTank) capability.orElse(null);
FluidStack fluid = capability.map(ifh -> ifh.getFluidInTank(0))
.orElse(FluidStack.EMPTY);
Search: Search:
@ -192,6 +199,8 @@ public class FluidTankConnectivityHandler {
if (simulate) if (simulate)
return amount; return amount;
boolean opaque = false;
for (int yOffset = 0; yOffset < height; yOffset++) { for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) { for (int xOffset = 0; xOffset < width; xOffset++) {
@ -201,10 +210,15 @@ public class FluidTankConnectivityHandler {
if (tank == te) if (tank == te)
continue; continue;
if (tank.isController()) { opaque |= !tank.window;
te.tankInventory.fill(tank.tankInventory.getFluid(), FluidAction.EXECUTE); FluidTank tankTank = tank.tankInventory;
tank.tankInventory.setFluid(FluidStack.EMPTY); 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); splitTankAndInvalidate(tank, cache, false);
tank.setController(origin); tank.setController(origin);
@ -220,6 +234,8 @@ public class FluidTankConnectivityHandler {
} }
} }
} }
te.setWindows(!opaque);
return amount; return amount;
} }
@ -243,8 +259,9 @@ public class FluidTankConnectivityHandler {
FluidStack toDistribute = te.tankInventory.getFluid() FluidStack toDistribute = te.tankInventory.getFluid()
.copy(); .copy();
int maxCapacity = FluidTankTileEntity.getCapacityMultiplier(); int maxCapacity = FluidTankTileEntity.getCapacityMultiplier();
if (!toDistribute.isEmpty()) if (!toDistribute.isEmpty() && !te.isRemoved())
toDistribute.shrink(maxCapacity); toDistribute.shrink(maxCapacity);
te.applyFluidTankSize(1);
for (int yOffset = 0; yOffset < height; yOffset++) { for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) { for (int xOffset = 0; xOffset < width; xOffset++) {
@ -259,14 +276,19 @@ public class FluidTankConnectivityHandler {
continue; continue;
FluidTankTileEntity controllerTE = tankAt.getControllerTE(); FluidTankTileEntity controllerTE = tankAt.getControllerTE();
tankAt.window = controllerTE == null || controllerTE.window; tankAt.window = controllerTE == null || controllerTE.window;
tankAt.removeController(); tankAt.removeController(true);
if (!toDistribute.isEmpty() && tankAt != te) { if (!toDistribute.isEmpty() && tankAt != te) {
int split = Math.min(maxCapacity, toDistribute.getAmount());
FluidStack copy = toDistribute.copy(); FluidStack copy = toDistribute.copy();
copy.setAmount(split); FluidTank tankInventory = tankAt.tankInventory;
toDistribute.shrink(split); if (tankInventory.isEmpty() && tankInventory instanceof CreativeSmartFluidTank)
tankAt.tankInventory.fill(copy, FluidAction.EXECUTE); ((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) { if (tryReconnect) {
@ -300,7 +322,7 @@ public class FluidTankConnectivityHandler {
return (FluidTankTileEntity) te; return (FluidTankTileEntity) te;
return null; return null;
} }
@Nullable @Nullable
public static FluidTankTileEntity anyTankAt(IBlockReader world, BlockPos pos) { public static FluidTankTileEntity anyTankAt(IBlockReader world, BlockPos pos) {
TileEntity te = world.getTileEntity(pos); TileEntity te = world.getTileEntity(pos);

View file

@ -6,6 +6,8 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -26,6 +28,23 @@ public class FluidTankItem extends BlockItem {
return initialResult; return initialResult;
} }
@Override
protected boolean onBlockPlaced(BlockPos p_195943_1_, World p_195943_2_, PlayerEntity p_195943_3_,
ItemStack p_195943_4_, BlockState p_195943_5_) {
MinecraftServer minecraftserver = p_195943_2_.getServer();
if (minecraftserver == null)
return false;
CompoundNBT nbt = p_195943_4_.getChildTag("BlockEntityTag");
if (nbt != null) {
nbt.remove("Luminosity");
nbt.remove("Size");
nbt.remove("Height");
nbt.remove("Controller");
nbt.remove("LastKnownPos");
}
return super.onBlockPlaced(p_195943_1_, p_195943_2_, p_195943_3_, p_195943_4_, p_195943_5_);
}
private void tryMultiPlace(BlockItemUseContext ctx) { private void tryMultiPlace(BlockItemUseContext ctx) {
PlayerEntity player = ctx.getPlayer(); PlayerEntity player = ctx.getPlayer();
if (player == null) if (player == null)

View file

@ -42,6 +42,7 @@ public class FluidTankTileEntity extends SmartTileEntity {
protected boolean forceFluidLevelUpdate; protected boolean forceFluidLevelUpdate;
protected FluidTank tankInventory; protected FluidTank tankInventory;
protected BlockPos controller; protected BlockPos controller;
protected BlockPos lastKnownPos;
protected boolean updateConnectivity; protected boolean updateConnectivity;
protected boolean window; protected boolean window;
protected int luminosity; protected int luminosity;
@ -88,6 +89,14 @@ public class FluidTankTileEntity extends SmartTileEntity {
if (syncCooldown == 0 && queuedSync) if (syncCooldown == 0 && queuedSync)
sendData(); sendData();
} }
if (lastKnownPos == null)
lastKnownPos = getPos();
else if (!lastKnownPos.equals(pos) && pos != null) {
onPositionChanged();
return;
}
if (updateConnectivity) if (updateConnectivity)
updateConnectivity(); updateConnectivity();
if (fluidLevel != null) if (fluidLevel != null)
@ -104,6 +113,11 @@ public class FluidTankTileEntity extends SmartTileEntity {
sendData(); sendData();
} }
private void onPositionChanged() {
removeController(true);
lastKnownPos = pos;
}
protected void onFluidStackChanged(FluidStack newFluidStack) { protected void onFluidStackChanged(FluidStack newFluidStack) {
if (!hasWorld()) if (!hasWorld())
return; return;
@ -163,11 +177,12 @@ public class FluidTankTileEntity extends SmartTileEntity {
forceFluidLevelUpdate = true; forceFluidLevelUpdate = true;
} }
public void removeController() { public void removeController(boolean keepFluids) {
if (world.isRemote) if (world.isRemote)
return; return;
updateConnectivity = true; updateConnectivity = true;
applyFluidTankSize(1); if (!keepFluids)
applyFluidTankSize(1);
controller = null; controller = null;
width = 1; width = 1;
height = 1; height = 1;
@ -292,7 +307,10 @@ public class FluidTankTileEntity extends SmartTileEntity {
updateConnectivity = compound.contains("Uninitialized"); updateConnectivity = compound.contains("Uninitialized");
luminosity = compound.getInt("Luminosity"); luminosity = compound.getInt("Luminosity");
controller = null; controller = null;
lastKnownPos = null;
if (compound.contains("LastKnownPos"))
lastKnownPos = NBTUtil.readBlockPos(compound.getCompound("LastKnownPos"));
if (compound.contains("Controller")) if (compound.contains("Controller"))
controller = NBTUtil.readBlockPos(compound.getCompound("Controller")); controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
@ -344,6 +362,8 @@ public class FluidTankTileEntity extends SmartTileEntity {
public void write(CompoundNBT compound, boolean clientPacket) { public void write(CompoundNBT compound, boolean clientPacket) {
if (updateConnectivity) if (updateConnectivity)
compound.putBoolean("Uninitialized", true); compound.putBoolean("Uninitialized", true);
if (lastKnownPos != null)
compound.put("LastKnownPos", NBTUtil.writeBlockPos(lastKnownPos));
if (!isController()) if (!isController())
compound.put("Controller", NBTUtil.writeBlockPos(controller)); compound.put("Controller", NBTUtil.writeBlockPos(controller));
if (isController()) { if (isController()) {

View file

@ -1,13 +1,20 @@
package com.simibubi.create.content.contraptions.goggles; package com.simibubi.create.content.contraptions.goggles;
import static com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation.spacing;
import java.util.ArrayList;
import java.util.List;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock; import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonPolePlacementHelper; import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonPolePlacementHelper;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.gui.GuiGameElement; import com.simibubi.create.foundation.gui.GuiGameElement;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
@ -26,15 +33,9 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import java.util.ArrayList;
import java.util.List;
import static com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation.spacing;
@EventBusSubscriber(value = Dist.CLIENT) @EventBusSubscriber(value = Dist.CLIENT)
public class GoggleOverlayRenderer { public class GoggleOverlayRenderer {
@SubscribeEvent @SubscribeEvent
public static void lookingAtBlocksThroughGogglesShowsTooltip(RenderGameOverlayEvent.Post event) { public static void lookingAtBlocksThroughGogglesShowsTooltip(RenderGameOverlayEvent.Post event) {
if (event.getType() != ElementType.HOTBAR) if (event.getType() != ElementType.HOTBAR)
@ -76,18 +77,26 @@ public class GoggleOverlayRenderer {
tooltip.remove(tooltip.size() - 1); tooltip.remove(tooltip.size() - 1);
} }
//break early if goggle or hover returned false when present // break early if goggle or hover returned false when present
if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation)) if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation))
return; return;
//check for piston poles if goggles are worn // check for piston poles if goggles are worn
BlockState state = world.getBlockState(pos); BlockState state = world.getBlockState(pos);
if (wearingGoggles && AllBlocks.PISTON_EXTENSION_POLE.has(state)) { if (wearingGoggles && AllBlocks.PISTON_EXTENSION_POLE.has(state)) {
Direction[] directions = Iterate.directionsInAxis(state.get(PistonExtensionPoleBlock.FACING).getAxis()); Direction[] directions = Iterate.directionsInAxis(state.get(PistonExtensionPoleBlock.FACING)
.getAxis());
int poles = 1; int poles = 1;
for (Direction dir : directions) boolean pistonFound = false;
poles += PistonPolePlacementHelper.attachedPoles(world, pos, dir); for (Direction dir : directions) {
int attachedPoles = PistonPolePlacementHelper.attachedPoles(world, pos, dir);
poles += attachedPoles;
pistonFound |= world.getBlockState(pos.offset(dir, attachedPoles + 1))
.getBlock() instanceof MechanicalPistonBlock;
}
if (!pistonFound)
return;
if (!tooltip.isEmpty()) if (!tooltip.isEmpty())
tooltip.add(""); tooltip.add("");
@ -99,15 +108,22 @@ public class GoggleOverlayRenderer {
RenderSystem.pushMatrix(); RenderSystem.pushMatrix();
Screen tooltipScreen = new TooltipScreen(null); Screen tooltipScreen = new TooltipScreen(null);
tooltipScreen.init(mc, mc.getWindow().getScaledWidth(), mc.getWindow().getScaledHeight()); tooltipScreen.init(mc, mc.getWindow()
.getScaledWidth(),
mc.getWindow()
.getScaledHeight());
int posX = tooltipScreen.width / 2 + AllConfigs.CLIENT.overlayOffsetX.get(); int posX = tooltipScreen.width / 2 + AllConfigs.CLIENT.overlayOffsetX.get();
int posY = tooltipScreen.height / 2 + AllConfigs.CLIENT.overlayOffsetY.get(); int posY = tooltipScreen.height / 2 + AllConfigs.CLIENT.overlayOffsetY.get();
//tooltipScreen.renderTooltip(tooltip, tooltipScreen.width / 2, tooltipScreen.height / 2); // tooltipScreen.renderTooltip(tooltip, tooltipScreen.width / 2,
// tooltipScreen.height / 2);
tooltipScreen.renderTooltip(tooltip, posX, posY); tooltipScreen.renderTooltip(tooltip, posX, posY);
ItemStack item = AllItems.GOGGLES.asStack(); ItemStack item = AllItems.GOGGLES.asStack();
//GuiGameElement.of(item).at(tooltipScreen.width / 2 + 10, tooltipScreen.height / 2 - 16).render(); // GuiGameElement.of(item).at(tooltipScreen.width / 2 + 10, tooltipScreen.height
GuiGameElement.of(item).at(posX + 10, posY - 16).render(); // / 2 - 16).render();
GuiGameElement.of(item)
.at(posX + 10, posY - 16)
.render();
RenderSystem.popMatrix(); RenderSystem.popMatrix();
} }

View file

@ -14,20 +14,19 @@ import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.crash.ReportedException;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class TileEntityRenderHelper { public class TileEntityRenderHelper {
public static void renderTileEntities(World world, Iterable<TileEntity> customRenderTEs, MatrixStack ms, public static void renderTileEntities(World world, Iterable<TileEntity> customRenderTEs, MatrixStack ms,
MatrixStack localTransform, IRenderTypeBuffer buffer) { MatrixStack localTransform, IRenderTypeBuffer buffer) {
float pt = Minecraft.getInstance() float pt = Minecraft.getInstance()
.getRenderPartialTicks(); .getRenderPartialTicks();
Matrix4f matrix = localTransform.peek() Matrix4f matrix = localTransform.peek()
.getModel(); .getModel();
for (Iterator<TileEntity> iterator = customRenderTEs.iterator(); iterator.hasNext();) { for (Iterator<TileEntity> iterator = customRenderTEs.iterator(); iterator.hasNext();) {
TileEntity tileEntity = iterator.next(); TileEntity tileEntity = iterator.next();
TileEntityRenderer<TileEntity> renderer = TileEntityRendererDispatcher.instance.getRenderer(tileEntity); TileEntityRenderer<TileEntity> renderer = TileEntityRendererDispatcher.instance.getRenderer(tileEntity);
@ -49,17 +48,18 @@ public class TileEntityRenderHelper {
OverlayTexture.DEFAULT_UV); OverlayTexture.DEFAULT_UV);
ms.pop(); ms.pop();
} catch (ReportedException e) { } catch (Exception e) {
if (AllConfigs.CLIENT.explainRenderErrors.get()) {
Create.logger.error("TileEntity " + tileEntity.getType()
.getRegistryName()
.toString() + " didn't want to render while moved.\n", e);
} else {
Create.logger.error("TileEntity " + tileEntity.getType()
.getRegistryName()
.toString() + " didn't want to render while moved.\n");
}
iterator.remove(); iterator.remove();
String message = "TileEntity " + tileEntity.getType()
.getRegistryName()
.toString() + " didn't want to render while moved.\n";
if (AllConfigs.CLIENT.explainRenderErrors.get()) {
Create.logger.error(message, e);
continue;
}
Create.logger.error(message);
continue; continue;
} }
} }

View file

@ -1,21 +1,30 @@
package com.simibubi.create.foundation.utility.worldWrappers; package com.simibubi.create.foundation.utility.worldWrappers;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.function.Predicate; import java.util.function.Predicate;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class PlacementSimulationWorld extends WrappedWorld { public class PlacementSimulationWorld extends WrappedWorld {
public HashMap<BlockPos, BlockState> blocksAdded; public HashMap<BlockPos, BlockState> blocksAdded;
public HashMap<BlockPos, TileEntity> tesAdded;
public PlacementSimulationWorld(World wrapped) { public PlacementSimulationWorld(World wrapped) {
super(wrapped); super(wrapped);
blocksAdded = new HashMap<>(); blocksAdded = new HashMap<>();
tesAdded = new HashMap<>();
} }
public void setTileEntities(Collection<TileEntity> tileEntities) {
tesAdded.clear();
tileEntities.forEach(te -> tesAdded.put(te.getPos(), te));
}
public void clear() { public void clear() {
blocksAdded.clear(); blocksAdded.clear();
} }
@ -31,16 +40,21 @@ public class PlacementSimulationWorld extends WrappedWorld {
return setBlockState(pos, state, 0); return setBlockState(pos, state, 0);
} }
@Override
public TileEntity getTileEntity(BlockPos pos) {
return tesAdded.get(pos);
}
@Override @Override
public boolean hasBlockState(BlockPos pos, Predicate<BlockState> condition) { public boolean hasBlockState(BlockPos pos, Predicate<BlockState> condition) {
return condition.test(getBlockState(pos)); return condition.test(getBlockState(pos));
} }
@Override @Override
public boolean isBlockPresent(BlockPos pos) { public boolean isBlockPresent(BlockPos pos) {
return true; return true;
} }
@Override @Override
public boolean isAreaLoaded(BlockPos center, int range) { public boolean isAreaLoaded(BlockPos center, int range) {
return true; return true;
@ -52,5 +66,5 @@ public class PlacementSimulationWorld extends WrappedWorld {
return blocksAdded.get(pos); return blocksAdded.get(pos);
return Blocks.AIR.getDefaultState(); return Blocks.AIR.getDefaultState();
} }
} }