forked from mirrors/NBTExplorer
More major interface untangling. Introduction of generic IxContainer interfaces.
This commit is contained in:
parent
3afb2238ef
commit
25f429f0cf
12 changed files with 778 additions and 138 deletions
|
@ -49,7 +49,15 @@ namespace NBToolkit.Map
|
||||||
public int Data
|
public int Data
|
||||||
{
|
{
|
||||||
get { return _data; }
|
get { return _data; }
|
||||||
set { _data = value; }
|
set
|
||||||
|
{
|
||||||
|
if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_id] != null) {
|
||||||
|
if (!BlockInfo.BlockTable[_id].TestData(value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_data = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SkyLight
|
public int SkyLight
|
||||||
|
|
|
@ -6,11 +6,95 @@ namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
using NBT;
|
using NBT;
|
||||||
|
|
||||||
public interface IBlockTileEntity
|
public enum BlockType
|
||||||
{
|
{
|
||||||
string TileEntityName { get; }
|
AIR = 0,
|
||||||
|
STONE = 1,
|
||||||
NBTCompoundNode TileEntitySchema { get; }
|
GRASS = 2,
|
||||||
|
DIRT = 3,
|
||||||
|
COBBLESTONE = 4,
|
||||||
|
WOOD_PLANK = 5,
|
||||||
|
SAPLING = 6,
|
||||||
|
BEDROCK = 7,
|
||||||
|
WATER = 8,
|
||||||
|
STATIONARY_WATER = 9,
|
||||||
|
LAVA = 10,
|
||||||
|
STATIONARY_LAVA = 11,
|
||||||
|
SAND = 12,
|
||||||
|
GRAVEL = 13,
|
||||||
|
GOLD_ORE = 14,
|
||||||
|
IRON_ORE = 15,
|
||||||
|
COAL_ORE = 16,
|
||||||
|
WOOD = 17,
|
||||||
|
LEAVES = 18,
|
||||||
|
SPONGE = 19,
|
||||||
|
GLASS = 20,
|
||||||
|
LAPIS_ORE = 21,
|
||||||
|
LAPIS_BLOCK = 22,
|
||||||
|
DISPENSER = 23,
|
||||||
|
SANDSTONE = 24,
|
||||||
|
NOTE_BLOCK = 25,
|
||||||
|
BED = 26,
|
||||||
|
WOOL = 35,
|
||||||
|
YELLOW_FLOWER = 37,
|
||||||
|
RED_ROSE = 38,
|
||||||
|
BROWN_MUSHROOM = 39,
|
||||||
|
RED_MUSHROOM = 40,
|
||||||
|
GOLD_BLOCK = 41,
|
||||||
|
IRON_BLOCK = 42,
|
||||||
|
DOUBLE_SLAB = 43,
|
||||||
|
SLAB = 44,
|
||||||
|
BRICK_BLOCK = 45,
|
||||||
|
TNT = 46,
|
||||||
|
BOOKSHELF = 47,
|
||||||
|
MOSS_STONE = 48,
|
||||||
|
OBSIDIAN = 49,
|
||||||
|
TORCH = 50,
|
||||||
|
FIRE = 51,
|
||||||
|
MONSTER_SPAWNER = 52,
|
||||||
|
WOOD_STAIRS = 53,
|
||||||
|
CHEST = 54,
|
||||||
|
REDSTONE_WIRE = 55,
|
||||||
|
DIAMOND_ORE = 56,
|
||||||
|
DIAMOND_BLOCK = 57,
|
||||||
|
CRAFTING_TABLE = 58,
|
||||||
|
CROPS = 59,
|
||||||
|
FARMLAND = 60,
|
||||||
|
FURNACE = 61,
|
||||||
|
BURNING_FURNACE = 62,
|
||||||
|
SIGN_POST = 63,
|
||||||
|
WOOD_DOOR = 64,
|
||||||
|
LADDER = 65,
|
||||||
|
RAILS = 66,
|
||||||
|
COBBLESTONE_STAIRS = 67,
|
||||||
|
WALL_SIGN = 68,
|
||||||
|
LEVER = 69,
|
||||||
|
STONE_PLATE = 70,
|
||||||
|
IRON_DOOR = 71,
|
||||||
|
WOOD_PLATE = 72,
|
||||||
|
REDSTONE_ORE = 73,
|
||||||
|
GLOWING_REDSTONE_ORE = 74,
|
||||||
|
REDSTONE_TORCH_OFF = 75,
|
||||||
|
REDSTONE_TORCH_ON = 76,
|
||||||
|
STONE_BUTTON = 77,
|
||||||
|
SNOW = 78,
|
||||||
|
ICE = 79,
|
||||||
|
SNOW_BLOCK = 80,
|
||||||
|
CACTUS = 81,
|
||||||
|
CLAY_BLOCK = 82,
|
||||||
|
SUGAR_CANE = 83,
|
||||||
|
JUKEBOX = 84,
|
||||||
|
FENCE = 85,
|
||||||
|
PUMPKIN = 86,
|
||||||
|
NETHERRACK = 87,
|
||||||
|
SOUL_SAND = 88,
|
||||||
|
GLOWSTONE_BLOCK = 89,
|
||||||
|
PORTAL = 90,
|
||||||
|
JACK_O_LANTERN = 91,
|
||||||
|
CAKE_BLOCK = 92,
|
||||||
|
REDSTONE_REPEATER_ON = 93,
|
||||||
|
REDSTONE_REPEATER_OFF = 94,
|
||||||
|
LOCKED_CHEST = 95,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BlockInfo
|
public class BlockInfo
|
||||||
|
@ -43,11 +127,48 @@ namespace NBToolkit.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DataLimits
|
||||||
|
{
|
||||||
|
private int _low;
|
||||||
|
private int _high;
|
||||||
|
private int _bitmask;
|
||||||
|
|
||||||
|
public int Low
|
||||||
|
{
|
||||||
|
get { return _low; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int High
|
||||||
|
{
|
||||||
|
get { return _high; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Bitmask
|
||||||
|
{
|
||||||
|
get { return _bitmask; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataLimits (int low, int high, int bitmask)
|
||||||
|
{
|
||||||
|
_low = low;
|
||||||
|
_high = high;
|
||||||
|
_bitmask = bitmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Test (int data)
|
||||||
|
{
|
||||||
|
int rdata = data & ~_bitmask;
|
||||||
|
return rdata >= _low && rdata <= _high;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int _id = 0;
|
private int _id = 0;
|
||||||
private string _name = "";
|
private string _name = "";
|
||||||
private int _opacity = MAX_OPACITY;
|
private int _opacity = MAX_OPACITY;
|
||||||
private int _luminance = MIN_LUMINANCE;
|
private int _luminance = MIN_LUMINANCE;
|
||||||
|
|
||||||
|
private DataLimits _dataLimits;
|
||||||
|
|
||||||
public static ItemCache<BlockInfo> BlockTable;
|
public static ItemCache<BlockInfo> BlockTable;
|
||||||
|
|
||||||
public static ItemCache<int> OpacityTable;
|
public static ItemCache<int> OpacityTable;
|
||||||
|
@ -103,16 +224,19 @@ namespace NBToolkit.Map
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static NBTCompoundNode tileEntitySchema = new NBTCompoundNode("")
|
public BlockInfo SetDataLimits (int low, int high, int bitmask)
|
||||||
{
|
{
|
||||||
new NBTScalerNode("id", NBT_Type.TAG_STRING),
|
_dataLimits = new DataLimits(low, high, bitmask);
|
||||||
new NBTScalerNode("x", NBT_Type.TAG_INT),
|
return this;
|
||||||
new NBTScalerNode("y", NBT_Type.TAG_INT),
|
}
|
||||||
new NBTScalerNode("z", NBT_Type.TAG_INT),
|
|
||||||
};
|
|
||||||
|
|
||||||
public const int AIR = 0;
|
public bool TestData (int data)
|
||||||
public const int FURNACE = 61;
|
{
|
||||||
|
if (_dataLimits == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return _dataLimits.Test(data);
|
||||||
|
}
|
||||||
|
|
||||||
public static BlockInfo Air;
|
public static BlockInfo Air;
|
||||||
public static BlockInfo Stone;
|
public static BlockInfo Stone;
|
||||||
|
@ -276,7 +400,7 @@ namespace NBToolkit.Map
|
||||||
Lever = new BlockInfo(69, "Lever").SetOpacity(0);
|
Lever = new BlockInfo(69, "Lever").SetOpacity(0);
|
||||||
StonePlate = new BlockInfo(70, "Stone Pressure Plate").SetOpacity(0);
|
StonePlate = new BlockInfo(70, "Stone Pressure Plate").SetOpacity(0);
|
||||||
IronDoor = new BlockInfo(71, "Iron Door").SetOpacity(0);
|
IronDoor = new BlockInfo(71, "Iron Door").SetOpacity(0);
|
||||||
WoodPlank = new BlockInfo(72, "Wooden Pressure Plate").SetOpacity(0);
|
WoodPlate = new BlockInfo(72, "Wooden Pressure Plate").SetOpacity(0);
|
||||||
RedstoneOre = new BlockInfo(73, "Redstone Ore");
|
RedstoneOre = new BlockInfo(73, "Redstone Ore");
|
||||||
GlowRedstoneOre = new BlockInfo(74, "Glowing Redstone Ore").SetLuminance(9);
|
GlowRedstoneOre = new BlockInfo(74, "Glowing Redstone Ore").SetLuminance(9);
|
||||||
RedstoneTorch = new BlockInfo(75, "Redstone Torch (Off)").SetOpacity(0);
|
RedstoneTorch = new BlockInfo(75, "Redstone Torch (Off)").SetOpacity(0);
|
||||||
|
@ -306,6 +430,8 @@ namespace NBToolkit.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set Tile Entity Data
|
||||||
|
|
||||||
Dispenser.SetTileEntity("Trap", TileEntity.TrapSchema);
|
Dispenser.SetTileEntity("Trap", TileEntity.TrapSchema);
|
||||||
NoteBlock.SetTileEntity("Music", TileEntity.MusicSchema);
|
NoteBlock.SetTileEntity("Music", TileEntity.MusicSchema);
|
||||||
MonsterSpawner.SetTileEntity("MonsterSpawner", TileEntity.MonsterSpawnerSchema);
|
MonsterSpawner.SetTileEntity("MonsterSpawner", TileEntity.MonsterSpawnerSchema);
|
||||||
|
@ -314,6 +440,45 @@ namespace NBToolkit.Map
|
||||||
BurningFurnace.SetTileEntity("Furnace", TileEntity.FurnaceSchema);
|
BurningFurnace.SetTileEntity("Furnace", TileEntity.FurnaceSchema);
|
||||||
SignPost.SetTileEntity("Sign", TileEntity.SignSchema);
|
SignPost.SetTileEntity("Sign", TileEntity.SignSchema);
|
||||||
WallSign.SetTileEntity("Sign", TileEntity.SignSchema);
|
WallSign.SetTileEntity("Sign", TileEntity.SignSchema);
|
||||||
|
|
||||||
|
// Set Data Limits
|
||||||
|
|
||||||
|
Wood.SetDataLimits(0, 2, 0);
|
||||||
|
Leaves.SetDataLimits(0, 2, 0);
|
||||||
|
Jukebox.SetDataLimits(0, 2, 0);
|
||||||
|
Sapling.SetDataLimits(0, 15, 0);
|
||||||
|
Cactus.SetDataLimits(0, 15, 0);
|
||||||
|
SugarCane.SetDataLimits(0, 15, 0);
|
||||||
|
Water.SetDataLimits(0, 7, 0x8);
|
||||||
|
Lava.SetDataLimits(0, 7, 0x8);
|
||||||
|
Crops.SetDataLimits(0, 7, 0);
|
||||||
|
Wool.SetDataLimits(0, 15, 0);
|
||||||
|
Torch.SetDataLimits(1, 5, 0);
|
||||||
|
RedstoneTorch.SetDataLimits(0, 5, 0);
|
||||||
|
RedstoneTorchOn.SetDataLimits(0, 5, 0);
|
||||||
|
Rails.SetDataLimits(0, 9, 0);
|
||||||
|
Ladder.SetDataLimits(2, 5, 0);
|
||||||
|
WoodStairs.SetDataLimits(0, 3, 0);
|
||||||
|
CobbleStairs.SetDataLimits(0, 3, 0);
|
||||||
|
Lever.SetDataLimits(0, 6, 0x8);
|
||||||
|
WoodDoor.SetDataLimits(0, 3, 0xC);
|
||||||
|
IronDoor.SetDataLimits(0, 3, 0xC);
|
||||||
|
StoneButton.SetDataLimits(1, 4, 0x8);
|
||||||
|
SignPost.SetDataLimits(0, 15, 0);
|
||||||
|
WallSign.SetDataLimits(2, 5, 0);
|
||||||
|
Furnace.SetDataLimits(2, 5, 0);
|
||||||
|
BurningFurnace.SetDataLimits(2, 5, 0);
|
||||||
|
Dispenser.SetDataLimits(2, 5, 0);
|
||||||
|
Pumpkin.SetDataLimits(0, 3, 0);
|
||||||
|
JackOLantern.SetDataLimits(0, 3, 0);
|
||||||
|
StonePlate.SetDataLimits(0, 0, 0x1);
|
||||||
|
WoodPlate.SetDataLimits(0, 0, 0x1);
|
||||||
|
Slab.SetDataLimits(0, 3, 0);
|
||||||
|
DoubleSlab.SetDataLimits(0, 3, 0);
|
||||||
|
Cactus.SetDataLimits(0, 5, 0);
|
||||||
|
Bed.SetDataLimits(0, 3, 0x8);
|
||||||
|
RedstoneRepeater.SetDataLimits(0, 0, 0xF);
|
||||||
|
RedstoneRepeaterOn.SetDataLimits(0, 0, 0xF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,16 @@ using System.Text;
|
||||||
|
|
||||||
namespace NBToolkit.Map
|
namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
public class BlockManager
|
/*public interface IBlockManager : IBlockContainer
|
||||||
|
{
|
||||||
|
Block GetBlock (int x, int y, int z);
|
||||||
|
BlockRef GetBlockRef (int x, int y, int z);
|
||||||
|
BlockInfo GetBlockInfo (int x, int y, int z);
|
||||||
|
|
||||||
|
bool SetBlock (int x, int y, int z, Block block);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public class BlockManager : IBlockContainer
|
||||||
{
|
{
|
||||||
public const int MIN_X = -32000000;
|
public const int MIN_X = -32000000;
|
||||||
public const int MAX_X = 32000000;
|
public const int MAX_X = 32000000;
|
||||||
|
@ -25,6 +34,8 @@ namespace NBToolkit.Map
|
||||||
public const int CHUNK_YMASK = 0x7F;
|
public const int CHUNK_YMASK = 0x7F;
|
||||||
public const int CHUNK_ZMASK = 0xF;
|
public const int CHUNK_ZMASK = 0xF;
|
||||||
|
|
||||||
|
public static bool EnforceDataLimits = true;
|
||||||
|
|
||||||
protected ChunkManager _chunkMan;
|
protected ChunkManager _chunkMan;
|
||||||
|
|
||||||
protected ChunkRef _cache;
|
protected ChunkRef _cache;
|
||||||
|
@ -39,6 +50,36 @@ namespace NBToolkit.Map
|
||||||
_chunkMan = bm._chunkMan;
|
_chunkMan = bm._chunkMan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GlobalX (int x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GlobalY (int y)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GlobalZ (int z)
|
||||||
|
{
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalX (int x)
|
||||||
|
{
|
||||||
|
return x & CHUNK_XMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalY (int y)
|
||||||
|
{
|
||||||
|
return y & CHUNK_YMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalZ (int z)
|
||||||
|
{
|
||||||
|
return z & CHUNK_ZMASK;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual Block GetBlock (int x, int y, int z)
|
public virtual Block GetBlock (int x, int y, int z)
|
||||||
{
|
{
|
||||||
_cache = GetChunk(x, y, z);
|
_cache = GetChunk(x, y, z);
|
||||||
|
@ -56,52 +97,67 @@ namespace NBToolkit.Map
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BlockRef(_cache, x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
return new BlockRef(_cache, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool GetBlockID (int x, int y, int z, out int id)
|
public virtual BlockInfo GetBlockInfo (int x, int y, int z)
|
||||||
{
|
{
|
||||||
_cache = GetChunk(x, y, z);
|
_cache = GetChunk(x, y, z);
|
||||||
if (_cache == null || !Check(x, y, z)) {
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
id = 0;
|
return null;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
id = _cache.GetBlockID(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
return _cache.GetBlockInfo(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool GetBlockData (int x, int y, int z, out int data) {
|
public virtual int GetBlockID (int x, int y, int z)
|
||||||
|
{
|
||||||
_cache = GetChunk(x, y, z);
|
_cache = GetChunk(x, y, z);
|
||||||
if (_cache == null || !Check(x, y, z)) {
|
if (_cache == null) {
|
||||||
data = 0;
|
return 0;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = _cache.GetBlockData(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
return _cache.GetBlockID(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool GetBlockLight (int x, int y, int z, out int light) {
|
public virtual int GetBlockData (int x, int y, int z)
|
||||||
|
{
|
||||||
_cache = GetChunk(x, y, z);
|
_cache = GetChunk(x, y, z);
|
||||||
if (_cache == null || !Check(x, y, z)) {
|
if (_cache == null) {
|
||||||
light = 0;
|
return 0;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
light = _cache.GetBlockLight(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
return _cache.GetBlockData(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool GetBlockSkyLight (int x, int y, int z, out int light) {
|
public virtual int GetBlockLight (int x, int y, int z)
|
||||||
|
{
|
||||||
_cache = GetChunk(x, y, z);
|
_cache = GetChunk(x, y, z);
|
||||||
if (_cache == null || !Check(x, y, z)) {
|
if (_cache == null) {
|
||||||
light = 0;
|
return 0;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
light = _cache.GetBlockSkyLight(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
return _cache.GetBlockLight(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
public virtual int GetBlockSkyLight (int x, int y, int z)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.GetBlockSkyLight(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SetBlock (int x, int y, int z, Block block)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cache.SetBlock(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool SetBlockID (int x, int y, int z, int id)
|
public virtual bool SetBlockID (int x, int y, int z, int id)
|
||||||
|
@ -124,11 +180,61 @@ namespace NBToolkit.Map
|
||||||
return _cache.SetBlockData(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, data);
|
return _cache.SetBlockData(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkRef GetChunk (int x, int y, int z)
|
public bool SetBlockLight (int x, int y, int z, int light)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.SetBlockID(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, light);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetBlockSkyLight (int x, int y, int z, int light)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.SetBlockSkyLight(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, light);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual TileEntity GetTileEntity (int x, int y, int z)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.GetTileEntity(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool SetTileEntity (int x, int y, int z, TileEntity te)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.SetTileEntity(x & CHUNK_XMASK, y, z & CHUNK_ZMASK, te);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool ClearTileEntity (int x, int y, int z)
|
||||||
|
{
|
||||||
|
_cache = GetChunk(x, y, z);
|
||||||
|
if (_cache == null || !Check(x, y, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache.ClearTileEntity(x & CHUNK_XMASK, y, z & CHUNK_ZMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ChunkRef GetChunk (int x, int y, int z)
|
||||||
{
|
{
|
||||||
x >>= CHUNK_XLOG;
|
x >>= CHUNK_XLOG;
|
||||||
z >>= CHUNK_ZLOG;
|
z >>= CHUNK_ZLOG;
|
||||||
return _chunkMan.GetChunk(x, z);
|
return _chunkMan.GetChunkRef(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -5,6 +5,107 @@ using System.Text;
|
||||||
namespace NBToolkit.Map
|
namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
public class BlockRef : IBlock
|
public class BlockRef : IBlock
|
||||||
|
{
|
||||||
|
protected IBlockContainer _container;
|
||||||
|
|
||||||
|
protected int _x;
|
||||||
|
protected int _y;
|
||||||
|
protected int _z;
|
||||||
|
|
||||||
|
public int X
|
||||||
|
{
|
||||||
|
get { return _container.GlobalX(_x); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Y
|
||||||
|
{
|
||||||
|
get { return _container.GlobalY(_y); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Z
|
||||||
|
{
|
||||||
|
get { return _container.GlobalZ(_z); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalX
|
||||||
|
{
|
||||||
|
get { return _container.LocalX(_x); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalY
|
||||||
|
{
|
||||||
|
get { return _container.LocalZ(_z); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalZ
|
||||||
|
{
|
||||||
|
get { return _z; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockInfo Info
|
||||||
|
{
|
||||||
|
get { return BlockInfo.BlockTable[_container.GetBlockID(_x, _y, _z)]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ID
|
||||||
|
{
|
||||||
|
get { return _container.GetBlockID(_x, _y, _z); }
|
||||||
|
set { _container.SetBlockID(_x, _y, _z, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Data
|
||||||
|
{
|
||||||
|
get { return _container.GetBlockData(_x, _y, _z); }
|
||||||
|
set { _container.SetBlockData(_x, _y, _z, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int BlockLight
|
||||||
|
{
|
||||||
|
get { return _container.GetBlockLight(_x, _y, _z); }
|
||||||
|
set { _container.SetBlockLight(_x, _y, _z, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SkyLight
|
||||||
|
{
|
||||||
|
get { return _container.GetBlockSkyLight(_x, _y, _z); }
|
||||||
|
set { _container.SetBlockSkyLight(_x, _y, _z, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockRef (IBlockContainer container, int x, int y, int z)
|
||||||
|
{
|
||||||
|
_container = container;
|
||||||
|
_x = x;
|
||||||
|
_y = y;
|
||||||
|
_z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyFrom (IBlock block)
|
||||||
|
{
|
||||||
|
ID = block.ID;
|
||||||
|
Data = block.Data;
|
||||||
|
BlockLight = block.BlockLight;
|
||||||
|
SkyLight = block.SkyLight;
|
||||||
|
|
||||||
|
SetTileEntity(block.GetTileEntity().Copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileEntity GetTileEntity ()
|
||||||
|
{
|
||||||
|
return _container.GetTileEntity(_x, _y, _z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetTileEntity (TileEntity te)
|
||||||
|
{
|
||||||
|
return _container.SetTileEntity(_x, _y, _z, te);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ClearTileEntity ()
|
||||||
|
{
|
||||||
|
return _container.ClearTileEntity(_x, _y, _z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public class BlockRef : IBlock
|
||||||
{
|
{
|
||||||
protected IChunk _chunk;
|
protected IChunk _chunk;
|
||||||
|
|
||||||
|
@ -101,5 +202,5 @@ namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
return _chunk.ClearTileEntity(_lx, _ly, _lz);
|
return _chunk.ClearTileEntity(_lx, _ly, _lz);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,41 @@ using System.IO;
|
||||||
namespace NBToolkit.Map
|
namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
using NBT;
|
using NBT;
|
||||||
|
using Utility;
|
||||||
|
|
||||||
public interface IChunk
|
public interface IBlockContainer
|
||||||
|
{
|
||||||
|
int GlobalX (int x);
|
||||||
|
int GlobalY (int y);
|
||||||
|
int GlobalZ (int z);
|
||||||
|
|
||||||
|
int LocalX (int x);
|
||||||
|
int LocalY (int y);
|
||||||
|
int LocalZ (int z);
|
||||||
|
|
||||||
|
Block GetBlock (int lx, int ly, int lz);
|
||||||
|
BlockRef GetBlockRef (int lx, int ly, int lz);
|
||||||
|
|
||||||
|
BlockInfo GetBlockInfo (int lx, int ly, int lz);
|
||||||
|
|
||||||
|
int GetBlockID (int lx, int ly, int lz);
|
||||||
|
int GetBlockData (int lx, int ly, int lz);
|
||||||
|
int GetBlockLight (int lx, int ly, int lz);
|
||||||
|
int GetBlockSkyLight (int lx, int ly, int lz);
|
||||||
|
|
||||||
|
void SetBlock (int lx, int ly, int lz, Block block);
|
||||||
|
|
||||||
|
bool SetBlockID (int lx, int ly, int lz, int id);
|
||||||
|
bool SetBlockData (int lx, int ly, int lz, int data);
|
||||||
|
bool SetBlockLight (int lx, int ly, int lz, int light);
|
||||||
|
bool SetBlockSkyLight (int lx, int ly, int lz, int light);
|
||||||
|
|
||||||
|
TileEntity GetTileEntity (int lx, int ly, int lz);
|
||||||
|
bool SetTileEntity (int lx, int ly, int lz, TileEntity te);
|
||||||
|
bool ClearTileEntity (int lx, int ly, int lz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IChunk : IBlockContainer
|
||||||
{
|
{
|
||||||
int X { get; }
|
int X { get; }
|
||||||
int Z { get; }
|
int Z { get; }
|
||||||
|
@ -14,31 +47,13 @@ namespace NBToolkit.Map
|
||||||
|
|
||||||
bool Save (Stream outStream);
|
bool Save (Stream outStream);
|
||||||
|
|
||||||
Block GetBlock (int lx, int ly, int lz);
|
|
||||||
BlockRef GetBlockRef (int lx, int ly, int lz);
|
|
||||||
BlockInfo GetBlockInfo (int lx, int ly, int lz);
|
|
||||||
|
|
||||||
int GetBlockID (int lx, int ly, int lz);
|
|
||||||
int GetBlockData (int lx, int ly, int lz);
|
|
||||||
int GetBlockLight (int lx, int ly, int lz);
|
|
||||||
int GetBlockSkyLight (int lx, int ly, int lz);
|
|
||||||
|
|
||||||
bool SetBlockID (int lx, int ly, int lz, int id);
|
|
||||||
bool SetBlockData (int lx, int ly, int lz, int data);
|
|
||||||
bool SetBlockLight (int lx, int ly, int lz, int light);
|
|
||||||
bool SetBlockSkyLight (int lx, int ly, int lz, int light);
|
|
||||||
|
|
||||||
int CountBlockID (int id);
|
int CountBlockID (int id);
|
||||||
int CountBlockData (int id, int data);
|
int CountBlockData (int id, int data);
|
||||||
|
|
||||||
int GetHeight (int lx, int lz);
|
int GetHeight (int lx, int lz);
|
||||||
|
|
||||||
TileEntity GetTileEntity (int lx, int ly, int lz);
|
|
||||||
bool SetTileEntity (int lx, int ly, int lz, TileEntity te);
|
|
||||||
bool ClearTileEntity (int lx, int ly, int lz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Chunk : IChunk
|
public class Chunk : IChunk, ICopyable<Chunk>
|
||||||
{
|
{
|
||||||
private NBT_Tree _tree;
|
private NBT_Tree _tree;
|
||||||
|
|
||||||
|
@ -134,6 +149,36 @@ namespace NBToolkit.Map
|
||||||
_tree.Root.Add("Level", level);
|
_tree.Root.Add("Level", level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GlobalX (int x)
|
||||||
|
{
|
||||||
|
return _cx * BlockManager.CHUNK_XLEN + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GlobalY (int y)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GlobalZ (int z)
|
||||||
|
{
|
||||||
|
return _cz * BlockManager.CHUNK_ZLEN + z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalX (int x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalY (int y)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalZ (int z)
|
||||||
|
{
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Save (Stream outStream)
|
public bool Save (Stream outStream)
|
||||||
{
|
{
|
||||||
if (outStream == null || !outStream.CanWrite) {
|
if (outStream == null || !outStream.CanWrite) {
|
||||||
|
@ -161,6 +206,19 @@ namespace NBToolkit.Map
|
||||||
return BlockInfo.BlockTable[GetBlockID(lx, ly, lz)];
|
return BlockInfo.BlockTable[GetBlockID(lx, ly, lz)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBlock (int lx, int ly, int lz, Block block)
|
||||||
|
{
|
||||||
|
int index = lx << 11 | lz << 7 | ly;
|
||||||
|
|
||||||
|
SetBlockID(lx, ly, lz, block.ID);
|
||||||
|
SetBlockData(lx, ly, lz, block.Data);
|
||||||
|
|
||||||
|
_blockLight[index] = block.BlockLight;
|
||||||
|
_skyLight[index] = block.SkyLight;
|
||||||
|
|
||||||
|
SetTileEntity(lx, ly, lz, block.GetTileEntity().Copy());
|
||||||
|
}
|
||||||
|
|
||||||
public int GetBlockID (int lx, int ly, int lz)
|
public int GetBlockID (int lx, int ly, int lz)
|
||||||
{
|
{
|
||||||
return _blocks.Data[lx << 11 | lz << 7 | ly];
|
return _blocks.Data[lx << 11 | lz << 7 | ly];
|
||||||
|
@ -197,17 +255,19 @@ namespace NBToolkit.Map
|
||||||
|
|
||||||
// Update height map
|
// Update height map
|
||||||
|
|
||||||
int tileHeight = GetHeight(lx, lz);
|
if (BlockInfo.BlockTable[id] != null) {
|
||||||
int newOpacity = BlockInfo.BlockTable[id].Opacity;
|
int tileHeight = GetHeight(lx, lz);
|
||||||
|
int newOpacity = BlockInfo.BlockTable[id].Opacity;
|
||||||
|
|
||||||
if (ly > tileHeight && newOpacity > BlockInfo.MIN_OPACITY) {
|
if (ly > tileHeight && newOpacity > BlockInfo.MIN_OPACITY) {
|
||||||
_heightMap[lz << 4 | lx] = (byte)ly;
|
_heightMap[lz << 4 | lx] = (byte)ly;
|
||||||
}
|
}
|
||||||
else if (ly == tileHeight && newOpacity == BlockInfo.MIN_OPACITY) {
|
else if (ly == tileHeight && newOpacity == BlockInfo.MIN_OPACITY) {
|
||||||
for (int i = ly - 1; i >= 0; i--) {
|
for (int i = ly - 1; i >= 0; i--) {
|
||||||
if (BlockInfo.BlockTable[GetBlockID(lx, i, lz)].Opacity > BlockInfo.MIN_OPACITY) {
|
if (BlockInfo.BlockTable[GetBlockID(lx, i, lz)].Opacity > BlockInfo.MIN_OPACITY) {
|
||||||
_heightMap[lz << 4 | lx] = (byte)i;
|
_heightMap[lz << 4 | lx] = (byte)i;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +285,12 @@ namespace NBToolkit.Map
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BlockManager.EnforceDataLimits && BlockInfo.BlockTable[_blocks[index]] != null) {
|
||||||
|
if (!BlockInfo.BlockTable[_blocks[index]].TestData(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_data[index] = data;
|
_data[index] = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -360,5 +426,14 @@ namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
return _cz * BlockManager.CHUNK_ZLEN + lz;
|
return _cz * BlockManager.CHUNK_ZLEN + lz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region ICopyable<Chunk> Members
|
||||||
|
|
||||||
|
public Chunk Copy ()
|
||||||
|
{
|
||||||
|
return new Chunk(_tree.Copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace NBToolkit.Map
|
||||||
_region = _enum.Current;
|
_region = _enum.Current;
|
||||||
}
|
}
|
||||||
if (MoveNextInRegion()) {
|
if (MoveNextInRegion()) {
|
||||||
_chunk = _cm.GetChunkInRegion(_region, _x, _z);
|
_chunk = _cm.GetChunkRefInRegion(_region, _x, _z);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,26 @@ using System.Text;
|
||||||
|
|
||||||
namespace NBToolkit.Map
|
namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
|
public interface IChunkManager
|
||||||
|
{
|
||||||
|
Chunk GetChunk (int cx, int cz);
|
||||||
|
ChunkRef GetChunkRef (int cx, int cz);
|
||||||
|
|
||||||
|
bool ChunkExists (int cx, int cz);
|
||||||
|
|
||||||
|
bool MarkChunkDirty (int cx, int cz);
|
||||||
|
bool MarkChunkClean (int cx, int cz);
|
||||||
|
|
||||||
|
int Save ();
|
||||||
|
bool Save (Chunk chunk);
|
||||||
|
|
||||||
|
ChunkRef CreateChunk (int cx, int cz);
|
||||||
|
bool DeleteChunk (int cx, int cz);
|
||||||
|
|
||||||
|
bool CopyChunk (int cx1, int cz1, int cx2, int cz2);
|
||||||
|
bool MoveChunk (int cx1, int cz1, int cx2, int cz2);
|
||||||
|
}
|
||||||
|
|
||||||
public class ChunkManager
|
public class ChunkManager
|
||||||
{
|
{
|
||||||
public const int REGION_XLEN = 32;
|
public const int REGION_XLEN = 32;
|
||||||
|
@ -27,7 +47,20 @@ namespace NBToolkit.Map
|
||||||
_dirty = new Dictionary<ChunkKey, ChunkRef>();
|
_dirty = new Dictionary<ChunkKey, ChunkRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkRef GetChunk (int cx, int cz)
|
public Chunk GetChunk (int cx, int cz)
|
||||||
|
{
|
||||||
|
int lcx = cx & REGION_XMASK;
|
||||||
|
int lcz = cz & REGION_ZMASK;
|
||||||
|
|
||||||
|
Region r = GetRegion(cx, cz);
|
||||||
|
if (r == null || !r.ChunkExists(lcx, lcz)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Chunk(r.GetChunkTree(lcx, lcz));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkRef GetChunkRef (int cx, int cz)
|
||||||
{
|
{
|
||||||
ChunkKey k = new ChunkKey(cx, cz);
|
ChunkKey k = new ChunkKey(cx, cz);
|
||||||
|
|
||||||
|
@ -55,45 +88,49 @@ namespace NBToolkit.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkRef GetChunkInRegion (Region r, int lcx, int lcz)
|
public bool ChunkExists (int cx, int cz)
|
||||||
{
|
{
|
||||||
int cx = r.X * REGION_XLEN + lcx;
|
Region r = GetRegion(cx, cz);
|
||||||
int cz = r.Z * REGION_ZLEN + lcz;
|
if (r == null) {
|
||||||
return GetChunk(cx, cz);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Region GetRegion (int cx, int cz)
|
return r.ChunkExists(cx & REGION_XMASK, cz & REGION_ZMASK);
|
||||||
{
|
|
||||||
cx >>= REGION_XLOG;
|
|
||||||
cz >>= REGION_ZLOG;
|
|
||||||
return _regionMan.GetRegion(cx, cz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MarkChunkDirty (int cx, int cz)
|
public bool MarkChunkDirty (int cx, int cz)
|
||||||
{
|
{
|
||||||
ChunkKey k = new ChunkKey(cx, cz);
|
ChunkKey k = new ChunkKey(cx, cz);
|
||||||
if (!_dirty.ContainsKey(k)) {
|
if (!_dirty.ContainsKey(k)) {
|
||||||
_dirty.Add(k, GetChunk(cx, cz));
|
_dirty.Add(k, GetChunkRef(cx, cz));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MarkChunkDirty (ChunkRef chunk)
|
public bool MarkChunkClean (int cx, int cz)
|
||||||
{
|
{
|
||||||
ChunkKey k = new ChunkKey(chunk.X, chunk.Z);
|
ChunkKey k = new ChunkKey(cx, cz);
|
||||||
if (!_dirty.ContainsKey(k)) {
|
if (_dirty.ContainsKey(k)) {
|
||||||
_dirty.Add(k, chunk);
|
_dirty.Remove(k);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SaveDirtyChunks ()
|
public int Save ()
|
||||||
{
|
{
|
||||||
int saved = 0;
|
int saved = 0;
|
||||||
foreach (ChunkRef c in _dirty.Values) {
|
foreach (ChunkRef c in _dirty.Values) {
|
||||||
if (c.Save()) {
|
int lcx = ChunkLocalX(c.X);
|
||||||
|
int lcz = ChunkLocalZ(c.Z);
|
||||||
|
|
||||||
|
Region r = GetRegion(c.X, c.Z);
|
||||||
|
if (r == null || !r.ChunkExists(lcx, lcz)) {
|
||||||
|
throw new MissingChunkException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.Save(r.GetChunkOutStream(lcx, lcz))) {
|
||||||
saved++;
|
saved++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,9 +139,14 @@ namespace NBToolkit.Map
|
||||||
return saved;
|
return saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionManager GetRegionManager ()
|
public bool Save (Chunk chunk)
|
||||||
{
|
{
|
||||||
return _regionMan;
|
Region r = GetRegion(chunk.X, chunk.Z);
|
||||||
|
if (r == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk.Save(r.GetChunkOutStream(chunk.X & REGION_XLEN, chunk.Z & REGION_ZLEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteChunk (int cx, int cz)
|
public bool DeleteChunk (int cx, int cz)
|
||||||
|
@ -128,6 +170,35 @@ namespace NBToolkit.Map
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RegionManager GetRegionManager ()
|
||||||
|
{
|
||||||
|
return _regionMan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChunkRef GetChunkRefInRegion (Region r, int lcx, int lcz)
|
||||||
|
{
|
||||||
|
int cx = r.X * REGION_XLEN + lcx;
|
||||||
|
int cz = r.Z * REGION_ZLEN + lcz;
|
||||||
|
return GetChunkRef(cx, cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int ChunkLocalX (int cx)
|
||||||
|
{
|
||||||
|
return cx & REGION_XMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int ChunkLocalZ (int cz)
|
||||||
|
{
|
||||||
|
return cz & REGION_ZMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Region GetRegion (int cx, int cz)
|
||||||
|
{
|
||||||
|
cx >>= REGION_XLOG;
|
||||||
|
cz >>= REGION_ZLOG;
|
||||||
|
return _regionMan.GetRegion(cx, cz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MissingChunkException : Exception
|
public class MissingChunkException : Exception
|
||||||
|
|
|
@ -27,45 +27,63 @@ namespace NBToolkit.Map
|
||||||
get { return _cz; }
|
get { return _cz; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int LocalX
|
|
||||||
{
|
|
||||||
get { return _cx & ChunkManager.REGION_XMASK; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int LocalZ
|
|
||||||
{
|
|
||||||
get { return _cz & ChunkManager.REGION_ZMASK; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChunkRef (ChunkManager cm, int cx, int cz)
|
public ChunkRef (ChunkManager cm, int cx, int cz)
|
||||||
{
|
{
|
||||||
_chunkMan = cm;
|
_chunkMan = cm;
|
||||||
_cx = cx;
|
_cx = cx;
|
||||||
_cz = cz;
|
_cz = cz;
|
||||||
|
|
||||||
Region r = cm.GetRegion(cx, cz);
|
if (!_chunkMan.ChunkExists(cx, cz)) {
|
||||||
if (r == null || !r.ChunkExists(LocalX, LocalZ)) {
|
|
||||||
throw new MissingChunkException();
|
throw new MissingChunkException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GlobalX (int x)
|
||||||
|
{
|
||||||
|
return _cx * BlockManager.CHUNK_XLEN + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GlobalY (int y)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GlobalZ (int z)
|
||||||
|
{
|
||||||
|
return _cz * BlockManager.CHUNK_ZLEN + z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalX (int x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalY (int y)
|
||||||
|
{
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int LocalZ (int z)
|
||||||
|
{
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
private Chunk GetChunk ()
|
private Chunk GetChunk ()
|
||||||
{
|
{
|
||||||
if (_chunk == null) {
|
if (_chunk == null) {
|
||||||
_chunk = new Chunk(GetTree());
|
_chunk = _chunkMan.GetChunk(_cx, _cz);
|
||||||
}
|
}
|
||||||
return _chunk;
|
return _chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NBT_Tree GetTree ()
|
/*private NBT_Tree GetTree ()
|
||||||
{
|
{
|
||||||
Region r = _chunkMan.GetRegion(_cx, _cz);
|
if (!_chunkMan.ChunkExists(_cx, _cz)) {
|
||||||
if (r == null || !r.ChunkExists(LocalX, LocalZ)) {
|
|
||||||
throw new MissingChunkException();
|
throw new MissingChunkException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.GetChunkTree(LocalX, LocalZ);
|
return r.GetChunkTree(LocalX, LocalZ);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private bool MarkDirty ()
|
private bool MarkDirty ()
|
||||||
{
|
{
|
||||||
|
@ -74,11 +92,11 @@ namespace NBToolkit.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
_chunkMan.MarkChunkDirty(this);
|
_chunkMan.MarkChunkDirty(_cx, _cz);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Save ()
|
/*public bool Save ()
|
||||||
{
|
{
|
||||||
if (_dirty) {
|
if (_dirty) {
|
||||||
Region r = _chunkMan.GetRegion(_cx, _cz);
|
Region r = _chunkMan.GetRegion(_cx, _cz);
|
||||||
|
@ -93,26 +111,46 @@ namespace NBToolkit.Map
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public ChunkRef GetNorthNeighbor ()
|
public ChunkRef GetNorthNeighbor ()
|
||||||
{
|
{
|
||||||
return _chunkMan.GetChunk(_cx - 1, _cz);
|
return _chunkMan.GetChunkRef(_cx - 1, _cz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkRef GetSouthNeighbor ()
|
public ChunkRef GetSouthNeighbor ()
|
||||||
{
|
{
|
||||||
return _chunkMan.GetChunk(_cx + 1, _cz);
|
return _chunkMan.GetChunkRef(_cx + 1, _cz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkRef GetEastNeighbor ()
|
public ChunkRef GetEastNeighbor ()
|
||||||
{
|
{
|
||||||
return _chunkMan.GetChunk(_cx, _cz - 1);
|
return _chunkMan.GetChunkRef(_cx, _cz - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkRef GetWestNeighbor ()
|
public ChunkRef GetWestNeighbor ()
|
||||||
{
|
{
|
||||||
return _chunkMan.GetChunk(_cx, _cz + 1);
|
return _chunkMan.GetChunkRef(_cx, _cz + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk GetChunkCopy ()
|
||||||
|
{
|
||||||
|
return GetChunk().Copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk GetChunkRef ()
|
||||||
|
{
|
||||||
|
Chunk chunk = GetChunk();
|
||||||
|
_chunk = null;
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetChunkRef (Chunk chunk)
|
||||||
|
{
|
||||||
|
_chunk = chunk;
|
||||||
|
_chunk.SetLocation(_cx, _cz);
|
||||||
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IChunk Members
|
#region IChunk Members
|
||||||
|
@ -156,6 +194,11 @@ namespace NBToolkit.Map
|
||||||
return GetChunk().GetBlockInfo(lx, ly, lz);
|
return GetChunk().GetBlockInfo(lx, ly, lz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBlock (int lx, int ly, int lz, Block block)
|
||||||
|
{
|
||||||
|
GetChunk().SetBlock(lx, ly, lz, block);
|
||||||
|
}
|
||||||
|
|
||||||
public int GetBlockID (int lx, int ly, int lz)
|
public int GetBlockID (int lx, int ly, int lz)
|
||||||
{
|
{
|
||||||
return GetChunk().GetBlockID(lx, ly, lz);
|
return GetChunk().GetBlockID(lx, ly, lz);
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace NBToolkit.Map.NBT
|
||||||
{
|
{
|
||||||
using Map.Utility;
|
using Map.Utility;
|
||||||
|
|
||||||
public class NBT_Tree
|
public class NBT_Tree : ICopyable<NBT_Tree>
|
||||||
{
|
{
|
||||||
private Stream _stream = null;
|
private Stream _stream = null;
|
||||||
private NBT_Compound _root = null;
|
private NBT_Compound _root = null;
|
||||||
|
@ -459,6 +459,18 @@ namespace NBToolkit.Map.NBT
|
||||||
WriteValue(val);
|
WriteValue(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region ICopyable<NBT_Tree> Members
|
||||||
|
|
||||||
|
public NBT_Tree Copy ()
|
||||||
|
{
|
||||||
|
NBT_Tree tree = new NBT_Tree();
|
||||||
|
tree._root = _root.Copy() as NBT_Compound;
|
||||||
|
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NBTException : Exception
|
public class NBTException : Exception
|
||||||
|
|
|
@ -8,6 +8,36 @@ namespace NBToolkit.Map
|
||||||
{
|
{
|
||||||
using NBT;
|
using NBT;
|
||||||
|
|
||||||
|
public interface IChunkContainer
|
||||||
|
{
|
||||||
|
int GlobalX (int cx);
|
||||||
|
int GlobalZ (int cz);
|
||||||
|
|
||||||
|
int LocalX (int cx);
|
||||||
|
int LocalZ (int cz);
|
||||||
|
|
||||||
|
Chunk GetChunk (int cx, int cz);
|
||||||
|
ChunkRef GetChunkRef (int cx, int cz);
|
||||||
|
|
||||||
|
bool ChunkExists (int cx, int cz);
|
||||||
|
|
||||||
|
bool DeleteChunk (int cx, int cz);
|
||||||
|
|
||||||
|
bool Save ();
|
||||||
|
bool SaveChunk (Chunk chunk);
|
||||||
|
|
||||||
|
bool MarkChunkDirty (int cx, int cz);
|
||||||
|
bool MarkChunkClean (int cx, int cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IRegion : IChunkContainer
|
||||||
|
{
|
||||||
|
int X { get; }
|
||||||
|
int Z { get; }
|
||||||
|
|
||||||
|
int ChunkCount ();
|
||||||
|
}
|
||||||
|
|
||||||
public class Region : IDisposable
|
public class Region : IDisposable
|
||||||
{
|
{
|
||||||
protected int _rx;
|
protected int _rx;
|
||||||
|
@ -20,6 +50,16 @@ namespace NBToolkit.Map
|
||||||
|
|
||||||
protected WeakReference _regionFile;
|
protected WeakReference _regionFile;
|
||||||
|
|
||||||
|
public int X
|
||||||
|
{
|
||||||
|
get { return _rx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Z
|
||||||
|
{
|
||||||
|
get { return _rz; }
|
||||||
|
}
|
||||||
|
|
||||||
public Region (RegionManager rm, int rx, int rz)
|
public Region (RegionManager rm, int rx, int rz)
|
||||||
{
|
{
|
||||||
_regionMan = rm;
|
_regionMan = rm;
|
||||||
|
@ -44,22 +84,6 @@ namespace NBToolkit.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int X
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _rx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Z
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _rz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Region ()
|
~Region ()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
|
@ -88,6 +112,20 @@ namespace NBToolkit.Map
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Chunk GetChunk (int lcx, int lcz)
|
||||||
|
{
|
||||||
|
if (!ChunkExists(lcx, lcz)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Chunk(GetChunkTree(lcx, lcz));
|
||||||
|
}
|
||||||
|
|
||||||
|
//public ChunkRef GetChunkRef (int lcx, int lcz)
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
public string GetFileName ()
|
public string GetFileName ()
|
||||||
{
|
{
|
||||||
return "r." + _rx + "." + _rz + ".mcr";
|
return "r." + _rx + "." + _rz + ".mcr";
|
||||||
|
|
|
@ -16,6 +16,15 @@ namespace NBToolkit.Map
|
||||||
get { return _tree; }
|
get { return _tree; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TileEntity (string id)
|
||||||
|
{
|
||||||
|
_tree = new NBT_Compound();
|
||||||
|
_tree["id"] = new NBT_String(id);
|
||||||
|
_tree["x"] = new NBT_Int();
|
||||||
|
_tree["y"] = new NBT_Int();
|
||||||
|
_tree["z"] = new NBT_Int();
|
||||||
|
}
|
||||||
|
|
||||||
public TileEntity (NBT_Compound tree)
|
public TileEntity (NBT_Compound tree)
|
||||||
{
|
{
|
||||||
_tree = tree;
|
_tree = tree;
|
||||||
|
@ -77,7 +86,7 @@ namespace NBToolkit.Map
|
||||||
new NBTStringNode("id", "Furnace"),
|
new NBTStringNode("id", "Furnace"),
|
||||||
new NBTScalerNode("BurnTime", NBT_Type.TAG_SHORT),
|
new NBTScalerNode("BurnTime", NBT_Type.TAG_SHORT),
|
||||||
new NBTScalerNode("CookTime", NBT_Type.TAG_SHORT),
|
new NBTScalerNode("CookTime", NBT_Type.TAG_SHORT),
|
||||||
new NBTListNode("Items", NBT_Type.TAG_COMPOUND),
|
new NBTListNode("Items", NBT_Type.TAG_COMPOUND, InventorySchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
public static readonly NBTCompoundNode SignSchema = BaseSchema.MergeInto(new NBTCompoundNode("")
|
public static readonly NBTCompoundNode SignSchema = BaseSchema.MergeInto(new NBTCompoundNode("")
|
||||||
|
|
|
@ -3,9 +3,9 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace NBToolkit
|
namespace NBToolkit.Map.Utility
|
||||||
{
|
{
|
||||||
public class NibbleArray
|
public class NibbleArray : ICopyable<NibbleArray>
|
||||||
{
|
{
|
||||||
protected readonly byte[] _data = null;
|
protected readonly byte[] _data = null;
|
||||||
|
|
||||||
|
@ -46,5 +46,17 @@ namespace NBToolkit
|
||||||
return _data.Length << 1;
|
return _data.Length << 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region ICopyable<NibbleArray> Members
|
||||||
|
|
||||||
|
public NibbleArray Copy ()
|
||||||
|
{
|
||||||
|
byte[] data = new byte[_data.Length];
|
||||||
|
_data.CopyTo(data, 0);
|
||||||
|
|
||||||
|
return new NibbleArray(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue