mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-25 14:17:29 -04:00
First part of per-level block definitions.
This commit is contained in:
parent
0d961a14b0
commit
b40f352c12
@ -1,7 +1,7 @@
|
||||
/*
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
@ -20,17 +20,11 @@ using System.Collections.Generic;
|
||||
|
||||
namespace MCGalaxy.Commands {
|
||||
|
||||
public sealed class CmdGlobalBlock : Command {
|
||||
|
||||
public override string name { get { return "globalblock"; } }
|
||||
public override string shortcut { get { return "gb"; } }
|
||||
public override string type { get { return CommandTypes.Building; } }
|
||||
public override bool museumUsable { get { return true; } }
|
||||
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
|
||||
public CmdGlobalBlock() { }
|
||||
static char[] trimChars = {' '};
|
||||
public abstract class CustomBlockCommand : Command {
|
||||
|
||||
public override void Use(Player p, string message) {
|
||||
static char[] trimChars = {' '};
|
||||
|
||||
protected void Execute(Player p, string message, bool global) {
|
||||
string[] parts = message.Split(trimChars, 4);
|
||||
for (int i = 0; i < Math.Min(parts.Length, 3); i++)
|
||||
parts[i] = parts[i].ToLower();
|
||||
@ -46,70 +40,66 @@ namespace MCGalaxy.Commands {
|
||||
switch (parts[0]) {
|
||||
case "add":
|
||||
case "create":
|
||||
AddHandler(p, parts); break;
|
||||
AddHandler(p, parts, global); break;
|
||||
case "delete":
|
||||
case "remove":
|
||||
RemoveHandler(p, parts); break;
|
||||
RemoveHandler(p, parts, global); break;
|
||||
case "list":
|
||||
case "ids":
|
||||
ListHandler(p, parts); break;
|
||||
ListHandler(p, parts, global); break;
|
||||
case "abort":
|
||||
Player.SendMessage(p, "Aborted the custom block creation process.");
|
||||
SetBD(p, null); break;
|
||||
case "edit":
|
||||
EditHandler(p, parts); break;
|
||||
EditHandler(p, parts, global); break;
|
||||
default:
|
||||
if (GetBD(p) != null)
|
||||
DefineBlockStep(p, message);
|
||||
DefineBlockStep(p, message, global);
|
||||
else
|
||||
Help(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int targetId;
|
||||
void AddHandler(Player p, string[] parts) {
|
||||
void AddHandler(Player p, string[] parts, bool global) {
|
||||
string cmd = global ? "/gb" : "/lb";
|
||||
int targetId;
|
||||
if (parts.Length >= 2 ) {
|
||||
string id = parts[1];
|
||||
if (!CheckBlockId(p, id, out targetId)) return;
|
||||
BlockDefinition def = BlockDefinition.GlobalDefinitions[targetId];
|
||||
BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs;
|
||||
BlockDefinition def = defs[targetId];
|
||||
|
||||
if (def != null) {
|
||||
Player.SendMessage(p, "There is already a custom block with the id " + id +
|
||||
", you must either use a different id or use \"/gb remove " + id + "\"");
|
||||
", you must either use a different id or use \"" + cmd + " remove " + id + "\"");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
targetId = GetFreeId();
|
||||
targetId = GetFreeId(global, p == null ? null : p.level);
|
||||
if (targetId == Block.Zero) {
|
||||
Player.SendMessage(p, "There are no custom block ids left, " +
|
||||
"you must /gb remove a custom block first.");
|
||||
"you must " + cmd +" remove a custom block first.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetBD(p, new BlockDefinition());
|
||||
GetBD(p).BlockID = (byte)targetId;
|
||||
Player.SendMessage(p, "Type '/gb abort' at anytime to abort the creation process.");
|
||||
Player.SendMessage(p, "Type '/gb revert' to go back a step in the creation process.");
|
||||
Player.SendMessage(p, "Use '/gb <arg>' to enter arguments for the creation process.");
|
||||
SetTargetId(p, targetId);
|
||||
Player.SendMessage(p, "Type '" + cmd + " abort' at anytime to abort the creation process.");
|
||||
Player.SendMessage(p, "Type '" + cmd + " revert' to go back a step in the creation process.");
|
||||
Player.SendMessage(p, "Use '" + cmd + " <arg>' to enter arguments for the creation process.");
|
||||
Player.SendMessage(p, "%f----------------------------------------------------------");
|
||||
SetStep(p, 2);
|
||||
SendStepHelp(p, GetStep(p));
|
||||
}
|
||||
|
||||
byte GetFreeId() {
|
||||
for (int i = 70; i < 255; i++) {
|
||||
if (BlockDefinition.GlobalDefinitions[i] == null)
|
||||
return (byte)i;
|
||||
}
|
||||
return Block.Zero;
|
||||
}
|
||||
|
||||
void ListHandler(Player p, string[] parts) {
|
||||
void ListHandler(Player p, string[] parts, bool global) {
|
||||
int offset = 0, index = 0, count = 0;
|
||||
if (parts.Length > 1) int.TryParse(parts[1], out offset);
|
||||
BlockDefinition[] defs = BlockDefinition.GlobalDefinitions;
|
||||
BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs;
|
||||
string cmd = global ? "/gb" : "/lb";
|
||||
|
||||
for( int i = 1; i < 256; i++ ) {
|
||||
BlockDefinition def = defs[i];
|
||||
@ -121,8 +111,8 @@ namespace MCGalaxy.Commands {
|
||||
Player.SendMessage(p, String.Format(format, def.BlockID, def.Name));
|
||||
|
||||
if (count >= 8) {
|
||||
const string helpFormat = "To see the next set of custom blocks, type %T/gb list {0}";
|
||||
Player.SendMessage(p, String.Format(helpFormat, offset + 8));
|
||||
const string helpFormat = "To see the next set of custom blocks, type %T{1} list {0}";
|
||||
Player.SendMessage(p, String.Format(helpFormat, offset + 8, cmd));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -130,28 +120,28 @@ namespace MCGalaxy.Commands {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveHandler(Player p, string[] parts) {
|
||||
void RemoveHandler(Player p, string[] parts, bool global) {
|
||||
if (parts.Length <= 1) { Help(p); return; }
|
||||
int blockID;
|
||||
if (!CheckBlockId(p, parts[1], out blockID)) return;
|
||||
|
||||
BlockDefinition def = BlockDefinition.GlobalDefinitions[blockID];
|
||||
if (def == null) {
|
||||
Player.SendMessage(p, "There is no globally defined custom block with that block id.");
|
||||
Player.SendMessage(p, "Use \"%T/gb list\" %Sto see a list of global custom blocks.");
|
||||
return;
|
||||
}
|
||||
BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs;
|
||||
BlockDefinition def = defs[blockID];
|
||||
if (def == null) { MessageNoBlock(p, global); return; }
|
||||
|
||||
BlockDefinition.RemoveGlobal(def);
|
||||
BlockDefinition.SaveGlobal();
|
||||
BlockDefinition.Remove(def, defs, p == null ? null : p.level);
|
||||
BlockDefinition globalDef = BlockDefinition.GlobalDefs[blockID];
|
||||
if (!global && globalDef != null) {
|
||||
BlockDefinition.Add(globalDef, defs, p == null ? null : p.level);
|
||||
}
|
||||
}
|
||||
|
||||
void DefineBlockStep(Player p, string value) {
|
||||
void DefineBlockStep(Player p, string value, bool global) {
|
||||
string opt = value.ToLower();
|
||||
int step = GetStep(p);
|
||||
if (opt == "revert" && step > 2) {
|
||||
step--;
|
||||
SendStepHelp(p, step);
|
||||
SendStepHelp(p, step);
|
||||
SetStep(p, step); return;
|
||||
}
|
||||
BlockDefinition bd = GetBD(p);
|
||||
@ -223,19 +213,22 @@ namespace MCGalaxy.Commands {
|
||||
SendStepHelp(p, step); return;
|
||||
}
|
||||
bd.FallBack = Block.Byte(value);
|
||||
BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs;
|
||||
BlockDefinition def = defs[bd.BlockID];
|
||||
|
||||
// in case the list is modified before we finish the command.
|
||||
if (BlockDefinition.GlobalDefinitions[bd.BlockID] != null) {
|
||||
bd.BlockID = GetFreeId();
|
||||
if (def != null) {
|
||||
bd.BlockID = GetFreeId(global, p == null ? null : p.level);
|
||||
if (bd.BlockID == Block.Zero) {
|
||||
string cmd = global ? "/gb" : "/lb";
|
||||
Player.SendMessage(p, "There are no custom block ids left, " +
|
||||
"you must /gb remove a custom block first.");
|
||||
"you must " + cmd + " remove a custom block first.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Player.SendMessage(p, "Created a new custom block " + bd.Name + "(" + bd.BlockID + ")");
|
||||
BlockDefinition.AddGlobal(bd);
|
||||
BlockDefinition.Add(bd, defs, p == null ? null : p.level);
|
||||
SetBD(p, null);
|
||||
SetStep(p, 0);
|
||||
return;
|
||||
@ -244,23 +237,7 @@ namespace MCGalaxy.Commands {
|
||||
SetStep(p, step);
|
||||
}
|
||||
|
||||
bool EditByte(Player p, string arg, string propName, ref byte target) {
|
||||
return EditByte(p, arg, propName, ref target, -1, 0, 0, 255);
|
||||
}
|
||||
|
||||
bool EditByte(Player p, string value, string propName, ref byte target,
|
||||
int step, int offset, byte min, byte max) {
|
||||
int temp = 0;
|
||||
if (!int.TryParse(value, out temp) || temp < min || temp > max) {
|
||||
Player.SendMessage(p, propName + " must be an integer between " + min + " and " + max + ".");
|
||||
if (step != -1) SendEditHelp(p, step, offset);
|
||||
return false;
|
||||
}
|
||||
target = (byte)temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditHandler(Player p, string[] parts) {
|
||||
void EditHandler(Player p, string[] parts, bool global) {
|
||||
if (parts.Length <= 3) {
|
||||
if(parts.Length == 1)
|
||||
Player.SendMessage(p, "Valid properties: name, collide, speed, toptex, sidetex, " +
|
||||
@ -271,14 +248,11 @@ namespace MCGalaxy.Commands {
|
||||
return;
|
||||
}
|
||||
int blockId;
|
||||
if (!CheckBlockId(p, parts[1], out blockId));
|
||||
if (!CheckBlockId(p, parts[1], out blockId)) return;
|
||||
BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs;
|
||||
BlockDefinition def = defs[blockId];
|
||||
if (def == null) { MessageNoBlock(p, global); return; }
|
||||
|
||||
BlockDefinition def = BlockDefinition.GlobalDefinitions[blockId];
|
||||
if (def == null) {
|
||||
Player.SendMessage(p, "There is no globally defined custom block with that block id.");
|
||||
Player.SendMessage(p, "Use \"%T/gb list\" %Sto see a list of global custom blocks.");
|
||||
return;
|
||||
}
|
||||
string value = parts[3];
|
||||
float fTemp;
|
||||
byte tempX, tempY, tempZ;
|
||||
@ -373,14 +347,47 @@ namespace MCGalaxy.Commands {
|
||||
def.FallBack = tempX; break;
|
||||
}
|
||||
|
||||
BlockDefinition.AddGlobal(def);
|
||||
BlockDefinition.Add(def, defs, p == null ? null : p.level);
|
||||
foreach (Player pl in Player.players) {
|
||||
if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) continue;
|
||||
if (pl.level == null || !pl.level.HasCustomBlocks) continue;
|
||||
if (!global && p.level != pl.level) continue;
|
||||
|
||||
Command.all.Find("reveal").Use(p, pl.name);
|
||||
}
|
||||
}
|
||||
|
||||
static byte GetFreeId(bool global, Level lvl) {
|
||||
BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : lvl.CustomBlockDefs;
|
||||
for (int i = 70; i < 255; i++) {
|
||||
if (defs[i] == null) return (byte)i;
|
||||
}
|
||||
return Block.Zero;
|
||||
}
|
||||
|
||||
static void MessageNoBlock(Player p, bool global) {
|
||||
string scope = global ? "global" : "level";
|
||||
string cmd = global ? "/gb" : "/lb";
|
||||
Player.SendMessage(p, "There is no " + scope + " custom block with that block id.");
|
||||
Player.SendMessage(p, "Type \"%T" + cmd +" list\" %Sto see a list of " + scope + " custom blocks.");
|
||||
}
|
||||
|
||||
static bool EditByte(Player p, string arg, string propName, ref byte target) {
|
||||
return EditByte(p, arg, propName, ref target, -1, 0, 0, 255);
|
||||
}
|
||||
|
||||
static bool EditByte(Player p, string value, string propName, ref byte target,
|
||||
int step, int offset, byte min, byte max) {
|
||||
int temp = 0;
|
||||
if (!int.TryParse(value, out temp) || temp < min || temp > max) {
|
||||
Player.SendMessage(p, propName + " must be an integer between " + min + " and " + max + ".");
|
||||
if (step != -1) SendEditHelp(p, step, offset);
|
||||
return false;
|
||||
}
|
||||
target = (byte)temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseCoords(string parts, out byte x, out byte y, out byte z) {
|
||||
x = 0; y = 0; z = 0;
|
||||
string[] coords = parts.Split(' ');
|
||||
@ -459,28 +466,69 @@ namespace MCGalaxy.Commands {
|
||||
|
||||
static BlockDefinition consoleBD;
|
||||
static int consoleStep = 0;
|
||||
static int consoleTargetId;
|
||||
|
||||
static BlockDefinition GetBD(Player p) { return p == null ? consoleBD : p.gbBlock; }
|
||||
static BlockDefinition GetBD(Player p) { return p == null ? consoleBD : p.bdBlock; }
|
||||
|
||||
static void SetBD(Player p, BlockDefinition bd) {
|
||||
if (p == null) consoleBD = bd;
|
||||
else p.gbBlock = bd;
|
||||
else p.bdBlock = bd;
|
||||
}
|
||||
|
||||
static int GetStep(Player p) { return p == null ? consoleStep : p.gbStep; }
|
||||
|
||||
static void SetTargetId(Player p, int targetId) {
|
||||
if (p == null) consoleTargetId = targetId;
|
||||
else p.bdTargetId = targetId;
|
||||
}
|
||||
|
||||
static int GetStep(Player p) { return p == null ? consoleStep : p.bdStep; }
|
||||
|
||||
static void SetStep(Player p, int step) {
|
||||
if (p == null) consoleStep = step;
|
||||
else p.gbStep = step;
|
||||
else p.bdStep = step;
|
||||
}
|
||||
|
||||
public override void Help(Player p) {
|
||||
Player.SendMessage(p, "%T/globalblock <add/remove/list/edit>");
|
||||
Player.SendMessage(p, "%H /gb add [id] - begins the creation a new custom block.");
|
||||
Player.SendMessage(p, "%H /gb remove id - removes the custom block with the given id.");
|
||||
Player.SendMessage(p, "%H /gb list [offset] - lists all custom blocks.");
|
||||
Player.SendMessage(p, "%H /gb edit id property value - edits the given property of the custom block with the given id.");
|
||||
Player.SendMessage(p, "%HTo see the list of editable properties, type /gb edit.");
|
||||
protected static void Help(Player p, bool global) {
|
||||
string fullCmd = global ? "/globalblock" : "/levelblock";
|
||||
string cmd = global ? "/gb" : "/lb";
|
||||
|
||||
Player.SendMessage(p, "%T" + fullCmd + " <add/remove/list/edit>");
|
||||
Player.SendMessage(p, "%H " + cmd + " add [id] - begins the creation a new custom block.");
|
||||
Player.SendMessage(p, "%H " + cmd + " remove id - removes the custom block with the given id.");
|
||||
Player.SendMessage(p, "%H " + cmd + " list [offset] - lists all custom blocks.");
|
||||
Player.SendMessage(p, "%H " + cmd + " edit id property value - edits the given property of the custom block with the given id.");
|
||||
Player.SendMessage(p, "%HTo see the list of editable properties, type " + cmd + " edit.");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CmdGlobalBlock : CustomBlockCommand {
|
||||
|
||||
public override string name { get { return "globalblock"; } }
|
||||
public override string shortcut { get { return "gb"; } }
|
||||
public override string type { get { return CommandTypes.Building; } }
|
||||
public override bool museumUsable { get { return true; } }
|
||||
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
|
||||
public CmdGlobalBlock() { }
|
||||
|
||||
public override void Use(Player p, string message) {
|
||||
Execute(p, message, true);
|
||||
}
|
||||
|
||||
public override void Help(Player p) { Help(p, true); }
|
||||
}
|
||||
|
||||
public sealed class CmdLevelBlock : CustomBlockCommand {
|
||||
|
||||
public override string name { get { return "levelblock"; } }
|
||||
public override string shortcut { get { return "lb"; } }
|
||||
public override string type { get { return CommandTypes.Building; } }
|
||||
public override bool museumUsable { get { return true; } }
|
||||
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
|
||||
public CmdLevelBlock() { }
|
||||
|
||||
public override void Use(Player p, string message) {
|
||||
Execute(p, message, false);
|
||||
}
|
||||
|
||||
public override void Help(Player p) { Help(p, false); }
|
||||
}
|
||||
}
|
@ -92,7 +92,7 @@ namespace MCGalaxy.Commands {
|
||||
extType = 0;
|
||||
if (type == Block.Zero) {
|
||||
// try treat as a block definition id.
|
||||
type = BlockDefinition.GetBlock(msg);
|
||||
type = BlockDefinition.GetBlock(msg, p);
|
||||
if (type == Block.Zero) {
|
||||
Player.SendMessage(p, "There is no block \"" + msg + "\".");
|
||||
return Block.Zero;
|
||||
|
@ -36,26 +36,20 @@ namespace MCGalaxy {
|
||||
public bool FullBright;
|
||||
public byte Shape;
|
||||
public byte BlockDraw;
|
||||
public byte FogDensity,FogR, FogG, FogB;
|
||||
public byte FallBack;
|
||||
public byte FogDensity,FogR, FogG, FogB;
|
||||
public byte FallBack;
|
||||
// BlockDefinitionsExt fields
|
||||
public byte MinX, MinY, MinZ;
|
||||
public byte MaxX, MaxY, MaxZ;
|
||||
public const string GlobalPath = "blockdefs/global.json", GlobalBackupPath = "blockdefs/global.json.bak";
|
||||
|
||||
public static BlockDefinition[] GlobalDefinitions = new BlockDefinition[256];
|
||||
public static BlockDefinition[] GlobalDefs;
|
||||
|
||||
public static void LoadGlobal() {
|
||||
try {
|
||||
if (File.Exists(GlobalPath)) {
|
||||
string json = File.ReadAllText(GlobalPath);
|
||||
GlobalDefinitions = JsonConvert.DeserializeObject<BlockDefinition[]>(json);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Server.ErrorLog(ex);
|
||||
GlobalDefinitions = new BlockDefinition[256];
|
||||
}
|
||||
|
||||
GlobalDefs = Load(true, null);
|
||||
GlobalDefs[0] = new BlockDefinition();
|
||||
GlobalDefs[0].Name = "Air fallback";
|
||||
|
||||
try {
|
||||
if (File.Exists(GlobalBackupPath))
|
||||
File.Delete(GlobalBackupPath);
|
||||
@ -63,25 +57,52 @@ namespace MCGalaxy {
|
||||
} catch (Exception ex) {
|
||||
Server.ErrorLog(ex);
|
||||
}
|
||||
Save(true, null);
|
||||
}
|
||||
|
||||
static BlockDefinition[] Load(bool global, Level lvl) {
|
||||
BlockDefinition[] defs = new BlockDefinition[256];
|
||||
string path = global ? GlobalPath : "blockdefs/" + lvl.name;
|
||||
try {
|
||||
if (File.Exists(GlobalPath)) {
|
||||
string json = File.ReadAllText(GlobalPath);
|
||||
defs = JsonConvert.DeserializeObject<BlockDefinition[]>(json);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Server.ErrorLog(ex);
|
||||
defs = new BlockDefinition[256];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (GlobalDefinitions[i] != null && GlobalDefinitions[i].Name == null)
|
||||
GlobalDefinitions[i] = null;
|
||||
}
|
||||
GlobalDefinitions[0] = new BlockDefinition();
|
||||
GlobalDefinitions[0].Name = "Air fallback";
|
||||
SaveGlobal();
|
||||
if (defs[i] != null && defs[i].Name == null)
|
||||
defs[i] = null;
|
||||
}
|
||||
return defs;
|
||||
}
|
||||
|
||||
public static void SaveGlobal() {
|
||||
string json = JsonConvert.SerializeObject(GlobalDefinitions);
|
||||
File.WriteAllText(GlobalPath, json);
|
||||
static void Save(bool global, Level lvl) {
|
||||
BlockDefinition[] defs = global ? GlobalDefs : lvl.CustomBlockDefs;
|
||||
string json = JsonConvert.SerializeObject(defs);
|
||||
string path = global ? GlobalPath : "blockdefs/" + lvl.name;
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
|
||||
public static void AddGlobal(BlockDefinition def) {
|
||||
GlobalDefinitions[def.BlockID] = def;
|
||||
public static void Add(BlockDefinition def, BlockDefinition[] defs, Level level) {
|
||||
byte id = def.BlockID;
|
||||
bool global = defs == GlobalDefs;
|
||||
if (global) {
|
||||
foreach (Level lvl in Server.levels) {
|
||||
if (lvl.CustomBlockDefs[id] == null)
|
||||
lvl.CustomBlockDefs[id] = def;
|
||||
}
|
||||
}
|
||||
defs[id] = def;
|
||||
|
||||
foreach (Player pl in Player.players) {
|
||||
if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) continue;
|
||||
if (!global && pl.level != level) continue;
|
||||
if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) continue;
|
||||
if (global && pl.level.CustomBlockDefs[id] != GlobalDefs[id]) continue;
|
||||
|
||||
if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt) && def.Shape != 0)
|
||||
SendDefineBlockExt(pl, def);
|
||||
else
|
||||
@ -90,23 +111,33 @@ namespace MCGalaxy {
|
||||
if (pl.HasCpeExt(CpeExt.BlockPermissions))
|
||||
pl.SendSetBlockPermission(def.BlockID, pl.level.Buildable, pl.level.Deletable);
|
||||
}
|
||||
SaveGlobal();
|
||||
Save(global, level);
|
||||
}
|
||||
|
||||
public static void RemoveGlobal(BlockDefinition def) {
|
||||
GlobalDefinitions[def.BlockID] = null;
|
||||
foreach (Player p in Player.players) {
|
||||
if (p.HasCpeExt(CpeExt.BlockDefinitions))
|
||||
p.SendRaw(Opcode.CpeRemoveBlockDefinition, def.BlockID);
|
||||
public static void Remove(BlockDefinition def, BlockDefinition[] defs, Level level) {
|
||||
byte id = def.BlockID;
|
||||
bool global = defs == GlobalDefs;
|
||||
if (global) {
|
||||
foreach (Level lvl in Server.levels) {
|
||||
if (lvl.CustomBlockDefs[id] == GlobalDefs[id])
|
||||
lvl.CustomBlockDefs[id] = null;
|
||||
}
|
||||
}
|
||||
SaveGlobal();
|
||||
defs[id] = null;
|
||||
|
||||
foreach (Player pl in Player.players) {
|
||||
if (!global && pl.level != level) continue;
|
||||
if (pl.HasCpeExt(CpeExt.BlockDefinitions))
|
||||
pl.SendRaw(Opcode.CpeRemoveBlockDefinition, id);
|
||||
}
|
||||
Save(global, level);
|
||||
}
|
||||
|
||||
public static void SendAll(Player pl) {
|
||||
if (!pl.HasCpeExt(CpeExt.BlockDefinitions)) return;
|
||||
for (int i = 1; i < GlobalDefinitions.Length; i++) {
|
||||
BlockDefinition def = GlobalDefinitions[i];
|
||||
if (def == null) continue;
|
||||
internal static void SendLevelCustomBlocks(Player pl) {
|
||||
BlockDefinition[] defs = pl.level.CustomBlockDefs;
|
||||
for (int i = 1; i < defs.Length; i++) {
|
||||
BlockDefinition def = defs[i];
|
||||
if (def == null) continue;
|
||||
if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt) && def.Shape != 0)
|
||||
SendDefineBlockExt(pl, def);
|
||||
else
|
||||
@ -117,9 +148,10 @@ namespace MCGalaxy {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte GetBlock(string msg) {
|
||||
for (int i = 1; i < 255; i++) {
|
||||
BlockDefinition def = GlobalDefinitions[i];
|
||||
public static byte GetBlock(string msg, Player p) {
|
||||
BlockDefinition[] defs = p.level.CustomBlockDefs;
|
||||
for (int i = 1; i < 255; i++) {
|
||||
BlockDefinition def = defs[i];
|
||||
if (def == null) continue;
|
||||
|
||||
if (def.Name.Replace(" ", "").Equals(msg, StringComparison.OrdinalIgnoreCase))
|
||||
@ -127,16 +159,11 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
byte type;
|
||||
if (!byte.TryParse(msg, out type) || BlockDefinition.GlobalDefinitions[type] == null)
|
||||
if (!byte.TryParse(msg, out type) || defs[type] == null)
|
||||
return Block.Zero;
|
||||
return type;
|
||||
}
|
||||
|
||||
public static byte Fallback(byte tile) {
|
||||
BlockDefinition def = GlobalDefinitions[tile];
|
||||
return def == null ? Block.air : def.FallBack;
|
||||
}
|
||||
|
||||
static void SendDefineBlock(Player p, BlockDefinition def) {
|
||||
byte[] buffer = new byte[80];
|
||||
buffer[0] = Opcode.CpeDefineBlock;
|
||||
|
@ -68,6 +68,23 @@ namespace MCGalaxy {
|
||||
chunk[(y & 0x0F) << 8 | (z & 0x0F) << 4 | (x & 0x0F)];
|
||||
}
|
||||
|
||||
public byte GetFallbackExtTile(ushort x, ushort y, ushort z) {
|
||||
byte tile = GetExtTile(x, y, z);
|
||||
BlockDefinition def = CustomBlockDefs[tile];
|
||||
return def == null ? Block.air : def.FallBack;
|
||||
}
|
||||
|
||||
public byte GetFallbackExtTile(int index) {
|
||||
byte tile = GetExtTile(index);
|
||||
BlockDefinition def = CustomBlockDefs[tile];
|
||||
return def == null ? Block.air : def.FallBack;
|
||||
}
|
||||
|
||||
public byte GetFallback(byte extType) {
|
||||
BlockDefinition def = CustomBlockDefs[extType];
|
||||
return def == null ? Block.air : def.FallBack;
|
||||
}
|
||||
|
||||
public void SetTile(int b, byte type) {
|
||||
if (blocks == null || b < 0 || b >= blocks.Length) return;
|
||||
blocks[b] = type;
|
||||
|
@ -152,6 +152,9 @@ namespace MCGalaxy
|
||||
|
||||
/// <summary> The block which will be displayed on the edge of the map. </summary>
|
||||
public byte EdgeBlock = Block.blackrock;
|
||||
|
||||
public BlockDefinition[] CustomBlockDefs;
|
||||
|
||||
public ushort jailx, jaily, jailz;
|
||||
public int lastCheck;
|
||||
public int lastUpdate;
|
||||
@ -216,6 +219,9 @@ namespace MCGalaxy
|
||||
if (Length < 16)
|
||||
Length = 16;
|
||||
|
||||
CustomBlockDefs = new BlockDefinition[256];
|
||||
for (int i = 0; i < CustomBlockDefs.Length; i++)
|
||||
CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i];
|
||||
name = n;
|
||||
EdgeLevel = (short)(y / 2);
|
||||
CloudsHeight = (short)(y + 2);
|
||||
|
@ -98,7 +98,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Commands\Building\CmdAbort.cs" />
|
||||
<Compile Include="Commands\building\CmdGlobalBlock.cs" />
|
||||
<Compile Include="Commands\Building\CmdBind.cs" />
|
||||
<Compile Include="Commands\Building\CmdCenter.cs" />
|
||||
<Compile Include="Commands\Building\CmdClick.cs" />
|
||||
@ -134,6 +133,7 @@
|
||||
<Compile Include="Commands\Building\CmdTree.cs" />
|
||||
<Compile Include="Commands\Building\CmdUndo.cs" />
|
||||
<Compile Include="Commands\Building\CmdWrite.cs" />
|
||||
<Compile Include="Commands\building\CustomBlockCommand.cs" />
|
||||
<Compile Include="Commands\building\DrawCmd.cs" />
|
||||
<Compile Include="Commands\building\ReplaceCmd.cs" />
|
||||
<Compile Include="Commands\Chat\CmdAdminChat.cs" />
|
||||
|
@ -74,7 +74,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
}
|
||||
|
||||
public bool hasCpe = false, hasCustomBlocks = false, hasTextColors, finishedLogin = false;
|
||||
public bool hasCpe = false, hasCustomBlocks = false, hasTextColors, finishedCpeLogin = false;
|
||||
public string appName;
|
||||
public int extensionCount;
|
||||
public List<string> extensions = new List<string>();
|
||||
@ -90,21 +90,13 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
void HandleExtEntry( byte[] message ) {
|
||||
AddExtension(enc.GetString(message, 0, 64).Trim(), NTHO_Int(message, 64));
|
||||
AddExtension(enc.GetString(message, 0, 64).Trim(), NetUtils.ReadI32(message, 64));
|
||||
extensionCount--;
|
||||
if (extensionCount <= 0 && !finishedLogin) {
|
||||
if (HasCpeExt(CpeExt.BlockDefinitions) || HasCpeExt(CpeExt.BlockDefinitionsExt))
|
||||
BlockDefinition.SendAll(this);
|
||||
if (extensionCount <= 0 && !finishedCpeLogin) {
|
||||
CompleteLoginProcess();
|
||||
finishedLogin = true;
|
||||
finishedCpeLogin = true;
|
||||
}
|
||||
}
|
||||
public static int NTHO_Int(byte[] x, int offset)
|
||||
{
|
||||
byte[] y = new byte[4];
|
||||
Buffer.BlockCopy(x, offset, y, 0, 4); Array.Reverse(y);
|
||||
return BitConverter.ToInt32(y, 0);
|
||||
}
|
||||
|
||||
void HandleCustomBlockSupportLevel( byte[] message ) {
|
||||
customBlockSupportLevel = message[0];
|
||||
@ -317,7 +309,7 @@ namespace MCGalaxy {
|
||||
if (hasBlockDefinitions)
|
||||
buffer[i + 4] = level.GetExtTile(i);
|
||||
else
|
||||
buffer[i + 4] = BlockDefinition.Fallback(level.GetExtTile(i));
|
||||
buffer[i + 4] = level.GetFallbackExtTile(i);
|
||||
} else {
|
||||
buffer[i + 4] = Block.Convert(block);
|
||||
}
|
||||
@ -329,8 +321,7 @@ namespace MCGalaxy {
|
||||
if (hasBlockDefinitions)
|
||||
buffer[i + 4] = Block.ConvertCPE(level.GetExtTile(i));
|
||||
else
|
||||
buffer[i + 4] = Block.ConvertCPE(
|
||||
BlockDefinition.Fallback(level.GetExtTile(i)));
|
||||
buffer[i + 4] = Block.ConvertCPE(level.GetFallbackExtTile(i));
|
||||
} else {
|
||||
buffer[i + 4] = Block.Convert(Block.ConvertCPE(level.blocks[i]));
|
||||
}
|
||||
@ -370,6 +361,8 @@ namespace MCGalaxy {
|
||||
SendCurrentEnvColors();
|
||||
if (HasCpeExt(CpeExt.EnvMapAppearance) || HasCpeExt(CpeExt.EnvMapAppearance, 2))
|
||||
SendCurrentMapAppearance();
|
||||
if (HasCpeExt(CpeExt.BlockDefinitions))
|
||||
BlockDefinition.SendLevelCustomBlocks(this);
|
||||
if ( OnSendMap != null )
|
||||
OnSendMap(this, buffer);
|
||||
if (!level.guns)
|
||||
@ -452,7 +445,7 @@ namespace MCGalaxy {
|
||||
if (HasCpeExt(CpeExt.BlockDefinitions))
|
||||
buffer[7] = level.GetExtTile(x, y, z);
|
||||
else
|
||||
buffer[7] = BlockDefinition.Fallback(level.GetExtTile(x, y, z));
|
||||
buffer[7] = level.GetFallbackExtTile(x, y, z);
|
||||
} else if (hasCustomBlocks) {
|
||||
buffer[7] = Block.Convert(type);
|
||||
} else {
|
||||
@ -476,7 +469,7 @@ namespace MCGalaxy {
|
||||
if (HasCpeExt(CpeExt.BlockDefinitions))
|
||||
buffer[7] = extType;
|
||||
else
|
||||
buffer[7] = BlockDefinition.Fallback(extType);
|
||||
buffer[7] = level.GetFallback(extType);
|
||||
} else if (hasCustomBlocks) {
|
||||
buffer[7] = Block.Convert(type);
|
||||
} else {
|
||||
|
@ -234,7 +234,7 @@ namespace MCGalaxy
|
||||
|
||||
if (!HasCpeExt(CpeExt.BlockDefinitions)) return;
|
||||
for (int i = count; i < 256; i++) {
|
||||
if (BlockDefinition.GlobalDefinitions[i] == null) continue;
|
||||
if (level.CustomBlockDefs[i] == null) continue;
|
||||
SendSetBlockPermission((byte)i, level.Buildable, level.Deletable);
|
||||
}
|
||||
}
|
||||
|
@ -230,8 +230,9 @@ namespace MCGalaxy {
|
||||
public int[] centerend = new int[3] { 0, 0, 0 };
|
||||
|
||||
// GlobalBlock
|
||||
internal int gbStep = 0;
|
||||
internal BlockDefinition gbBlock;
|
||||
internal int bdStep = 0;
|
||||
internal int bdTargetId = 0;
|
||||
internal BlockDefinition bdBlock;
|
||||
|
||||
public string model = "humanoid";
|
||||
public bool spawned = false;
|
||||
@ -1055,8 +1056,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
if (type >= Block.CpeCount) {
|
||||
if (!HasCpeExt(CpeExt.BlockDefinitions)
|
||||
|| BlockDefinition.GlobalDefinitions[type] == null) {
|
||||
if (!HasCpeExt(CpeExt.BlockDefinitions) || level.CustomBlockDefs[type] == null) {
|
||||
SendMessage("Invalid block type: " + type); return;
|
||||
}
|
||||
extType = type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user