/** * Copyright (c) Lambda Innovation, 2013-2016 * This file is part of the AcademyCraft mod. * https://github.com/LambdaInnovation/AcademyCraft * Licensed under GPLv3, see project root for more information. */ package cn.academy.energy.block.wind; import cn.academy.core.block.TileGeneratorBase; import cn.academy.energy.IFConstants; import cn.academy.energy.ModuleEnergy; import cn.academy.energy.api.IFItemManager; import cn.academy.energy.client.render.block.RenderWindGenBase; import cn.lambdalib.annoreg.core.Registrant; import cn.lambdalib.annoreg.mc.RegTileEntity; import cn.lambdalib.multiblock.BlockMulti; import cn.lambdalib.multiblock.IMultiTile; import cn.lambdalib.multiblock.InfoBlockMulti; import cn.lambdalib.util.generic.MathUtils; import cn.lambdalib.util.helper.TickScheduler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; /** * @author WeAthFolD */ @Registrant @RegTileEntity @RegTileEntity.HasRender public class TileWindGenBase extends TileGeneratorBase implements IMultiTile { public static double MAX_GENERATION_SPEED = 15; public enum Completeness { BASE_ONLY, NO_TOP, COMPLETE, COMPLETE_NOT_WORKING } private static final IFItemManager itemManager = IFItemManager.instance; @SideOnly(Side.CLIENT) @RegTileEntity.Render public static RenderWindGenBase renderer; // CLIENT STATES private TileWindGenMain mainTile; private boolean noObstacle; private Completeness completeness = Completeness.BASE_ONLY; private TickScheduler scheduler = new TickScheduler(); { scheduler.every(10).run(() -> { updateMainTile(); noObstacle = (mainTile != null && mainTile.noObstacle); }); } public TileWindGenBase() { super("windgen_base", 1, 20000, IFConstants.LATENCY_MK3); } @Override public double getGeneration(double required) { double sim = getSimulatedGeneration(); return Math.min(required, sim); } // TODO: Improve the fomula? public double getSimulatedGeneration() { if(shouldGenerate()) { int y = mainTile.yCoord; double heightFactor = MathUtils.lerp(0.5, 1, MathUtils.clampd(0, 1, (y - 70.0) / 90.0)); return heightFactor * MAX_GENERATION_SPEED; } else { return 0.0; } } private void updateChargeOut() { ItemStack stack = this.getStackInSlot(0); if (stack != null) { tryChargeStack(stack); } } // InfoBlockMulti delegates private InfoBlockMulti info = new InfoBlockMulti(this); @Override public void updateEntity() { super.updateEntity(); info.update(); scheduler.runTick(); updateChargeOut(); } public boolean isComplete() { return completeness == Completeness.COMPLETE; } public Completeness getCompleteness() { if (completeness == Completeness.COMPLETE) { return shouldGenerate() ? Completeness.COMPLETE : Completeness.COMPLETE_NOT_WORKING; } else { return completeness; } } private boolean shouldGenerate() { return completeness == Completeness.COMPLETE && mainTile.complete && mainTile.isFanInstalled(); } @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); info = new InfoBlockMulti(this, tag); } @Override public void writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); info.save(tag); } @Override public InfoBlockMulti getBlockInfo() { return info; } @Override public void setBlockInfo(InfoBlockMulti i) { info = i; } @SideOnly(Side.CLIENT) @Override public AxisAlignedBB getRenderBoundingBox() { Block block = getBlockType(); if(block instanceof BlockMulti) { return ((BlockMulti) block).getRenderBB(xCoord, yCoord, zCoord, info.getDir()); } else { return super.getRenderBoundingBox(); } } private void updateMainTile() { int pillars = 0; TileWindGenMain mainTile; Completeness comp; for(int y = yCoord + 2; ; ++y) { TileEntity te = worldObj.getTileEntity(xCoord, y, zCoord); Block block = worldObj.getBlock(xCoord, y, zCoord); if(block == ModuleEnergy.windgenPillar) { ++pillars; if(pillars > WindGenerator.MAX_PILLARS) { comp = Completeness.NO_TOP; mainTile = null; break; } } else if(te instanceof TileWindGenMain) { TileWindGenMain gen = (TileWindGenMain) te; if(gen.getBlockInfo().getSubID() == 0 && pillars >= WindGenerator.MIN_PILLARS) { mainTile = gen; comp = Completeness.COMPLETE; break; } else { comp = Completeness.NO_TOP; mainTile = null; break; } } else { comp = pillars < WindGenerator.MIN_PILLARS ? Completeness.BASE_ONLY : Completeness.NO_TOP; mainTile = null; break; } } this.mainTile = mainTile; this.completeness = comp; } }