/* * 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 mods.railcraft.api.tracks.ISwitchDevice; import mods.railcraft.api.tracks.ITrackSwitch; import mods.railcraft.common.blocks.tracks.TrackSwitchBase; import mods.railcraft.common.blocks.tracks.TrackTools; import mods.railcraft.common.plugins.forge.PowerPlugin; import mods.railcraft.common.util.misc.Game; import mods.railcraft.common.util.sounds.SoundHelper; import net.minecraft.entity.item.EntityMinecart; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.EnumSet; public abstract class TileSwitchBase extends TileSignalFoundation implements ISwitchDevice { private static final int ARROW_UPDATE_INTERVAL = 16; private byte facing = (byte) ForgeDirection.NORTH.ordinal(); private boolean powered; private boolean lastSwitchState; private ArrowDirection redArrowRenderState = ArrowDirection.EAST_WEST; private ArrowDirection whiteArrowRenderState = ArrowDirection.NORTH_SOUTH; public ArrowDirection getRedArrowRenderState() { return redArrowRenderState; } public ArrowDirection getWhiteArrowRenderState() { return whiteArrowRenderState; } @Override public void setBlockBoundsBasedOnState(IBlockAccess world, int i, int j, int k) { getBlockType().setBlockBounds(0.2f, 0f, 0.2f, 0.8f, 0.8f, 0.8f); } @Override public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k) { return AxisAlignedBB.getBoundingBox(i + 0.2f, j, k + 0.2f, i + 0.8f, j + 0.4F, k + 0.8f); } @Override public AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int i, int j, int k) { return AxisAlignedBB.getBoundingBox(i + 0.2f, j, k + 0.2f, i + 0.8f, j + 0.8f, k + 0.8f); } @Override public boolean blockActivated(int side, EntityPlayer player) { powered = !powered; sendUpdateToClient(); return true; } @Override public abstract boolean shouldSwitch(ITrackSwitch switchTrack, EntityMinecart cart); @Override public boolean canUpdate() { return true; } @Override public void updateEntity() { super.updateEntity(); if (Game.isHost(worldObj)) return; if (clock % ARROW_UPDATE_INTERVAL == 0) updateArrows(); } @Override public void onSwitch(boolean isSwitched) { if (lastSwitchState != isSwitched) { lastSwitchState = isSwitched; if (isSwitched) SoundHelper.playSound(worldObj, getX(), getY(), getZ(), "tile.piston.in", 0.25f, worldObj.rand.nextFloat() * 0.25F + 0.7F); else SoundHelper.playSound(worldObj, getX(), getY(), getZ(), "tile.piston.out", 0.25f, worldObj.rand.nextFloat() * 0.25F + 0.7F); } } @Override @Deprecated public void setRenderState(ArrowDirection redArrow, ArrowDirection whiteArrow) { } @Override public void updateArrows() { ArrowDirection redArrow = null; ArrowDirection whiteArrow = null; for (ForgeDirection side : EnumSet.of(ForgeDirection.EAST, ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.WEST)) { TrackSwitchBase trackSwitch = TrackTools.getTrackInstance(tileCache.getTileOnSide(side), TrackSwitchBase.class); if (trackSwitch != null) { redArrow = mergeArrowDirection(redArrow, trackSwitch.getRedSignDirection()); whiteArrow = mergeArrowDirection(whiteArrow, trackSwitch.getWhiteSignDirection()); } } boolean changed = false; if (redArrow != null && redArrowRenderState != redArrow) { redArrowRenderState = redArrow; changed = true; } if (whiteArrow != null && whiteArrowRenderState != whiteArrow) { whiteArrowRenderState = whiteArrow; changed = true; } if (changed) markBlockForUpdate(); } private ArrowDirection mergeArrowDirection(ArrowDirection arrow1, ArrowDirection arrow2) { if (arrow1 == arrow2) return arrow1; if (arrow1 == null) return arrow2; if (arrow2 == null) return arrow1; if (isEastOrWest(arrow1) && isEastOrWest(arrow2)) return ArrowDirection.EAST_WEST; return ArrowDirection.NORTH_SOUTH; } private boolean isEastOrWest(ArrowDirection arrowDirection) { switch (arrowDirection) { case EAST: case WEST: case EAST_WEST: return true; } return false; } @Override public void writeToNBT(NBTTagCompound data) { super.writeToNBT(data); data.setBoolean("Powered", isPowered()); data.setBoolean("lastSwitchState", lastSwitchState); data.setByte("Facing", facing); } @Override public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); powered = data.getBoolean("Powered"); lastSwitchState = data.getBoolean("lastSwitchState"); facing = data.getByte("Facing"); } @Override public void writePacketData(DataOutputStream data) throws IOException { super.writePacketData(data); data.writeByte(facing); data.writeBoolean(powered); } @Override public void readPacketData(DataInputStream data) throws IOException { super.readPacketData(data); byte f = data.readByte(); if (facing != f) { facing = f; markBlockForUpdate(); } powered = data.readBoolean(); } public byte getFacing() { return facing; } public void setFacing(byte facing) { this.facing = facing; } public boolean isPowered() { return powered; } protected void setPowered(boolean p) { powered = p; sendUpdateToClient(); } protected boolean isBeingPoweredByRedstone() { return PowerPlugin.isBlockBeingPowered(worldObj, xCoord, yCoord, zCoord) || PowerPlugin.isRedstonePowered(worldObj, xCoord, yCoord, zCoord); } }