use of buildcraft.core.builders.BuildingSlotBlock in project BuildCraft by BuildCraft.
the class BuildingSlotMapIterator method next.
public BuildingSlotBlock next() {
if (slots == null) {
findNextKey();
}
while (slots != null) {
slotPos++;
while (slotFound < MAX_PER_ITEM && slotPos < slots.size()) {
BuildingSlotBlock b = slots.get(slotPos);
if (b != null) {
slotFound++;
currentKey.position = slotPos + 1;
return b;
}
slotPos++;
}
if (slotFound >= MAX_PER_ITEM) {
currentKey.position = slotPos;
} else if (slotPos >= slots.size()) {
currentKey.position = 0;
}
findNextKey();
}
return null;
}
use of buildcraft.core.builders.BuildingSlotBlock in project BuildCraft by BuildCraft.
the class BuildingSlotMapIterator method remove.
public void remove() {
BuildingSlotBlock slot = slots.get(slotPos);
slots.set(slotPos, null);
builderBlueprint.onRemoveBuildingSlotBlock(slot);
}
use of buildcraft.core.builders.BuildingSlotBlock in project BuildCraft by BuildCraft.
the class BptBuilderBlueprint method addToBuildList.
private void addToBuildList(BuildingSlotBlock b) {
if (b != null) {
BuilderItemMetaPair imp = new BuilderItemMetaPair(context, b);
if (!buildList.containsKey(imp)) {
buildList.put(imp, new ArrayList<BuildingSlotBlock>());
}
buildList.get(imp).add(b);
if (buildStageOccurences == null) {
buildStageOccurences = new int[Math.max(3, b.buildStage + 1)];
} else if (buildStageOccurences.length <= b.buildStage) {
int[] newBSO = new int[b.buildStage + 1];
System.arraycopy(buildStageOccurences, 0, newBSO, 0, buildStageOccurences.length);
buildStageOccurences = newBSO;
}
buildStageOccurences[b.buildStage]++;
if (b.mode == Mode.Build) {
requirementMap.add(b, context);
b.internalRequirementRemovalListener = requirementMap;
}
}
}
use of buildcraft.core.builders.BuildingSlotBlock in project BuildCraft by BuildCraft.
the class BptBuilderBlueprint method internalInit.
@Override
protected void internalInit() {
BlockPos worldOffset = pos.subtract(blueprint.anchor);
BlockPos bptMin = BlockPos.ORIGIN;
if (worldOffset.getY() < 0)
bptMin = VecUtil.replaceValue(bptMin, Axis.Y, -worldOffset.getY());
BlockPos bptMax = blueprint.size.subtract(Utils.POS_ONE);
if (worldOffset.add(bptMax).getY() > context.world().getHeight()) {
bptMax = VecUtil.replaceValue(bptMax, Axis.Y, context.world().getHeight() - worldOffset.getY());
}
/* Check to make sure the max is bigger than the min- if its not it means that the size was 0 for one of the
* axis */
if (Utils.min(bptMin, bptMax).equals(bptMin) && Utils.max(bptMin, bptMax).equals(bptMax)) {
try {
for (BlockPos bptOffset : Utils.getAllInBox(bptMin, bptMax, getOrder())) {
BlockPos pointWorldOffset = worldOffset.add(bptOffset);
if (!isLocationUsed(pointWorldOffset)) {
SchematicBlock slot = (SchematicBlock) blueprint.get(bptOffset);
if (slot == null && !blueprint.excavate) {
continue;
}
if (slot == null) {
slot = new SchematicBlock();
slot.state = Blocks.AIR.getDefaultState();
}
if (!SchematicRegistry.INSTANCE.isAllowedForBuilding(slot.state)) {
continue;
}
BuildingSlotBlock b = new BuildingSlotBlock();
b.schematic = slot;
b.pos = pointWorldOffset;
b.mode = Mode.ClearIfInvalid;
b.buildStage = 0;
addToBuildList(b);
}
}
} catch (ArrayIndexOutOfBoundsException aioobe) {
BCLog.logger.warn("Attempted to use the positions " + bptMin + ", " + bptMax + " to access a blueprint with a size of " + blueprint.size);
throw BCLog.logger.throwing(aioobe);
}
LinkedList<BuildingSlotBlock> tmpStandalone = new LinkedList<>();
LinkedList<BuildingSlotBlock> tmpExpanding = new LinkedList<>();
for (BlockPos bptOffset : Utils.getAllInBox(bptMin, bptMax, getOrder())) {
BlockPos pointWorldOffset = worldOffset.add(bptOffset);
SchematicBlock slot = (SchematicBlock) blueprint.get(bptOffset);
if (slot == null) {
continue;
}
if (!SchematicRegistry.INSTANCE.isAllowedForBuilding(slot.state)) {
continue;
}
BuildingSlotBlock b = new BuildingSlotBlock();
b.schematic = slot;
b.pos = pointWorldOffset;
b.mode = Mode.Build;
if (!isLocationUsed(pointWorldOffset)) {
switch(slot.getBuildStage()) {
case STANDALONE:
tmpStandalone.add(b);
b.buildStage = 1;
break;
case EXPANDING:
tmpExpanding.add(b);
b.buildStage = 2;
break;
}
} else {
postProcessing.add(b);
}
}
for (BuildingSlotBlock b : tmpStandalone) {
addToBuildList(b);
}
for (BuildingSlotBlock b : tmpExpanding) {
addToBuildList(b);
}
}
int seqId = 0;
for (SchematicEntity e : ((Blueprint) blueprint).entities) {
BuildingSlotEntity b = new BuildingSlotEntity();
b.schematic = e;
b.sequenceNumber = seqId;
if (!builtEntities.contains(seqId)) {
entityList.add(b);
} else {
postProcessing.add(b);
}
seqId++;
}
recomputeNeededItems();
}
use of buildcraft.core.builders.BuildingSlotBlock in project BuildCraft by BuildCraft.
the class BptBuilderBlueprint method internalGetNextBlock.
/**
* Gets the next available block. If builder is not null, then building will be verified and performed. Otherwise,
* the next possible building slot is returned, possibly for reservation, with no building.
*/
private BuildingSlot internalGetNextBlock(World world, TileAbstractBuilder builder) {
if (!readyForSlotLookup(builder)) {
return null;
}
if (iterator == null) {
iterator = new BuildingSlotMapIterator(this, builder);
}
iterator.refresh(builder);
while (readyForSlotLookup(builder)) {
BuildingSlotBlock slot = iterator.next();
if (slot == null)
break;
if (!world.isBlockLoaded(pos))
continue;
boolean skipped = false;
for (int i = 0; i < slot.buildStage; i++) {
if (buildStageOccurences[i] > 0) {
iterator.skipKey();
skipped = true;
break;
}
}
if (skipped) {
continue;
}
if (slot.built) {
iterator.remove();
markLocationUsed(slot.pos);
postProcessing.add(slot);
continue;
}
if (slot.reserved) {
continue;
}
try {
if (slot.isAlreadyBuilt(context)) {
if (slot.mode == Mode.Build) {
requirementMap.remove(slot);
// Even slots that considered already built may need
// post processing calls. For example, flowing water
// may need to be adjusted, engines may need to be
// turned to the right direction, etc.
postProcessing.add(slot);
}
iterator.remove();
continue;
}
if (BlockUtil.isUnbreakableBlock(world, slot.pos)) {
// if the block can't be broken, just forget this iterator
iterator.remove();
markLocationUsed(slot.pos);
requirementMap.remove(slot);
} else {
if (slot.mode == Mode.ClearIfInvalid) {
if (BuildCraftAPI.isSoftBlock(world, slot.pos) || isBlockBreakCanceled(world, slot.pos)) {
iterator.remove();
markLocationUsed(slot.pos);
} else {
if (builder == null) {
createDestroyItems(slot);
return slot;
} else if (canDestroy(builder, context, slot)) {
consumeEnergyToDestroy(builder, slot);
createDestroyItems(slot);
iterator.remove();
markLocationUsed(slot.pos);
return slot;
}
}
} else if (!slot.schematic.doNotBuild()) {
if (builder == null) {
return slot;
} else if (checkRequirements(builder, slot.schematic)) {
if (!BuildCraftAPI.isSoftBlock(world, slot.pos) || requirementMap.contains(slot.pos)) {
// Can't build yet, wait (#2751)
continue;
} else if (isBlockPlaceCanceled(world, slot.pos, slot.schematic)) {
// Forge does not allow us to place a block in
// this position.
iterator.remove();
requirementMap.remove(slot);
markLocationUsed(slot.pos);
continue;
}
// At this stage, regardless of the fact that the
// block can actually be built or not, we'll try.
// When the item reaches the actual block, we'll
// verify that the location is indeed clear, and
// avoid building otherwise.
builder.consumeEnergy(slot.getEnergyRequirement());
useRequirements(builder, slot);
iterator.remove();
markLocationUsed(slot.pos);
postProcessing.add(slot);
return slot;
}
} else {
// Even slots that don't need to be build may need
// post processing, see above for the argument.
postProcessing.add(slot);
requirementMap.remove(slot);
iterator.remove();
}
}
} catch (Throwable t) {
// Defensive code against errors in implementers
t.printStackTrace();
BCLog.logger.throwing(t);
iterator.remove();
requirementMap.remove(slot);
}
}
return null;
}
Aggregations