package micdoodle8.mods.galacticraft.api.world; import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldProvider; import java.lang.reflect.Method; public class OxygenHooks { private static Class<?> oxygenUtilClass; private static Method combusionTestMethod; private static Method breathableAirBlockMethod; private static Method breathableAirBlockEntityMethod; private static Method torchHasOxygenMethod; private static Method oxygenBubbleMethod; private static Method validOxygenSetupMethod; /** * Test whether fire can burn in this world's atmosphere (outside any oxygen bubble). * * @param provider The WorldProvider for this dimension * * @return False if fire burns normally * True if fire cannot burn in this world * */ public static boolean noAtmosphericCombustion(WorldProvider provider) { try { if (combusionTestMethod == null) { if (oxygenUtilClass == null) { oxygenUtilClass = Class.forName("micdoodle8.mods.galacticraft.core.util.OxygenUtil"); } combusionTestMethod = oxygenUtilClass.getDeclaredMethod("noAtmosphericCombustion", WorldProvider.class); } return (Boolean)combusionTestMethod.invoke(null, provider); } catch (Exception e) { e.printStackTrace(); } return false; } /** * Test whether a bounding box (normally a block but it could be an entity) * is inside an oxygen bubble or oxygen sealed space, on an otherwise * oxygen-free world. (Do not use this on the Overworld or other oxygen-rich * world,, it will return false negatives!!) * * NOTE: In a complex build where this block is surrounded by air-permeable blocks * on all sides (for example torches, ladders, signs, wires, chests etc etc) * then it may have to look quite far to find whether it is in oxygen or not - * it will check up to 5 blocks in each direction. This can impose a performance * load in the unlikely event there are permeable blocks in all directions. It is * therefore advisable not to call this every tick: 1 tick in 5 should be plenty. * * @param world The World * @param bb AxisAligned BB representing the block (e.g. a torch), or maybe the side of a block * @return True if the bb is in oxygen, otherwise false. */ public static boolean isAABBInBreathableAirBlock(World world, AxisAlignedBB bb) { try { if (breathableAirBlockMethod == null) { if (oxygenUtilClass == null) { oxygenUtilClass = Class.forName("micdoodle8.mods.galacticraft.core.util.OxygenUtil"); } breathableAirBlockMethod = oxygenUtilClass.getDeclaredMethod("isAABBInBreathableAirBlock", World.class, AxisAlignedBB.class); } return (Boolean)breathableAirBlockMethod.invoke(null, world, bb); } catch (Exception e) { e.printStackTrace(); } return false; } /** * Special version of the oxygen AABB check for living entities. * This is based on checking the oxygen contact of a small box centred * at the entity's eye height. The small box has sides equal to half * the width of the entity. This is a good approximation to head size and * position for most types of mobs. * * @param entity * @return True if the entity's head is in an oxygen bubble or block, false otherwise */ public static boolean isAABBInBreathableAirBlock(EntityLivingBase entity) { try { if (breathableAirBlockEntityMethod == null) { if (oxygenUtilClass == null) { oxygenUtilClass = Class.forName("micdoodle8.mods.galacticraft.core.util.OxygenUtil"); } breathableAirBlockEntityMethod = oxygenUtilClass.getDeclaredMethod("isAABBInBreathableAirBlock", EntityLivingBase.class); } return (Boolean)breathableAirBlockEntityMethod.invoke(null, entity); } catch (Exception e) { e.printStackTrace(); } return false; } /** * Simplified (better performance) version of the block oxygen check * for use with torch blocks and other oxygen-requiring blocks * which can access oxygen on any side. * * NOTE: this does not run an inOxygenBubble() check, you will need to do * that also. * * @param world * @param block The block type of this torch being checked - currently unused * @param pos The x, y, z position of the torch * @return True if there is a (sealed) oxygen block accessible, otherwise false. */ public static boolean checkTorchHasOxygen(World world, Block block, BlockPos pos) { try { if (torchHasOxygenMethod == null) { if (oxygenUtilClass == null) { oxygenUtilClass = Class.forName("micdoodle8.mods.galacticraft.core.util.OxygenUtil"); } torchHasOxygenMethod = oxygenUtilClass.getDeclaredMethod("checkTorchHasOxygen", World.class, BlockPos.class); } return (Boolean)torchHasOxygenMethod.invoke(null, world, pos); } catch (Exception e) { e.printStackTrace(); } return false; } /** * Test whether a location is inside an Oxygen Bubble from an Oxygen Distributor * * @param worldObj World * @param avgX avg X, avgY, avgZ are the average co-ordinates of the location * @param avgY (for example, the central point of a block being tested * @param avgZ or the average position of the centre of a living entity) * @return True if it is in an oxygen bubble, otherwise false */ public static boolean inOxygenBubble(World worldObj, double avgX, double avgY, double avgZ) { try { if (oxygenBubbleMethod == null) { if (oxygenUtilClass == null) { oxygenUtilClass = Class.forName("micdoodle8.mods.galacticraft.core.util.OxygenUtil"); } oxygenBubbleMethod = oxygenUtilClass.getDeclaredMethod("inOxygenBubble", World.class, double.class, double.class, double.class); } return (Boolean)oxygenBubbleMethod.invoke(null, worldObj, avgX, avgY, avgZ); } catch (Exception e) { e.printStackTrace(); } return false; } /** * Test whether a player is wearing a working set of Galacticraft * oxygen-breathing apparatus (mask, gear + tank) * * @param player * @return True if the setup is valid, otherwise false */ public static boolean hasValidOxygenSetup(EntityPlayerMP player) { try { if (validOxygenSetupMethod == null) { if (oxygenUtilClass == null) { oxygenUtilClass = Class.forName("micdoodle8.mods.galacticraft.core.util.OxygenUtil"); } validOxygenSetupMethod = oxygenUtilClass.getDeclaredMethod("hasValidOxygenSetup", EntityPlayerMP.class); } return (Boolean)validOxygenSetupMethod.invoke(null, player); } catch (Exception e) { e.printStackTrace(); } return false; } }