added pipe covering
This commit is contained in:
parent
cd1c508b6a
commit
ff5368b108
Binary file not shown.
After Width: | Height: | Size: 850 KiB |
|
@ -18,6 +18,7 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.text.*;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.util.INBTSerializable;
|
||||
|
@ -33,7 +34,7 @@ import java.util.stream.Stream;
|
|||
|
||||
public final class Utility {
|
||||
|
||||
public static <T extends TileEntity> T getTileEntity(Class<T> type, World world, BlockPos pos) {
|
||||
public static <T extends TileEntity> T getTileEntity(Class<T> type, IBlockReader world, BlockPos pos) {
|
||||
TileEntity tile = world.getTileEntity(pos);
|
||||
return type.isInstance(tile) ? (T) tile : null;
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ public final class Utility {
|
|||
public static void sendTileEntityToClients(TileEntity tile) {
|
||||
ServerWorld world = (ServerWorld) tile.getWorld();
|
||||
Stream<ServerPlayerEntity> entities = world.getChunkProvider().chunkManager.getTrackingPlayers(new ChunkPos(tile.getPos()), false);
|
||||
SUpdateTileEntityPacket packet = tile.getUpdatePacket();
|
||||
SUpdateTileEntityPacket packet = new SUpdateTileEntityPacket(tile.getPos(), -1, tile.write(new CompoundNBT()));
|
||||
entities.forEach(e -> e.connection.sendPacket(packet));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
package de.ellpeck.prettypipes.items;
|
||||
|
||||
import de.ellpeck.prettypipes.Registry;
|
||||
import de.ellpeck.prettypipes.Utility;
|
||||
import de.ellpeck.prettypipes.pipe.PipeBlock;
|
||||
import de.ellpeck.prettypipes.pipe.ConnectionType;
|
||||
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.loot.LootContext;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
|
@ -16,11 +23,15 @@ import net.minecraft.util.SoundEvents;
|
|||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WrenchItem extends Item {
|
||||
|
||||
public WrenchItem() {
|
||||
super(new Item.Properties().maxStackSize(1).group(Registry.GROUP));
|
||||
}
|
||||
|
@ -29,20 +40,54 @@ public class WrenchItem extends Item {
|
|||
public ActionResultType onItemUse(ItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
BlockPos pos = context.getPos();
|
||||
PlayerEntity player = context.getPlayer();
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!(state.getBlock() instanceof PipeBlock))
|
||||
return ActionResultType.PASS;
|
||||
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, world, pos);
|
||||
if (tile == null)
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
if (context.getPlayer().isSneaking()) {
|
||||
if (player.isSneaking()) {
|
||||
if (!world.isRemote) {
|
||||
Block.spawnDrops(state, world, pos, world.getTileEntity(pos), null, ItemStack.EMPTY);
|
||||
if (tile.cover != null) {
|
||||
// remove the cover
|
||||
List<ItemStack> drops = Block.getDrops(tile.cover, (ServerWorld) world, pos, null, player, player.getHeldItem(context.getHand()));
|
||||
for (ItemStack drop : drops)
|
||||
Block.spawnAsEntity(world, pos, drop);
|
||||
|
||||
tile.cover = null;
|
||||
Utility.sendTileEntityToClients(tile);
|
||||
} else {
|
||||
// remove the pipe
|
||||
Block.spawnDrops(state, world, pos, tile, null, ItemStack.EMPTY);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_REMOVE_ITEM, SoundCategory.PLAYERS, 1, 1);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
return ActionResultType.func_233537_a_(world.isRemote);
|
||||
}
|
||||
|
||||
// Blocking
|
||||
// placing covers
|
||||
if (tile.cover == null) {
|
||||
ItemStack offhand = player.getHeldItemOffhand();
|
||||
if (offhand.getItem() instanceof BlockItem) {
|
||||
if (!world.isRemote) {
|
||||
BlockItemUseContext blockContext = new BlockItemUseContext(context);
|
||||
Block block = ((BlockItem) offhand.getItem()).getBlock();
|
||||
BlockState cover = block.getStateForPlacement(blockContext);
|
||||
if (cover != null && !block.hasTileEntity(cover)) {
|
||||
tile.cover = cover;
|
||||
Utility.sendTileEntityToClients(tile);
|
||||
offhand.shrink(1);
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ADD_ITEM, SoundCategory.PLAYERS, 1, 1);
|
||||
}
|
||||
}
|
||||
return ActionResultType.func_233537_a_(world.isRemote);
|
||||
}
|
||||
}
|
||||
|
||||
// disabling directions
|
||||
for (Map.Entry<Direction, VoxelShape> entry : PipeBlock.DIR_SHAPES.entrySet()) {
|
||||
AxisAlignedBB box = entry.getValue().getBoundingBox().offset(pos).grow(0.001F);
|
||||
if (!box.contains(context.getHitVec()))
|
||||
|
@ -66,8 +111,28 @@ public class WrenchItem extends Item {
|
|||
PipeBlock.onStateChanged(world, pos, newState);
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ROTATE_ITEM, SoundCategory.PLAYERS, 1, 1);
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
return ActionResultType.func_233537_a_(world.isRemote);
|
||||
}
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
|
||||
Utility.addTooltip(this.getRegistryName().getPath(), tooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnchantable(ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemEnchantability(ItemStack stack) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
|
||||
return enchantment == Enchantments.SILK_TOUCH;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
@ -34,6 +35,7 @@ import net.minecraftforge.fml.network.NetworkHooks;
|
|||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
|
@ -42,7 +44,7 @@ import java.util.Map;
|
|||
public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
||||
|
||||
public static final Map<Direction, EnumProperty<ConnectionType>> DIRECTIONS = new HashMap<>();
|
||||
private static final Map<BlockState, VoxelShape> SHAPE_CACHE = new HashMap<>();
|
||||
private static final Map<Pair<BlockState, BlockState>, VoxelShape> SHAPE_CACHE = new HashMap<>();
|
||||
private static final VoxelShape CENTER_SHAPE = makeCuboidShape(5, 5, 5, 11, 11, 11);
|
||||
public static final Map<Direction, VoxelShape> DIR_SHAPES = ImmutableMap.<Direction, VoxelShape>builder()
|
||||
.put(Direction.UP, makeCuboidShape(5, 10, 5, 11, 16, 11))
|
||||
|
@ -131,16 +133,29 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable {
|
|||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
VoxelShape shape = SHAPE_CACHE.get(state);
|
||||
if (shape != null)
|
||||
return shape;
|
||||
|
||||
shape = CENTER_SHAPE;
|
||||
for (Map.Entry<Direction, EnumProperty<ConnectionType>> entry : DIRECTIONS.entrySet()) {
|
||||
if (state.get(entry.getValue()).isConnected())
|
||||
shape = VoxelShapes.or(shape, DIR_SHAPES.get(entry.getKey()));
|
||||
VoxelShape coverShape = null;
|
||||
BlockState cover = null;
|
||||
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, worldIn, pos);
|
||||
if (tile != null && tile.cover != null) {
|
||||
cover = tile.cover;
|
||||
// try catch since the block might expect to find itself at the position
|
||||
try {
|
||||
coverShape = cover.getShape(worldIn, pos, context);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
Pair<BlockState, BlockState> key = Pair.of(state, cover);
|
||||
VoxelShape shape = SHAPE_CACHE.get(key);
|
||||
if (shape == null) {
|
||||
shape = CENTER_SHAPE;
|
||||
for (Map.Entry<Direction, EnumProperty<ConnectionType>> entry : DIRECTIONS.entrySet()) {
|
||||
if (state.get(entry.getValue()).isConnected())
|
||||
shape = VoxelShapes.or(shape, DIR_SHAPES.get(entry.getKey()));
|
||||
}
|
||||
if (coverShape != null)
|
||||
shape = VoxelShapes.or(shape, coverShape);
|
||||
SHAPE_CACHE.put(key, shape);
|
||||
}
|
||||
SHAPE_CACHE.put(state, shape);
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package de.ellpeck.prettypipes.pipe;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import de.ellpeck.prettypipes.Registry;
|
||||
import de.ellpeck.prettypipes.network.PipeItem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -24,17 +29,30 @@ public class PipeRenderer extends TileEntityRenderer<PipeTileEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(PipeTileEntity tile, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer iRenderTypeBuffer, int k, int i1) {
|
||||
if (tile.getItems().isEmpty())
|
||||
return;
|
||||
matrixStack.push();
|
||||
BlockPos tilePos = tile.getPos();
|
||||
matrixStack.translate(-tilePos.getX(), -tilePos.getY(), -tilePos.getZ());
|
||||
for (PipeItem item : tile.getItems()) {
|
||||
public void render(PipeTileEntity tile, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
if (!tile.getItems().isEmpty()) {
|
||||
matrixStack.push();
|
||||
item.render(tile, matrixStack, this.random, partialTicks, k, i1, iRenderTypeBuffer);
|
||||
BlockPos tilePos = tile.getPos();
|
||||
matrixStack.translate(-tilePos.getX(), -tilePos.getY(), -tilePos.getZ());
|
||||
for (PipeItem item : tile.getItems()) {
|
||||
matrixStack.push();
|
||||
item.render(tile, matrixStack, this.random, partialTicks, light, overlay, buffer);
|
||||
matrixStack.pop();
|
||||
}
|
||||
matrixStack.pop();
|
||||
}
|
||||
if (tile.cover != null) {
|
||||
matrixStack.push();
|
||||
BlockModelRenderer.enableCache();
|
||||
for (RenderType layer : RenderType.getBlockRenderTypes()) {
|
||||
if (!RenderTypeLookup.canRenderInLayer(tile.cover, layer))
|
||||
continue;
|
||||
ForgeHooksClient.setRenderLayer(layer);
|
||||
Minecraft.getInstance().getBlockRendererDispatcher().renderBlock(tile.cover, matrixStack, buffer, light, overlay, EmptyModelData.INSTANCE);
|
||||
}
|
||||
ForgeHooksClient.setRenderLayer(null);
|
||||
BlockModelRenderer.disableCache();
|
||||
matrixStack.pop();
|
||||
}
|
||||
matrixStack.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import de.ellpeck.prettypipes.network.PipeNetwork;
|
|||
import de.ellpeck.prettypipes.pipe.containers.MainPipeContainer;
|
||||
import de.ellpeck.prettypipes.pressurizer.PressurizerTileEntity;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.ChestBlock;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
|
@ -21,15 +22,21 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
import net.minecraft.tileentity.ChestTileEntity;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
@ -66,6 +73,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
public final Queue<NetworkLock> craftIngredientRequests = new LinkedList<>();
|
||||
public final List<Pair<BlockPos, ItemStack>> craftResultRequests = new ArrayList<>();
|
||||
public PressurizerTileEntity pressurizer;
|
||||
public BlockState cover;
|
||||
public int moduleDropCheck;
|
||||
protected List<PipeItem> items;
|
||||
private int lastItemAmount;
|
||||
|
@ -84,6 +92,8 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
compound.put("modules", this.modules.serializeNBT());
|
||||
compound.putInt("module_drop_check", this.moduleDropCheck);
|
||||
compound.put("requests", Utility.serializeAll(this.craftIngredientRequests));
|
||||
if (this.cover != null)
|
||||
compound.put("cover", NBTUtil.writeBlockState(this.cover));
|
||||
ListNBT results = new ListNBT();
|
||||
for (Pair<BlockPos, ItemStack> triple : this.craftResultRequests) {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
|
@ -99,6 +109,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
public void read(BlockState state, CompoundNBT compound) {
|
||||
this.modules.deserializeNBT(compound.getCompound("modules"));
|
||||
this.moduleDropCheck = compound.getInt("module_drop_check");
|
||||
this.cover = compound.contains("cover") ? NBTUtil.readBlockState(compound.getCompound("cover")) : null;
|
||||
this.craftIngredientRequests.clear();
|
||||
this.craftIngredientRequests.addAll(Utility.deserializeAll(compound.getList("requests", NBT.TAG_COMPOUND), NetworkLock::new));
|
||||
this.craftResultRequests.clear();
|
||||
|
@ -128,6 +139,11 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
items.addAll(Utility.deserializeAll(nbt.getList("items", NBT.TAG_COMPOUND), PipeItem::load));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
|
||||
this.read(this.getBlockState(), pkt.getNbtCompound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
// invalidate our pressurizer reference if it was removed
|
||||
|
@ -355,4 +371,11 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
|
|||
public Container createMenu(int window, PlayerInventory inv, PlayerEntity player) {
|
||||
return new MainPipeContainer(Registry.pipeContainer, window, player, PipeTileEntity.this.pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public AxisAlignedBB getRenderBoundingBox() {
|
||||
// our render bounding box should always be the full block in case we're covered
|
||||
return new AxisAlignedBB(this.pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,11 +78,6 @@ public class PressurizerTileEntity extends TileEntity implements INamedContainer
|
|||
this.read(state, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SUpdateTileEntityPacket getUpdatePacket() {
|
||||
return new SUpdateTileEntityPacket(this.pos, -1, this.write(new CompoundNBT()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
|
||||
this.read(this.getBlockState(), pkt.getNbtCompound());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"item.prettypipes.wrench": "Pipe Wrench",
|
||||
"info.prettypipes.wrench": "Allows modifying pipe connections\nPlaces blocks in offhand as covers\nSneak to remove cover or pipe",
|
||||
"item.prettypipes.blank_module": "Blank Module",
|
||||
"item.prettypipes.pipe_frame": "Pipe Frame",
|
||||
"info.prettypipes.pipe_frame": "Attach to a pipe or pipe-adjacent block\nShows amount of an item in the pipe's network",
|
||||
|
|
Loading…
Reference in New Issue