implemented iterative reading of architect, for #1477

This commit is contained in:
SpaceToad 2014-03-08 16:23:08 +01:00
parent 46628683c1
commit 8948339b15
2 changed files with 122 additions and 94 deletions

View file

@ -9,7 +9,6 @@
package buildcraft.builders; package buildcraft.builders;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@ -17,16 +16,15 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftBuilders; import buildcraft.BuildCraftBuilders;
import buildcraft.api.blueprints.IBuilderContext;
import buildcraft.api.core.IAreaProvider; import buildcraft.api.core.IAreaProvider;
import buildcraft.core.BlockIndex;
import buildcraft.core.BlockScanner;
import buildcraft.core.Box; import buildcraft.core.Box;
import buildcraft.core.Box.Kind; import buildcraft.core.Box.Kind;
import buildcraft.core.IBoxProvider; import buildcraft.core.IBoxProvider;
import buildcraft.core.TileBuildCraft; import buildcraft.core.TileBuildCraft;
import buildcraft.core.blueprints.Blueprint; import buildcraft.core.blueprints.Blueprint;
import buildcraft.core.blueprints.BlueprintBase;
import buildcraft.core.blueprints.BptContext; import buildcraft.core.blueprints.BptContext;
import buildcraft.core.blueprints.Template;
import buildcraft.core.network.NetworkData; import buildcraft.core.network.NetworkData;
import buildcraft.core.network.RPC; import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler; import buildcraft.core.network.RPCHandler;
@ -35,14 +33,19 @@ import buildcraft.core.utils.Utils;
public class TileArchitect extends TileBuildCraft implements IInventory, IBoxProvider { public class TileArchitect extends TileBuildCraft implements IInventory, IBoxProvider {
// TODO: In release, this should go down to 100
private final static int SCANNER_ITERATION = 1000;
private Blueprint writingBlueprint;
private BptContext writingContext;
private BlockScanner blockScanner;
public int computingTime = 0;
public @NetworkData public @NetworkData
Box box = new Box(); Box box = new Box();
private ItemStack items[] = new ItemStack[2]; private ItemStack items[] = new ItemStack[2];
private boolean isComputing = false;
public int computingTime = 0;
public @NetworkData public @NetworkData
String name = ""; String name = "";
@ -56,11 +59,19 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
public void updateEntity() { public void updateEntity() {
super.updateEntity(); super.updateEntity();
if (!worldObj.isRemote && isComputing) { if (!worldObj.isRemote && blockScanner != null) {
if (computingTime < 200) { if (blockScanner.blocksLeft() != 0) {
computingTime++; for (BlockIndex index : blockScanner) {
writingBlueprint.readFromWorld(writingContext, this,
index.x, index.y, index.z);
}
computingTime = (int) ((1 - (float) blockScanner.blocksLeft()
/ (float) blockScanner.totalBlocks()) * 100);
} else { } else {
createBpt(); createBpt();
computingTime = 0;
} }
} }
} }
@ -83,51 +94,33 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
} }
public void createBpt() { public void createBpt() {
if (!box.isInitialized() || items[1] != null) {
return;
}
BlueprintBase result;
BptContext context = null;
if (items[0].getItem() instanceof ItemBlueprint) {
result = createBptBlueprint();
context = result.getContext(worldObj, box);
} else {
result = createBptTemplate();
context = result.getContext(worldObj, box);
}
result.id.name = name;
result.author = currentAuthorName;
result.anchorX = xCoord - box.xMin;
result.anchorY = yCoord - box.yMin;
result.anchorZ = zCoord - box.zMin;
ForgeDirection o = ForgeDirection.values()[worldObj.getBlockMetadata( ForgeDirection o = ForgeDirection.values()[worldObj.getBlockMetadata(
xCoord, yCoord, zCoord)].getOpposite(); xCoord, yCoord, zCoord)].getOpposite();
if (o == ForgeDirection.EAST) { if (o == ForgeDirection.EAST) {
// Do nothing // Do nothing
} else if (o == ForgeDirection.SOUTH) { } else if (o == ForgeDirection.SOUTH) {
result.rotateLeft(context); writingBlueprint.rotateLeft(writingContext);
result.rotateLeft(context); writingBlueprint.rotateLeft(writingContext);
result.rotateLeft(context); writingBlueprint.rotateLeft(writingContext);
} else if (o == ForgeDirection.WEST) { } else if (o == ForgeDirection.WEST) {
result.rotateLeft(context); writingBlueprint.rotateLeft(writingContext);
result.rotateLeft(context); writingBlueprint.rotateLeft(writingContext);
} else if (o == ForgeDirection.NORTH) { } else if (o == ForgeDirection.NORTH) {
result.rotateLeft(context); writingBlueprint.rotateLeft(writingContext);
} }
BuildCraftBuilders.serverDB.add(result); BuildCraftBuilders.serverDB.add(writingBlueprint);
setInventorySlotContents(1, ItemBlueprint.getBlueprintItem(result)); setInventorySlotContents(1, ItemBlueprint.getBlueprintItem(writingBlueprint));
setInventorySlotContents(0, null); setInventorySlotContents(0, null);
writingBlueprint = null;
writingContext = null;
blockScanner = null;
} }
public BlueprintBase createBptTemplate() { /*public BlueprintBase createBptTemplate() {
int mask1 = 1; int mask1 = 1;
int mask0 = 0; int mask0 = 0;
@ -151,22 +144,7 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
} }
return result; return result;
} }*/
private BlueprintBase createBptBlueprint() {
Blueprint result = new Blueprint(box.sizeX(), box.sizeY(), box.sizeZ());
IBuilderContext context = result.getContext(worldObj, box);
for (int x = box.xMin; x <= box.xMax; ++x) {
for (int y = box.yMin; y <= box.yMax; ++y) {
for (int z = box.zMin; z <= box.zMax; ++z) {
result.readFromWorld(context, this, x, y, z);
}
}
}
return result;
}
@RPC (RPCSide.SERVER) @RPC (RPCSide.SERVER)
public void handleClientInput(char c) { public void handleClientInput(char c) {
@ -253,8 +231,12 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
public void readFromNBT(NBTTagCompound nbttagcompound) { public void readFromNBT(NBTTagCompound nbttagcompound) {
super.readFromNBT(nbttagcompound); super.readFromNBT(nbttagcompound);
computingTime = nbttagcompound.getInteger("computingTime"); // For now, scan states don't get saved. Would need to save
isComputing = nbttagcompound.getBoolean("isComputing"); // blueprints too.
/*if (nbttagcompound.hasKey("scanner")) {
blockScanner = new BlockScanner();
blockScanner.readFromNBT(nbttagcompound.getCompoundTag("scanner"));
}*/
if (nbttagcompound.hasKey("box")) { if (nbttagcompound.hasKey("box")) {
box.initialize(nbttagcompound.getCompoundTag("box")); box.initialize(nbttagcompound.getCompoundTag("box"));
@ -281,8 +263,13 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
public void writeToNBT(NBTTagCompound nbttagcompound) { public void writeToNBT(NBTTagCompound nbttagcompound) {
super.writeToNBT(nbttagcompound); super.writeToNBT(nbttagcompound);
nbttagcompound.setInteger("computingTime", computingTime); // For now, scan states don't get saved. Would need to save
nbttagcompound.setBoolean("isComputing", isComputing); // blueprints too.
/*if (blockScanner != null) {
NBTTagCompound scanner = new NBTTagCompound();
blockScanner.writeToNBT(scanner);
nbttagcompound.setTag("scanner", scanner);
}*/
if (box.isInitialized()) { if (box.isInitialized()) {
NBTTagCompound boxStore = new NBTTagCompound(); NBTTagCompound boxStore = new NBTTagCompound();
@ -314,24 +301,39 @@ public class TileArchitect extends TileBuildCraft implements IInventory, IBoxPro
private void initializeComputing() { private void initializeComputing() {
if (!box.isInitialized()) { if (!box.isInitialized()) {
return; return;
} else if (!isComputing) { } else if (blockScanner == null) {
if (items[0] != null && items[0].getItem() instanceof ItemBlueprint && items[1] == null) { if (items[0] != null && items[0].getItem() instanceof ItemBlueprint && items[1] == null) {
isComputing = true; if (!box.isInitialized() || items[1] != null) {
computingTime = 0; return;
}
blockScanner = new BlockScanner(box, getWorld(), SCANNER_ITERATION);
writingBlueprint = new Blueprint(box.sizeX(), box.sizeY(), box.sizeZ());
writingContext = writingBlueprint.getContext(worldObj, box);
writingBlueprint.id.name = name;
writingBlueprint.author = currentAuthorName;
writingBlueprint.anchorX = xCoord - box.xMin;
writingBlueprint.anchorY = yCoord - box.yMin;
writingBlueprint.anchorZ = zCoord - box.zMin;
} else { } else {
isComputing = false;
computingTime = 0;
} }
} else { } else {
if (items[0] == null || !(items[0].getItem() instanceof ItemBlueprint)) { if (items[0] == null || !(items[0].getItem() instanceof ItemBlueprint)) {
isComputing = false; blockScanner = null;
computingTime = 0; writingBlueprint = null;
writingContext = null;
} }
} }
} }
public int getComputingProgressScaled(int i) { public int getComputingProgressScaled(int scale) {
return (computingTime * i) / 200; if (blockScanner == null) {
return 0;
} else {
return (int) ((float) computingTime / (float) 100 * scale);
}
} }
@Override @Override

View file

@ -10,53 +10,48 @@ package buildcraft.core;
import java.util.Iterator; import java.util.Iterator;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockScanner implements Iterable<BlockWrapper> { public class BlockScanner implements Iterable<BlockIndex> {
Box box; Box box = new Box ();
World world; World world;
int x, y, z; int x, y, z;
int iterations; int iterationsPerCycle;
int blocksDone = 0;
class BlockIt implements Iterator<BlockWrapper> { class BlockIt implements Iterator<BlockIndex> {
int it = 0; int it = 0;
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return it <= iterations; return z <= box.zMax && it <= iterationsPerCycle;
} }
@Override @Override
public BlockWrapper next() { public BlockIndex next() {
if (x <= box.xMax) { BlockIndex index = new BlockIndex(x, y, z);
it++;
blocksDone++;
if (x < box.xMax) {
x++; x++;
} else { } else {
x = box.xMin; x = box.xMin;
if (y <= box.yMax) { if (y < box.yMax) {
y++; y++;
} else { } else {
y = box.yMin; y = box.yMin;
if (z <= box.zMax) { z++;
z++;
} else {
z = box.zMin;
}
} }
} }
it++; return index;
BlockWrapper w = new BlockWrapper();
w.index = new BlockIndex(x, y, z);
w.block = world.getBlock (x, y, z);
w.tile = world.getTileEntity(x, y, z);
return w;
} }
@Override @Override
@ -65,19 +60,50 @@ public class BlockScanner implements Iterable<BlockWrapper> {
} }
} }
public BlockScanner (Box box, World world, int iterations) { public BlockScanner (Box box, World world, int iterationsPreCycle) {
this.box = box; this.box = box;
this.world = world; this.world = world;
this.iterations = iterations; this.iterationsPerCycle = iterationsPreCycle;
x = box.xMin; x = box.xMin;
y = box.yMin; y = box.yMin;
z = box.zMin; z = box.zMin;
} }
public BlockScanner () {
}
@Override @Override
public Iterator<BlockWrapper> iterator() { public Iterator<BlockIndex> iterator() {
return new BlockIt(); return new BlockIt();
} }
public int totalBlocks () {
return box.sizeX() * box.sizeY() * box.sizeZ();
}
public int blocksLeft () {
return totalBlocks() - blocksDone;
}
public void writeToNBT (NBTTagCompound nbt) {
nbt.setInteger("x", x);
nbt.setInteger("y", y);
nbt.setInteger("z", z);
nbt.setInteger("blocksDone", blocksDone);
nbt.setInteger("iterationsPerCycle", iterationsPerCycle);
NBTTagCompound boxNBT = new NBTTagCompound();
box.writeToNBT(boxNBT);
nbt.setTag("box", boxNBT);
}
public void readFromNBT (NBTTagCompound nbt) {
x = nbt.getInteger("x");
y = nbt.getInteger("y");
z = nbt.getInteger("z");
blocksDone = nbt.getInteger("blocksDone");
iterationsPerCycle = nbt.getInteger("iterationsPerCycle");
box.initialize(nbt.getCompoundTag("box"));
}
} }