Overhauled Schematic Importing and Exporting #56
@@ -1,13 +1,17 @@
|
|||||||
package StevenDimDoors.mod_pocketDim.commands;
|
package StevenDimDoors.mod_pocketDim.commands;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||||
import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
||||||
import StevenDimDoors.mod_pocketDim.LinkData;
|
import StevenDimDoors.mod_pocketDim.LinkData;
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.DungeonSchematic;
|
||||||
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
|
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
|
||||||
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
|
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
|
||||||
|
import StevenDimDoors.mod_pocketDim.schematic.InvalidSchematicException;
|
||||||
|
|
||||||
public class CommandCreateDungeonRift extends DDCommandBase
|
public class CommandCreateDungeonRift extends DDCommandBase
|
||||||
{
|
{
|
||||||
@@ -81,6 +85,25 @@ public class CommandCreateDungeonRift extends DDCommandBase
|
|||||||
link = dimHelper.instance.createPocket(link, true, true);
|
link = dimHelper.instance.createPocket(link, true, true);
|
||||||
dimHelper.dimList.get(link.destDimID).dungeonGenerator = result;
|
dimHelper.dimList.get(link.destDimID).dungeonGenerator = result;
|
||||||
sender.sendChatToPlayer("Created a rift to \"" + getSchematicName(result) + "\" dungeon (Dimension ID = " + link.destDimID + ").");
|
sender.sendChatToPlayer("Created a rift to \"" + getSchematicName(result) + "\" dungeon (Dimension ID = " + link.destDimID + ").");
|
||||||
|
|
||||||
|
/*try {
|
||||||
|
DungeonSchematic dungeon;
|
||||||
|
if ((new File(result.schematicPath)).exists())
|
||||||
|
{
|
||||||
|
dungeon = DungeonSchematic.readFromFile(result.schematicPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dungeon = DungeonSchematic.readFromResource(result.schematicPath);
|
||||||
|
}
|
||||||
|
dungeon.ApplyImportFilters(DDProperties.instance());
|
||||||
|
dungeon.copyToWorld(sender.worldObj, x, y, z);
|
||||||
|
} catch (InvalidSchematicException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
112
StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java
Normal file
112
StevenDimDoors/mod_pocketDim/dungeon/DungeonSchematic.java
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.dungeon;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||||
|
import StevenDimDoors.mod_pocketDim.schematic.CompoundFilter;
|
||||||
|
import StevenDimDoors.mod_pocketDim.schematic.InvalidSchematicException;
|
||||||
|
import StevenDimDoors.mod_pocketDim.schematic.ReplacementFilter;
|
||||||
|
import StevenDimDoors.mod_pocketDim.schematic.Schematic;
|
||||||
|
|
||||||
|
public class DungeonSchematic extends Schematic {
|
||||||
|
|
||||||
|
private static final short MAX_VANILLA_BLOCK_ID = 158;
|
||||||
|
private static final short STANDARD_FABRIC_OF_REALITY_ID = 1973;
|
||||||
|
private static final short STANDARD_ETERNAL_FABRIC_ID = 220;
|
||||||
|
private static final short[] MOD_BLOCK_FILTER_EXCEPTIONS = new short[] {
|
||||||
|
STANDARD_FABRIC_OF_REALITY_ID,
|
||||||
|
STANDARD_ETERNAL_FABRIC_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
private DungeonSchematic(Schematic source)
|
||||||
|
{
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DungeonSchematic()
|
||||||
|
{
|
||||||
|
//Used to create a dummy instance for readFromResource()
|
||||||
|
super((short) 0, (short) 0, (short) 0, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DungeonSchematic readFromFile(String schematicPath) throws FileNotFoundException, InvalidSchematicException
|
||||||
|
{
|
||||||
|
return readFromFile(new File(schematicPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DungeonSchematic readFromFile(File schematicFile) throws FileNotFoundException, InvalidSchematicException
|
||||||
|
{
|
||||||
|
return readFromStream(new FileInputStream(schematicFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DungeonSchematic readFromResource(String resourcePath) throws InvalidSchematicException
|
||||||
|
{
|
||||||
|
//We need an instance of a class in the mod to retrieve a resource
|
||||||
|
DungeonSchematic empty = new DungeonSchematic();
|
||||||
|
InputStream schematicStream = empty.getClass().getResourceAsStream(resourcePath);
|
||||||
|
return readFromStream(schematicStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DungeonSchematic readFromStream(InputStream schematicStream) throws InvalidSchematicException
|
||||||
|
{
|
||||||
|
return new DungeonSchematic(Schematic.readFromStream(schematicStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyImportFilters(DDProperties properties)
|
||||||
|
{
|
||||||
|
//Filter out mod blocks except some of our own
|
||||||
|
CompoundFilter standardizer = new CompoundFilter();
|
||||||
|
standardizer.addFilter(new ModBlockFilter(MAX_VANILLA_BLOCK_ID, MOD_BLOCK_FILTER_EXCEPTIONS,
|
||||||
|
(short) properties.FabricBlockID, (byte) 0));
|
||||||
|
|
||||||
|
//Also convert standard DD block IDs to local versions
|
||||||
|
Map<Short, Short> mapping = getAssignedToStandardIDMapping(properties);
|
||||||
|
|
||||||
|
for (Entry<Short, Short> entry : mapping.entrySet())
|
||||||
|
{
|
||||||
|
if (entry.getKey() != entry.getValue())
|
||||||
|
{
|
||||||
|
standardizer.addFilter(new ReplacementFilter(entry.getValue(), entry.getKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
standardizer.apply(this, this.blocks, this.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyExportFilters(DDProperties properties)
|
||||||
|
{
|
||||||
|
//Check if some block IDs assigned by Forge differ from our standard IDs
|
||||||
|
//If so, change the IDs to standard values
|
||||||
|
CompoundFilter standardizer = new CompoundFilter();
|
||||||
|
Map<Short, Short> mapping = getAssignedToStandardIDMapping(properties);
|
||||||
|
|
||||||
|
for (Entry<Short, Short> entry : mapping.entrySet())
|
||||||
|
{
|
||||||
|
if (entry.getKey() != entry.getValue())
|
||||||
|
{
|
||||||
|
standardizer.addFilter(new ReplacementFilter(entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
standardizer.apply(this, this.blocks, this.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
|
||||||
|
{
|
||||||
|
//If we ever need this broadly or support other mods, this should be moved to a separate class
|
||||||
|
TreeMap<Short, Short> mapping = new TreeMap<Short, Short>();
|
||||||
|
mapping.put((short) properties.FabricBlockID, STANDARD_FABRIC_OF_REALITY_ID);
|
||||||
|
mapping.put((short) properties.PermaFabricBlockID, STANDARD_ETERNAL_FABRIC_ID);
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DungeonSchematic copyFromWorld(World world, int x, int y, int z, short width, short height, short length, boolean doCompactBounds)
|
||||||
|
{
|
||||||
|
return new DungeonSchematic(Schematic.copyFromWorld(world, x, y, z, width, height, length, doCompactBounds));
|
||||||
|
}
|
||||||
|
}
|
||||||
51
StevenDimDoors/mod_pocketDim/dungeon/ModBlockFilter.java
Normal file
51
StevenDimDoors/mod_pocketDim/dungeon/ModBlockFilter.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.dungeon;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import StevenDimDoors.mod_pocketDim.schematic.SchematicFilter;
|
||||||
|
|
||||||
|
public class ModBlockFilter extends SchematicFilter {
|
||||||
|
|
||||||
|
private short maxVanillaBlockID;
|
||||||
|
private short[] exceptions;
|
||||||
|
private short replacementBlockID;
|
||||||
|
private byte replacementMetadata;
|
||||||
|
|
||||||
|
public ModBlockFilter(short maxVanillaBlockID, short[] exceptions, short replacementBlockID, byte replacementMetadata)
|
||||||
|
{
|
||||||
|
super("ModBlockFilter");
|
||||||
|
this.maxVanillaBlockID = maxVanillaBlockID;
|
||||||
|
this.exceptions = exceptions;
|
||||||
|
this.replacementBlockID = replacementBlockID;
|
||||||
|
this.replacementMetadata = replacementMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean applyToBlock(int index, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
short currentID = blocks[index];
|
||||||
|
if (currentID > maxVanillaBlockID || (currentID != 0 && Block.blocksList[currentID] == null))
|
||||||
|
{
|
||||||
|
//This might be a mod block. Check if an exception exists.
|
||||||
|
for (k = 0; k < exceptions.length; k++)
|
||||||
|
{
|
||||||
|
if (currentID == exceptions[k])
|
||||||
|
{
|
||||||
|
//Exception found, not considered a mod block
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//No matching exception found. Replace the block.
|
||||||
|
blocks[index] = replacementBlockID;
|
||||||
|
metadata[index] = replacementMetadata;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean terminates()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,8 +17,8 @@ import StevenDimDoors.mod_pocketDim.DimData;
|
|||||||
import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
||||||
import StevenDimDoors.mod_pocketDim.LinkData;
|
import StevenDimDoors.mod_pocketDim.LinkData;
|
||||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.DungeonSchematic;
|
||||||
import StevenDimDoors.mod_pocketDim.items.itemDimDoor;
|
import StevenDimDoors.mod_pocketDim.items.itemDimDoor;
|
||||||
import StevenDimDoors.mod_pocketDim.schematic.Schematic;
|
|
||||||
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
||||||
|
|
||||||
public class DungeonHelper
|
public class DungeonHelper
|
||||||
@@ -383,9 +383,10 @@ public class DungeonHelper
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
short size = (short) 2 * MAX_EXPORT_RADIUS + 1;
|
short size = (short) 2 * MAX_EXPORT_RADIUS + 1;
|
||||||
Schematic schematic = Schematic.copyFromWorld(world,
|
DungeonSchematic dungeon = DungeonSchematic.copyFromWorld(world,
|
||||||
centerX - MAX_EXPORT_RADIUS, centerY - MAX_EXPORT_RADIUS, centerZ - MAX_EXPORT_RADIUS, size, size, size, true);
|
centerX - MAX_EXPORT_RADIUS, centerY - MAX_EXPORT_RADIUS, centerZ - MAX_EXPORT_RADIUS, size, size, size, true);
|
||||||
schematic.writeToFile(exportPath);
|
dungeon.ApplyExportFilters(properties);
|
||||||
|
dungeon.writeToFile(exportPath);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
|
|||||||
58
StevenDimDoors/mod_pocketDim/schematic/CompoundFilter.java
Normal file
58
StevenDimDoors/mod_pocketDim/schematic/CompoundFilter.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.schematic;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class CompoundFilter extends SchematicFilter {
|
||||||
|
|
||||||
|
private ArrayList<SchematicFilter> filters;
|
||||||
|
|
||||||
|
public CompoundFilter()
|
||||||
|
{
|
||||||
|
super("CompoundFilter");
|
||||||
|
filters = new ArrayList<SchematicFilter>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFilter(SchematicFilter filter)
|
||||||
|
{
|
||||||
|
filters.add(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean initialize(Schematic schematic, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
for (SchematicFilter filter : filters)
|
||||||
|
{
|
||||||
|
if (!filter.initialize(schematic, blocks, metadata))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !filters.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean finish()
|
||||||
|
{
|
||||||
|
for (SchematicFilter filter : filters)
|
||||||
|
{
|
||||||
|
if (!filter.finish())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean applyToBlock(int index, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
for (SchematicFilter filter : filters)
|
||||||
|
{
|
||||||
|
if (!filter.applyToBlock(index, blocks, metadata))
|
||||||
|
{
|
||||||
|
return !filter.terminates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.schematic;
|
||||||
|
|
||||||
|
public class ReplacementFilter extends SchematicFilter {
|
||||||
|
|
||||||
|
private short targetBlock;
|
||||||
|
private byte targetMetadata;
|
||||||
|
private boolean matchMetadata;
|
||||||
|
private short replacementBlock;
|
||||||
|
private byte replacementMetadata;
|
||||||
|
private boolean changeMetadata;
|
||||||
|
|
||||||
|
public ReplacementFilter(short targetBlock, byte targetMetadata, short replacementBlock, byte replacementMetadata)
|
||||||
|
{
|
||||||
|
super("ReplacementFilter");
|
||||||
|
this.targetBlock = targetBlock;
|
||||||
|
this.targetMetadata = targetMetadata;
|
||||||
|
this.matchMetadata = true;
|
||||||
|
this.replacementBlock = replacementBlock;
|
||||||
|
this.replacementMetadata = replacementMetadata;
|
||||||
|
this.changeMetadata = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplacementFilter(short targetBlock, short replacementBlock, byte replacementMetadata)
|
||||||
|
{
|
||||||
|
super("ReplacementFilter");
|
||||||
|
this.targetBlock = targetBlock;
|
||||||
|
this.matchMetadata = false;
|
||||||
|
this.replacementBlock = replacementBlock;
|
||||||
|
this.replacementMetadata = replacementMetadata;
|
||||||
|
this.changeMetadata = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplacementFilter(short targetBlock, byte targetMetadata, short replacementBlock)
|
||||||
|
{
|
||||||
|
super("ReplacementFilter");
|
||||||
|
this.targetBlock = targetBlock;
|
||||||
|
this.targetMetadata = targetMetadata;
|
||||||
|
this.matchMetadata = true;
|
||||||
|
this.replacementBlock = replacementBlock;
|
||||||
|
this.changeMetadata = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReplacementFilter(short targetBlock, short replacementBlock)
|
||||||
|
{
|
||||||
|
super("ReplacementFilter");
|
||||||
|
this.targetBlock = targetBlock;
|
||||||
|
this.matchMetadata = false;
|
||||||
|
this.replacementBlock = replacementBlock;
|
||||||
|
this.changeMetadata = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean applyToBlock(int index, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
if (blocks[index] == targetBlock)
|
||||||
|
{
|
||||||
|
if ((matchMetadata && metadata[index] == targetMetadata) || !matchMetadata)
|
||||||
|
{
|
||||||
|
blocks[index] = replacementBlock;
|
||||||
|
if (changeMetadata)
|
||||||
|
{
|
||||||
|
metadata[index] = replacementMetadata;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean terminates()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,11 +7,14 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.nbt.CompressedStreamTools;
|
import net.minecraft.nbt.CompressedStreamTools;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +29,7 @@ public class Schematic {
|
|||||||
|
|
||||||
protected short[] blocks;
|
protected short[] blocks;
|
||||||
protected byte[] metadata;
|
protected byte[] metadata;
|
||||||
protected NBTTagList tileEntities = new NBTTagList();
|
protected NBTTagList tileEntities;
|
||||||
|
|
||||||
protected Schematic(short width, short height, short length, short[] blocks, byte[] metadata, NBTTagList tileEntities)
|
protected Schematic(short width, short height, short length, short[] blocks, byte[] metadata, NBTTagList tileEntities)
|
||||||
{
|
{
|
||||||
@@ -37,8 +40,20 @@ public class Schematic {
|
|||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
this.tileEntities = tileEntities;
|
this.tileEntities = tileEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Schematic(Schematic source)
|
||||||
|
{
|
||||||
|
//Shallow copy constructor - critical for code reuse in derived classes since
|
||||||
|
//source's fields will be inaccessible if the derived class is in another package.
|
||||||
|
this.width = source.width;
|
||||||
|
this.height = source.height;
|
||||||
|
this.length = source.length;
|
||||||
|
this.blocks = source.blocks;
|
||||||
|
this.metadata = source.metadata;
|
||||||
|
this.tileEntities = source.tileEntities;
|
||||||
|
}
|
||||||
|
|
||||||
private int calculateIndex(int x, int y, int z)
|
protected int calculateIndex(int x, int y, int z)
|
||||||
{
|
{
|
||||||
if (x < 0 || x >= width)
|
if (x < 0 || x >= width)
|
||||||
throw new IndexOutOfBoundsException("x must be non-negative and less than width");
|
throw new IndexOutOfBoundsException("x must be non-negative and less than width");
|
||||||
@@ -83,7 +98,7 @@ public class Schematic {
|
|||||||
return readFromStream(schematicStream);
|
return readFromStream(schematicStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Schematic readFromStream(InputStream schematicStream) throws InvalidSchematicException
|
public static Schematic readFromStream(InputStream schematicStream) throws InvalidSchematicException
|
||||||
{
|
{
|
||||||
short width;
|
short width;
|
||||||
short height;
|
short height;
|
||||||
@@ -165,7 +180,8 @@ public class Schematic {
|
|||||||
//Get the list of tile entities
|
//Get the list of tile entities
|
||||||
tileEntities = schematicTag.getTagList("TileEntities");
|
tileEntities = schematicTag.getTagList("TileEntities");
|
||||||
|
|
||||||
return new Schematic(width, height, length, blocks, metadata, tileEntities);
|
Schematic result = new Schematic(width, height, length, blocks, metadata, tileEntities);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch (InvalidSchematicException ex)
|
catch (InvalidSchematicException ex)
|
||||||
{
|
{
|
||||||
@@ -246,7 +262,13 @@ public class Schematic {
|
|||||||
return writeToNBT(true);
|
return writeToNBT(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBTTagCompound writeToNBT(boolean copyTileEntities)
|
protected NBTTagCompound writeToNBT(boolean copyTileEntities)
|
||||||
|
{
|
||||||
|
return writeToNBT(width, height, length, blocks, metadata, tileEntities, copyTileEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static NBTTagCompound writeToNBT(short width, short height, short length, short[] blocks, byte[] metadata,
|
||||||
|
NBTTagList tileEntities, boolean copyTileEntities)
|
||||||
{
|
{
|
||||||
//This is the main storage function. Schematics are really compressed NBT tags, so if we can generate
|
//This is the main storage function. Schematics are really compressed NBT tags, so if we can generate
|
||||||
//the tags, most of the work is done. All the other storage functions will rely on this one.
|
//the tags, most of the work is done. All the other storage functions will rely on this one.
|
||||||
@@ -301,6 +323,11 @@ public class Schematic {
|
|||||||
outputStream.close();
|
outputStream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean applyFilter(SchematicFilter filter)
|
||||||
|
{
|
||||||
|
return filter.apply(this, this.blocks, this.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
public void copyToWorld(World world, int x, int y, int z)
|
public void copyToWorld(World world, int x, int y, int z)
|
||||||
{
|
{
|
||||||
//This isn't implemented as a WorldOperation because it doesn't quite fit the structure of those operations.
|
//This isn't implemented as a WorldOperation because it doesn't quite fit the structure of those operations.
|
||||||
@@ -317,8 +344,8 @@ public class Schematic {
|
|||||||
{
|
{
|
||||||
for (dx = 0; dx < width; dx++)
|
for (dx = 0; dx < width; dx++)
|
||||||
{
|
{
|
||||||
//Don't cause block updates!
|
//In the future, we might want to make this more efficient by building whole chunks at a time
|
||||||
world.setBlock(x + dx, y + dy, z + dz, blocks[index], metadata[index], 2);
|
setBlockDirectly(world, x + dx, y + dy, z + dz, blocks[index], metadata[index]);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,4 +366,38 @@ public class Schematic {
|
|||||||
world.setBlockTileEntity(dx, dy, dz, TileEntity.createAndLoadEntity(tileTag));
|
world.setBlockTileEntity(dx, dy, dz, TileEntity.createAndLoadEntity(tileTag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void setBlockDirectly(World world, int x, int y, int z, int blockID, int metadata)
|
||||||
|
{
|
||||||
|
if (blockID != 0 && Block.blocksList[blockID] == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cX = x >> 4;
|
||||||
|
int cZ = z >> 4;
|
||||||
|
int cY = y >> 4;
|
||||||
|
Chunk chunk;
|
||||||
|
|
||||||
|
int localX = (x % 16) < 0 ? (x % 16) + 16 : (x % 16);
|
||||||
|
int localZ = (z % 16) < 0 ? (z % 16) + 16 : (z % 16);
|
||||||
|
ExtendedBlockStorage extBlockStorage;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
chunk = world.getChunkFromChunkCoords(cX, cZ);
|
||||||
|
extBlockStorage = chunk.getBlockStorageArray()[cY];
|
||||||
|
if (extBlockStorage == null)
|
||||||
|
{
|
||||||
|
extBlockStorage = new ExtendedBlockStorage(cY << 4, !world.provider.hasNoSky);
|
||||||
|
chunk.getBlockStorageArray()[cY] = extBlockStorage;
|
||||||
|
}
|
||||||
|
extBlockStorage.setExtBlockID(localX, y & 15, localZ, blockID);
|
||||||
|
extBlockStorage.setExtBlockMetadata(localX, y & 15, localZ, metadata);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
StevenDimDoors/mod_pocketDim/schematic/SchematicFilter.java
Normal file
55
StevenDimDoors/mod_pocketDim/schematic/SchematicFilter.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package StevenDimDoors.mod_pocketDim.schematic;
|
||||||
|
|
||||||
|
public class SchematicFilter {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
protected SchematicFilter(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(Schematic schematic, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
if (!initialize(schematic, blocks, metadata))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int index = 0; index < blocks.length; index++)
|
||||||
|
{
|
||||||
|
if (!applyToBlock(index, blocks, metadata) && terminates())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean initialize(Schematic schematic, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean applyToBlock(int index, short[] blocks, byte[] metadata)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean finish()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean terminates()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user