/**
* 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 @ [Feb 2, 2014, 6:31:19 PM (GMT)]
*/
package vazkii.botania.common.block.tile;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.internal.VanillaPacketDispatcher;
import vazkii.botania.api.mana.IManaReceiver;
import vazkii.botania.api.recipe.RecipeRuneAltar;
import vazkii.botania.api.sound.BotaniaSoundEvents;
import vazkii.botania.client.core.handler.HUDHandler;
import vazkii.botania.client.core.helper.RenderHelper;
import vazkii.botania.common.Botania;
import vazkii.botania.common.block.ModBlocks;
import vazkii.botania.common.core.helper.Vector3;
import vazkii.botania.common.item.ModItems;
import vazkii.botania.common.network.PacketBotaniaEffect;
import vazkii.botania.common.network.PacketHandler;
public class TileRuneAltar extends TileSimpleInventory implements IManaReceiver {
private static final String TAG_MANA = "mana";
private static final String TAG_MANA_TO_GET = "manaToGet";
private static final int SET_KEEP_TICKS_EVENT = 0;
private static final int SET_COOLDOWN_EVENT = 1;
RecipeRuneAltar currentRecipe;
public int manaToGet = 0;
int mana = 0;
int cooldown = 0;
public int signal = 0;
List<ItemStack> lastRecipe = null;
int recipeKeepTicks = 0;
public boolean addItem(@Nullable EntityPlayer player, ItemStack stack, @Nullable EnumHand hand) {
if(cooldown > 0 || stack.getItem() == ModItems.twigWand || stack.getItem() == ModItems.lexicon)
return false;
if(stack.getItem() == Item.getItemFromBlock(ModBlocks.livingrock) && stack.getItemDamage() == 0) {
if(!world.isRemote) {
ItemStack toSpawn = player != null && player.capabilities.isCreativeMode ? stack.copy().splitStack(1) : stack.splitStack(1);
EntityItem item = new EntityItem(world, getPos().getX() + 0.5, getPos().getY() + 1, getPos().getZ() + 0.5, toSpawn);
item.setPickupDelay(40);
item.motionX = item.motionY = item.motionZ = 0;
world.spawnEntity(item);
}
return true;
}
if(manaToGet != 0)
return false;
boolean did = false;
for(int i = 0; i < getSizeInventory(); i++)
if(itemHandler.getStackInSlot(i).isEmpty()) {
did = true;
ItemStack stackToAdd = stack.copy();
stackToAdd.setCount(1);
itemHandler.setStackInSlot(i, stackToAdd);
if(player == null || !player.capabilities.isCreativeMode) {
stack.shrink(1);
}
break;
}
if(did)
VanillaPacketDispatcher.dispatchTEToNearbyPlayers(world, pos);
return true;
}
@Override
public boolean receiveClientEvent(int id, int param) {
switch (id) {
case SET_KEEP_TICKS_EVENT: recipeKeepTicks = param; return true;
case SET_COOLDOWN_EVENT: cooldown = param; return true;
default: return super.receiveClientEvent(id, param);
}
}
@Override
public void update() {
// Update every tick.
recieveMana(0);
if(!world.isRemote) {
if(manaToGet == 0) {
List<EntityItem> items = world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(pos, pos.add(1, 1, 1)));
for(EntityItem item : items)
if(!item.isDead && !item.getEntityItem().isEmpty() && item.getEntityItem().getItem() != Item.getItemFromBlock(ModBlocks.livingrock)) {
ItemStack stack = item.getEntityItem();
addItem(null, stack, null);
}
}
int newSignal = 0;
if(manaToGet > 0) {
newSignal++;
if(mana >= manaToGet)
newSignal++;
}
if(newSignal != signal) {
signal = newSignal;
world.updateComparatorOutputLevel(pos, world.getBlockState(pos).getBlock());
}
updateRecipe();
} else {
if (manaToGet > 0 && mana >= manaToGet && world.rand.nextInt(20) == 0) {
Vector3 vec = Vector3.fromTileEntityCenter(this);
Vector3 endVec = vec.add(0, 2.5, 0);
Botania.proxy.lightningFX(vec, endVec, 2F, 0x00948B, 0x00E4D7);
}
if (cooldown > 0)
Botania.proxy.wispFX(pos.getX() + Math.random(), pos.getY() + 0.8, pos.getZ() + Math.random(), 0.2F, 0.2F, 0.2F, 0.2F, -0.025F);
}
if(cooldown > 0) {
cooldown--;
}
if(recipeKeepTicks > 0)
--recipeKeepTicks;
else lastRecipe = null;
}
public void updateRecipe() {
int manaToGet = this.manaToGet;
getMana : {
if(currentRecipe != null)
this.manaToGet = currentRecipe.getManaUsage();
else {
for(RecipeRuneAltar recipe : BotaniaAPI.runeAltarRecipes)
if(recipe.matches(itemHandler)) {
this.manaToGet = recipe.getManaUsage();
break getMana;
}
this.manaToGet = 0;
}
}
if(manaToGet != this.manaToGet) {
world.playSound(null, pos, BotaniaSoundEvents.runeAltarStart, SoundCategory.BLOCKS, 1, 1);
VanillaPacketDispatcher.dispatchTEToNearbyPlayers(world, pos);
}
}
public void saveLastRecipe() {
lastRecipe = new ArrayList<>();
for(int i = 0; i < getSizeInventory(); i++) {
ItemStack stack = itemHandler.getStackInSlot(i);
if(stack.isEmpty())
break;
lastRecipe.add(stack.copy());
}
recipeKeepTicks = 400;
world.addBlockEvent(getPos(), ModBlocks.runeAltar, SET_KEEP_TICKS_EVENT, 400);
}
public void trySetLastRecipe(EntityPlayer player) {
TileAltar.tryToSetLastRecipe(player, itemHandler, lastRecipe);
if(!isEmpty())
VanillaPacketDispatcher.dispatchTEToNearbyPlayers(world, pos);
}
public boolean hasValidRecipe() {
for(RecipeRuneAltar recipe : BotaniaAPI.runeAltarRecipes)
if(recipe.matches(itemHandler))
return true;
return false;
}
public void onWanded(EntityPlayer player, ItemStack wand) {
if (world.isRemote)
return;
RecipeRuneAltar recipe = null;
if(currentRecipe != null)
recipe = currentRecipe;
else for(RecipeRuneAltar recipe_ : BotaniaAPI.runeAltarRecipes) {
if(recipe_.matches(itemHandler)) {
recipe = recipe_;
break;
}
}
if(manaToGet > 0 && mana >= manaToGet) {
List<EntityItem> items = world.getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(pos, pos.add(1, 1, 1)));
EntityItem livingrock = null;
for(EntityItem item : items)
if(!item.isDead && !item.getEntityItem().isEmpty() && item.getEntityItem().getItem() == Item.getItemFromBlock(ModBlocks.livingrock)) {
livingrock = item;
break;
}
if(livingrock != null) {
int mana = recipe.getManaUsage();
recieveMana(-mana);
ItemStack output = recipe.getOutput().copy();
EntityItem outputItem = new EntityItem(world, pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5, output);
world.spawnEntity(outputItem);
currentRecipe = null;
world.addBlockEvent(getPos(), ModBlocks.runeAltar, SET_COOLDOWN_EVENT, 60);
saveLastRecipe();
for(int i = 0; i < getSizeInventory(); i++) {
ItemStack stack = itemHandler.getStackInSlot(i);
if(!stack.isEmpty()) {
if(stack.getItem() == ModItems.rune && (player == null || !player.capabilities.isCreativeMode)) {
EntityItem outputRune = new EntityItem(world, getPos().getX() + 0.5, getPos().getY() + 1.5, getPos().getZ() + 0.5, stack.copy());
world.spawnEntity(outputRune);
}
itemHandler.setStackInSlot(i, ItemStack.EMPTY);
}
}
livingrock.getEntityItem().shrink(1);
craftingFanciness();
}
}
}
public void craftingFanciness() {
world.playSound(null, pos, BotaniaSoundEvents.runeAltarCraft, SoundCategory.BLOCKS, 1, 1);
PacketHandler.sendToNearby(world, getPos(),
new PacketBotaniaEffect(PacketBotaniaEffect.EffectType.RUNE_CRAFT, getPos().getX(), getPos().getY(), getPos().getZ()));
}
public boolean isEmpty() {
for(int i = 0; i < getSizeInventory(); i++)
if(!itemHandler.getStackInSlot(i).isEmpty())
return false;
return true;
}
@Override
public void writePacketNBT(NBTTagCompound par1nbtTagCompound) {
super.writePacketNBT(par1nbtTagCompound);
par1nbtTagCompound.setInteger(TAG_MANA, mana);
par1nbtTagCompound.setInteger(TAG_MANA_TO_GET, manaToGet);
}
@Override
public void readPacketNBT(NBTTagCompound par1nbtTagCompound) {
super.readPacketNBT(par1nbtTagCompound);
mana = par1nbtTagCompound.getInteger(TAG_MANA);
manaToGet = par1nbtTagCompound.getInteger(TAG_MANA_TO_GET);
}
@Override
public int getSizeInventory() {
return 16;
}
@Nonnull
@Override
public AxisAlignedBB getRenderBoundingBox() {
return INFINITE_EXTENT_AABB;
}
@Override
protected SimpleItemStackHandler createItemHandler() {
return new SimpleItemStackHandler(this, false) {
@Override
protected int getStackLimit(int slot, @Nonnull ItemStack stack) {
return 1;
}
};
}
@Override
public int getCurrentMana() {
return mana;
}
@Override
public boolean isFull() {
return mana >= manaToGet;
}
@Override
public void recieveMana(int mana) {
this.mana = Math.min(this.mana + mana, manaToGet);
}
@Override
public boolean canRecieveManaFromBursts() {
return !isFull();
}
public void renderHUD(Minecraft mc, ScaledResolution res) {
int xc = res.getScaledWidth() / 2;
int yc = res.getScaledHeight() / 2;
float angle = -90;
int radius = 24;
int amt = 0;
for(int i = 0; i < getSizeInventory(); i++) {
if(itemHandler.getStackInSlot(i).isEmpty())
break;
amt++;
}
if(amt > 0) {
float anglePer = 360F / amt;
for(RecipeRuneAltar recipe : BotaniaAPI.runeAltarRecipes)
if(recipe.matches(itemHandler)) {
GlStateManager.enableBlend();
GlStateManager.enableRescaleNormal();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
recipe.getOutput();
float progress = (float) mana / (float) manaToGet;
mc.renderEngine.bindTexture(HUDHandler.manaBar);
GlStateManager.color(1F, 1F, 1F, 1F);
RenderHelper.drawTexturedModalRect(xc + radius + 9, yc - 8, 0, progress == 1F ? 0 : 22, 8, 22, 15);
net.minecraft.client.renderer.RenderHelper.enableGUIStandardItemLighting();
if(progress == 1F) {
mc.getRenderItem().renderItemIntoGUI(new ItemStack(ModBlocks.livingrock), xc + radius + 16, yc + 8);
GlStateManager.translate(0F, 0F, 100F);
mc.getRenderItem().renderItemIntoGUI(new ItemStack(ModItems.twigWand), xc + radius + 24, yc + 8);
GlStateManager.translate(0F, 0F, -100F);
}
RenderHelper.renderProgressPie(xc + radius + 32, yc - 8, progress, recipe.getOutput());
net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting();
if(progress == 1F)
mc.fontRendererObj.drawStringWithShadow("+", xc + radius + 14, yc + 12, 0xFFFFFF);
}
net.minecraft.client.renderer.RenderHelper.enableGUIStandardItemLighting();
for(int i = 0; i < amt; i++) {
double xPos = xc + Math.cos(angle * Math.PI / 180D) * radius - 8;
double yPos = yc + Math.sin(angle * Math.PI / 180D) * radius - 8;
GlStateManager.translate(xPos, yPos, 0);
mc.getRenderItem().renderItemIntoGUI(itemHandler.getStackInSlot(i), 0, 0);
GlStateManager.translate(-xPos, -yPos, 0);
angle += anglePer;
}
net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting();
} else if(recipeKeepTicks > 0) {
String s = I18n.format("botaniamisc.altarRefill0");
mc.fontRendererObj.drawStringWithShadow(s, xc - mc.fontRendererObj.getStringWidth(s) / 2, yc + 10, 0xFFFFFF);
s = I18n.format("botaniamisc.altarRefill1");
mc.fontRendererObj.drawStringWithShadow(s, xc - mc.fontRendererObj.getStringWidth(s) / 2, yc + 20, 0xFFFFFF);
}
}
public int getTargetMana() {
return manaToGet;
}
}