use of micdoodle8.mods.galacticraft.api.vector.BlockVec3 in project Galacticraft by micdoodle8.
the class ThreadFindSeal method unseal.
private void unseal() {
// Local variables are fractionally faster than statics
Block breatheableAirID = GCBlocks.breatheableAir;
Block breatheableAirIDBright = GCBlocks.brightBreatheableAir;
Block oxygenSealerID = GCBlocks.oxygenSealer;
Block fireBlock = Blocks.fire;
Block airBlock = Blocks.air;
Block airBlockBright = GCBlocks.brightAir;
List<BlockVec3> toReplaceLocal = this.breatheableToReplace;
List<BlockVec3> toReplaceLocalBright = this.breatheableToReplaceBright;
LinkedList<BlockVec3> nextLayer = new LinkedList<>();
World world = this.world;
int side, bits;
while (this.currentLayer.size() > 0) {
for (BlockVec3 vec : this.currentLayer) {
side = 0;
bits = vec.sideDoneBits;
do {
if ((bits & (1 << side)) == 0) {
if (!checkedContains(vec, side)) {
BlockVec3 sideVec = vec.newVecSide(side);
Block id = sideVec.getBlockIDsafe_noChunkLoad(world);
if (id == breatheableAirID) {
toReplaceLocal.add(sideVec);
nextLayer.add(sideVec);
checkedAdd(sideVec);
} else if (id == breatheableAirIDBright) {
toReplaceLocalBright.add(sideVec);
nextLayer.add(sideVec);
checkedAdd(sideVec);
} else if (id == fireBlock) {
this.fireToReplace.add(sideVec);
nextLayer.add(sideVec);
checkedAdd(sideVec);
} else if (id == oxygenSealerID) {
TileEntityOxygenSealer sealer = this.sealersAround.get(sideVec);
if (sealer != null && !this.sealers.contains(sealer)) {
if (side == 0) {
// Accessing the vent side of the sealer, so add it
this.otherSealers.add(sealer);
checkedAdd(sideVec);
}
// if side is not 0, do not add to checked so can be rechecked from other sides
} else {
checkedAdd(sideVec);
}
} else {
if (id != null && id != airBlock && id != airBlockBright) {
// This test applies any necessary checkedAdd();
if (this.canBlockPassAirCheck(id, sideVec, side)) {
// Look outbound through partially sealable blocks in case there is breatheableAir to clear beyond
nextLayer.add(sideVec);
}
} else {
if (id != null)
checkedAdd(sideVec);
}
}
}
}
side++;
} while (side < 6);
}
// Set up the next layer as current layer for the while loop
this.currentLayer = nextLayer;
nextLayer = new LinkedList<BlockVec3>();
}
}
use of micdoodle8.mods.galacticraft.api.vector.BlockVec3 in project Galacticraft by micdoodle8.
the class ThreadFindSeal method check.
public void check() {
long time1 = System.nanoTime();
this.sealed = true;
TileEntity tile = this.head.getTileEntityOnSide(world, EnumFacing.DOWN);
this.foundAmbientThermal = tile instanceof TileEntityOxygenSealer && ((TileEntityOxygenSealer) tile).thermalControlEnabled();
this.checkedAdd(this.head);
this.currentLayer = new LinkedList<BlockVec3>();
this.airToReplace = new LinkedList<BlockVec3>();
this.airToReplaceBright = new LinkedList<BlockVec3>();
this.ambientThermalTracked = new LinkedList<BlockVec3>();
this.ambientThermalTrackedBright = new LinkedList<BlockVec3>();
if (this.checkCount > 0) {
this.currentLayer.add(this.head);
if (this.head.x < -29990000 || this.head.z < -29990000 || this.head.x >= 29990000 || this.head.z >= 29990000) {
Block b = this.head.getBlockID_noChunkLoad(this.world);
if (Blocks.air == b) {
this.airToReplace.add(this.head.clone());
} else if (b == GCBlocks.brightAir) {
this.airToReplaceBright.add(this.head.clone());
}
this.doLayerNearMapEdge();
} else {
Block headblock = this.head.getBlockIDsafe_noChunkLoad(this.world);
if (Blocks.air == headblock) {
this.airToReplace.add(this.head.clone());
} else if (headblock == GCBlocks.brightAir) {
this.airToReplaceBright.add(this.head.clone());
}
this.doLayer();
}
} else {
this.sealed = false;
}
long time2 = System.nanoTime();
// Can only be properly sealed if there is at least one sealer here (on edge check)
if (this.sealers.isEmpty()) {
this.sealed = false;
}
if (this.sealed) {
this.makeSealGood(this.foundAmbientThermal);
this.leakTrace = null;
} else {
int checkedSave = checkedSize;
checkedClear();
this.breatheableToReplace = new LinkedList<BlockVec3>();
this.breatheableToReplaceBright = new LinkedList<BlockVec3>();
this.fireToReplace = new LinkedList<BlockVec3>();
this.otherSealers = new LinkedList<TileEntityOxygenSealer>();
// unseal() will mark breatheableAir blocks for change as it
// finds them, also searches for unchecked sealers
this.currentLayer.clear();
this.currentLayer.add(this.head);
this.torchesToUpdate.clear();
if (this.head.x < -29990000 || this.head.z < -29990000 || this.head.x >= 29990000 || this.head.z >= 29990000) {
this.unsealNearMapEdge();
} else {
this.unseal();
}
if (!this.otherSealers.isEmpty()) {
// OtherSealers will have members if the space to be made
// unbreathable actually still has an unchecked sealer in it
List<TileEntityOxygenSealer> sealersSave = this.sealers;
List<BlockVec3> torchesSave = this.torchesToUpdate;
List<TileEntityOxygenSealer> sealersDone = new ArrayList<>();
sealersDone.addAll(this.sealers);
for (TileEntityOxygenSealer otherSealer : this.otherSealers) {
// sealed
if (!sealersDone.contains(otherSealer) && otherSealer.getFindSealChecks() > 0) {
BlockVec3 newhead = new BlockVec3(otherSealer).translate(0, 1, 0);
this.sealed = true;
this.checkCount = otherSealer.getFindSealChecks();
this.sealers = new LinkedList<TileEntityOxygenSealer>();
this.sealers.add(otherSealer);
if (otherSealer.thermalControlEnabled()) {
foundAmbientThermal = true;
}
checkedClear();
this.checkedAdd(newhead);
this.currentLayer.clear();
this.airToReplace.clear();
this.airToReplaceBright.clear();
this.torchesToUpdate = new LinkedList<BlockVec3>();
this.currentLayer.add(newhead.clone());
if (newhead.x < -29990000 || newhead.z < -29990000 || newhead.x >= 29990000 || newhead.z >= 29990000) {
this.doLayerNearMapEdge();
} else {
this.doLayer();
}
// should take over as head
if (this.sealed) {
if (ConfigManagerCore.enableDebug) {
GCLog.info("Oxygen Sealer replacing head at x" + this.head.x + " y" + (this.head.y - 1) + " z" + this.head.z);
}
if (!sealersSave.isEmpty()) {
TileEntityOxygenSealer oldHead = sealersSave.get(0);
if (!this.sealers.contains(oldHead)) {
this.sealers.add(oldHead);
if (oldHead.thermalControlEnabled()) {
foundAmbientThermal = true;
}
}
}
this.head = newhead.clone();
otherSealer.threadSeal = this;
otherSealer.stopSealThreadCooldown = 75 + TileEntityOxygenSealer.countEntities;
checkedSave += checkedSize;
break;
} else {
sealersDone.addAll(this.sealers);
}
checkedSave += checkedSize;
}
}
// result in a seal
if (!this.sealed) {
this.sealers = sealersSave;
this.torchesToUpdate = torchesSave;
} else {
// If the second search sealed the area, there may also be air or torches to update
this.makeSealGood(foundAmbientThermal);
}
}
checkedSize = checkedSave;
if (!this.sealed) {
if (this.head.getBlockID(this.world) == GCBlocks.breatheableAir) {
this.breatheableToReplace.add(this.head);
}
if (this.head.getBlockID(this.world) == GCBlocks.brightBreatheableAir) {
this.breatheableToReplaceBright.add(this.head);
}
this.makeSealBad();
} else {
this.leakTrace = null;
}
}
// Set any sealers found which are not the head sealer, not to run their
// own seal checks for a while
// (The player can control which is the head sealer in a space by
// enabling just that one and disabling all the others)
TileEntityOxygenSealer headSealer = this.sealersAround.get(this.head.clone().translate(0, -1, 0));
// If it is sealed, cooldown can be extended as frequent checks are not needed
if (headSealer != null) {
headSealer.stopSealThreadCooldown = 75 + TileEntityOxygenSealer.countEntities;
}
for (TileEntityOxygenSealer sealer : this.sealers) {
// inactive ones)
if (sealer != headSealer && headSealer != null) {
sealer.threadSeal = this;
sealer.stopSealThreadCooldown = headSealer.stopSealThreadCooldown + 51;
}
}
this.sealedFinal.set(this.sealed);
this.looping.set(false);
if (ConfigManagerCore.enableDebug) {
long time3 = System.nanoTime();
float total = (time3 - time1) / 1000000.0F;
float looping = (time2 - time1) / 1000000.0F;
float replacing = (time3 - time2) / 1000000.0F;
GCLog.info("Oxygen Sealer Check Completed at x" + this.head.x + " y" + this.head.y + " z" + this.head.z);
GCLog.info(" Sealed: " + this.sealed + " ~ " + this.sealers.size() + " sealers ~ " + (checkedSize - 1) + " blocks");
GCLog.info(" Total Time taken: " + String.format("%.2f", total) + "ms ~ " + String.format("%.2f", looping) + " + " + String.format("%.2f", replacing) + "");
}
}
use of micdoodle8.mods.galacticraft.api.vector.BlockVec3 in project Galacticraft by micdoodle8.
the class FluidNetwork method split.
@Override
public void split(IBufferTransmitter<FluidStack> splitPoint) {
if (splitPoint instanceof TileEntity) {
this.pipes.remove(splitPoint);
/**
* Loop through the connected blocks and attempt to see if there are
* connections between the two points elsewhere.
*/
TileEntity[] connectedBlocks = splitPoint.getAdjacentConnections();
for (TileEntity connectedBlockA : connectedBlocks) {
if (connectedBlockA instanceof INetworkConnection) {
for (final TileEntity connectedBlockB : connectedBlocks) {
if (connectedBlockA != connectedBlockB && connectedBlockB instanceof INetworkConnection) {
Pathfinder finder = new PathfinderChecker(((TileEntity) splitPoint).getWorld(), (INetworkConnection) connectedBlockB, NetworkType.FLUID, splitPoint);
finder.init(new BlockVec3(connectedBlockA));
if (finder.results.size() > 0) {
for (BlockVec3 node : finder.closedSet) {
TileEntity nodeTile = node.getTileEntity(((TileEntity) splitPoint).getWorld());
if (nodeTile instanceof INetworkProvider) {
if (nodeTile != splitPoint) {
((INetworkProvider) nodeTile).setNetwork(this);
}
}
}
} else {
/**
* The connections A and B are not connected
* anymore. Give both of them a new network.
*/
FluidNetwork newNetwork = new FluidNetwork();
for (BlockVec3 node : finder.closedSet) {
TileEntity nodeTile = node.getTileEntity(((TileEntity) splitPoint).getWorld());
if (nodeTile instanceof IBufferTransmitter) {
if (nodeTile != splitPoint) {
newNetwork.pipes.add((IBufferTransmitter<FluidStack>) nodeTile);
newNetwork.pipesAdded.add((IBufferTransmitter<FluidStack>) nodeTile);
newNetwork.onTransmitterAdded((IBufferTransmitter<FluidStack>) nodeTile);
this.pipes.remove(nodeTile);
}
}
}
newNetwork.refresh();
newNetwork.register();
}
}
}
}
}
if (this.pipes.isEmpty()) {
this.unregister();
} else {
this.updateCapacity();
}
}
}
use of micdoodle8.mods.galacticraft.api.vector.BlockVec3 in project Galacticraft by micdoodle8.
the class ThreadFindSeal method makeSealGood.
private void makeSealGood(boolean ambientThermal) {
if (!this.airToReplace.isEmpty() || !this.airToReplaceBright.isEmpty() || !ambientThermalTracked.isEmpty() || !ambientThermalTracked.isEmpty()) {
List<ScheduledBlockChange> changeList = new LinkedList<ScheduledBlockChange>();
Block breatheableAirID = GCBlocks.breatheableAir;
Block breatheableAirIDBright = GCBlocks.brightBreatheableAir;
int metadata = ambientThermal ? 1 : 0;
// TODO: Can we somehow detect only changes in state of ambientThermal since last check? tricky...
for (BlockVec3 checkedVec : this.airToReplace) {
// No block update for performance reasons; deal with unlit torches separately
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), breatheableAirID, metadata, 0));
}
for (BlockVec3 checkedVec : this.airToReplaceBright) {
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), breatheableAirIDBright, metadata, 0));
}
for (BlockVec3 checkedVec : this.ambientThermalTracked) {
if (checkedVec.getBlockMetadata(this.world) != metadata) {
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), breatheableAirID, metadata, 0));
}
}
for (BlockVec3 checkedVec : this.ambientThermalTrackedBright) {
if (checkedVec.getBlockMetadata(this.world) != metadata) {
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), breatheableAirIDBright, metadata, 0));
}
}
TickHandlerServer.scheduleNewBlockChange(GCCoreUtil.getDimensionID(this.world), changeList);
}
if (!this.torchesToUpdate.isEmpty()) {
TickHandlerServer.scheduleNewTorchUpdate(GCCoreUtil.getDimensionID(this.world), this.torchesToUpdate);
}
}
use of micdoodle8.mods.galacticraft.api.vector.BlockVec3 in project Galacticraft by micdoodle8.
the class ThreadFindSeal method makeSealBad.
private void makeSealBad() {
if (!this.breatheableToReplace.isEmpty() || !this.breatheableToReplaceBright.isEmpty()) {
List<ScheduledBlockChange> changeList = new LinkedList<ScheduledBlockChange>();
for (BlockVec3 checkedVec : this.breatheableToReplace) {
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), Blocks.air, 0, 0));
}
for (BlockVec3 checkedVec : this.fireToReplace) {
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), Blocks.air, 0, 2));
}
for (BlockVec3 checkedVec : this.breatheableToReplaceBright) {
changeList.add(new ScheduledBlockChange(checkedVec.toBlockPos(), GCBlocks.brightAir, 0, 0));
}
TickHandlerServer.scheduleNewBlockChange(GCCoreUtil.getDimensionID(this.world), changeList);
}
if (!this.torchesToUpdate.isEmpty()) {
TickHandlerServer.scheduleNewTorchUpdate(GCCoreUtil.getDimensionID(this.world), this.torchesToUpdate);
}
}
Aggregations