Package micdoodle8.mods.galacticraft.core.util

Source Code of micdoodle8.mods.galacticraft.core.util.OxygenUtil

package micdoodle8.mods.galacticraft.core.util;

import cpw.mods.fml.client.FMLClientHandler;
import mekanism.api.gas.IGasTransmitter;
import mekanism.api.gas.ITubeConnection;
import mekanism.api.transmitters.TransmissionType;
import micdoodle8.mods.galacticraft.api.block.IPartialSealableBlock;
import micdoodle8.mods.galacticraft.api.item.IBreathableArmor;
import micdoodle8.mods.galacticraft.api.item.IBreathableArmor.EnumGearType;
import micdoodle8.mods.galacticraft.api.transmission.NetworkType;
import micdoodle8.mods.galacticraft.api.transmission.tile.IConnector;
import micdoodle8.mods.galacticraft.api.vector.BlockVec3;
import micdoodle8.mods.galacticraft.core.blocks.GCBlocks;
import micdoodle8.mods.galacticraft.core.energy.EnergyConfigHandler;
import micdoodle8.mods.galacticraft.core.entities.player.GCPlayerStats;
import micdoodle8.mods.galacticraft.core.items.ItemOxygenGear;
import micdoodle8.mods.galacticraft.core.items.ItemOxygenMask;
import micdoodle8.mods.galacticraft.core.items.ItemOxygenTank;
import micdoodle8.mods.galacticraft.core.oxygen.OxygenPressureProtocol;
import micdoodle8.mods.galacticraft.core.tile.TileEntityOxygenDistributor;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class OxygenUtil
{
    private static HashSet<BlockVec3> checked;

    public static boolean shouldDisplayTankGui(GuiScreen gui)
    {
        if (FMLClientHandler.instance().getClient().gameSettings.hideGUI)
        {
            return false;
        }

        if (gui == null)
        {
            return true;
        }

        if (gui instanceof GuiInventory)
        {
            return false;
        }

        return gui instanceof GuiChat;

    }

    public static boolean isAABBInBreathableAirBlock(EntityLivingBase entity)
    {
        double y = entity.posY + entity.getEyeHeight();
        double x = entity.posX;
        double z = entity.posZ;

        double sx = entity.boundingBox.maxX - entity.boundingBox.minX;
        double sy = entity.boundingBox.maxY - entity.boundingBox.minY;
        double sz = entity.boundingBox.maxZ - entity.boundingBox.minZ;

        //A good first estimate of head size is that it's the smallest of the entity's 3 dimensions (e.g. front to back, for Steve)
        double smin = Math.min(sx, Math.min(sy, sz)) / 2;

        return OxygenUtil.isAABBInBreathableAirBlock(entity.worldObj, AxisAlignedBB.getBoundingBox(x - smin, y - smin, z - smin, x + smin, y + smin, z + smin));
    }

    @SuppressWarnings("rawtypes")
    public static boolean isAABBInBreathableAirBlock(World world, AxisAlignedBB bb)
    {
        if (!world.isRemote)
        {

            final double avgX = (bb.minX + bb.maxX) / 2.0D;
            final double avgY = (bb.minY + bb.maxY) / 2.0D;
            final double avgZ = (bb.minZ + bb.maxZ) / 2.0D;

            final List l = world.loadedTileEntityList;

            for (final Object o : l)
            {
                if (o instanceof TileEntityOxygenDistributor)
                {
                    final TileEntityOxygenDistributor distributor = (TileEntityOxygenDistributor) o;

                    if (distributor.oxygenBubble != null)
                    {
                        final double dist = distributor.getDistanceFromServer(avgX, avgY, avgZ);
                        double r = distributor.oxygenBubble.getSize();

                        if (dist < r * r)
                        {
                            return true;
                        }
                    }
                }
            }

        }
        return OxygenUtil.isInOxygenBlock(world, bb.copy().contract(0.001D, 0.001D, 0.001D));
    }

    public static boolean isInOxygenBlock(World world, AxisAlignedBB bb)
    {
        int i = MathHelper.floor_double(bb.minX);
        int j = MathHelper.floor_double(bb.maxX);
        int k = MathHelper.floor_double(bb.minY);
        int l = MathHelper.floor_double(bb.maxY);
        int i1 = MathHelper.floor_double(bb.minZ);
        int j1 = MathHelper.floor_double(bb.maxZ);

        OxygenUtil.checked = new HashSet();
        if (world.checkChunksExist(i, k, i1, j, l, j1))
        {
            for (int x = i; x <= j; ++x)
            {
                for (int y = k; y <= l; ++y)
                {
                    for (int z = i1; z <= j1; ++z)
                    {
                        Block block = world.getBlock(x, y, z);
                        if (OxygenUtil.testContactWithBreathableAir(world, block, x, y, z, 0))
                        {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    /*
     * A simplified version of the breathable air check which checks
     * all 6 sides of the given block (because a torch can pass air on all sides)
     * Used in BlockUnlitTorch.
     */
    public static boolean checkTorchHasOxygen(World world, Block block, int x, int y, int z)
    {
        OxygenUtil.checked = new HashSet();
        BlockVec3 vec = new BlockVec3(x, y, z);
        for (int side = 0; side < 6; side++)
        {
            BlockVec3 sidevec = vec.newVecSide(side);
            Block newblock = sidevec.getBlockID_noChunkLoad(world);
            if (OxygenUtil.testContactWithBreathableAir(world, newblock, sidevec.x, sidevec.y, sidevec.z, 1))
            {
                return true;
            }
        }
        return false;
    }

    /*
     * Test whether the given block at (x,y,z) coordinates is either:
     * - breathable air (returns true)
     * - solid, or air which is not breathable (returns false)
     * - an air-permeable block, for example a torch, in which case test the surrounding
     * air-reachable blocks (up to 5 blocks away) and return true if breathable air is found
     * in one of them, or false if not.
     */
    public static boolean testContactWithBreathableAir(World world, Block block, int x, int y, int z, int limitCount)
    {
        BlockVec3 vec = new BlockVec3(x, y, z);
        checked.add(vec);
        if (block == GCBlocks.breatheableAir || block == GCBlocks.brightBreatheableAir)
        {
            return true;
        }

        if (block.getMaterial() == Material.air)
        {
            return false;
        }

        //Test for non-sided permeable or solid blocks first
        boolean permeableFlag = false;
        if (!(block instanceof BlockLeavesBase))
        {
            if (block.isOpaqueCube())
            {
                if (block instanceof BlockGravel || block.getMaterial() == Material.cloth || block instanceof BlockSponge)
                {
                    permeableFlag = true;
                }
                else
                {
                    return false;
                }
            }
            else if (block instanceof BlockGlass || block instanceof BlockStainedGlass)
            {
                return false;
            }
            else if (block instanceof BlockLiquid)
            {
                return false;
            }
            else if (OxygenPressureProtocol.nonPermeableBlocks.containsKey(block))
            {
                ArrayList<Integer> metaList = OxygenPressureProtocol.nonPermeableBlocks.get(block);
                if (metaList.contains(Integer.valueOf(-1)) || metaList.contains(world.getBlockMetadata(x, y, z)))
                {
                    return false;
                }
            }
        }
        else
        {
            permeableFlag = true;
        }

        //Testing a non-air, permeable block (for example a torch or a ladder)
        if (limitCount < 5)
        {
            for (int side = 0; side < 6; side++)
            {
                if (permeableFlag || OxygenUtil.canBlockPassAirOnSide(world, block, vec, side))
                {
                    BlockVec3 sidevec = vec.newVecSide(side);
                    if (!checked.contains(sidevec))
                    {
                        Block newblock = sidevec.getBlockID_noChunkLoad(world);
                        if (OxygenUtil.testContactWithBreathableAir(world, newblock, sidevec.x, sidevec.y, sidevec.z, limitCount + 1))
                        {
                            return true;
                        }
                    }
                }
            }
        }

        return false;
    }
    //TODO - performance, could add a 'safe' version of this code (inside world borders)

    //TODO - add more performance increase, these sided checks could be done once only
    private static boolean canBlockPassAirOnSide(World world, Block block, BlockVec3 vec, int side)
    {
        if (block instanceof IPartialSealableBlock)
        {
            return !((IPartialSealableBlock) block).isSealed(world, vec.x, vec.y, vec.z, ForgeDirection.getOrientation(side));
        }

        //Half slab seals on the top side or the bottom side according to its metadata
        if (block instanceof BlockSlab)
        {
            return !(side == 0 && (vec.getBlockMetadata(world) & 8) == 8 || side == 1 && (vec.getBlockMetadata(world) & 8) == 0);
        }

        //Farmland etc only seals on the solid underside
        if (block instanceof BlockFarmland || block instanceof BlockEnchantmentTable || block instanceof BlockLiquid)
        {
            return side != 1;
        }

        if (block instanceof BlockPistonBase)
        {
            BlockPistonBase piston = (BlockPistonBase) block;
            int meta = vec.getBlockMetadata(world);
            if (BlockPistonBase.isExtended(meta))
            {
                int facing = BlockPistonBase.getPistonOrientation(meta);
                return side != facing;
            }
            return false;
        }

        return !block.isSideSolid(world, vec.x, vec.y, vec.z, ForgeDirection.getOrientation(side ^ 1));
    }

    public static int getDrainSpacing(ItemStack tank, ItemStack tank2)
    {
        boolean tank1Valid = tank != null && tank.getItem() instanceof ItemOxygenTank && tank.getMaxDamage() - tank.getItemDamage() > 0;
        boolean tank2Valid = tank2 != null && tank2.getItem() instanceof ItemOxygenTank && tank2.getMaxDamage() - tank2.getItemDamage() > 0;

        if (!tank1Valid && !tank2Valid)
        {
            return 0;
        }

        if (tank1Valid && !tank2Valid || !tank1Valid && tank2Valid)
        {
            return 9;
        }

        return 18;
    }

    public static boolean hasValidOxygenSetup(EntityPlayerMP player)
    {
        boolean missingComponent = false;

        GCPlayerStats stats = GCPlayerStats.get(player);

        if (stats.extendedInventory.getStackInSlot(0) == null || !OxygenUtil.isItemValidForPlayerTankInv(0, stats.extendedInventory.getStackInSlot(0)))
        {
            boolean handled = false;

            for (final ItemStack armorStack : player.inventory.armorInventory)
            {
                if (armorStack != null && armorStack.getItem() instanceof IBreathableArmor)
                {
                    final IBreathableArmor breathableArmor = (IBreathableArmor) armorStack.getItem();

                    if (breathableArmor.handleGearType(EnumGearType.HELMET))
                    {
                        if (breathableArmor.canBreathe(armorStack, player, EnumGearType.HELMET))
                        {
                            handled = true;
                        }
                    }
                }
            }

            if (!handled)
            {
                missingComponent = true;
            }
        }

        if (stats.extendedInventory.getStackInSlot(1) == null || !OxygenUtil.isItemValidForPlayerTankInv(1, stats.extendedInventory.getStackInSlot(1)))
        {
            boolean handled = false;

            for (final ItemStack armorStack : player.inventory.armorInventory)
            {
                if (armorStack != null && armorStack.getItem() instanceof IBreathableArmor)
                {
                    final IBreathableArmor breathableArmor = (IBreathableArmor) armorStack.getItem();

                    if (breathableArmor.handleGearType(EnumGearType.GEAR))
                    {
                        if (breathableArmor.canBreathe(armorStack, player, EnumGearType.GEAR))
                        {
                            handled = true;
                        }
                    }
                }
            }

            if (!handled)
            {
                missingComponent = true;
            }
        }

        if ((stats.extendedInventory.getStackInSlot(2) == null || !OxygenUtil.isItemValidForPlayerTankInv(2, stats.extendedInventory.getStackInSlot(2))) && (stats.extendedInventory.getStackInSlot(3) == null || !OxygenUtil.isItemValidForPlayerTankInv(3, stats.extendedInventory.getStackInSlot(3))))
        {
            boolean handled = false;

            for (final ItemStack armorStack : player.inventory.armorInventory)
            {
                if (armorStack != null && armorStack.getItem() instanceof IBreathableArmor)
                {
                    final IBreathableArmor breathableArmor = (IBreathableArmor) armorStack.getItem();

                    if (breathableArmor.handleGearType(EnumGearType.TANK1))
                    {
                        if (breathableArmor.canBreathe(armorStack, player, EnumGearType.TANK1))
                        {
                            handled = true;
                        }
                    }

                    if (breathableArmor.handleGearType(EnumGearType.TANK2))
                    {
                        if (breathableArmor.canBreathe(armorStack, player, EnumGearType.TANK2))
                        {
                            handled = true;
                        }
                    }
                }
            }

            if (!handled)
            {
                missingComponent = true;
            }
        }

        return !missingComponent;
    }

    public static boolean isItemValidForPlayerTankInv(int slotIndex, ItemStack stack)
    {
        switch (slotIndex)
        {
        case 0:
            return stack.getItem() instanceof ItemOxygenMask;
        case 1:
            return stack.getItem() instanceof ItemOxygenGear;
        case 2:
            return stack.getItem() instanceof ItemOxygenTank;
        case 3:
            return stack.getItem() instanceof ItemOxygenTank;
        }

        return false;
    }

    public static TileEntity[] getAdjacentOxygenConnections(TileEntity tile)
    {
        TileEntity[] adjacentConnections = new TileEntity[ForgeDirection.VALID_DIRECTIONS.length];

        boolean isMekLoaded = EnergyConfigHandler.isMekanismLoaded();

        BlockVec3 thisVec = new BlockVec3(tile);
        for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS)
        {
            TileEntity tileEntity = thisVec.getTileEntityOnSide(tile.getWorldObj(), direction);

            if (tileEntity instanceof IConnector)
            {
                if (((IConnector) tileEntity).canConnect(direction.getOpposite(), NetworkType.OXYGEN))
                {
                    adjacentConnections[direction.ordinal()] = tileEntity;
                }
            }
            else if (isMekLoaded)
            {
                if (tileEntity instanceof ITubeConnection && (!(tileEntity instanceof IGasTransmitter) || TransmissionType.checkTransmissionType(tileEntity, TransmissionType.GAS, tileEntity)))
                {
                    if (((ITubeConnection) tileEntity).canTubeConnect(direction))
                    {
                        adjacentConnections[direction.ordinal()] = tileEntity;
                    }
                }
            }
        }

        return adjacentConnections;
    }
}
TOP

Related Classes of micdoodle8.mods.galacticraft.core.util.OxygenUtil

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.