use of net.minecraft.block.BlockAir in project Galacticraft by micdoodle8.
the class TileEntityArclamp method lightArea.
public void lightArea() {
if (this.usingBuckets.getAndSet(true) || this.usingLightList.getAndSet(true)) {
return;
}
// long time1 = System.nanoTime();
int index = 0;
Block air = Blocks.AIR;
Block breatheableAirID = GCBlocks.breatheableAir;
IBlockState brightAir = GCBlocks.brightAir.getDefaultState();
IBlockState brightBreatheableAir = GCBlocks.brightBreatheableAir.getDefaultState();
boolean dirty = false;
checkedClear();
HashSet<BlockVec3> airToRevert = new HashSet<>();
airToRevert.addAll(airToRestore);
LinkedList<BlockVec3> airNew = new LinkedList<>();
LinkedList<BlockVec3> currentLayer = new LinkedList<>();
LinkedList<BlockVec3> nextLayer = new LinkedList<>();
BlockVec3 thisvec = new BlockVec3(this);
currentLayer.add(thisvec);
World world = this.world;
int sideskip1 = this.sideRear;
int sideskip2 = this.facingSide ^ 1;
int side, bits;
for (int i = 0; i < 6; i++) {
if (i != sideskip1 && i != sideskip2 && i != (sideskip1 ^ 1) && i != (sideskip2 ^ 1)) {
BlockVec3 onEitherSide = thisvec.newVecSide(i);
IBlockState state = onEitherSide.getBlockStateSafe_noChunkLoad(world);
if (state != null && state.getBlock().getLightOpacity(state) < 15) {
currentLayer.add(onEitherSide);
}
}
}
BlockVec3 inFront = new BlockVec3(this);
for (int i = 0; i < 4; i++) {
inFront = inFront.newVecSide(this.facingSide);
IBlockState state = inFront.getBlockStateSafe_noChunkLoad(world);
if (state != null && state.getBlock().getLightOpacity(state) == 15) {
break;
}
inFront = inFront.newVecSide(sideskip1 ^ 1);
state = inFront.getBlockStateSafe_noChunkLoad(world);
if (state != null && state.getBlock().getLightOpacity(state) < 15) {
currentLayer.add(inFront);
} else {
break;
}
}
inFront = new BlockVec3(this).newVecSide(this.facingSide);
for (int count = 0; count < LIGHTRANGE; count++) {
for (BlockVec3 vec : currentLayer) {
// Shape the arc lamp lighted area to more of a cone in front of it
if (count > 1) {
int offset = 0;
switch(this.facingSide) {
case 0:
offset = inFront.y - vec.y;
break;
case 1:
offset = vec.y - inFront.y;
break;
case 2:
offset = inFront.z - vec.z;
break;
case 3:
offset = vec.z - inFront.z;
break;
case 4:
offset = inFront.x - vec.x;
break;
case 5:
offset = vec.x - inFront.x;
break;
}
int offset2 = 0;
switch(this.sideRear ^ 1) {
case 0:
offset2 = inFront.y - vec.y;
break;
case 1:
offset2 = vec.y - inFront.y;
break;
case 2:
offset2 = inFront.z - vec.z;
break;
case 3:
offset2 = vec.z - inFront.z;
break;
case 4:
offset2 = inFront.x - vec.x;
break;
case 5:
offset2 = vec.x - inFront.x;
break;
}
if (offset2 - 2 > offset)
offset = offset2 - 2;
if (Math.abs(vec.x - inFront.x) > offset + 2)
continue;
if (Math.abs(vec.y - inFront.y) > offset + 2)
continue;
if (Math.abs(vec.z - inFront.z) > offset + 2)
continue;
}
// Now process each layer outwards from the source, finding new blocks to light (similar to ThreadFindSeal)
// This is high performance code using our own custom HashSet (that's intBucket)
side = 0;
bits = vec.sideDoneBits;
boolean doShine = false;
do {
// and never go 'backwards'
if ((bits & (1 << side)) == 0) {
BlockVec3 sideVec = vec.newVecSide(side);
boolean toAdd = false;
if (!checkedContains(vec, side)) {
checkedAdd(sideVec);
toAdd = true;
}
IBlockState bs = sideVec.getBlockStateSafe_noChunkLoad(world);
if (bs == null) {
side++;
continue;
}
Block b = bs.getBlock();
if (b instanceof BlockAir) {
if (toAdd && side != sideskip1 && side != sideskip2) {
nextLayer.add(sideVec);
}
} else {
doShine = true;
// Glass blocks go through to the next layer as well
if (side != sideskip1 && side != sideskip2) {
if (toAdd && b != null && b.getLightOpacity(bs, world, sideVec.toBlockPos()) == 0) {
nextLayer.add(sideVec);
}
}
}
}
side++;
} while (side < 6);
if (doShine) {
airNew.add(vec);
Block id = vec.getBlockStateSafe_noChunkLoad(world).getBlock();
if (Blocks.AIR == id) {
this.brightenAir(world, vec, brightAir);
index = this.checkLightPartA(EnumSkyBlock.BLOCK, vec.toBlockPos(), index);
dirty = true;
} else if (id == breatheableAirID) {
this.brightenAir(world, vec, brightBreatheableAir);
index = this.checkLightPartA(EnumSkyBlock.BLOCK, vec.toBlockPos(), index);
dirty = true;
}
}
}
if (nextLayer.size() == 0) {
break;
}
currentLayer = nextLayer;
nextLayer = new LinkedList<BlockVec3>();
}
if (dirty) {
this.markDirty();
this.checkLightPartB(EnumSkyBlock.BLOCK, index);
}
// Look for any holdover bright blocks which are no longer lit (e.g. because the Arc Lamp became blocked in a tunnel)
airToRevert.removeAll(airNew);
index = 0;
dirty = false;
for (Object obj : airToRevert) {
BlockVec3 vec = (BlockVec3) obj;
this.setDarkerAir(vec);
index = this.checkLightPartA(EnumSkyBlock.BLOCK, vec.toBlockPos(), index);
this.airToRestore.remove(vec);
dirty = true;
}
if (dirty) {
this.markDirty();
this.checkLightPartB(EnumSkyBlock.BLOCK, index);
}
// long time3 = System.nanoTime();
// float total = (time3 - time1) / 1000000.0F;
// GCLog.info(" Total Time taken: " + String.format("%.2f", total) + "ms");
this.usingBuckets.set(false);
this.usingLightList.set(false);
}
use of net.minecraft.block.BlockAir in project Galacticraft by micdoodle8.
the class TileEntityOxygenCollector method update.
@Override
public void update() {
super.update();
if (!this.world.isRemote) {
producedLastTick = this.getOxygenStored() < this.getMaxOxygenStored();
this.produceOxygen();
// Approximately once every 40 ticks, search out oxygen producing blocks
if (this.world.rand.nextInt(10) == 0) {
if (this.hasEnoughEnergyToRun) {
// The later calculations are more efficient if power is a float, so
// there are fewer casts
float nearbyLeaves = 0;
if (!this.isInitialised) {
this.noAtmosphericOxygen = (this.world.provider instanceof IGalacticraftWorldProvider && !((IGalacticraftWorldProvider) this.world.provider).isGasPresent(EnumAtmosphericGas.OXYGEN));
this.isInitialised = true;
}
if (this.noAtmosphericOxygen) {
// loop
if (this.getPos().getX() > -29999995 && this.getPos().getY() < 2999995 && this.getPos().getZ() > -29999995 && this.getPos().getZ() < 29999995) {
// Test the y coordinates, so code doesn't have to keep
// testing that either
int miny = this.getPos().getY() - 5;
int maxy = this.getPos().getY() + 5;
if (miny < 0) {
miny = 0;
}
if (maxy >= this.world.getHeight()) {
maxy = this.world.getHeight() - 1;
}
// coordinates
for (int x = this.getPos().getX() - 5; x <= this.getPos().getX() + 5; x++) {
int chunkx = x >> 4;
int intrachunkx = x & 15;
// Preload the first chunk for the z loop - there
// can be a maximum of 2 chunks in the z loop
int chunkz = this.getPos().getZ() - 5 >> 4;
Chunk chunk = this.world.getChunkFromChunkCoords(chunkx, chunkz);
for (int z = this.getPos().getZ() - 5; z <= this.getPos().getZ() + 5; z++) {
if (z >> 4 != chunkz) {
// moved across z chunk boundary into a new
// chunk, so load the new chunk
chunkz = z >> 4;
chunk = this.world.getChunkFromChunkCoords(chunkx, chunkz);
}
for (int y = miny; y <= maxy; y++) {
// chunk.getBlockID is like world.getBlock
// but faster - needs to be given
// intra-chunk coordinates though
final IBlockState state = chunk.getBlockState(intrachunkx, y, z & 15);
// in the blocksList
if (!(state.getBlock() instanceof BlockAir)) {
BlockPos pos = new BlockPos(x, y, z);
if (state.getBlock().isLeaves(state, this.world, pos) || state.getBlock() instanceof IPlantable && ((IPlantable) state.getBlock()).getPlantType(this.world, pos) == EnumPlantType.Crop) {
nearbyLeaves += OXYGEN_PER_PLANT;
}
}
}
}
}
}
} else {
nearbyLeaves = 9.3F * 10F;
}
nearbyLeaves = (float) Math.floor(nearbyLeaves);
this.lastOxygenCollected = nearbyLeaves / 10F;
this.tank.setFluid(new FluidStack(GCFluids.fluidOxygenGas, (int) Math.max(Math.min(this.getOxygenStored() + nearbyLeaves, this.getMaxOxygenStored()), 0)));
} else {
this.lastOxygenCollected = 0;
}
}
}
}
Aggregations