/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [May 1, 2014, 6:08:25 PM (GMT)]
*/
package vazkii.botania.common.block.subtile.functional;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.item.ItemPiston;
import org.lwjgl.opengl.GL11;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemBlockSpecial;
import net.minecraft.item.ItemRedstone;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import vazkii.botania.api.item.IFloatingFlower;
import vazkii.botania.api.item.IFlowerPlaceable;
import vazkii.botania.api.lexicon.LexiconEntry;
import vazkii.botania.api.subtile.ISubTileContainer;
import vazkii.botania.api.subtile.RadiusDescriptor;
import vazkii.botania.api.subtile.SubTileEntity;
import vazkii.botania.api.subtile.SubTileFunctional;
import vazkii.botania.common.core.handler.ConfigHandler;
import vazkii.botania.common.core.handler.MethodHandles;
import vazkii.botania.common.item.block.ItemBlockSpecialFlower;
import vazkii.botania.common.lexicon.LexiconData;
import vazkii.botania.common.lib.LibObfuscation;
public class SubTileRannuncarpus extends SubTileFunctional {
private static final int RANGE = 2;
private static final int RANGE_Y = 3;
private static final int RANGE_PLACE_MANA = 8;
private static final int RANGE_PLACE = 6;
private static final int RANGE_PLACE_Y = 6;
private static final int RANGE_PLACE_MANA_MINI = 3;
private static final int RANGE_PLACE_MINI = 2;
private static final int RANGE_PLACE_Y_MINI = 2;
@Override
public void onUpdate() {
super.onUpdate();
if(supertile.getWorld().isRemote || redstoneSignal > 0)
return;
if(ticksExisted % 10 == 0) {
IBlockState filter = getUnderlyingBlock();
boolean scanned = false;
List<BlockPos> validPositions = new ArrayList<>();
int rangePlace = getRange();
int rangePlaceY = getRangeY();
BlockPos pos = supertile.getPos();
List<EntityItem> items = supertile.getWorld().getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(supertile.getPos().add(-RANGE, -RANGE_Y, -RANGE), supertile.getPos().add(RANGE + 1, RANGE_Y + 1, RANGE + 1)));
int slowdown = getSlowdownFactor();
for(EntityItem item : items) {
int age;
try {
age = (int) MethodHandles.itemAge_getter.invokeExact(item);
} catch (Throwable t) {
continue;
}
if(age < 60 + slowdown || item.isDead || item.getEntityItem().isEmpty())
continue;
ItemStack stack = item.getEntityItem();
Item stackItem = stack.getItem();
if(stackItem instanceof ItemBlock || stackItem instanceof ItemBlockSpecial || stackItem instanceof ItemRedstone || stackItem instanceof IFlowerPlaceable) {
if(!scanned) {
for(BlockPos pos_ : BlockPos.getAllInBox(pos.add(-rangePlace, -rangePlaceY, -rangePlace), pos.add(rangePlace, rangePlaceY, rangePlace))) {
IBlockState stateAbove = supertile.getWorld().getBlockState(pos_.up());
Block blockAbove = stateAbove.getBlock();
BlockPos up = pos_.up();
if(filter == supertile.getWorld().getBlockState(pos_)
&& (blockAbove.isAir(stateAbove, supertile.getWorld(), up)
|| blockAbove.isReplaceable(supertile.getWorld(), up)))
validPositions.add(up);
}
scanned = true;
}
if(!validPositions.isEmpty()) {
BlockPos coords = validPositions.get(supertile.getWorld().rand.nextInt(validPositions.size()));
IBlockState stateToPlace = null;
if(stackItem instanceof IFlowerPlaceable)
stateToPlace = ((IFlowerPlaceable) stackItem).getBlockToPlaceByFlower(stack, this, coords);
if(stackItem instanceof ItemBlock) {
int blockMeta = stackItem.getMetadata(stack.getItemDamage());
if(stackItem instanceof ItemPiston) // Workaround because the blockMeta ItemPiston gives crashes getStateFromMeta
blockMeta = 0;
stateToPlace = ((ItemBlock) stackItem).block.getStateFromMeta(blockMeta);
}
else if(stackItem instanceof ItemBlockSpecial)
stateToPlace = ((Block) ReflectionHelper.getPrivateValue(ItemBlockSpecial.class, (ItemBlockSpecial) stackItem, LibObfuscation.REED_ITEM)).getDefaultState();
else if(stackItem instanceof ItemRedstone)
stateToPlace = Blocks.REDSTONE_WIRE.getDefaultState();
if(stateToPlace != null) {
if(stateToPlace.getBlock().canPlaceBlockAt(supertile.getWorld(), coords)) {
supertile.getWorld().setBlockState(coords, stateToPlace, 1 | 2);
if(ConfigHandler.blockBreakParticles)
supertile.getWorld().playEvent(2001, coords, Block.getStateId(stateToPlace));
validPositions.remove(coords);
TileEntity tile = supertile.getWorld().getTileEntity(coords);
if(tile != null && tile instanceof ISubTileContainer) {
ISubTileContainer container = (ISubTileContainer) tile;
String subtileName = ItemBlockSpecialFlower.getType(stack);
container.setSubTile(subtileName);
SubTileEntity subtile = container.getSubTile();
subtile.onBlockPlacedBy(supertile.getWorld(), coords, supertile.getWorld().getBlockState(coords), null, stack);
}
if(stackItem instanceof IFlowerPlaceable)
((IFlowerPlaceable) stackItem).onBlockPlacedByFlower(stack, this, coords);
stack.shrink(1);
if(mana > 1)
mana--;
return;
}
}
}
}
}
}
}
public IBlockState getUnderlyingBlock() {
return supertile.getWorld().getBlockState(supertile.getPos().down(supertile instanceof IFloatingFlower ? 1 : 2));
}
@Override
public boolean acceptsRedstone() {
return true;
}
@SideOnly(Side.CLIENT)
@Override
public void renderHUD(Minecraft mc, ScaledResolution res) {
super.renderHUD(mc, res);
IBlockState filter = getUnderlyingBlock();
ItemStack recieverStack = new ItemStack(Item.getItemFromBlock(filter.getBlock()), 1, filter.getBlock().getMetaFromState(filter));
int color = getColor();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if(!recieverStack.isEmpty()) {
String stackName = recieverStack.getDisplayName();
int width = 16 + mc.fontRendererObj.getStringWidth(stackName) / 2;
int x = res.getScaledWidth() / 2 - width;
int y = res.getScaledHeight() / 2 + 30;
mc.fontRendererObj.drawStringWithShadow(stackName, x + 20, y + 5, color);
RenderHelper.enableGUIStandardItemLighting();
mc.getRenderItem().renderItemAndEffectIntoGUI(recieverStack, x, y);
RenderHelper.disableStandardItemLighting();
}
GlStateManager.disableLighting();
GlStateManager.disableBlend();
}
@Override
public RadiusDescriptor getRadius() {
return new RadiusDescriptor.Square(toBlockPos(), getRange());
}
public int getRange() {
return mana > 0 ? RANGE_PLACE_MANA : RANGE_PLACE;
}
public int getRangeY() {
return RANGE_PLACE_Y;
}
@Override
public int getMaxMana() {
return 20;
}
@Override
public int getColor() {
return 0xFFB27F;
}
@Override
public LexiconEntry getEntry() {
return LexiconData.rannuncarpus;
}
public static class Mini extends SubTileRannuncarpus {
@Override public int getRange() { return mana > 0 ? RANGE_PLACE_MANA_MINI : RANGE_PLACE_MINI; }
@Override public int getRangeY() { return RANGE_PLACE_Y_MINI; }
}
}