Physics: fire now properly kills custom blocks which are killed by lava. (Thanks Odd0002)

also minor perf optimisations
This commit is contained in:
UnknownShadow200 2017-01-04 17:40:02 +11:00
parent ab3efd28ee
commit 355223048f
6 changed files with 159 additions and 128 deletions

View File

@ -64,8 +64,125 @@ namespace MCGalaxy
}
}
SaveBlocks(BlockList);
UpdateRankPerms();
}
internal static void UpdateRankPerms() {
foreach (Group grp in Group.GroupList) {
grp.FillBlocks();
}
}
public static bool canPlace(Player p, byte block) {
Blocks b = BlockList[block];
LevelPermission perm = p.Rank;
return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm)))
&& (b.disallow == null || !b.disallow.Contains(perm));
}
public static bool canPlace(LevelPermission perm, byte block) {
Blocks b = BlockList[block];
return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm)))
&& (b.disallow == null || !b.disallow.Contains(perm));
}
public static void ResendBlockPermissions(byte block) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (!pl.HasCpeExt(CpeExt.BlockPermissions)) continue;
int count = pl.hasCustomBlocks ? Block.CpeCount : Block.OriginalCount;
if (block < count) {
bool canAffect = Block.canPlace(pl, block);
pl.Send(Packet.BlockPermission(block, canAffect, canAffect));
}
}
}
static void LoadVersion2(string[] lines) {
string[] colon = new string[] { " : " };
foreach (string line in lines) {
if (line == "" || line[0] == '#') continue;
//Name : Lowest : Disallow : Allow
string[] block = line.Split(colon, StringSplitOptions.None);
Blocks newBlock = new Blocks();
if (Block.Byte(block[0]) == Block.Invalid) continue;
newBlock.type = Block.Byte(block[0]);
string[] disallow = null;
if (block[2] != "") disallow = block[2].Split(',');
string[] allow = null;
if (block[3] != "") allow = block[3].Split(',');
try {
newBlock.lowestRank = (LevelPermission)int.Parse(block[1]);
if (disallow != null) {
newBlock.disallow = new List<LevelPermission>();
foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); }
}
if (allow != null) {
newBlock.allow = new List<LevelPermission>();
foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); }
}
} catch {
Server.s.Log("Hit an error on the block " + line);
continue;
}
BlockList[newBlock.type] = newBlock;
}
}
static void LoadVersion1(string[] lines) {
foreach (string line in lines) {
if (line == "" || line[0] == '#') continue;
try {
byte block = Block.Byte(line.Split(' ')[0]);
LevelPermission lowestRank = Level.PermissionFromName(line.Split(' ')[2]);
if (lowestRank != LevelPermission.Null)
BlockList[block].lowestRank = lowestRank;
else
throw new InvalidDataException("Line " + line + " is invalid.");
}
catch { Server.s.Log("Could not find the rank given on " + line + ". Using default"); }
}
}
static readonly object saveLock = new object();
public static void SaveBlocks(IEnumerable<Blocks> givenList) {
try {
lock (saveLock)
SaveBlocksCore(givenList);
} catch (Exception e) {
Server.ErrorLog(e);
}
}
static void SaveBlocksCore(IEnumerable<Blocks> givenList) {
using (StreamWriter w = new StreamWriter("properties/block.properties")) {
w.WriteLine("#Version 2");
w.WriteLine("# This file dictates which ranks may use what blocks");
w.WriteLine("# If someone has royally screwed up the ranks, just delete this file and let the server restart");
w.WriteLine("# Allowed ranks: " + Group.concatList(false, false, true));
w.WriteLine("# Disallow and allow can be left empty, just make sure there's 2 spaces between the colons");
w.WriteLine("# This works entirely on permission values, not names. Do not enter a rank name. Use its permission value");
w.WriteLine("# BlockName : LowestRank : Disallow : Allow");
w.WriteLine("# lava : 60 : 80,67 : 40,41,55");
w.WriteLine("");
foreach (Blocks bs in givenList) {
if (!bs.IncludeInBlockProperties()) continue;
string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : "
+ GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow);
w.WriteLine(line);
}
}
}
static void InitDefaults() {
for (int i = 0; i < 256; i++) {
Blocks b = new Blocks();
@ -282,113 +399,5 @@ namespace MCGalaxy
BlockList[i] = b;
}
}
public static bool canPlace(Player p, byte block) {
Blocks b = BlockList[block];
LevelPermission perm = p.Rank;
return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm)))
&& (b.disallow == null || !b.disallow.Contains(perm));
}
public static bool canPlace(LevelPermission perm, byte block) {
Blocks b = BlockList[block];
return (perm >= b.lowestRank || (b.allow != null && b.allow.Contains(perm)))
&& (b.disallow == null || !b.disallow.Contains(perm));
}
public static void ResendBlockPermissions(byte block) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (!pl.HasCpeExt(CpeExt.BlockPermissions)) continue;
int count = pl.hasCustomBlocks ? Block.CpeCount : Block.OriginalCount;
if (block < count) {
bool canAffect = Block.canPlace(pl, block);
pl.Send(Packet.BlockPermission(block, canAffect, canAffect));
}
}
}
static void LoadVersion2(string[] lines) {
string[] colon = new string[] { " : " };
foreach (string line in lines) {
if (line == "" || line[0] == '#') continue;
//Name : Lowest : Disallow : Allow
string[] block = line.Split(colon, StringSplitOptions.None);
Blocks newBlock = new Blocks();
if (Block.Byte(block[0]) == Block.Invalid) continue;
newBlock.type = Block.Byte(block[0]);
string[] disallow = null;
if (block[2] != "") disallow = block[2].Split(',');
string[] allow = null;
if (block[3] != "") allow = block[3].Split(',');
try {
newBlock.lowestRank = (LevelPermission)int.Parse(block[1]);
if (disallow != null) {
newBlock.disallow = new List<LevelPermission>();
foreach (string s in disallow) { newBlock.disallow.Add((LevelPermission)int.Parse(s)); }
}
if (allow != null) {
newBlock.allow = new List<LevelPermission>();
foreach (string s in allow) { newBlock.allow.Add((LevelPermission)int.Parse(s)); }
}
} catch {
Server.s.Log("Hit an error on the block " + line);
continue;
}
BlockList[newBlock.type] = newBlock;
}
}
static void LoadVersion1(string[] lines) {
foreach (string line in lines) {
if (line == "" || line[0] == '#') continue;
try {
byte block = Block.Byte(line.Split(' ')[0]);
LevelPermission lowestRank = Level.PermissionFromName(line.Split(' ')[2]);
if (lowestRank != LevelPermission.Null)
BlockList[block].lowestRank = lowestRank;
else
throw new InvalidDataException("Line " + line + " is invalid.");
}
catch { Server.s.Log("Could not find the rank given on " + line + ". Using default"); }
}
}
static readonly object saveLock = new object();
public static void SaveBlocks(IEnumerable<Blocks> givenList) {
try {
lock (saveLock)
SaveBlocksCore(givenList);
} catch (Exception e) {
Server.ErrorLog(e);
}
}
static void SaveBlocksCore(IEnumerable<Blocks> givenList) {
using (StreamWriter w = new StreamWriter("properties/block.properties")) {
w.WriteLine("#Version 2");
w.WriteLine("# This file dictates which ranks may use what blocks");
w.WriteLine("# If someone has royally screwed up the ranks, just delete this file and let the server restart");
w.WriteLine("# Allowed ranks: " + Group.concatList(false, false, true));
w.WriteLine("# Disallow and allow can be left empty, just make sure there's 2 spaces between the colons");
w.WriteLine("# This works entirely on permission values, not names. Do not enter a rank name. Use its permission value");
w.WriteLine("# BlockName : LowestRank : Disallow : Allow");
w.WriteLine("# lava : 60 : 80,67 : 40,41,55");
w.WriteLine("");
foreach (Blocks bs in givenList) {
if (!bs.IncludeInBlockProperties()) continue;
string line = Block.Name(bs.type) + " : " + (int)bs.lowestRank + " : "
+ GrpCommands.getInts(bs.disallow) + " : " + GrpCommands.getInts(bs.allow);
w.WriteLine(line);
}
}
}
}
}

View File

@ -30,28 +30,41 @@ namespace MCGalaxy.Blocks.Physics {
}
static void ExpandDiagonal(Level lvl, ushort x, ushort y, ushort z,
int xOffset, int yOffset, int zOffset) {
if (!Block.FireKill(lvl.GetTile((ushort)(x + xOffset),
(ushort)(y + yOffset), (ushort)(z + zOffset))))
return;
int dx, int dy, int dz) {
byte block = lvl.GetTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
if (block == Block.air) return;
if (xOffset != 0)
lvl.AddUpdate(lvl.PosToInt((ushort)(x + xOffset), y, z), Block.fire);
if (yOffset != 0)
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + yOffset), z), Block.fire);
if (zOffset != 0)
lvl.AddUpdate(lvl.PosToInt(x, y, (ushort)(z + zOffset)), Block.fire);
if (block == Block.custom_block) {
block = lvl.GetExtTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
if (!lvl.CustomBlockProps[block].LavaKills) return;
} else {
if (!Block.Props[block].LavaKills) return;
}
if (dx != 0)
lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), y, z), Block.fire);
if (dy != 0)
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y + dy), z), Block.fire);
if (dz != 0)
lvl.AddUpdate(lvl.PosToInt(x, y, (ushort)(z + dz)), Block.fire);
}
static void ExpandAvanced(Level lvl, int x, int y, int z) {
int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z);
if (index < 0) return;
byte block = lvl.blocks[index];
if (Block.FireKill(block))
lvl.AddUpdate(index, Block.fire);
else if (block == Block.tnt)
byte block = lvl.blocks[index];
if (block == Block.air) return;
if (block == Block.tnt) {
lvl.MakeExplosion((ushort)x, (ushort)y, (ushort)z, -1);
} else if (block == Block.custom_block) {
block = lvl.GetExtTileNoCheck((ushort)x, (ushort)y, (ushort)z);
if (lvl.CustomBlockProps[block].LavaKills)
lvl.AddUpdate(index, Block.fire);
} else if (Block.Props[block].LavaKills) {
lvl.AddUpdate(index, Block.fire);
}
}
public static void Do(Level lvl, ref Check C) {

View File

@ -37,8 +37,9 @@ namespace MCGalaxy.Commands {
if (p != null && !Block.canPlace(p, block)) { Formatter.MessageBlock(p, "change permissions of ", block); return; }
Block.BlockList[block].lowestRank = grp.Permission;
Block.UpdateRankPerms();
Block.SaveBlocks(Block.BlockList);
Block.ResendBlockPermissions(block);
Block.ResendBlockPermissions(block);
// TODO: custom blocks permissions
Chat.MessageAll("&d{0}%S's permission was changed to {1}", Block.Name(block), grp.ColoredName);

View File

@ -52,8 +52,8 @@ namespace MCGalaxy {
}
public byte GetExtTile(ushort x, ushort y, ushort z) {
int index = PosToInt(x, y, z);
if (index < 0 || blocks == null) return Block.Invalid;
if (x >= Width || y >= Height || z >= Length || blocks == null)
return Block.Invalid;
int cx = x >> 4, cy = y >> 4, cz = z >> 4;
byte[] chunk = CustomBlocks[(cy * ChunksZ + cz) * ChunksX + cx];
@ -241,8 +241,8 @@ namespace MCGalaxy {
}
public bool CheckAffectPermissions(Player p, ushort x, ushort y, ushort z,
byte b, byte block, byte extBlock = 0) {
if (!Block.AllowBreak(b) && !Block.canPlace(p, b) && !Block.BuildIn(b)) return false;
byte old, byte block, byte extBlock = 0) {
if (!p.group.CanModify[old] && !Block.AllowBreak(old) && !Block.BuildIn(old)) return false;
if (p.PlayingTntWars && !CheckTNTWarsChange(p, x, y, z, ref block)) return false;
bool inZone = false;

View File

@ -51,6 +51,7 @@ namespace MCGalaxy {
public string fileName;
public PlayerList playerList;
public string MOTD = "";
public bool[] CanModify = new bool[256];
/// <summary> Create a new group object </summary>
public Group() {
@ -90,6 +91,12 @@ namespace MCGalaxy {
commands = _commands;
}
/// <summary> Fill the blocks that this group can use </summary>
public void FillBlocks() {
for (int i = 0; i < CanModify.Length; i++)
CanModify[i] = Block.canPlace(Permission, (byte)i);
}
public bool CanExecute(string cmdName) {
return commands.Contains(Command.all.Find(cmdName));
}

View File

@ -69,8 +69,9 @@ namespace MCGalaxy {
Save(allowedCommands);
}
foreach (Group grp in Group.GroupList)
foreach (Group grp in Group.GroupList) {
grp.fillCommands();
}
}
static void ReadVersion2(string[] lines, List<string> cmdNames) {