package crazypants.enderio.machine.obelisk.weather; import java.awt.Color; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; import com.enderio.core.api.common.util.IProgressTile; import com.enderio.core.api.common.util.ITankAccess; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import crazypants.enderio.EnderIO; import crazypants.enderio.ModObject; import crazypants.enderio.machine.AbstractPowerConsumerEntity; import crazypants.enderio.machine.SlotDefinition; import crazypants.enderio.network.PacketHandler; import crazypants.enderio.power.Capacitors; import crazypants.enderio.power.ICapacitor; public class TileWeatherObelisk extends AbstractPowerConsumerEntity implements IProgressTile, IFluidHandler, ITankAccess { public enum WeatherTask { CLEAR(Color.YELLOW) { @Override void complete(World world) { rain(world, false); thunder(world, false); } }, RAIN(new Color(120, 120, 255)) { @Override void complete(World world) { rain(world, true); thunder(world, false); } }, STORM(Color.DARK_GRAY) { @Override void complete(World world) { rain(world, true); thunder(world, true); } }; final Color color; WeatherTask(Color color) { this.color = color; } abstract void complete(World world); protected void rain(World world, boolean state) { world.getWorldInfo().setRaining(state); } protected void thunder(World world, boolean state) { world.getWorldInfo().setThundering(state); } public static boolean worldIsState(WeatherTask task, World world) { if (world.isRaining()) { return world.isThundering() ? task == STORM : task == RAIN; } return task == CLEAR; } public static WeatherTask fromFluid(Fluid f) { if (f == EnderIO.fluidLiquidSunshine) { return CLEAR; } else if (f == EnderIO.fluidCloudSeed) { return RAIN; } else if (f == EnderIO.fluidCloudSeedConcentrated) { return STORM; } return null; } } private int fluidUsed = 0; private WeatherTask activeTask = null; private boolean canBeActive = true; private boolean tanksDirty; private static final ICapacitor cap = Capacitors.BASIC_CAPACITOR.capacitor; private FluidTank inputTank = new FluidTank(8000); /* client fields */ private float progress = 0; // client only private boolean playedFuse = false; public TileWeatherObelisk() { super(new SlotDefinition(1, 0, 0)); } @Override public void init() { setCapacitor(Capacitors.ACTIVATED_CAPACITOR); } @Override public String getMachineName() { return ModObject.blockWeatherObelisk.unlocalisedName; } @Override protected boolean isMachineItemValidForSlot(int i, ItemStack itemstack) { return i == 0 && itemstack != null && itemstack.getItem() == Items.fireworks; } @Override public boolean isActive() { return canBeActive && getActiveTask() != null; } @Override public float getProgress() { return isActive() ? worldObj.isRemote ? progress : (float) fluidUsed / 1000 : 0; } @Override public void setProgress(float progress) { this.progress = progress; } @Override protected int getProgressUpdateFreq() { return 3; } @Override public TileEntity getTileEntity() { return this; } @Override public ICapacitor getCapacitor() { return cap; } public WeatherTask getActiveTask() { return activeTask; } @Override public void doUpdate() { super.doUpdate(); if (worldObj.isRemote && isActive() && worldObj.getTotalWorldTime() % 2 == 0) { doLoadingParticles(); } } @SideOnly(Side.CLIENT) private void doLoadingParticles() { if (progress < 0.9f) { Color c = getActiveTask().color; double correction = 0.1; double xf = xCoord + 0.5 + correction; double yf = yCoord + 0.8; double zf = zCoord + 0.5 + correction; Block b = getBlockType(); double yi = yCoord + b.getBlockBoundsMaxY() - 0.1; double offset = 0.3; Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFluidLoadingFX(worldObj, xCoord + offset + correction, yi, zCoord + offset + correction, xf, yf, zf, c)); Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFluidLoadingFX(worldObj, xCoord + (1 - offset) + correction, yi, zCoord + offset + correction, xf, yf, zf, c)); Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFluidLoadingFX(worldObj, xCoord + (1 - offset) + correction, yi, zCoord + (1 - offset) + correction, xf, yf, zf, c)); Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFluidLoadingFX(worldObj, xCoord + offset + correction, yi, zCoord + (1 - offset) + correction, xf, yf, zf, c)); } else if (!playedFuse) { worldObj.playSound(xCoord, yCoord, zCoord, "game.tnt.primed", 1, 1, true); playedFuse = true; } } @Override protected boolean processTasks(boolean redstoneCheckPassed) { boolean res = false; if(!redstoneCheckPassed) { if(canBeActive) { canBeActive = false; res = true; } return res; } else { canBeActive = true; if(isActive()) { if(getEnergyStored() > getPowerUsePerTick() && inputTank.getFluidAmount() > 3) { setEnergyStored(getEnergyStored() - getPowerUsePerTick()); int toUse = 4; inputTank.drain(toUse, true); fluidUsed += toUse; tanksDirty = true; res = true; } if (fluidUsed >= 1000) { EntityWeatherRocket e = new EntityWeatherRocket(worldObj, activeTask); e.setPosition(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5); worldObj.spawnEntityInWorld(e); stopTask(); res = true; } } } if(tanksDirty) { PacketHandler.sendToAllAround(new PacketWeatherTank(this), this); tanksDirty = false; } return res; } /** * If the task can be started based on the current inventory. Does not take * into account the world's weather state. * * @param task * The task to check * @return True if the task can be started with the item in the inventory. */ public boolean canStartTask(WeatherTask task) { return getActiveTask() == null && !WeatherTask.worldIsState(task, worldObj) && getStackInSlot(0) != null && inputTank.getFluidAmount() >= 1000; } /** * @return If the operation was successful. */ public boolean startTask() { if(getActiveTask() == null && inputTank.getFluidAmount() > 0) { fluidUsed = 0; WeatherTask task = WeatherTask.fromFluid(inputTank.getFluid().getFluid()); if(canStartTask(task)) { decrStackSize(0, 1); activeTask = task; return true; } } return false; } public void stopTask() { if (getActiveTask() != null) { activeTask = null; fluidUsed = 0; if (!worldObj.isRemote) { PacketHandler.INSTANCE.sendToDimension(new PacketActivateWeather(this), worldObj.provider.dimensionId); } else { playedFuse = false; } } } @Override public void writeCommon(NBTTagCompound nbtRoot) { super.writeCommon(nbtRoot); nbtRoot.setTag("tank", inputTank.writeToNBT(new NBTTagCompound())); } @Override public void readCommon(NBTTagCompound nbtRoot) { super.readCommon(nbtRoot); inputTank.readFromNBT(nbtRoot.getCompoundTag("tank")); } private boolean isValidFluid(Fluid f) { return f == EnderIO.fluidLiquidSunshine || f == EnderIO.fluidCloudSeed || f == EnderIO.fluidCloudSeedConcentrated; } @Override public FluidTank getInputTank(FluidStack forFluidType) { return forFluidType != null && forFluidType.getFluid() != null && isValidFluid(forFluidType.getFluid()) ? inputTank : null; } FluidTank getInputTank() { return inputTank; } @Override public FluidTank[] getOutputTanks() { return new FluidTank[0]; } @Override public void setTanksDirty() { tanksDirty = true; } @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { if (resource != null && canFill(from, resource.getFluid())) { int res = inputTank.fill(resource, doFill); if (res > 0 && doFill) { tanksDirty = true; } return res; } return 0; } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { return null; } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { return null; } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return isValidFluid(fluid); } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { return false; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { return new FluidTankInfo[] { inputTank.getInfo() }; } }