From 610a1ca61c2e24c3d1250cddd93b792b3d0a671d Mon Sep 17 00:00:00 2001 From: Michael Hillcox Date: Sat, 9 Jan 2021 15:39:18 +0000 Subject: [PATCH] Extended base tile entity, added battery box base tile, and more --- .../api/energy/IProvidesEnergy.java | 4 + .../common/blocks/BlockShapes.java | 44 +++++ .../common/blocks/FunctionalBlock.java | 155 ++++++++++++++++++ .../blocks/functional/BatteryBoxBlock.java | 62 ++++--- .../common/blocks/functional/FeederBlock.java | 59 +------ .../common/blocks/package-info.java | 7 + .../common/tiles/BatteryBoxTile.java | 6 + 7 files changed, 262 insertions(+), 75 deletions(-) create mode 100644 src/main/java/de/ellpeck/actuallyadditions/api/energy/IProvidesEnergy.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/common/blocks/BlockShapes.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/common/blocks/FunctionalBlock.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/common/blocks/package-info.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/common/tiles/BatteryBoxTile.java diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/energy/IProvidesEnergy.java b/src/main/java/de/ellpeck/actuallyadditions/api/energy/IProvidesEnergy.java new file mode 100644 index 000000000..71b9d3765 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/api/energy/IProvidesEnergy.java @@ -0,0 +1,4 @@ +package de.ellpeck.actuallyadditions.api.energy; + +public interface IProvidesEnergy { +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/BlockShapes.java b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/BlockShapes.java new file mode 100644 index 000000000..29353548f --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/BlockShapes.java @@ -0,0 +1,44 @@ +package de.ellpeck.actuallyadditions.common.blocks; + +import net.minecraft.block.Block; +import net.minecraft.util.math.shapes.IBooleanFunction; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; + +import java.util.stream.Stream; + +/** + * This class just contains messy code for the block shapes. + */ +public final class BlockShapes { + public static final VoxelShape BATTERYBOX_SHAPE = Stream.of( + Block.makeCuboidShape(2, 1, 1, 14, 2, 2), Block.makeCuboidShape(0, 0, 0, 16, 1, 16), + Block.makeCuboidShape(2, 2, 2, 14, 5, 14), Block.makeCuboidShape(5, 5, 5, 6, 7, 6), + Block.makeCuboidShape(10, 5, 10, 11, 7, 11), Block.makeCuboidShape(5, 5, 10, 6, 7, 11), + Block.makeCuboidShape(1, 1, 14, 2, 6, 15), Block.makeCuboidShape(14, 1, 14, 15, 6, 15), + Block.makeCuboidShape(1, 1, 1, 2, 6, 2), Block.makeCuboidShape(14, 1, 1, 15, 6, 2), + Block.makeCuboidShape(1, 5, 2, 2, 6, 14), Block.makeCuboidShape(14, 1, 2, 15, 2, 14), + Block.makeCuboidShape(14, 5, 2, 15, 6, 14), Block.makeCuboidShape(1, 1, 2, 2, 2, 14), + Block.makeCuboidShape(2, 5, 14, 14, 6, 15), Block.makeCuboidShape(2, 5, 1, 14, 6, 2), + Block.makeCuboidShape(2, 1, 14, 14, 2, 15), Block.makeCuboidShape(10, 5, 5, 11, 7, 6), + Block.makeCuboidShape(5.5, 6, 6, 6, 7, 10), Block.makeCuboidShape(10, 6, 6, 10.5, 7, 10), + Block.makeCuboidShape(6, 6, 5.5, 10, 7, 6), Block.makeCuboidShape(6, 6, 10, 10, 7, 10.5), + Block.makeCuboidShape(6, 5, 6, 10, 7, 10) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); + + public static final VoxelShape FEEDER_SHAPE = Stream.of( + Block.makeCuboidShape(0, 15, 0, 1, 16, 16), Block.makeCuboidShape(15, 15, 0, 16, 16, 16), + Block.makeCuboidShape(1, 15, 0, 15, 16, 1), Block.makeCuboidShape(1, 15, 15, 15, 16, 16), + Block.makeCuboidShape(1, 0, 15, 15, 1, 16), Block.makeCuboidShape(1, 0, 0, 15, 1, 1), + Block.makeCuboidShape(15, 0, 0, 16, 1, 16), Block.makeCuboidShape(0, 0, 0, 1, 1, 16), + Block.makeCuboidShape(0, 1, 15, 1, 15, 16), Block.makeCuboidShape(15, 1, 15, 16, 15, 16), + Block.makeCuboidShape(15, 1, 0, 16, 15, 1), Block.makeCuboidShape(0, 1, 0, 1, 15, 1), + Block.makeCuboidShape(11, 14, 11, 12, 15, 12), Block.makeCuboidShape(11, 14, 4, 12, 15, 5), + Block.makeCuboidShape(4, 14, 11, 5, 15, 12), Block.makeCuboidShape(4, 14, 4, 5, 15, 5), + Block.makeCuboidShape(4, 13, 4, 12, 14, 12), Block.makeCuboidShape(4, 14, 12, 12, 15, 15), + Block.makeCuboidShape(4, 14, 1, 12, 15, 4), Block.makeCuboidShape(1, 14, 1, 4, 15, 15), + Block.makeCuboidShape(12, 14, 1, 15, 15, 15), Block.makeCuboidShape(1, 1, 1, 15, 2, 15), + Block.makeCuboidShape(14, 2, 1, 15, 14, 15), Block.makeCuboidShape(1, 2, 1, 2, 14, 15), + Block.makeCuboidShape(2, 2, 14, 14, 14, 15), Block.makeCuboidShape(2, 2, 1, 14, 14, 2) + ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/FunctionalBlock.java b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/FunctionalBlock.java new file mode 100644 index 000000000..8d853f2fc --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/FunctionalBlock.java @@ -0,0 +1,155 @@ +package de.ellpeck.actuallyadditions.common.blocks; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; + +import javax.annotation.Nullable; +import java.util.function.Supplier; + +/** + * Abstract class to wrap shared logic and controls for Block Tiles (Tile Entities). + * Do not use for normal blocks! + */ +public abstract class FunctionalBlock extends ActuallyBlock { + private final Supplier createTile; + private final Class tileClass; + + public FunctionalBlock(Properties properties, Supplier tile, Class tileClass) { + super(properties); + this.createTile = tile; + this.tileClass = tileClass; + } + + /** + * Not not override without first calling super otherwise right click will not work. This also handles instance checking + * although, not super pretty. It'll do :D + */ + @Override + public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { + // We should always have a tile + TileEntity tile = worldIn.getTileEntity(pos); + if (tile == null || !tile.getClass().isInstance(this.tileClass)) { + return ActionResultType.FAIL; + } + + return this.onRightClick(new ActivatedContext(tile, state, pos, worldIn, player, handIn, hit, player.getHeldItem(handIn))); + } + + public abstract ActionResultType onRightClick(ActivatedContext context); + + /** + * This is always true. Do not override as this class is only for functional blocks. + */ + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + /** + * Creates a tile based on our supplier. + */ + @Nullable + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return this.createTile.get(); + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + super.onReplaced(state, worldIn, pos, newState, isMoving); + System.out.println("Hello"); + + if (newState != state && this.dropsInventory(worldIn, pos)) { + System.out.println("Should have dropped"); + } + } + + /** + * Controls if the tile drops items when being broken. By default we'll try and drop anything in and inv cap + * unless told not to. + */ + public boolean dropsInventory(World world, BlockPos pos) { + return true; + } + + public static class ActivatedContext { + TileEntity entity; + BlockState state; + BlockPos pos; + World world; + PlayerEntity player; + Hand hand; + BlockRayTraceResult trace; + ItemStack heldItem; + + public ActivatedContext(TileEntity entity, BlockState state, BlockPos pos, World world, PlayerEntity player, Hand hand, BlockRayTraceResult trace, ItemStack heldItem) { + this.entity = entity; + this.state = state; + this.pos = pos; + this.world = world; + this.player = player; + this.hand = hand; + this.trace = trace; + this.heldItem = heldItem; + } + + public TileEntity getTile() { + return this.entity; + } + + public BlockState getState() { + return this.state; + } + + public BlockPos getPos() { + return this.pos; + } + + public World getWorld() { + return this.world; + } + + public PlayerEntity getPlayer() { + return this.player; + } + + public Hand getHand() { + return this.hand; + } + + public BlockRayTraceResult getTrace() { + return this.trace; + } + + public ItemStack getHeldItem() { + return this.heldItem; + } + + /** + * Simple wrapper, does not guarantee an inventory. + */ + public LazyOptional getInv() { + return this.entity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); + } + + /** + * Simple wrapper, does not guarantee energy + */ + public LazyOptional getEnergy() { + return this.entity.getCapability(CapabilityEnergy.ENERGY); + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/BatteryBoxBlock.java b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/BatteryBoxBlock.java index 26f8be2e7..ee8db45b5 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/BatteryBoxBlock.java +++ b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/BatteryBoxBlock.java @@ -1,40 +1,54 @@ package de.ellpeck.actuallyadditions.common.blocks.functional; -import de.ellpeck.actuallyadditions.common.blocks.ActuallyBlock; -import net.minecraft.block.Block; +import de.ellpeck.actuallyadditions.common.blocks.BlockShapes; +import de.ellpeck.actuallyadditions.common.blocks.FunctionalBlock; +import de.ellpeck.actuallyadditions.common.items.useables.BatteryItem; +import de.ellpeck.actuallyadditions.common.tiles.BatteryBoxTile; import net.minecraft.block.BlockState; import net.minecraft.block.material.Material; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResultType; import net.minecraft.util.math.BlockPos; -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; import net.minecraft.world.IBlockReader; -import java.util.stream.Stream; - -public class BatteryBoxBlock extends ActuallyBlock { +public class BatteryBoxBlock extends FunctionalBlock { public BatteryBoxBlock() { - super(Properties.create(Material.ROCK)); + super(Properties.create(Material.ROCK), BatteryBoxTile::new, BatteryBoxTile.class); } - private static final VoxelShape BATTERYBOX_SHAPE = Stream.of( - Block.makeCuboidShape(2, 1, 1, 14, 2, 2), Block.makeCuboidShape(0, 0, 0, 16, 1, 16), - Block.makeCuboidShape(2, 2, 2, 14, 5, 14), Block.makeCuboidShape(5, 5, 5, 6, 7, 6), - Block.makeCuboidShape(10, 5, 10, 11, 7, 11), Block.makeCuboidShape(5, 5, 10, 6, 7, 11), - Block.makeCuboidShape(1, 1, 14, 2, 6, 15), Block.makeCuboidShape(14, 1, 14, 15, 6, 15), - Block.makeCuboidShape(1, 1, 1, 2, 6, 2), Block.makeCuboidShape(14, 1, 1, 15, 6, 2), - Block.makeCuboidShape(1, 5, 2, 2, 6, 14), Block.makeCuboidShape(14, 1, 2, 15, 2, 14), - Block.makeCuboidShape(14, 5, 2, 15, 6, 14), Block.makeCuboidShape(1, 1, 2, 2, 2, 14), - Block.makeCuboidShape(2, 5, 14, 14, 6, 15), Block.makeCuboidShape(2, 5, 1, 14, 6, 2), - Block.makeCuboidShape(2, 1, 14, 14, 2, 15), Block.makeCuboidShape(10, 5, 5, 11, 7, 6), - Block.makeCuboidShape(5.5, 6, 6, 6, 7, 10), Block.makeCuboidShape(10, 6, 6, 10.5, 7, 10), - Block.makeCuboidShape(6, 6, 5.5, 10, 7, 6), Block.makeCuboidShape(6, 6, 10, 10, 7, 10.5), - Block.makeCuboidShape(6, 5, 6, 10, 7, 10) - ).reduce((v1, v2) -> {return VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR);}).get(); - @Override public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - return BATTERYBOX_SHAPE; + return BlockShapes.BATTERYBOX_SHAPE; + } + + @Override + public ActionResultType onRightClick(ActivatedContext context) { + ItemStack held = context.getHeldItem(); + ItemStack invItem = context.getInv().map(e -> e.getStackInSlot(0)).orElse(ItemStack.EMPTY); + + if (!held.isEmpty()) { + // Place the battery onto the battery box + if (held.getItem() instanceof BatteryItem && invItem.isEmpty()) { + ItemStack inserted = context.getInv().map(e -> e.insertItem(0, held.copy(), false)).orElse(held); + + // Only remove from the player if the insert was successful. + if (inserted.isEmpty()) { + context.getPlayer().setHeldItem(context.getHand(), ItemStack.EMPTY); + } + } + } else { + if (!invItem.isEmpty()) { + ItemStack removed = context.getInv().map(e -> e.extractItem(0, 1, false)).orElse(ItemStack.EMPTY); + + // Only remove from the player if the insert was successful. + if (!removed.isEmpty()) { + context.getPlayer().setHeldItem(context.getHand(), removed); + } + } + } + + return ActionResultType.SUCCESS; } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/FeederBlock.java b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/FeederBlock.java index 3997f0ccf..d464f4bf8 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/FeederBlock.java +++ b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/functional/FeederBlock.java @@ -1,79 +1,36 @@ package de.ellpeck.actuallyadditions.common.blocks.functional; -import de.ellpeck.actuallyadditions.common.blocks.ActuallyBlock; -import de.ellpeck.actuallyadditions.common.tiles.ActuallyTiles; +import de.ellpeck.actuallyadditions.common.blocks.BlockShapes; +import de.ellpeck.actuallyadditions.common.blocks.FunctionalBlock; import de.ellpeck.actuallyadditions.common.tiles.FeederTileEntity; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.material.Material; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; -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; import net.minecraft.world.IBlockReader; -import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkHooks; -import javax.annotation.Nullable; -import java.util.stream.Stream; - -public class FeederBlock extends ActuallyBlock { +public class FeederBlock extends FunctionalBlock { public FeederBlock() { - super(Properties.create(Material.ROCK)); - } - - private static final VoxelShape FEEDER_SHAPE = Stream.of( - Block.makeCuboidShape(0, 15, 0, 1, 16, 16), Block.makeCuboidShape(15, 15, 0, 16, 16, 16), - Block.makeCuboidShape(1, 15, 0, 15, 16, 1), Block.makeCuboidShape(1, 15, 15, 15, 16, 16), - Block.makeCuboidShape(1, 0, 15, 15, 1, 16), Block.makeCuboidShape(1, 0, 0, 15, 1, 1), - Block.makeCuboidShape(15, 0, 0, 16, 1, 16), Block.makeCuboidShape(0, 0, 0, 1, 1, 16), - Block.makeCuboidShape(0, 1, 15, 1, 15, 16), Block.makeCuboidShape(15, 1, 15, 16, 15, 16), - Block.makeCuboidShape(15, 1, 0, 16, 15, 1), Block.makeCuboidShape(0, 1, 0, 1, 15, 1), - Block.makeCuboidShape(11, 14, 11, 12, 15, 12), Block.makeCuboidShape(11, 14, 4, 12, 15, 5), - Block.makeCuboidShape(4, 14, 11, 5, 15, 12), Block.makeCuboidShape(4, 14, 4, 5, 15, 5), - Block.makeCuboidShape(4, 13, 4, 12, 14, 12), Block.makeCuboidShape(4, 14, 12, 12, 15, 15), - Block.makeCuboidShape(4, 14, 1, 12, 15, 4), Block.makeCuboidShape(1, 14, 1, 4, 15, 15), - Block.makeCuboidShape(12, 14, 1, 15, 15, 15), Block.makeCuboidShape(1, 1, 1, 15, 2, 15), - Block.makeCuboidShape(14, 2, 1, 15, 14, 15), Block.makeCuboidShape(1, 2, 1, 2, 14, 15), - Block.makeCuboidShape(2, 2, 14, 14, 14, 15), Block.makeCuboidShape(2, 2, 1, 14, 14, 2) - ).reduce((v1, v2) -> VoxelShapes.combineAndSimplify(v1, v2, IBooleanFunction.OR)).get(); - - @Nullable - @Override - public TileEntity createTileEntity(BlockState state, IBlockReader world) { - return ActuallyTiles.FEEDER_TILE.get().create(); + super(Properties.create(Material.ROCK), FeederTileEntity::new, FeederTileEntity.class); } @Override - public boolean hasTileEntity(BlockState state) { - return true; - } - - @Override - public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - if (worldIn.isRemote) { + public ActionResultType onRightClick(ActivatedContext context) { + if (context.getWorld().isRemote) { return ActionResultType.SUCCESS; } - TileEntity te = worldIn.getTileEntity(pos); - if (! (te instanceof FeederTileEntity)) { - return ActionResultType.FAIL; - } - - NetworkHooks.openGui((ServerPlayerEntity) player, (FeederTileEntity) te, pos); + NetworkHooks.openGui((ServerPlayerEntity) context.getPlayer(), (FeederTileEntity) context.getTile(), context.getPos()); return ActionResultType.SUCCESS; } @Override public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - return FEEDER_SHAPE; + return BlockShapes.FEEDER_SHAPE; } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/blocks/package-info.java b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/package-info.java new file mode 100644 index 000000000..f58e15a1d --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/blocks/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package de.ellpeck.actuallyadditions.common.blocks; + +import mcp.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/de/ellpeck/actuallyadditions/common/tiles/BatteryBoxTile.java b/src/main/java/de/ellpeck/actuallyadditions/common/tiles/BatteryBoxTile.java new file mode 100644 index 000000000..ee55db26d --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/common/tiles/BatteryBoxTile.java @@ -0,0 +1,6 @@ +package de.ellpeck.actuallyadditions.common.tiles; + +import net.minecraft.tileentity.TileEntity; + +public class BatteryBoxTile extends TileEntity { +}