/* * Copyright (c) CovertJaguar, 2014 http://railcraft.info * * This code is the property of CovertJaguar * and may only be used with explicit written * permission unless otherwise specified on the * license page at http://railcraft.info/wiki/info:license. */ package mods.railcraft.common.blocks.signals; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import mods.railcraft.api.signals.SignalAspect; import mods.railcraft.common.gui.EnumGui; import mods.railcraft.common.gui.GuiHandler; import mods.railcraft.common.gui.buttons.IButtonTextureSet; import mods.railcraft.common.gui.buttons.IMultiButtonState; import mods.railcraft.common.gui.buttons.MultiButtonController; import mods.railcraft.common.gui.buttons.StandardButtonTextureSets; import mods.railcraft.common.gui.tooltips.ToolTip; import mods.railcraft.common.plugins.forge.LocalizationPlugin; import mods.railcraft.common.plugins.forge.PowerPlugin; import mods.railcraft.common.util.misc.Game; import mods.railcraft.common.util.misc.MiscTools; import mods.railcraft.common.util.network.IGuiReturnHandler; import net.minecraft.block.Block; import net.minecraftforge.common.util.ForgeDirection; import static mods.railcraft.common.plugins.forge.PowerPlugin.*; public class TileBoxCapacitor extends TileBoxBase implements IGuiReturnHandler { private short ticksPowered; public short ticksToPower = 200; private SignalAspect aspect = SignalAspect.OFF; private final MultiButtonController<EnumStateMode> stateModeController = new MultiButtonController(EnumStateMode.IMMEDIATE.ordinal(), EnumStateMode.values()); public TileBoxCapacitor() { } public enum EnumStateMode implements IMultiButtonState { IMMEDIATE("railcraft.gui.box.capacitor.immediate"), DELAYED("railcraft.gui.box.capacitor.delayed"); private final String label; private final ToolTip tip; private EnumStateMode(String label){ this.label = label; this.tip = ToolTip.buildToolTip(label + ".tip"); } @Override public String getLabel() { return LocalizationPlugin.translate(label); } @Override public IButtonTextureSet getTextureSet() { return StandardButtonTextureSets.SMALL_BUTTON; } @Override public ToolTip getToolTip() { return tip; } } public MultiButtonController<EnumStateMode> getStateModeController(){ return stateModeController; } @Override public EnumSignal getSignalType() { return EnumSignal.BOX_CAPACITOR; } @Override public boolean blockActivated(int side, EntityPlayer player) { if (player.isSneaking()) return false; GuiHandler.openGui(EnumGui.BOX_CAPACITOR, player, worldObj, xCoord, yCoord, zCoord); return true; } @Override public void updateEntity() { super.updateEntity(); if (Game.isNotHost(worldObj)) return; if (ticksPowered > 0) { ticksPowered--; if (stateModeController.getButtonState().equals(EnumStateMode.DELAYED)){ //new behavior SignalAspect tmpaspect = SignalAspect.GREEN; Boolean hasInput = false; if (PowerPlugin.isBlockBeingPoweredByRepeater(worldObj, xCoord, yCoord, zCoord)) hasInput = true; for (int side = 2; side < 6; side++) { //get most restrictive aspect from adjacent (active) boxes ForgeDirection forgeSide = ForgeDirection.getOrientation(side); TileEntity tile = tileCache.getTileOnSide(forgeSide); if (tile instanceof TileBoxBase) { TileBoxBase box = (TileBoxBase) tile; if (box.isEmittingRedstone(forgeSide.getOpposite())) { hasInput = true; tmpaspect = SignalAspect.mostRestrictive(tmpaspect, box.getBoxSignalAspect(forgeSide.getOpposite())); } } } if (hasInput){ ticksPowered = ticksToPower; //undo any previous decrements if (!aspect.equals(tmpaspect) ) { aspect = tmpaspect; //change to the most restrictive aspect found above. updateNeighbors(); } } } //in all cases: if (ticksPowered <= 0) updateNeighbors(); } } @Override public void onNeighborBlockChange(Block block) { super.onNeighborBlockChange(block); if (worldObj.isRemote) return; boolean p = PowerPlugin.isBlockBeingPoweredByRepeater(worldObj, xCoord, yCoord, zCoord); if (ticksPowered <= 0 && p) { ticksPowered = ticksToPower; if (stateModeController.getButtonState().equals(EnumStateMode.IMMEDIATE)) aspect = SignalAspect.GREEN; updateNeighbors(); } } @Override public void onNeighborStateChange(TileBoxBase neighbor, ForgeDirection side) { if (neighbor.isEmittingRedstone(side)) { ticksPowered = ticksToPower; if (stateModeController.getButtonState().equals(EnumStateMode.IMMEDIATE)) aspect = neighbor.getBoxSignalAspect(side); updateNeighbors(); } } private void updateNeighbors() { sendUpdateToClient(); notifyBlocksOfNeighborChange(); updateNeighborBoxes(); } @Override public int getPowerOutput(int side) { TileEntity tile = tileCache.getTileOnSide(MiscTools.getOppositeSide(side)); if (tile instanceof TileBoxBase) return NO_POWER; return ticksPowered > 0 ? FULL_POWER : NO_POWER; } @Override public void writeToNBT(NBTTagCompound data) { super.writeToNBT(data); data.setShort("ticksPowered", ticksPowered); data.setShort("ticksToPower", ticksToPower); data.setByte("aspect", (byte) aspect.ordinal()); stateModeController.writeToNBT(data, "mode"); } @Override public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); ticksPowered = data.getShort("ticksPowered"); ticksToPower = data.getShort("ticksToPower"); aspect = SignalAspect.values()[data.getByte("aspect")]; if (data.hasKey("mode")) stateModeController.readFromNBT(data, "mode"); else //set old boxes to immediate mode to retain old behavior stateModeController.setCurrentState(EnumStateMode.IMMEDIATE.ordinal()); } @Override public void writePacketData(DataOutputStream data) throws IOException { super.writePacketData(data); data.writeBoolean(ticksPowered > 0); data.writeShort(ticksToPower); data.writeByte(aspect.ordinal()); data.writeByte(stateModeController.getCurrentState()); } @Override public void readPacketData(DataInputStream data) throws IOException { super.readPacketData(data); ticksPowered = (short) (data.readBoolean() ? 1 : 0); ticksToPower = data.readShort(); aspect = SignalAspect.values()[data.readByte()]; stateModeController.setCurrentState(data.readByte()); markBlockForUpdate(); } @Override public void writeGuiData(DataOutputStream data) throws IOException { data.writeShort(ticksToPower); data.writeByte(stateModeController.getCurrentState()); } @Override public void readGuiData(DataInputStream data, EntityPlayer sender) throws IOException { ticksToPower = data.readShort(); stateModeController.setCurrentState(data.readByte()); } @Override public boolean isConnected(ForgeDirection side) { TileEntity tile = tileCache.getTileOnSide(side); if (tile instanceof TileBoxBase) return ((TileBoxBase) tile).canTransferAspect() || ((TileBoxBase) tile).canReceiveAspect(); return false; } @Override public SignalAspect getBoxSignalAspect(ForgeDirection side) { return ticksPowered > 0 ? aspect : SignalAspect.RED; } @Override public boolean canReceiveAspect() { return true; } @Override public boolean canTransferAspect() { return true; } }