Package pneumaticCraft.common.tileentity

Source Code of pneumaticCraft.common.tileentity.TileEntitySecurityStation

package pneumaticCraft.common.tileentity;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.AxisAlignedBB;

import org.lwjgl.opengl.GL11;

import pneumaticCraft.client.render.RenderProgressingLine;
import pneumaticCraft.common.block.Blockss;
import pneumaticCraft.common.item.ItemMachineUpgrade;
import pneumaticCraft.common.item.ItemNetworkComponents;
import pneumaticCraft.common.network.NetworkHandler;
import pneumaticCraft.common.network.PacketRenderRangeLines;
import pneumaticCraft.lib.Log;
import pneumaticCraft.lib.TileEntityConstants;

import com.mojang.authlib.GameProfile;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class TileEntitySecurityStation extends TileEntityBase implements ISidedInventory, IGUITextFieldSensitive,
        IRangeLineShower, IRedstoneControl{
    private ItemStack[] inventory;
    private final int INVENTORY_SIZE = 39;
    public static final int UPGRADE_SLOT_START = 35;
    public static final int UPGRADE_SLOT_END = 38;
    public final List<GameProfile> hackedUsers = new ArrayList<GameProfile>(); //Stores all the users that have hacked this Security Station.
    public final List<GameProfile> sharedUsers = new ArrayList<GameProfile>(); //Stores all the users that have been allowed by the stationOwner.
    private int rebootTimer;//When the player decides to reset the station, this variable will hold the remaining reboot time.
    public String textFieldText = "";
    private int securityRange;
    private int oldSecurityRange; //range used by the range line renderer, to figure out if the range has been changed.
    private List<RenderProgressingLine> rangeLines;
    private int rangeLinesTimer = 0;

    public int redstoneMode;
    public boolean oldRedstoneStatus;

    private boolean validNetwork;

    public TileEntitySecurityStation(){
        inventory = new ItemStack[INVENTORY_SIZE];
        setUpgradeSlots(new int[]{UPGRADE_SLOT_START, 36, 37, UPGRADE_SLOT_END});
    }

    @Override
    public void updateEntity(){
        if(rebootTimer > 0) {
            rebootTimer--;
            if(!worldObj.isRemote) {
                if(rebootTimer == 0) {
                    hackedUsers.clear();
                }
                if(rebootTimer % 60 == 0) {
                    sendDescriptionPacket();
                }
            }
        }
        if(worldObj.isRemote && rangeLines != null) {
            if(rangeLinesTimer > 0) {
                rangeLinesTimer--;
                for(RenderProgressingLine line : rangeLines) {
                    if(line.getProgress() > 0.005F || worldObj.rand.nextInt(60) == 0) {
                        line.incProgress(0.01F);
                    }
                }
            } else {
                Iterator<RenderProgressingLine> iterator = rangeLines.iterator();
                while(iterator.hasNext()) {
                    RenderProgressingLine line = iterator.next();
                    if(line.getProgress() > 0.005F) {
                        line.incProgress(0.01F);
                    }
                    if(worldObj.rand.nextInt(10) == 0) {
                        iterator.remove();
                    }
                }
            }
        }
        if(/* !worldObj.isRemote && */oldRedstoneStatus != shouldEmitRedstone()) {
            oldRedstoneStatus = shouldEmitRedstone();
            updateNeighbours();
        }

        securityRange = Math.min(2 + getUpgrades(ItemMachineUpgrade.UPGRADE_RANGE, getUpgradeSlots()), TileEntityConstants.SECURITY_STATION_MAX_RANGE);

        super.updateEntity();

    }

    public void rebootStation(){
        rebootTimer = TileEntityConstants.SECURITY_STATION_REBOOT_TIME;
    }

    public int getRebootTime(){
        return rebootTimer;
    }

    /**
     * Will initiate the wireframe rendering. When invoked on the server, it sends a packet to every client to render the box.
     */
    @Override
    public void showRangeLines(){
        if(worldObj.isRemote) {
            rangeLinesTimer = 200;
        } else {
            NetworkHandler.sendToAllAround(new PacketRenderRangeLines(this), worldObj, TileEntityConstants.PACKET_UPDATE_DISTANCE + getSecurityRange());
        }
    }

    @SideOnly(Side.CLIENT)
    public void renderRangeLines(){
        if(oldSecurityRange != getSecurityRange() || oldSecurityRange == 0) {
            showRangeLines();
            oldSecurityRange = getSecurityRange();
            rangeLines = new ArrayList<RenderProgressingLine>();
            double renderSecurityRange = securityRange + 0.5D;
            for(int i = 0; i < securityRange * 16 + 8; i++) {
                //Add the vertical lines of the walls
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange + i / 8D, -renderSecurityRange + 1, -renderSecurityRange, -renderSecurityRange + i / 8D, renderSecurityRange + 1, -renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(renderSecurityRange - i / 8D, -renderSecurityRange + 1, renderSecurityRange, renderSecurityRange - i / 8D, renderSecurityRange + 1, renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange, -renderSecurityRange + 1, renderSecurityRange - i / 8D, -renderSecurityRange, renderSecurityRange + 1, renderSecurityRange - i / 8D));
                rangeLines.add(new RenderProgressingLine(renderSecurityRange, -renderSecurityRange + 1, -renderSecurityRange + i / 8D, renderSecurityRange, renderSecurityRange + 1, -renderSecurityRange + i / 8D));

                //Add the horizontal lines of the walls
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange, -renderSecurityRange + i / 8D + 1, -renderSecurityRange, -renderSecurityRange, -renderSecurityRange + i / 8D + 1, renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(renderSecurityRange, -renderSecurityRange + i / 8D + 1, -renderSecurityRange, renderSecurityRange, -renderSecurityRange + i / 8D + 1, renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange, renderSecurityRange - i / 8D + 1, -renderSecurityRange, renderSecurityRange, renderSecurityRange - i / 8D + 1, -renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange, -renderSecurityRange + i / 8D + 1, renderSecurityRange, renderSecurityRange, -renderSecurityRange + i / 8D + 1, renderSecurityRange));

                //Add the roof and floor
                rangeLines.add(new RenderProgressingLine(renderSecurityRange - i / 8D, -renderSecurityRange + 1, -renderSecurityRange, renderSecurityRange - i / 8D, -renderSecurityRange + 1, renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(renderSecurityRange - i / 8D, renderSecurityRange + 1, -renderSecurityRange, renderSecurityRange - i / 8D, renderSecurityRange + 1, renderSecurityRange));
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange, -renderSecurityRange + 1, -renderSecurityRange + i / 8D, renderSecurityRange, -renderSecurityRange + 1, -renderSecurityRange + i / 8D));
                rangeLines.add(new RenderProgressingLine(-renderSecurityRange, renderSecurityRange + 1, -renderSecurityRange + i / 8D, renderSecurityRange, renderSecurityRange + 1, -renderSecurityRange + i / 8D));

            }
        }
        GL11.glDisable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glColor4d(1, 0, 0, 0.2D);
        GL11.glLineWidth(1.0F);
        for(RenderProgressingLine line : rangeLines) {
            line.render();
        }
        GL11.glColor4d(1, 1, 1, 1);
        GL11.glDisable(GL11.GL_BLEND);
        GL11.glEnable(GL11.GL_TEXTURE_2D);

    }

    @Override
    public void handleGUIButtonPress(int buttonID, EntityPlayer player){
        if(buttonID == 0) {
            redstoneMode++;
            if(redstoneMode > 2) redstoneMode = 0;
            updateNeighbours();
        } else if(buttonID == 2) {
            rebootStation();
        } else if(buttonID > 2 && buttonID - 3 < sharedUsers.size()) {
            sharedUsers.remove(buttonID - 3);
        }
        sendDescriptionPacket();
    }

    public void addSharedUser(GameProfile user){
        for(GameProfile sharedUser : sharedUsers) {
            if(gameProfileEquals(sharedUser, user)) return;
        }
        sharedUsers.add(user);
    }

    public void addHacker(GameProfile user){
        for(GameProfile hackedUser : hackedUsers) {
            if(gameProfileEquals(hackedUser, user)) {
                return;
            }
        }
        hackedUsers.add(user);
    }

    private boolean gameProfileEquals(GameProfile profile1, GameProfile profile2){
        return profile1.getId() != null && profile2.getId() != null ? profile1.getId().equals(profile2.getId()) : profile1.getName().equals(profile2.getName());
    }

    public boolean shouldEmitRedstone(){
        switch(redstoneMode){
            case 0:
                return false;
            case 1:
                return isHacked();
            case 2:
                return getRebootTime() <= 0;
        }
        return false;
    }

    public boolean isHacked(){
        return hackedUsers.size() > 0;
    }

    @Override
    @SideOnly(Side.CLIENT)
    public AxisAlignedBB getRenderBoundingBox(){
        if(rangeLines == null || rangeLines.size() == 0) return super.getRenderBoundingBox();
        int range = getSecurityRange();
        return AxisAlignedBB.getBoundingBox(xCoord - range, yCoord - range, zCoord - range, xCoord + 1 + range, yCoord + 1 + range, zCoord + 1 + range);
    }

    public int getSecurityRange(){
        return securityRange;
    }

    /**
     * Returns the number of slots in the inventory.
     */
    @Override
    public int getSizeInventory(){
        return inventory.length;
    }

    /**
     * Returns the stack in slot i
     */
    @Override
    public ItemStack getStackInSlot(int slot){
        return inventory[slot];
    }

    @Override
    public ItemStack decrStackSize(int slot, int amount){
        ItemStack itemStack = getStackInSlot(slot);
        if(itemStack != null) {
            if(itemStack.stackSize <= amount) {
                setInventorySlotContents(slot, null);
            } else {
                itemStack = itemStack.splitStack(amount);
                if(itemStack.stackSize == 0) {
                    setInventorySlotContents(slot, null);
                }
            }
        }

        return itemStack;
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slot){
        ItemStack itemStack = getStackInSlot(slot);
        if(itemStack != null) {
            setInventorySlotContents(slot, null);
        }
        return itemStack;
    }

    @Override
    public void setInventorySlotContents(int slot, ItemStack itemStack){
        inventory[slot] = itemStack;
        if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) {
            itemStack.stackSize = getInventoryStackLimit();
        }
        checkForNetworkValidity();
    }

    @Override
    public String getInventoryName(){
        return Blockss.securityStation.getUnlocalizedName();
    }

    @Override
    public int getInventoryStackLimit(){
        return 64;
    }

    @Override
    public void readFromNBT(NBTTagCompound tag){

        super.readFromNBT(tag);
        redstoneMode = tag.getInteger("redstoneMode");
        rebootTimer = tag.getInteger("startupTimer");
        // Read in the ItemStacks in the inventory from NBT
        NBTTagList tagList = tag.getTagList("Items", 10);
        inventory = new ItemStack[getSizeInventory()];
        for(int i = 0; i < tagList.tagCount(); ++i) {
            NBTTagCompound tagCompound = tagList.getCompoundTagAt(i);
            byte slot = tagCompound.getByte("Slot");
            if(slot >= 0 && slot < inventory.length) {
                inventory[slot] = ItemStack.loadItemStackFromNBT(tagCompound);
            }
        }

        sharedUsers.clear();
        NBTTagList sharedList = tag.getTagList("SharedUsers", 10);
        for(int i = 0; i < sharedList.tagCount(); ++i) {
            NBTTagCompound tagCompound = sharedList.getCompoundTagAt(i);
            sharedUsers.add(new GameProfile(tagCompound.hasKey("uuid") ? UUID.fromString(tagCompound.getString("uuid")) : null, tagCompound.getString("name")));
        }

        hackedUsers.clear();
        NBTTagList hackedList = tag.getTagList("HackedUsers", 10);
        for(int i = 0; i < hackedList.tagCount(); ++i) {
            NBTTagCompound tagCompound = hackedList.getCompoundTagAt(i);
            hackedUsers.add(new GameProfile(tagCompound.hasKey("uuid") ? UUID.fromString(tagCompound.getString("uuid")) : null, tagCompound.getString("name")));
        }

        checkForNetworkValidity();
    }

    @Override
    public void writeToNBT(NBTTagCompound tag){

        super.writeToNBT(tag);
        tag.setInteger("redstoneMode", redstoneMode);
        tag.setInteger("startupTimer", rebootTimer);
        // Write the ItemStacks in the inventory to NBT
        NBTTagList tagList = new NBTTagList();
        for(int currentIndex = 0; currentIndex < inventory.length; ++currentIndex) {
            if(inventory[currentIndex] != null) {
                NBTTagCompound tagCompound = new NBTTagCompound();
                tagCompound.setByte("Slot", (byte)currentIndex);
                inventory[currentIndex].writeToNBT(tagCompound);
                tagList.appendTag(tagCompound);
            }
        }
        tag.setTag("Items", tagList);

        NBTTagList sharedList = new NBTTagList();
        for(int i = 0; i < sharedUsers.size(); i++) {
            NBTTagCompound tagCompound = new NBTTagCompound();
            tagCompound.setString("name", sharedUsers.get(i).getName());
            if(sharedUsers.get(i).getId() != null) tagCompound.setString("uuid", sharedUsers.get(i).getId().toString());
            sharedList.appendTag(tagCompound);
        }
        tag.setTag("SharedUsers", sharedList);

        NBTTagList hackedList = new NBTTagList();
        for(int i = 0; i < hackedUsers.size(); i++) {
            NBTTagCompound tagCompound = new NBTTagCompound();
            tagCompound.setString("name", hackedUsers.get(i).getName());
            if(hackedUsers.get(i).getId() != null) tagCompound.setString("uuid", hackedUsers.get(i).getId().toString());
            hackedList.appendTag(tagCompound);
        }
        tag.setTag("HackedUsers", hackedList);
    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack){
        return false;
    }

    @Override
    // upgrades in bottom, fuel in the rest.
    public int[] getAccessibleSlotsFromSide(int var1){
        return new int[0];
    }

    @Override
    public boolean canInsertItem(int i, ItemStack itemstack, int j){
        return false;
    }

    @Override
    public boolean canExtractItem(int i, ItemStack itemstack, int j){
        return false;
    }

    @Override
    public void setText(int textFieldID, String text){
        textFieldText = text;
    }

    @Override
    public String getText(int textFieldID){
        return textFieldText;
    }

    /**
     * Returns true if the given player is allowed to interact with the covered area of this Security Station.
     * @param player
     * @return
     */
    public boolean doesAllowPlayer(EntityPlayer player){
        return rebootTimer > 0 || isPlayerOnWhiteList(player) || hasPlayerHacked(player);
    }

    public boolean isPlayerOnWhiteList(EntityPlayer player){
        for(int i = 0; i < sharedUsers.size(); i++) {
            GameProfile user = sharedUsers.get(i);
            if(gameProfileEquals(user, player.getGameProfile())) {
                if(user.getId() == null && player.getGameProfile().getId() != null) {
                    sharedUsers.set(i, player.getGameProfile());
                    Log.info("Legacy conversion: Security Station shared username '" + player.getCommandSenderName() + "' is now using UUID '" + player.getGameProfile().getId() + "'.");
                }
                return true;
            }
        }
        return false;
    }

    public boolean hasPlayerHacked(EntityPlayer player){
        for(int i = 0; i < hackedUsers.size(); i++) {
            GameProfile user = hackedUsers.get(i);
            if(gameProfileEquals(user, player.getGameProfile())) {
                if(user.getId() == null && player.getGameProfile().getId() != null) {
                    hackedUsers.set(i, player.getGameProfile());
                    Log.info("Legacy conversion: Security Station hacked username '" + player.getCommandSenderName() + "' is now using UUID '" + player.getGameProfile().getId() + "'.");
                }
                return true;
            }
        }
        return false;
    }

    /**
     * Returns true if the given slots are connected in the network. For this to be true both slots need to have a network component stored as well.
     * @param firstSlot
     * @param secondSlot
     * @return
     */
    public boolean connects(int firstSlot, int secondSlot){
        if(firstSlot < 0 || secondSlot < 0 || firstSlot >= 35 || secondSlot >= 35 || firstSlot == secondSlot || getStackInSlot(firstSlot) == null || getStackInSlot(secondSlot) == null) return false;
        for(int column = -1; column <= 1; column++) {
            for(int row = -1; row <= 1; row++) {
                if(firstSlot + row * 5 + column == secondSlot) {
                    if(firstSlot % 5 > 0 && firstSlot % 5 < 4 || secondSlot % 5 > 0 && secondSlot % 5 < 4 || secondSlot % 5 == firstSlot % 5) return true;
                }
            }
        }
        return false;
    }

    public boolean hasValidNetwork(){
        return validNetwork;
    }

    public enum EnumNetworkValidityProblem{
        NONE, NO_SUBROUTINE, NO_IO_PORT, NO_REGISTRY, TOO_MANY_SUBROUTINES, TOO_MANY_IO_PORTS, TOO_MANY_REGISTRIES, NO_CONNECTION_SUB_AND_IO_PORT, NO_CONNECTION_IO_PORT_AND_REGISTRY
    }

    /**
     * Method used to update the check of the validity of the network.
     * @return optional problem enum
     */
    public EnumNetworkValidityProblem checkForNetworkValidity(){
        validNetwork = false;
        int ioPortSlot = -1;
        int registrySlot = -1;
        int subroutineSlot = -1;
        for(int i = 0; i < 35; i++) {
            if(getStackInSlot(i) != null) {
                switch(getStackInSlot(i).getItemDamage()){
                    case ItemNetworkComponents.DIAGNOSTIC_SUBROUTINE:
                        if(subroutineSlot != -1) return EnumNetworkValidityProblem.TOO_MANY_SUBROUTINES;//only one subroutine per network
                        subroutineSlot = i;
                        break;
                    case ItemNetworkComponents.NETWORK_IO_PORT:
                        if(ioPortSlot != -1) return EnumNetworkValidityProblem.TOO_MANY_IO_PORTS;//only one subroutine per network
                        ioPortSlot = i;
                        break;
                    case ItemNetworkComponents.NETWORK_REGISTRY:
                        if(registrySlot != -1) return EnumNetworkValidityProblem.TOO_MANY_REGISTRIES;//only one subroutine per network
                        registrySlot = i;
                        break;
                }
            }
        }
        if(subroutineSlot == -1) return EnumNetworkValidityProblem.NO_SUBROUTINE;
        if(ioPortSlot == -1) return EnumNetworkValidityProblem.NO_IO_PORT;
        if(registrySlot == -1) return EnumNetworkValidityProblem.NO_REGISTRY;
        if(!traceComponent(subroutineSlot, ioPortSlot, new boolean[35])) return EnumNetworkValidityProblem.NO_CONNECTION_SUB_AND_IO_PORT;//check if there's a valid route between the subroutine/ioPort
        if(!traceComponent(ioPortSlot, registrySlot, new boolean[35])) return EnumNetworkValidityProblem.NO_CONNECTION_IO_PORT_AND_REGISTRY; // and ioPort/registry.
        validNetwork = true;
        return EnumNetworkValidityProblem.NONE;
    }

    private boolean traceComponent(int startSlot, int targetSlot, boolean[] slotsDone){
        for(int i = 0; i < 35; i++) {
            if(!slotsDone[i] && connects(startSlot, i)) {
                if(i == targetSlot) return true;
                slotsDone[i] = true;
                if(traceComponent(i, targetSlot, slotsDone)) return true;
            }
        }
        return false;
    }

    public int getDetectionChance(){
        return Math.min(100, 20 + 20 * getUpgrades(ItemMachineUpgrade.UPGRADE_ENTITY_TRACKER, getUpgradeSlots()));
    }

    public int getSecurityLevel(){
        return 1 + getUpgrades(ItemMachineUpgrade.UPGRADE_SECURITY, getUpgradeSlots());
    }

    @Override
    public boolean hasCustomInventoryName(){
        return false;
    }

    @Override
    public boolean isUseableByPlayer(EntityPlayer var1){
        return isGuiUseableByPlayer(var1);
    }

    @Override
    public boolean isGuiUseableByPlayer(EntityPlayer par1EntityPlayer){
        return worldObj.getTileEntity(xCoord, yCoord, zCoord) == this;
    }

    @Override
    public void openInventory(){}

    @Override
    public void closeInventory(){}

    @Override
    public int getRedstoneMode(){
        return redstoneMode;
    }
}
TOP

Related Classes of pneumaticCraft.common.tileentity.TileEntitySecurityStation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.