simple-tech

Minecraft: Better than Adventure! mod that adds simple blocks to automate tasks
git clone git://memoryshards.xyz/simple-tech.git
Log | Files | Refs | README | LICENSE

BlockAllocator.java (14674B)


      1 package ambos.simpletech.block;
      2 
      3 import net.minecraft.core.block.Block;
      4 import net.minecraft.core.block.BlockTileEntity;
      5 import net.minecraft.core.block.entity.TileEntity;
      6 import net.minecraft.core.block.entity.TileEntityChest;
      7 import net.minecraft.core.block.entity.TileEntityFurnace;
      8 import net.minecraft.core.block.material.Material;
      9 import net.minecraft.core.entity.Entity;
     10 import net.minecraft.core.entity.EntityItem;
     11 import net.minecraft.core.entity.EntityLiving;
     12 import net.minecraft.core.entity.player.EntityPlayer;
     13 import net.minecraft.core.entity.vehicle.EntityMinecart;
     14 import net.minecraft.core.item.ItemStack;
     15 import net.minecraft.core.player.inventory.IInventory;
     16 import net.minecraft.core.player.inventory.InventoryLargeChest;
     17 import net.minecraft.core.sound.SoundType;
     18 import net.minecraft.core.util.helper.Direction;
     19 import net.minecraft.core.util.helper.Side;
     20 import net.minecraft.core.util.phys.AABB;
     21 import net.minecraft.core.world.World;
     22 
     23 import java.util.List;
     24 import java.util.Random;
     25 
     26 import ambos.simpletech.IPlayerDisplayer;
     27 import ambos.simpletech.SimpleTech;
     28 import ambos.simpletech.block.entity.TileEntityAllocator;
     29 
     30 public class BlockAllocator extends BlockTileEntity {
     31     private final boolean allowFiltering;
     32     private final boolean subItemFiltering;
     33 
     34     public BlockAllocator(String key, int id, Material material, boolean allowFiltering, boolean subItemFiltering) {
     35         super(key, id, material);
     36         this.allowFiltering = allowFiltering;
     37         this.subItemFiltering = subItemFiltering;
     38     }
     39 
     40     @Override
     41     protected TileEntity getNewBlockEntity() {
     42         return new TileEntityAllocator();
     43     }
     44 
     45     @Override
     46     public boolean blockActivated(World world, int x, int y, int z, EntityPlayer player) {
     47         if (!this.allowFiltering) {
     48             return false;
     49         } else if (world.isClientSide) {
     50             return true;
     51         } else {
     52             TileEntityAllocator allocator = (TileEntityAllocator) world.getBlockTileEntity(x, y, z);
     53             ((IPlayerDisplayer) player).simple_tech$displayGUIAllocator(allocator);
     54             return true;
     55         }
     56     }
     57 
     58     @Override
     59     public void updateTick(World world, int x, int y, int z, Random rand) {
     60         if (world.isBlockIndirectlyGettingPowered(x, y, z) || world.isBlockIndirectlyGettingPowered(x, y + 1, z)) {
     61             this.allocateItems(world, x, y, z, rand);
     62         }
     63     }
     64 
     65     @Override
     66     public void onNeighborBlockChange(World world, int x, int y, int z, int blockId) {
     67         if (blockId > 0 && Block.blocksList[blockId].canProvidePower() &&
     68                 (world.isBlockIndirectlyGettingPowered(x, y, z) ||
     69                         world.isBlockIndirectlyGettingPowered(x, y + 1, z))) {
     70             world.scheduleBlockUpdate(x, y, z, this.id, this.tickRate());
     71         }
     72     }
     73 
     74     @Override
     75     public int tickRate() {
     76         return 1;
     77     }
     78 
     79     @Override
     80     public void onBlockAdded(World world, int x, int y, int z) {
     81         super.onBlockAdded(world, x, y, z);
     82     }
     83 
     84     @Override
     85     public int getBlockTextureFromSideAndMetadata(Side side, int meta) {
     86         int direction = SimpleTech.get3DDirectionFromMeta(meta);
     87 
     88         if (direction > 5) {
     89             return this.atlasIndices[Side.WEST.getId()]; // Defaults to top/bottom texture.
     90         } else if (side.getId() == SimpleTech.getOppositeDirectionById(direction)) {
     91             if (side.getId() == Side.TOP.getId() || side.getId() == Side.BOTTOM.getId()) {
     92                 return this.atlasIndices[Side.TOP.getId()]; // Returns back top/bottom texture.
     93             }
     94             return this.atlasIndices[Side.NORTH.getId()]; // Returns back texture.
     95         } else if (side.getId() == direction) {
     96             if (side.getId() == Side.TOP.getId() || side.getId() == Side.BOTTOM.getId()) {
     97                 return this.atlasIndices[Side.BOTTOM.getId()]; // Returns front top/bottom texture.
     98             }
     99             return this.atlasIndices[Side.SOUTH.getId()]; // Returns front texture.
    100         } else {
    101             if (side.getId() == Side.TOP.getId() || side.getId() == Side.BOTTOM.getId()) {
    102                 return this.atlasIndices[Side.WEST.getId()]; // Returns top/bottom texture.
    103             } else {
    104                 return this.atlasIndices[Side.EAST.getId()]; // Returns side texture.
    105             }
    106         }
    107     }
    108 
    109     @Override
    110     public void onBlockPlaced(World world, int x, int y, int z, Side side, EntityLiving entity, double sideHeight) {
    111         Direction placementDirection = entity.getPlacementDirection(side).getOpposite();
    112         world.setBlockMetadataWithNotify(x, y, z, placementDirection.getId());
    113     }
    114 
    115     public int getRandomItemFromContainer(IInventory inventory, Random rand, World world, int x, int y, int z) {
    116         if (inventory == null) {
    117             return -1;
    118         } else {
    119             int i = -1;
    120             int j = 1;
    121 
    122             byte startAt = 0;
    123 
    124             if (inventory instanceof TileEntityFurnace) {
    125                 startAt = 2;
    126             }
    127 
    128             for (int k = startAt; k < inventory.getSizeInventory(); ++k) {
    129                 if (inventory.getStackInSlot(k) != null && this.passesFilter(world, x, y, z,
    130                         inventory.getStackInSlot(k)) && rand.nextInt(j) == 0) {
    131                     i = k;
    132                     ++j;
    133                 }
    134             }
    135 
    136             return i;
    137         }
    138     }
    139 
    140     protected IInventory containerAtPos(World world, int x, int y, int z) {
    141         TileEntity tile = world.getBlockTileEntity(x, y, z);
    142         return !(tile instanceof IInventory) ? null : this.getDoubleChest(world, x, y, z);
    143     }
    144 
    145     protected boolean blockingCubeAtPos(World world, int x, int y, int z) {
    146         int blockID = world.getBlockId(x, y, z);
    147         boolean isOpaque = Block.translucent[blockID];
    148 
    149         return isOpaque || blockID == Block.glass.id ||
    150                 blockID == Block.cactus.id ||
    151                 blockID == Block.cake.id ||
    152                 blockID == Block.blockSnow.id ||
    153                 blockID == Block.mobspawner.id ||
    154                 blockID == Block.fencePlanksOak.id;
    155     }
    156 
    157     private void putItemInContainer(IInventory inventory, ItemStack item, int index) {
    158         if (item != null) {
    159             if (index >= 0) {
    160                 ItemStack stack = inventory.getStackInSlot(index);
    161 
    162                 if (stack != null) {
    163                     stack.stackSize += item.stackSize;
    164                     inventory.setInventorySlotContents(index, stack);
    165                 } else {
    166                     inventory.setInventorySlotContents(index, item);
    167                 }
    168             }
    169         }
    170     }
    171 
    172     private void dispenseItem(World world, int x, int y, int z, int dx, int dy, int dz, ItemStack item, Random rand) {
    173         double d = (double) x + (double) dx * 0.5D + 0.5D;
    174         double d1 = (double) y + (double) dy * 0.5D + 0.5D;
    175         double d2 = (double) z + (double) dz * 0.5D + 0.5D;
    176         double d3 = rand.nextDouble() * 0.1D + 0.2D;
    177 
    178         EntityItem entityItem = new EntityItem(world, d, d1, d2, item);
    179 
    180         // Item movement.
    181         entityItem.xd = (double) dx * d3;
    182         entityItem.yd = (double) dy * d3;
    183         entityItem.zd = (double) dz * d3;
    184         entityItem.xd += rand.nextGaussian() * (double) 0.0075F * 6.0D;
    185         entityItem.yd += rand.nextGaussian() * (double) 0.0075F * 6.0D;
    186         entityItem.xd += rand.nextGaussian() * (double) 0.0075F * 6.0D;
    187 
    188         world.entityJoinedWorld(entityItem);
    189         world.playSoundEffect(SoundType.GUI_SOUNDS, x, y, z, "random.click", 1.0f, 1.0f);
    190 
    191         // Particle rendering.
    192         for (int i = 0; i < 10; ++i) {
    193             double d4 = rand.nextDouble() * 0.2D + 0.01D;
    194             double d5 = d + (double) dx * 0.01D + (rand.nextDouble() - 0.5D) * (double) dz * 0.5D;
    195             double d6 = d1 + (rand.nextDouble() - 0.5D) * 0.5D;
    196             double d7 = d2 + (double) dz * 0.01D + (rand.nextDouble() - 0.5D) * (double) dx * 0.5D;
    197             double d8 = (double) dx * d4 + rand.nextGaussian() * 0.01D;
    198             double d9 = -0.03D + rand.nextGaussian() * 0.01D;
    199             double d10 = (double) dz * d4 + rand.nextGaussian() * 0.01D;
    200 
    201             world.spawnParticle("smoke", d5, d6, d7, d8, d9, d10);
    202         }
    203     }
    204 
    205     private boolean outputItem(World world, int x, int y, int z, int dx, int dy, int dz, ItemStack item, Random rand) {
    206         IInventory outputContainer = this.containerAtPos(world, x + dx, y + dy, z + dz);
    207 
    208         if (outputContainer == null) {
    209             List<Entity> index = world.getEntitiesWithinAABB(IInventory.class, AABB.getBoundingBoxFromPool(
    210                     x + dx, y + dy, z + dz, x + dx + 1, y + dy + 1, z + dz + 1));
    211 
    212             if (!index.isEmpty() && (!(index.get(0) instanceof EntityMinecart) ||
    213                     ((EntityMinecart) index.get(0)).minecartType == 1)) {
    214                 outputContainer = (IInventory) index.get(0);
    215             }
    216         }
    217 
    218         if (outputContainer == null) {
    219             if (!this.blockingCubeAtPos(world, x + dx, y + dy, z + dz)) {
    220                 this.dispenseItem(world, x, y, z, dx, dy, dz, item, rand);
    221 
    222                 return true;
    223             }
    224         } else {
    225             int index1 = this.getFirstFreeInventorySlotOfKind(outputContainer, item);
    226 
    227             if (index1 >= 0) {
    228                 this.putItemInContainer(outputContainer, item, index1);
    229                 return true;
    230             }
    231         }
    232 
    233         return false;
    234     }
    235 
    236     private IInventory getDoubleChest(World world, int x, int y, int z) {
    237         TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
    238         if (!(tileEntity instanceof TileEntityChest)) {
    239             return tileEntity instanceof IInventory ? (IInventory) tileEntity : null;
    240         } else {
    241             int blockId = world.getBlockId(x, y, z);
    242 
    243             IInventory chest1 = (IInventory) world.getBlockTileEntity(x, y, z);
    244             IInventory chest2;
    245 
    246             if (world.getBlockId(x + 1, y, z) == blockId) {
    247                 chest2 = (IInventory) world.getBlockTileEntity(x + 1, y, z);
    248 
    249                 return new InventoryLargeChest("", chest1, chest2);
    250             } else if (world.getBlockId(x - 1, y, z) == blockId) {
    251                 chest2 = (IInventory) world.getBlockTileEntity(x - 1, y, z);
    252 
    253                 return new InventoryLargeChest("", chest2, chest1);
    254             } else if (world.getBlockId(x, y, z + 1) == blockId) {
    255                 chest2 = (IInventory) world.getBlockTileEntity(x, y, z + 1);
    256 
    257                 return new InventoryLargeChest("", chest1, chest2);
    258             } else if (world.getBlockId(x, y, z - 1) == blockId) {
    259                 chest2 = (IInventory) world.getBlockTileEntity(x, y, z - 1);
    260 
    261                 return new InventoryLargeChest("", chest2, chest1);
    262             } else {
    263                 return chest1;
    264             }
    265         }
    266     }
    267 
    268     private void allocateItems(World world, int x, int y, int z, Random rand) {
    269         int dx = SimpleTech.getDirectionX(world, x, y, z);
    270         int dy = SimpleTech.getDirectionY(world, x, y, z);
    271         int dz = SimpleTech.getDirectionZ(world, x, y, z);
    272 
    273         IInventory inputContainer = this.containerAtPos(world, x - dx, y - dy, z - dz);
    274 
    275         List<Entity> entities;
    276 
    277         if (inputContainer == null) {
    278             entities = world.getEntitiesWithinAABB(IInventory.class, AABB.getBoundingBoxFromPool(
    279                     x - dx, y - dy, z - dz, x - dx + 1, y - dy + 1, z - dz + 1));
    280 
    281             if (!entities.isEmpty() && (!(entities.get(0) instanceof EntityMinecart) ||
    282                     ((EntityMinecart) entities.get(0)).minecartType == 1)) {
    283                 inputContainer = (IInventory) entities.get(0);
    284             }
    285         }
    286 
    287         int itemIndex;
    288         if (inputContainer == null) {
    289             entities = world.getEntitiesWithinAABB(EntityItem.class, AABB.getBoundingBoxFromPool(
    290                     x - dx, y - dy, z - dz, x - dx + 1, y - dy + 1, z - dz + 1));
    291 
    292             for (itemIndex = 0; itemIndex < entities.size(); ++itemIndex) {
    293                 if (entities.get(itemIndex) instanceof EntityItem) {
    294                     EntityItem itemType = (EntityItem) entities.get(itemIndex);
    295 
    296                     if (itemType.isAlive() && this.passesFilter(world, x, y, z, itemType.item) &&
    297                             this.outputItem(world, x, y, z, dx, dy, dz, itemType.item, rand)) {
    298                         itemType.outOfWorld();
    299                     }
    300                 }
    301             }
    302         } else {
    303             itemIndex = this.getRandomItemFromContainer(inputContainer, rand, world, x, y, z);
    304 
    305             if (itemIndex >= 0) {
    306                 int itemDamage = inputContainer.getStackInSlot(itemIndex).getItemDamageForDisplay();
    307 
    308                 ItemStack item = new ItemStack(inputContainer.getStackInSlot(itemIndex)
    309                         .getItem(), 1, itemDamage);
    310 
    311                 if (this.outputItem(world, x, y, z, dx, dy, dz, item, rand)) {
    312                     inputContainer.decrStackSize(itemIndex, 1);
    313                 }
    314             }
    315         }
    316     }
    317 
    318     private int getFirstFreeInventorySlotOfKind(IInventory inventory, ItemStack item) {
    319         int inventorySize = inventory.getSizeInventory();
    320 
    321         if (inventory instanceof TileEntityFurnace) {
    322             --inventorySize;
    323         }
    324 
    325         for (int i = 0; i < inventorySize; ++i) {
    326             boolean canStack = false;
    327 
    328             if (inventory.getStackInSlot(i) != null && inventory.getStackInSlot(i).itemID == item.itemID &&
    329                     (!item.getItem().getHasSubtypes() ||
    330                             inventory.getStackInSlot(i).getItemDamageForDisplay() == item.getItemDamageForDisplay())) {
    331                 canStack = inventory.getStackInSlot(i).stackSize <= item.getMaxStackSize() - item.stackSize;
    332             }
    333 
    334             if (inventory.getStackInSlot(i) == null || canStack) {
    335                 return i;
    336             }
    337         }
    338 
    339         return -1;
    340     }
    341 
    342     private boolean passesFilter(World world, int x, int y, int z, ItemStack item) {
    343         if (!this.allowFiltering) {
    344             return true;
    345         } else {
    346             TileEntityAllocator tileentityallocator = (TileEntityAllocator) world.getBlockTileEntity(x, y, z);
    347             ItemStack filterItem = tileentityallocator.getStackInSlot(0);
    348             if (filterItem == null) {
    349                 return true;
    350             } else {
    351                 boolean filterSubItems = true;
    352                 if (this.subItemFiltering) {
    353                     filterSubItems = filterItem.getItemDamageForDisplay() == item.getItemDamageForDisplay();
    354                 }
    355 
    356                 return filterItem.itemID == item.getItem().id && filterSubItems;
    357             }
    358         }
    359     }
    360 }