Fix /rs to work with custom blocks, modify more commands to use UpdateBlock now.

This commit is contained in:
UnknownShadow200 2016-02-28 19:47:57 +11:00
parent ff46ad26c2
commit 9b63b0bd69
12 changed files with 166 additions and 285 deletions

View File

@ -16,59 +16,51 @@
permissions and limitations under the Licenses.
*/
using System;
using System.IO;
using System.IO.Compression;
using MCGalaxy.Levels.IO;
namespace MCGalaxy.Commands
{
public sealed class CmdRestoreSelection : Command
{
namespace MCGalaxy.Commands {
public sealed class CmdRestoreSelection : Command {
public override string name { get { return "rs"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Moderation; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public override void Use(Player p, string message)
{
if (message != "")
if (File.Exists(@Server.backupLocation + "/" + p.level.name + "/" + message + "/" + p.level.name + ".lvl"))
{
try
{
p.blockchangeObject = new CatchPos() { backup = int.Parse(message) };
public override void Use(Player p, string message) {
if (message == "") { Help(p); return; }
if (LevelInfo.ExistsBackup(p.level.name, message)) {
p.blockchangeObject = new CatchPos() { backup = message };
p.ClearBlockchange();
p.Blockchange += Blockchange1;
p.SendMessage("Select two corners for restore.");
} else {
Player.SendMessage(p, "Backup " + message + " does not exist.");
}
catch { Server.s.Log("Restore fail"); }
}
else Player.SendMessage(p, "Backup " + message + " does not exist.");
else Help(p);
}
public void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
{
void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos bp = (CatchPos)p.blockchangeObject;
bp.x = x; bp.y = y; bp.z = z; p.blockchangeObject = bp;
p.Blockchange += Blockchange2;
}
public void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
{
void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
string path = @Server.backupLocation + "/" + p.level.name + "/" + cpos.backup + "/" + p.level.name + ".lvl";
string path = LevelInfo.BackupPath(p.level.name, cpos.backup);
try {
using(Level other = LvlFile.Load("tempLevel", path, false)) {
using(Level other = LvlFile.Load("tempLevel", path)) {
if (!CopyBlocks(p, other, x, y, z, cpos)) return;
}
if (p.staticCommands)
p.Blockchange += Blockchange1;
} catch {
} catch (Exception ex) {
Server.ErrorLog(ex);
Server.s.Log("Restore selection failed");
}
}
@ -79,34 +71,22 @@ namespace MCGalaxy.Commands
p.SendMessage("Cant restore selection of different size maps.");
return false;
}
int width = other.Width, height = other.Length;
if (p.level.bufferblocks && !p.level.Instant) {
int width = other.Width, length = other.Length;
for (ushort yy = Math.Min(cpos.y, y); yy <= Math.Max(cpos.y, y); ++yy)
for (ushort zz = Math.Min(cpos.z, z); zz <= Math.Max(cpos.z, z); ++zz)
for (ushort xx = Math.Min(cpos.x, x); xx <= Math.Max(cpos.x, x); ++xx)
{
BlockQueue.Addblock(p, xx, yy, zz, blocks[xx + (zz * width) + (yy * width * height)]);
}
} else {
for (ushort yy = Math.Min(cpos.y, y); yy <= Math.Max(cpos.y, y); ++yy)
for (ushort zz = Math.Min(cpos.z, z); zz <= Math.Max(cpos.z, z); ++zz)
for (ushort xx = Math.Min(cpos.x, x); xx <= Math.Max(cpos.x, x); ++xx)
{
p.level.Blockchange(p, xx, yy, zz, blocks[xx + (zz * width) + (yy * width * height)]);
}
byte tile = blocks[xx + width * (zz + yy * length)], extTile = 0;
if (tile == Block.custom_block) extTile = other.GetExtTile(xx, yy, zz);
p.level.UpdateBlock(p, xx, yy, zz, tile, extTile);
}
return true;
}
struct CatchPos
{
public int backup;
public ushort x, y, z;
}
struct CatchPos { public string backup; public ushort x, y, z; }
public override void Help(Player p)
{
public override void Help(Player p) {
Player.SendMessage(p, "/restoreselection <number> - restores a previous backup of the current selection");
}
}

View File

@ -35,7 +35,7 @@ namespace MCGalaxy.Commands {
int xCen = (int)((p.centerstart[0] + p.centerend[0]) / 2);
int yCen = (int)((p.centerstart[1] + p.centerend[1]) / 2);
int zCen = (int)((p.centerstart[2] + p.centerend[2]) / 2);
p.level.Blockchange(p, (ushort)xCen, (ushort)yCen, (ushort)zCen, (byte)Block.goldsolid);
p.level.UpdateBlock(p, (ushort)xCen, (ushort)yCen, (ushort)zCen, (byte)Block.goldsolid, 0);
Player.SendMessage(p, "A gold block was placed at (" + xCen + ", " + yCen + ", " + zCen + ").");
}

View File

@ -167,7 +167,7 @@ namespace MCGalaxy.Commands
{
byte b = p.level.GetTile(xx, yy, zz);
if (b != Block.air && Block.canPlace(p, b))
p.level.Blockchange(p, xx, yy, zz, Block.air);
p.level.UpdateBlock(p, xx, yy, zz, Block.air, 0);
}
Player.SendMessage(p, (state.Volume - totalAir) + " blocks copied.");

View File

@ -97,19 +97,12 @@ namespace MCGalaxy.Commands
return;
}
buffer.ForEach(delegate(Pos pos1)
{
p.level.Blockchange(p, pos1.x, pos1.y, pos1.z, Block.air);
});
buffer.ForEach(P => p.level.UpdateBlock(p, P.x, P.y, P.z, Block.air, 0));
Player.SendMessage(p, "You hollowed " + buffer.Count + " blocks.");
if (p.staticCommands) p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
}
void BufferAdd(List<Pos> list, ushort x, ushort y, ushort z)
{
Pos pos; pos.x = x; pos.y = y; pos.z = z; list.Add(pos);
}
struct Pos
{

View File

@ -125,9 +125,9 @@ namespace MCGalaxy.Commands
{
if (wall[xx, zz])
{
p.level.Blockchange(p, (ushort)(xx + minX+1), y, (ushort)(zz + minZ+1), Block.staircasefull);
p.level.Blockchange(p, (ushort)(xx + minX+1), (ushort)(y + 1), (ushort)(zz + minZ+1), Block.leaf);
p.level.Blockchange(p, (ushort)(xx + minX+1), (ushort)(y + 2), (ushort)(zz + minZ+1), Block.leaf);
p.level.UpdateBlock(p, (ushort)(xx + minX+1), y, (ushort)(zz + minZ+1), Block.staircasefull, 0);
p.level.UpdateBlock(p, (ushort)(xx + minX+1), (ushort)(y + 1), (ushort)(zz + minZ+1), Block.leaf, 0);
p.level.UpdateBlock(p, (ushort)(xx + minX+1), (ushort)(y + 2), (ushort)(zz + minZ+1), Block.leaf, 0);
}
}
}

View File

@ -42,7 +42,7 @@ namespace MCGalaxy.Commands
if (type2 == 255) { Player.SendMessage(p, "There is no block \"" + t2 + "\"."); return; }
if (!Block.canPlace(p, type2)) { Player.SendMessage(p, "Cannot place that block type."); return; }
CatchPos cpos; cpos.type2 = type2; cpos.type = type;
CatchPos cpos; cpos.newType = type2; cpos.type = type;
cpos.x = 0; cpos.y = 0; cpos.z = 0; p.blockchangeObject = cpos;
Player.SendMessage(p, "Place two blocks to determine the edges.");
@ -94,19 +94,11 @@ namespace MCGalaxy.Commands
return;
}
buffer.ForEach(delegate(Pos pos1)
{
p.level.Blockchange(p, pos1.x, pos1.y, pos1.z, cpos.type2);
});
buffer.ForEach(P => p.level.UpdateBlock(p, P.x, P.y, P.z, cpos.newType, 0));
Player.SendMessage(p, "You outlined " + buffer.Count + " blocks.");
if (p.staticCommands) p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
}
void BufferAdd(List<Pos> list, ushort x, ushort y, ushort z)
{
Pos pos; pos.x = x; pos.y = y; pos.z = z; list.Add(pos);
}
struct Pos
{
@ -115,7 +107,7 @@ namespace MCGalaxy.Commands
struct CatchPos
{
public byte type;
public byte type2;
public byte newType;
public ushort x, y, z;
}

View File

@ -75,19 +75,19 @@ namespace MCGalaxy.Commands {
dirZ = z > cpos.z ? 1 : -1;
ushort endX = (ushort)(cpos.x + dirX * distance);
ushort endZ = (ushort)(cpos.z + dirZ * distance);
p.level.Blockchange(p, endX, cpos.y, endZ, Block.rock);
p.level.UpdateBlock(p, endX, cpos.y, endZ, Block.rock, 0);
if (interval > 0) {
ushort xx = cpos.x, zz = cpos.z;
int delta = 0;
while (xx < p.level.Width && zz < p.level.Length && delta < distance) {
p.level.Blockchange(p, xx, cpos.y, zz, Block.rock);
p.level.UpdateBlock(p, xx, cpos.y, zz, Block.rock, 0);
xx = (ushort)(xx + dirX * interval);
zz = (ushort)(zz + dirZ * interval);
delta = Math.Abs(xx - cpos.x) + Math.Abs(zz - cpos.z);
}
} else {
p.level.Blockchange(p, cpos.x, cpos.y, cpos.z, Block.rock);
p.level.UpdateBlock(p, cpos.x, cpos.y, cpos.z, Block.rock, 0);
}
if (interval > 0)

View File

@ -116,10 +116,7 @@ namespace MCGalaxy.Commands
}
Player.SendMessage(p, buffer.Count.ToString() + " blocks.");
buffer.ForEach(delegate(Pos pos)
{
p.level.Blockchange(p, pos.x, pos.y, pos.z, pos.newType); //update block for everyone
});
buffer.ForEach(P => p.level.UpdateBlock(p, P.x, P.y, P.z, P.newType, 0));
if (p.staticCommands) p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
}

View File

@ -33,102 +33,54 @@ namespace MCGalaxy {
{
byte height = (byte)Rand.Next(5, 8);
short top = (short)(height - Rand.Next(2, 4));
ushort xxx, yyy, zzz;
for (ushort yy = 0; yy < top + height - 1; yy++)
{
for (ushort yy = 0; yy < top + height - 1; yy++) {
if (overwrite || Lvl.GetTile(x, (ushort)(y + yy), z) == Block.air || (y + yy == y && Lvl.GetTile(x, (ushort)(y + yy), z) == Block.shrub))
if (blockChange)
if (p == null) Lvl.Blockchange(x, (ushort)(y + yy), z, Block.trunk);
else Lvl.Blockchange(p, x, (ushort)(y + yy), z, Block.trunk);
else Lvl.SetTile(x, (ushort)(y + yy), z, Block.trunk);
PlaceBlock(Lvl, blockChange, p, x, (ushort)(y + yy), z, Block.trunk);
}
for (short xx = (short)-top; xx <= top; ++xx)
{
for (short yy = (short)-top; yy <= top; ++yy)
{
for (short zz = (short)-top; zz <= top; ++zz)
{
short Dist = (short)(Math.Sqrt(xx * xx + yy * yy + zz * zz));
if (Dist < top + 1)
{
if (Rand.Next((int)(Dist)) < 2)
{
try
{
xxx = (ushort)(x + xx);
yyy = (ushort)(y + yy + height);
zzz = (ushort)(z + zz);
if ((Dist < top + 1) && Rand.Next(Dist) < 2) {
ushort xxx = (ushort)(x + xx), yyy = (ushort)(y + yy + height), zzz = (ushort)(z + zz);
if ((xxx != x || zzz != z || yy >= top - 1) && (overwrite || Lvl.GetTile(xxx, yyy, zzz) == Block.air))
if (blockChange)
if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf);
else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf);
else Lvl.SetTile(xxx, yyy, zzz, Block.leaf);
}
catch { }
}
}
}
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
}
}
}
public static void AddNotchTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte dist, tile;
byte height = (byte)Rand.Next(3, 7);
byte top = (byte)(height - 2);
short xx, yy, zz;
ushort xxx, yyy, zzz;
for (yy = 0; yy <= height; yy++)
{
yyy = (ushort)(y + yy);
tile = Lvl.GetTile(x, yyy, z);
for (int yy = 0; yy <= height; yy++) {
ushort yyy = (ushort)(y + yy);
byte tile = Lvl.GetTile(x, yyy, z);
if (overwrite || tile == Block.air || (yyy == y && tile == Block.shrub))
if (blockChange)
if (p == null) Lvl.Blockchange(x, yyy, z, Block.trunk);
else Lvl.Blockchange(p, x, yyy, z, Block.trunk);
else Lvl.SetTile(x, yyy, z, Block.trunk);
PlaceBlock(Lvl, blockChange, p, x, yyy, z, Block.trunk);
}
for (yy = top; yy <= height + 1; yy++)
for (int yy = top; yy <= height + 1; yy++) {
int dist = yy > height - 1 ? 1 : 2;
for (int xx = -dist; xx <= dist; xx++)
for (int zz = -dist; zz <= dist; zz++)
{
dist = yy > height - 1 ? (byte)1 : (byte)2;
for (xx = (short)-dist; xx <= dist; xx++)
{
for (zz = (short)-dist; zz <= dist; zz++)
{
xxx = (ushort)(x + xx);
yyy = (ushort)(y + yy);
zzz = (ushort)(z + zz);
tile = Lvl.GetTile(xxx, yyy, zzz);
//Server.s.Log(String.Format("{0} {1} {2}", xxx, yyy, zzz));
ushort xxx = (ushort)(x + xx), yyy = (ushort)(y + yy), zzz = (ushort)(z + zz);
byte tile = Lvl.GetTile(xxx, yyy, zzz);
if ((xxx == x && zzz == z && yy <= height) || (!overwrite && tile != Block.air))
continue;
if (Math.Abs(xx) == dist && Math.Abs(zz) == dist)
{
if (yy > height)
continue;
if (Math.Abs(xx) == dist && Math.Abs(zz) == dist) {
if (yy > height) continue;
if (Rand.Next(2) == 0)
{
if (blockChange)
if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf);
else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf);
else Lvl.SetTile(xxx, yyy, zzz, Block.leaf);
}
}
else
{
if (blockChange)
if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf);
else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf);
else Lvl.SetTile(xxx, yyy, zzz, Block.leaf);
}
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
} else {
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
}
}
}
@ -147,58 +99,33 @@ namespace MCGalaxy {
public static void AddNotchSwampTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte dist, tile;
byte height = (byte)Rand.Next(4, 8);
byte top = (byte)(height - 2);
short xx, yy, zz;
ushort xxx, yyy, zzz;
for (yy = 0; yy <= height; yy++)
{
yyy = (ushort)(y + yy);
tile = Lvl.GetTile(x, yyy, z);
for (int yy = 0; yy <= height; yy++) {
ushort yyy = (ushort)(y + yy);
byte tile = Lvl.GetTile(x, yyy, z);
if (overwrite || tile == Block.air || (yyy == y && tile == Block.shrub))
if (blockChange)
if (p == null) Lvl.Blockchange(x, yyy, z, Block.trunk);
else Lvl.Blockchange(p, x, yyy, z, Block.trunk);
else Lvl.SetTile(x, yyy, z, Block.trunk);
PlaceBlock(Lvl, blockChange, p, x, yyy, z, Block.trunk);
}
for (yy = top; yy <= height + 1; yy++)
for (int yy = top; yy <= height + 1; yy++) {
int dist = yy > height - 1 ? 2 : 3;
for (int xx = (short)-dist; xx <= dist; xx++)
for (int zz = (short)-dist; zz <= dist; zz++)
{
dist = yy > height - 1 ? (byte)2 : (byte)3;
for (xx = (short)-dist; xx <= dist; xx++)
{
for (zz = (short)-dist; zz <= dist; zz++)
{
xxx = (ushort)(x + xx);
yyy = (ushort)(y + yy);
zzz = (ushort)(z + zz);
tile = Lvl.GetTile(xxx, yyy, zzz);
//Server.s.Log(String.Format("{0} {1} {2}", xxx, yyy, zzz));
ushort xxx = (ushort)(x + xx), yyy = (ushort)(y + yy), zzz = (ushort)(z + zz);
byte tile = Lvl.GetTile(xxx, yyy, zzz);
if ((xxx == x && zzz == z && yy <= height) || (!overwrite && tile != Block.air))
continue;
if (Math.Abs(xx) == dist && Math.Abs(zz) == dist)
{
if (yy > height)
continue;
if (Math.Abs(xx) == dist && Math.Abs(zz) == dist) {
if (yy > height) continue;
if (Rand.Next(2) == 0)
{
if (blockChange)
if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf);
else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf);
else Lvl.SetTile(xxx, yyy, zzz, Block.leaf);
}
}
else
{
if (blockChange)
if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf);
else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf);
else Lvl.SetTile(xxx, yyy, zzz, Block.leaf);
}
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
} else {
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
}
}
}
@ -207,62 +134,48 @@ namespace MCGalaxy {
public static void AddCactus(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte height = (byte)Rand.Next(3, 6);
ushort yy;
for (yy = 0; yy <= height; yy++)
{
for (ushort yy = 0; yy <= height; yy++) {
if (overwrite || Lvl.GetTile(z, (ushort)(y + yy), z) == Block.air)
if (blockChange)
if (p == null) Lvl.Blockchange(x, (ushort)(y + yy), z, Block.green);
else Lvl.Blockchange(p, x, (ushort)(y + yy), z, Block.green);
else Lvl.SetTile(x, (ushort)(y + yy), z, Block.green);
PlaceBlock(Lvl, blockChange, p, x, (ushort)(y + yy), z, Block.green);
}
int inX = 0, inZ = 0;
switch (Rand.Next(1, 3))
{
switch (Rand.Next(1, 3)) {
case 1: inX = -1; break;
case 2:
default: inZ = -1; break;
}
for (yy = height; yy <= Rand.Next(height + 2, height + 5); yy++)
{
for (ushort yy = height; yy <= Rand.Next(height + 2, height + 5); yy++) {
if (overwrite || Lvl.GetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ)) == Block.air)
if (blockChange)
if (p == null) Lvl.Blockchange((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green);
else Lvl.Blockchange(p, (ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green);
else Lvl.SetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green);
PlaceBlock(Lvl, blockChange, p, (ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green);
}
for (yy = height; yy <= Rand.Next(height + 2, height + 5); yy++)
{
if (overwrite || Lvl.GetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ)) == Block.air)
if (blockChange)
if (p == null) Lvl.Blockchange((ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green);
else Lvl.Blockchange(p, (ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green);
else Lvl.SetTile((ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green);
for (ushort yy = height; yy <= Rand.Next(height + 2, height + 5); yy++) {
if (overwrite || Lvl.GetTile((ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ)) == Block.air)
PlaceBlock(Lvl, blockChange, p, (ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green);
}
}
public static bool TreeCheck(Level Lvl, ushort x, ushort z, ushort y, short dist) //return true if tree is near
{
byte foundTile;
public static bool TreeCheck(Level Lvl, ushort x, ushort z, ushort y, short dist) { //return true if tree is near
for (short yy = (short)-dist; yy <= +dist; ++yy)
for (short zz = (short)-dist; zz <= +dist; ++zz)
for (short xx = (short)-dist; xx <= +dist; ++xx)
{
for (short yy = (short)-dist; yy <= +dist; ++yy)
{
for (short zz = (short)-dist; zz <= +dist; ++zz)
{
foundTile = Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz), (ushort)(y + yy));
if (foundTile == Block.trunk || foundTile == Block.green)
{
return true;
}
}
}
byte foundTile = Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz), (ushort)(y + yy));
if (foundTile == Block.trunk || foundTile == Block.green) return true;
}
return false;
}
static void PlaceBlock(Level lvl, bool blockChange, Player p, ushort x, ushort y, ushort z, byte type) {
if (blockChange) {
if (p == null) lvl.Blockchange(x, y, z, type);
else lvl.UpdateBlock(p, x, y, z, type, 0);
} else {
lvl.SetTile(x, y, z, type);
}
}
}
}

View File

@ -77,7 +77,7 @@ namespace MCGalaxy.Levels.IO {
}
}
public static Level Load(string name, string file, bool loadTexturesConfig = true) {
public static Level Load(string name, string file) {
using (Stream fs = File.OpenRead(file),
gs = new GZipStream(fs, CompressionMode.Decompress, true))
{
@ -97,8 +97,7 @@ namespace MCGalaxy.Levels.IO {
vars[1] = BitConverter.ToUInt16(header, offset);
vars[2] = BitConverter.ToUInt16(header, offset + 2);
Level level = new Level(name, vars[0], vars[2], vars[1],
"full_empty", 0, loadTexturesConfig);
Level level = new Level(name, vars[0], vars[2], vars[1], "full_empty");
level.spawnx = BitConverter.ToUInt16(header, offset + 4);
level.spawnz = BitConverter.ToUInt16(header, offset + 6);
level.spawny = BitConverter.ToUInt16(header, offset + 8);

View File

@ -443,8 +443,7 @@ namespace MCGalaxy {
public int PosToInt(ushort x, ushort y, ushort z) {
if (x < 0 || x >= Width || y < 0 || y >= Height || z < 0 || z >= Length)
return -1;
return x + (z * Width) + (y * Width * Length);
//alternate method: (h * widthY + y) * widthX + x;
return x + Width * (z + y * Length);
}
public void IntToPos(int pos, out ushort x, out ushort y, out ushort z) {

View File

@ -47,6 +47,14 @@ namespace MCGalaxy {
return File.Exists("levels/" + name.ToLower() + ".lvl");
}
public static bool ExistsBackup(string name, string backup) {
return File.Exists(BackupPath(name, backup));
}
public static string BackupPath(string name, string backup) {
return Server.backupLocation + "/" + name + "/" + backup + "/" + name + ".lvl";
}
public static string FindOfflineProperty(string name, string propKey) {
string file = "levels/level properties/" + name + ".properties";
if (!File.Exists(file))