/**
* 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 @ [Jan 24, 2014, 8:03:36 PM (GMT)]
*/
package vazkii.botania.api.subtile;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.api.internal.IManaNetwork;
import vazkii.botania.api.mana.IManaCollector;
/**
* The basic class for a Generating Flower.
*/
public class SubTileGenerating extends SubTileEntity {
public static final int RANGE = 6;
private static final String TAG_MANA = "mana";
private static final String TAG_COLLECTOR_X = "collectorX";
private static final String TAG_COLLECTOR_Y = "collectorY";
private static final String TAG_COLLECTOR_Z = "collectorZ";
private static final String TAG_PASSIVE_DECAY_TICKS = "passiveDecayTicks";
protected int mana;
public int redstoneSignal = 0;
int sizeLastCheck = -1;
protected TileEntity linkedCollector = null;
public int knownMana = -1;
public int passiveDecayTicks;
ChunkCoordinates cachedCollectorCoordinates = null;
/**
* If set to true, redstoneSignal will be updated every tick.
*/
public boolean acceptsRedstone() {
return false;
}
@Override
public void onUpdate() {
super.onUpdate();
linkCollector();
if(canGeneratePassively()) {
int delay = getDelayBetweenPassiveGeneration();
if(delay > 0 && ticksExisted % delay == 0 && !supertile.getWorldObj().isRemote) {
if(shouldSyncPassiveGeneration())
sync();
addMana(getValueForPassiveGeneration());
}
}
emptyManaIntoCollector();
if(acceptsRedstone()) {
redstoneSignal = 0;
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
int redstoneSide = supertile.getWorldObj().getIndirectPowerLevelTo(supertile.xCoord + dir.offsetX, supertile.yCoord + dir.offsetY, supertile.zCoord + dir.offsetZ, dir.ordinal());
redstoneSignal = Math.max(redstoneSignal, redstoneSide);
}
}
if(supertile.getWorldObj().isRemote) {
double particleChance = 1F - (double) mana / (double) getMaxMana() / 3.5F;
Color color = new Color(getColor());
if(Math.random() > particleChance)
BotaniaAPI.internalHandler.sparkleFX(supertile.getWorldObj(), supertile.xCoord + 0.3 + Math.random() * 0.5, supertile.yCoord + 0.5 + Math.random() * 0.5, supertile.zCoord + 0.3 + Math.random() * 0.5, color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F, (float) Math.random(), 5);
}
boolean passive = isPassiveFlower();
if(!supertile.getWorldObj().isRemote) {
int muhBalance = BotaniaAPI.internalHandler.getPassiveFlowerDecay();
if(passive && muhBalance > 0 && passiveDecayTicks > muhBalance) {
supertile.getWorldObj().playAuxSFX(2001, supertile.xCoord, supertile.yCoord, supertile.zCoord, Block.getIdFromBlock(supertile.getBlockType()));
if(supertile.getWorldObj().getBlock(supertile.xCoord, supertile.yCoord - 1, supertile.zCoord).isSideSolid(supertile.getWorldObj(), supertile.xCoord, supertile.yCoord - 1, supertile.zCoord, ForgeDirection.UP))
supertile.getWorldObj().setBlock(supertile.xCoord, supertile.yCoord, supertile.zCoord, Blocks.deadbush);
else supertile.getWorldObj().setBlockToAir(supertile.xCoord, supertile.yCoord, supertile.zCoord);
}
}
if(!overgrowth && passive)
passiveDecayTicks++;
}
public void linkCollector() {
boolean needsNew = false;
if(linkedCollector == null) {
needsNew = true;
if(cachedCollectorCoordinates != null) {
needsNew = false;
if(supertile.getWorldObj().blockExists(cachedCollectorCoordinates.posX, cachedCollectorCoordinates.posY, cachedCollectorCoordinates.posZ)) {
needsNew = true;
TileEntity tileAt = supertile.getWorldObj().getTileEntity(cachedCollectorCoordinates.posX, cachedCollectorCoordinates.posY, cachedCollectorCoordinates.posZ);
if(tileAt != null && tileAt instanceof IManaCollector && !tileAt.isInvalid()) {
linkedCollector = tileAt;
needsNew = false;
}
cachedCollectorCoordinates = null;
}
}
} else {
TileEntity tileAt = supertile.getWorldObj().getTileEntity(linkedCollector.xCoord, linkedCollector.yCoord, linkedCollector.zCoord);
if(tileAt != null && tileAt instanceof IManaCollector)
linkedCollector = tileAt;
}
if(needsNew && ticksExisted == 1) { // New flowers only
IManaNetwork network = BotaniaAPI.internalHandler.getManaNetworkInstance();
int size = network.getAllCollectorsInWorld(supertile.getWorldObj()).size();
if(BotaniaAPI.internalHandler.shouldForceCheck() || size != sizeLastCheck) {
ChunkCoordinates coords = new ChunkCoordinates(supertile.xCoord, supertile.yCoord, supertile.zCoord);
linkedCollector = network.getClosestCollector(coords, supertile.getWorldObj(), RANGE);
sizeLastCheck = size;
}
}
}
public void linkToForcefully(TileEntity collector) {
linkedCollector = collector;
}
public void addMana(int mana) {
this.mana = Math.min(getMaxMana(), this.mana + mana);
}
public void emptyManaIntoCollector() {
if(linkedCollector != null && isValidBinding()) {
IManaCollector collector = (IManaCollector) linkedCollector;
if(!collector.isFull() && mana > 0) {
int manaval = Math.min(mana, collector.getMaxMana() - collector.getCurrentMana());
mana -= manaval;
collector.recieveMana(manaval);
}
}
}
public boolean isPassiveFlower() {
return false;
}
public boolean shouldSyncPassiveGeneration() {
return false;
}
public boolean canGeneratePassively() {
return false;
}
public int getDelayBetweenPassiveGeneration() {
return 20;
}
public int getValueForPassiveGeneration() {
return 1;
}
@Override
public ArrayList<ItemStack> getDrops(ArrayList<ItemStack> list) {
ArrayList<ItemStack> drops = super.getDrops(list);
populateDropStackNBTs(drops);
return drops;
}
public void populateDropStackNBTs(List<ItemStack> drops) {
if(isPassiveFlower() && ticksExisted > 0 && BotaniaAPI.internalHandler.getPassiveFlowerDecay() > 0) {
ItemStack drop = drops.get(0);
if(drop != null) {
if(!drop.hasTagCompound())
drop.setTagCompound(new NBTTagCompound());
NBTTagCompound cmp = drop.getTagCompound();
cmp.setInteger(TAG_PASSIVE_DECAY_TICKS, passiveDecayTicks);
}
}
}
@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entity, ItemStack stack) {
super.onBlockPlacedBy(world, x, y, z, entity, stack);
if(isPassiveFlower()) {
NBTTagCompound cmp = stack.getTagCompound();
passiveDecayTicks = cmp.getInteger(TAG_PASSIVE_DECAY_TICKS);
}
}
@Override
public boolean onWanded(EntityPlayer player, ItemStack wand) {
if(player == null)
return false;
if(!player.worldObj.isRemote)
sync();
knownMana = mana;
player.worldObj.playSoundAtEntity(player, "botania:ding", 0.1F, 1F);
return super.onWanded(player, wand);
}
public int getMaxMana() {
return 20;
}
public int getColor() {
return 0xFFFFFF;
}
@Override
public void readFromPacketNBT(NBTTagCompound cmp) {
mana = cmp.getInteger(TAG_MANA);
passiveDecayTicks = cmp.getInteger(TAG_PASSIVE_DECAY_TICKS);
int x = cmp.getInteger(TAG_COLLECTOR_X);
int y = cmp.getInteger(TAG_COLLECTOR_Y);
int z = cmp.getInteger(TAG_COLLECTOR_Z);
cachedCollectorCoordinates = y < 0 ? null : new ChunkCoordinates(x, y, z);
}
@Override
public void writeToPacketNBT(NBTTagCompound cmp) {
cmp.setInteger(TAG_MANA, mana);
cmp.setInteger(TAG_TICKS_EXISTED, ticksExisted);
cmp.setInteger(TAG_PASSIVE_DECAY_TICKS, passiveDecayTicks);
if(cachedCollectorCoordinates != null) {
cmp.setInteger(TAG_COLLECTOR_X, cachedCollectorCoordinates.posX);
cmp.setInteger(TAG_COLLECTOR_Y, cachedCollectorCoordinates.posY);
cmp.setInteger(TAG_COLLECTOR_Z, cachedCollectorCoordinates.posZ);
} else {
int x = linkedCollector == null ? 0 : linkedCollector.xCoord;
int y = linkedCollector == null ? -1 : linkedCollector.yCoord;
int z = linkedCollector == null ? 0 : linkedCollector.zCoord;
cmp.setInteger(TAG_COLLECTOR_X, x);
cmp.setInteger(TAG_COLLECTOR_Y, y);
cmp.setInteger(TAG_COLLECTOR_Z, z);
}
}
@Override
public ChunkCoordinates getBinding() {
if(linkedCollector == null)
return null;
return new ChunkCoordinates(linkedCollector.xCoord, linkedCollector.yCoord, linkedCollector.zCoord);
}
@Override
public boolean canSelect(EntityPlayer player, ItemStack wand, int x, int y, int z, int side) {
return true;
}
@Override
public boolean bindTo(EntityPlayer player, ItemStack wand, int x, int y, int z, int side) {
int range = 6;
range *= range;
double dist = (x - supertile.xCoord) * (x - supertile.xCoord) + (y - supertile.yCoord) * (y - supertile.yCoord) + (z - supertile.zCoord) * (z - supertile.zCoord);
if(range >= dist) {
TileEntity tile = player.worldObj.getTileEntity(x, y, z);
if(tile instanceof IManaCollector) {
linkedCollector = tile;
return true;
}
}
return false;
}
public boolean isValidBinding() {
return linkedCollector != null && !linkedCollector.isInvalid() && supertile.getWorldObj().getTileEntity(linkedCollector.xCoord, linkedCollector.yCoord, linkedCollector.zCoord) == linkedCollector;
}
@Override
public void renderHUD(Minecraft mc, ScaledResolution res) {
String name = StatCollector.translateToLocal("tile.botania:flower." + getUnlocalizedName() + ".name");
int color = getColor();
BotaniaAPI.internalHandler.drawComplexManaHUD(color, knownMana, getMaxMana(), name, res, BotaniaAPI.internalHandler.getBindDisplayForFlowerType(this), isValidBinding());
}
@Override
public boolean isOvergrowthAffected() {
return !isPassiveFlower();
}
}