added the adept hopper

This commit is contained in:
Ellpeck 2018-12-27 13:57:23 +01:00
parent 7ee06acffa
commit 104b5538e5
14 changed files with 715 additions and 6 deletions

View file

@ -0,0 +1,133 @@
package de.ellpeck.naturesaura.blocks;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityGratedChute;
import net.minecraft.block.BlockHopper;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
import java.util.List;
public class BlockGratedChute extends BlockContainerImpl {
public static final PropertyDirection FACING = BlockHopper.FACING;
private static final AxisAlignedBB BASE_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.625D, 1.0D);
private static final AxisAlignedBB SOUTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D);
private static final AxisAlignedBB NORTH_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D);
private static final AxisAlignedBB WEST_AABB = new AxisAlignedBB(0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
private static final AxisAlignedBB EAST_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D);
public BlockGratedChute() {
super(Material.IRON, "grated_chute", TileEntityGratedChute.class, "grated_chute");
this.setHardness(3.0F);
this.setResistance(8.0F);
this.setSoundType(SoundType.METAL);
}
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
return FULL_BLOCK_AABB;
}
@Override
public void addCollisionBoxToList(IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, @Nullable Entity entityIn, boolean isActualState) {
addCollisionBoxToList(pos, entityBox, collidingBoxes, BASE_AABB);
addCollisionBoxToList(pos, entityBox, collidingBoxes, EAST_AABB);
addCollisionBoxToList(pos, entityBox, collidingBoxes, WEST_AABB);
addCollisionBoxToList(pos, entityBox, collidingBoxes, SOUTH_AABB);
addCollisionBoxToList(pos, entityBox, collidingBoxes, NORTH_AABB);
}
@Override
public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) {
EnumFacing newFacing = facing.getOpposite();
if (newFacing == EnumFacing.UP)
newFacing = EnumFacing.DOWN;
return this.getDefaultState().withProperty(FACING, newFacing);
}
@Override
public boolean isTopSolid(IBlockState state) {
return true;
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state) {
return EnumBlockRenderType.MODEL;
}
@Override
public boolean isFullCube(IBlockState state) {
return false;
}
@Override
public boolean isOpaqueCube(IBlockState state) {
return false;
}
@Override
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) {
return true;
}
@Override
public boolean hasComparatorInputOverride(IBlockState state) {
return true;
}
@Override
public int getComparatorInputOverride(IBlockState blockState, World worldIn, BlockPos pos) {
return 0; //TODO Comparator
}
@Override
@SideOnly(Side.CLIENT)
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT_MIPPED;
}
@Override
public IBlockState getStateFromMeta(int meta) {
return this.getDefaultState().withProperty(FACING, EnumFacing.byIndex(meta));
}
@Override
public int getMetaFromState(IBlockState state) {
return state.getValue(FACING).getIndex();
}
@Override
public IBlockState withRotation(IBlockState state, Rotation rot) {
return state.withProperty(FACING, rot.rotate(state.getValue(FACING)));
}
@Override
public IBlockState withMirror(IBlockState state, Mirror mirrorIn) {
return state.withRotation(mirrorIn.toRotation(state.getValue(FACING)));
}
@Override
protected BlockStateContainer createBlockState() {
return new BlockStateContainer(this, FACING);
}
@Override
public BlockFaceShape getBlockFaceShape(IBlockAccess worldIn, IBlockState state, BlockPos pos, EnumFacing face) {
return face == EnumFacing.UP ? BlockFaceShape.BOWL : BlockFaceShape.UNDEFINED;
}
}

View file

@ -39,4 +39,5 @@ public final class ModBlocks {
public static final Block SPAWN_LAMP = new BlockSpawnLamp(); public static final Block SPAWN_LAMP = new BlockSpawnLamp();
public static final Block ANIMAL_GENERATOR = new BlockAnimalGenerator(); public static final Block ANIMAL_GENERATOR = new BlockAnimalGenerator();
public static final Block END_FLOWER = new BlockEndFlower(); public static final Block END_FLOWER = new BlockEndFlower();
public static final Block GRATED_CHUTE = new BlockGratedChute();
} }

View file

@ -22,7 +22,9 @@ public class ItemStackHandlerNA extends ItemStackHandler {
@Override @Override
protected void onContentsChanged(int slot) { protected void onContentsChanged(int slot) {
if (this.sendToClients && !this.tile.getWorld().isRemote) { if (this.tile != null) {
this.tile.markDirty();
if (this.sendToClients && !this.tile.getWorld().isRemote)
this.tile.sendToClients(); this.tile.sendToClients();
} }
} }

View file

@ -0,0 +1,140 @@
package de.ellpeck.naturesaura.blocks.tiles;
import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.blocks.BlockGratedChute;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import java.util.List;
public class TileEntityGratedChute extends TileEntityImpl implements ITickable {
private final ItemStackHandlerNA items = new ItemStackHandlerNA(1, this, false) {
@Override
protected boolean canExtract(ItemStack stack, int slot, int amount) {
return TileEntityGratedChute.this.redstonePower <= 0;
}
@Override
protected boolean canInsert(ItemStack stack, int slot) {
return TileEntityGratedChute.this.isItemInFrame(stack);
}
};
private int cooldown;
@Override
public void update() {
if (!this.world.isRemote) {
if (this.cooldown <= 0) {
this.cooldown = 6;
if (this.redstonePower > 0)
return;
ItemStack curr = this.items.getStackInSlot(0);
push:
if (!curr.isEmpty()) {
IBlockState state = this.world.getBlockState(this.pos);
EnumFacing facing = state.getValue(BlockGratedChute.FACING);
TileEntity tile = this.world.getTileEntity(this.pos.offset(facing));
if (tile == null || !tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY,
facing.getOpposite()))
break push;
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY,
facing.getOpposite());
if (handler == null)
break push;
for (int i = 0; i < handler.getSlots(); i++) {
ItemStack theoreticalDrain = this.items.extractItem(0, 1, true);
if (!theoreticalDrain.isEmpty()) {
ItemStack left = handler.insertItem(i, theoreticalDrain, false);
if (left.isEmpty()) {
this.items.extractItem(0, 1, false);
break push;
}
}
}
}
pull:
if (curr.isEmpty() || curr.getCount() < curr.getMaxStackSize()) {
List<EntityItem> items = this.world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(
this.pos.getX(), this.pos.getY() + 0.5, this.pos.getZ(),
this.pos.getX() + 1, this.pos.getY() + 2, this.pos.getZ() + 1));
for (EntityItem item : items) {
if (item.isDead)
continue;
ItemStack stack = item.getItem();
if (stack.isEmpty())
continue;
ItemStack left = this.items.insertItem(0, stack, false);
if (!ItemStack.areItemStacksEqual(stack, left)) {
if (left.isEmpty())
item.setDead();
else
item.setItem(left);
break pull;
}
}
TileEntity tileUp = this.world.getTileEntity(this.pos.up());
if (tileUp == null || !tileUp.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN))
break pull;
IItemHandler handlerUp = tileUp.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.DOWN);
if (handlerUp == null)
break pull;
for (int i = 0; i < handlerUp.getSlots(); i++) {
ItemStack theoreticalDrain = handlerUp.extractItem(i, 1, true);
if (!theoreticalDrain.isEmpty()) {
ItemStack left = this.items.insertItem(0, theoreticalDrain, false);
if (left.isEmpty()) {
handlerUp.extractItem(i, 1, false);
break pull;
}
}
}
}
} else
this.cooldown--;
}
}
private boolean isItemInFrame(ItemStack stack) {
List<EntityItemFrame> frames = Helper.getAttachedItemFrames(this.world, this.pos);
if (frames.isEmpty())
return true;
for (EntityItemFrame frame : frames) {
ItemStack frameStack = frame.getDisplayedItem();
if (Helper.areItemsEqual(stack, frameStack, true)) {
return true;
}
}
return false;
}
@Override
public void writeNBT(NBTTagCompound compound, SaveType type) {
super.writeNBT(compound, type);
compound.setInteger("cooldown", this.cooldown);
}
@Override
public void readNBT(NBTTagCompound compound, SaveType type) {
super.readNBT(compound, type);
this.cooldown = compound.getInteger("cooldown");
}
@Override
public IItemHandlerModifiable getItemHandler(EnumFacing facing) {
return this.items;
}
}

View file

@ -24,12 +24,11 @@ public class TileEntityHopperUpgrade extends TileEntityImpl implements ITickable
if (IAuraChunk.getAuraInArea(this.world, this.pos, 25) < 1000) if (IAuraChunk.getAuraInArea(this.world, this.pos, 25) < 1000)
return; return;
TileEntity tile = this.world.getTileEntity(this.pos.down()); TileEntity tile = this.world.getTileEntity(this.pos.down());
if (!(tile instanceof TileEntityHopper) || !BlockHopper.isEnabled(tile.getBlockMetadata())) if (!isValidHopper(tile))
return; return;
TileEntityHopper hopper = (TileEntityHopper) tile; if (!tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP))
if (!hopper.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP))
return; return;
IItemHandler handler = hopper.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP); IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP);
if (handler == null) if (handler == null)
return; return;
@ -67,4 +66,12 @@ public class TileEntityHopperUpgrade extends TileEntityImpl implements ITickable
} }
} }
} }
private static boolean isValidHopper(TileEntity tile) {
if (tile instanceof TileEntityHopper)
return BlockHopper.isEnabled(tile.getBlockMetadata());
if (tile instanceof TileEntityGratedChute)
return ((TileEntityGratedChute) tile).redstonePower <= 0;
return false;
}
} }

View file

@ -0,0 +1,35 @@
{
"forge_marker": 1,
"defaults": {
"model": "naturesaura:grated_chute_down",
"textures": {
"particle": "naturesaura:blocks/grated_chute_outside",
"top": "naturesaura:blocks/grated_chute_top",
"side": "naturesaura:blocks/grated_chute_outside",
"inside": "naturesaura:blocks/grated_chute_inside"
},
"transform": "forge:default-block"
},
"variants": {
"normal": [{}],
"inventory": [{}],
"facing=down": {
"model": "naturesaura:grated_chute_down"
},
"facing=north": {
"model": "naturesaura:grated_chute_side"
},
"facing=south": {
"model": "naturesaura:grated_chute_side",
"y": 180
},
"facing=west": {
"model": "naturesaura:grated_chute_side",
"y": 270
},
"facing=east": {
"model": "naturesaura:grated_chute_side",
"y": 90
}
}
}

View file

@ -36,6 +36,7 @@ tile.naturesaura.pickup_stopper.name=Item Grounder
tile.naturesaura.spawn_lamp.name=Lamp of Sanctuary tile.naturesaura.spawn_lamp.name=Lamp of Sanctuary
tile.naturesaura.animal_generator.name=Disentangler of Mortals tile.naturesaura.animal_generator.name=Disentangler of Mortals
tile.naturesaura.end_flower.name=Rose of Oblivion tile.naturesaura.end_flower.name=Rose of Oblivion
tile.naturesaura.grated_chute.name=Adept Hopper
item.naturesaura.eye.name=Environmental Eye item.naturesaura.eye.name=Environmental Eye
item.naturesaura.eye_improved.name=Environmental Ocular item.naturesaura.eye_improved.name=Environmental Ocular

View file

@ -0,0 +1,173 @@
{
"ambientocclusion": false,
"elements": [
{
"from": [0, 10, 0],
"to": [16, 11, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#inside"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [0, 11, 0],
"to": [2, 16, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [14, 11, 0],
"to": [16, 16, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [2, 11, 0],
"to": [14, 16, 2],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [2, 11, 14],
"to": [14, 16, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [4, 4, 4],
"to": [12, 10, 12],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#side"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [6, 0, 6],
"to": [10, 4, 10],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#side"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
}
]
}

View file

@ -0,0 +1,173 @@
{
"ambientocclusion": false,
"elements": [
{
"from": [0, 10, 0],
"to": [16, 11, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#inside"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [0, 11, 0],
"to": [2, 16, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [14, 11, 0],
"to": [16, 16, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [2, 11, 0],
"to": [14, 16, 2],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [2, 11, 14],
"to": [14, 16, 16],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#top"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [4, 4, 4],
"to": [12, 10, 12],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#side"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
},
{
"from": [6, 4, 0],
"to": [10, 8, 4],
"faces": {
"down": {
"texture": "#side"
},
"up": {
"texture": "#side"
},
"north": {
"texture": "#side"
},
"south": {
"texture": "#side"
},
"west": {
"texture": "#side"
},
"east": {
"texture": "#side"
}
}
}
]
}

View file

@ -0,0 +1,21 @@
{
"name": "Adept Hopper",
"icon": "naturesaura:grated_chute",
"category": "devices",
"advancement": "naturesaura:infused_materials",
"pages": [
{
"type": "text",
"text": "A lot of times when dealing with mechanical devices, $(thing)transporting items$() is of great importance and can become a nuisance if done on a large scale, especially because of the lack of $(thing)filtering$() abilities. The $(item)Adept Hopper$() creates the ability to filter items travelling through $(item)Hoppers$() with ease."
},
{
"type": "text",
"text": "The $(item)Adept Hopper$() works just like a normal $(item)Hopper$(), except that it is a bit faster and that it can filter items as follows: Attaching any number of $(item)Item Frames$() to any side of it and placing items inside will cause $(thing)only those items$() to be let through. This counts both for pulling items from chests and the world and for having items inserted into it.$(p)It should additionally be noted that the $(l:using/hopper_upgrade)Hopper Enhancement$() can be combined with this to pick up only filtered items."
},
{
"type": "crafting",
"text": "Creating the $(item)Adept Hopper$()",
"recipe": "naturesaura:grated_chute"
}
]
}

View file

@ -0,0 +1,23 @@
{
"type": "forge:ore_shaped",
"pattern": [
"IHI",
"ICI",
" I "
],
"key": {
"C": {
"type": "forge:ore_dict",
"ore": "chestWood"
},
"I": {
"item": "naturesaura:infused_iron"
},
"H": {
"item": "minecraft:hopper"
}
},
"result": {
"item": "naturesaura:grated_chute"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B