mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 12:42:22 -04:00
This commit is contained in:
parent
2b5f0406af
commit
4d15eed405
@ -196,7 +196,7 @@ namespace MCGalaxy {
|
||||
case 209:
|
||||
case 210:
|
||||
case 213:
|
||||
case Door_Air2_air:
|
||||
case 214:
|
||||
case 215:
|
||||
case 216:
|
||||
case Door_Air_air:
|
||||
|
@ -278,7 +278,7 @@ namespace MCGalaxy
|
||||
public const byte Door_Green_air = 211;
|
||||
public const byte Door_TNT_air = 212;
|
||||
//public const byte Door_Slab_air = 213; // unused in core
|
||||
public const byte Door_Air2_air = 214;
|
||||
//public const byte Door_AirActivatable_air = 214;
|
||||
//public const byte Door_Water_air = 215; // unused in core
|
||||
//public const byte Door_Lava_air = 216; // unused in core
|
||||
public const byte Door_Air_air = 217;
|
||||
|
@ -216,9 +216,17 @@ namespace MCGalaxy.Blocks {
|
||||
}
|
||||
|
||||
public static class CollideType {
|
||||
public const byte WalkThrough = 0; // i.e. gas or sprite
|
||||
public const byte SwimThrough = 1; // i.e. liquid
|
||||
public const byte Solid = 2; // i.e. solid
|
||||
public const byte WalkThrough = 0; // Gas (usually also used by sprite)
|
||||
public const byte SwimThrough = 1; // Liquid
|
||||
public const byte Solid = 2; // Solid
|
||||
public const byte Ice = 3; // Solid and partially slidable on.
|
||||
public const byte SlipperyIce = 4; // Solid and fully slidable on.
|
||||
public const byte LiquidWater = 5; // Water style 'swimming'/'bobbing'
|
||||
public const byte LiquidLava = 6; // Lava style 'swimming'/'bobbing'
|
||||
|
||||
public static bool IsSolid(byte collide) {
|
||||
return collide >= Solid && collide <= SlipperyIce;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SoundType : byte {
|
||||
|
@ -297,9 +297,9 @@ namespace MCGalaxy.Commands.CPE {
|
||||
static void EditHandler(Player p, string[] parts, bool global, string cmd) {
|
||||
if (parts.Length <= 3) {
|
||||
if (parts.Length == 1) {
|
||||
Player.Message(p, "Valid properties: name, collide, speed, toptex, alltex, sidetex, " +
|
||||
"bottomtex, blockslight, sound, fullbright, shape, blockdraw, min, max, " +
|
||||
"fogdensity, fogcolor, fallback, lefttex, righttex, fronttex, backtex");
|
||||
Player.Message(p, "Valid properties: " + helpSections.Keys.Join());
|
||||
} else if (parts.Length == 3) {
|
||||
Help(p, cmd, "edit " + parts[2]);
|
||||
} else {
|
||||
Help(p, cmd);
|
||||
}
|
||||
@ -321,125 +321,89 @@ namespace MCGalaxy.Commands.CPE {
|
||||
float fTemp;
|
||||
bool temp = false, changedFallback = false;
|
||||
|
||||
switch (parts[2].ToLower()) {
|
||||
string arg = MapPropertyName(parts[2].ToLower());
|
||||
switch (arg) {
|
||||
case "name":
|
||||
def.Name = value; break;
|
||||
|
||||
case "collide":
|
||||
if (!EditByte(p, value, "Collide type", ref def.CollideType, 9, 1, 0, 6)) return;
|
||||
if (!EditByte(p, value, "Collide type", ref def.CollideType, "collide", 0, 6)) return;
|
||||
break;
|
||||
|
||||
case "speed":
|
||||
if (!Utils.TryParseDecimal(value, out fTemp) || fTemp < 0.25f || fTemp > 3.96f) {
|
||||
SendEditHelp(p, 10, 0); return;
|
||||
SendEditHelp(p, "speed"); return;
|
||||
}
|
||||
def.Speed = fTemp; break;
|
||||
|
||||
case "top":
|
||||
case "toptex":
|
||||
if (!EditByte(p, value, "Top texture", ref def.TopTex)) return;
|
||||
if (!EditByte(p, value, "Top texture", ref def.TopTex, "top")) return;
|
||||
break;
|
||||
|
||||
case "all":
|
||||
case "alltex":
|
||||
if (!EditByte(p, value, "All textures", ref def.SideTex)) return;
|
||||
if (!EditByte(p, value, "All textures", ref def.SideTex, "all")) return;
|
||||
def.SetAllTex(def.SideTex);
|
||||
break;
|
||||
|
||||
case "side":
|
||||
case "sidetex":
|
||||
if (!EditByte(p, value, "Side texture", ref def.SideTex)) return;
|
||||
if (!EditByte(p, value, "Side texture", ref def.SideTex, "sides")) return;
|
||||
def.SetSideTex(def.SideTex);
|
||||
break;
|
||||
|
||||
case "left":
|
||||
case "lefttex":
|
||||
if (!EditByte(p, value, "Left texture", ref def.LeftTex)) return;
|
||||
if (!EditByte(p, value, "Left texture", ref def.LeftTex, "left")) return;
|
||||
break;
|
||||
|
||||
case "right":
|
||||
case "righttex":
|
||||
if (!EditByte(p, value, "Right texture", ref def.RightTex)) return;
|
||||
if (!EditByte(p, value, "Right texture", ref def.RightTex, "right")) return;
|
||||
break;
|
||||
|
||||
case "front":
|
||||
case "fronttex":
|
||||
if (!EditByte(p, value, "Front texture", ref def.FrontTex)) return;
|
||||
if (!EditByte(p, value, "Front texture", ref def.FrontTex, "front")) return;
|
||||
break;
|
||||
|
||||
case "back":
|
||||
case "backtex":
|
||||
if (!EditByte(p, value, "Back texture", ref def.BackTex)) return;
|
||||
if (!EditByte(p, value, "Back texture", ref def.BackTex, "back")) return;
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
case "bottomtex":
|
||||
if (!EditByte(p, value, "Bottom texture", ref def.BottomTex)) return;
|
||||
if (!EditByte(p, value, "Bottom texture", ref def.BottomTex, "bottom")) return;
|
||||
break;
|
||||
|
||||
case "light":
|
||||
case "blockslight":
|
||||
if (!CommandParser.GetBool(p, value, ref temp)) {
|
||||
SendEditHelp(p, 11, 0); return;
|
||||
SendEditHelp(p, "shadow"); return;
|
||||
}
|
||||
def.BlocksLight = temp;
|
||||
break;
|
||||
|
||||
case "sound":
|
||||
case "walksound":
|
||||
if (!EditByte(p, value, "Walk sound", ref def.WalkSound, 12, 1, 0, 11)) return;
|
||||
if (!EditByte(p, value, "Walk sound", ref def.WalkSound, "sound", 0, 11)) return;
|
||||
break;
|
||||
|
||||
case "bright":
|
||||
case "fullbright":
|
||||
if (!CommandParser.GetBool(p, value, ref temp)) {
|
||||
SendEditHelp(p, 13, 0); return;
|
||||
SendEditHelp(p, "bright"); return;
|
||||
}
|
||||
def.FullBright = temp;
|
||||
break;
|
||||
|
||||
case "shape":
|
||||
if (!CommandParser.GetBool(p, value, ref temp)) {
|
||||
SendEditHelp(p, 3, 0); return;
|
||||
SendEditHelp(p,"shape"); return;
|
||||
}
|
||||
def.Shape = temp ? (byte)0 : def.MaxZ;
|
||||
break;
|
||||
|
||||
case "draw":
|
||||
case "blockdraw":
|
||||
if (!EditByte(p, value, "Block draw", ref def.BlockDraw, 14, 1, 0, 255)) return;
|
||||
if (!EditByte(p, value, "Block draw", ref def.BlockDraw, "draw", 0, 255)) return;
|
||||
break;
|
||||
|
||||
case "min":
|
||||
case "mincoords":
|
||||
if (!ParseCoords(value, ref def.MinX, ref def.MinY, ref def.MinZ)) {
|
||||
SendEditHelp(p, 7, 0); return;
|
||||
}
|
||||
|
||||
break;
|
||||
SendEditHelp(p, "min"); return;
|
||||
} break;
|
||||
case "max":
|
||||
case "maxcoords":
|
||||
if (!ParseCoords(value, ref def.MaxX, ref def.MaxY, ref def.MaxZ)) {
|
||||
SendEditHelp(p, 8, 0); return;
|
||||
}
|
||||
break;
|
||||
SendEditHelp(p, "max"); return;
|
||||
} break;
|
||||
|
||||
case "density":
|
||||
case "fogdensity":
|
||||
if (!EditByte(p, value, "Fog density", ref def.FogDensity)) return;
|
||||
if (!EditByte(p, value, "Fog density", ref def.FogDensity, "fog")) return;
|
||||
break;
|
||||
|
||||
case "col":
|
||||
case "fogcol":
|
||||
case "fogcolor":
|
||||
CustomColor rgb = default(CustomColor);
|
||||
if (!CommandParser.GetHex(p, value, ref rgb)) return;
|
||||
def.FogR = rgb.R; def.FogG = rgb.G; def.FogB = rgb.B;
|
||||
break;
|
||||
|
||||
case "fallback":
|
||||
case "fallbackid":
|
||||
case "fallbackblock":
|
||||
byte fallback = GetFallback(p, value);
|
||||
if (fallback == Block.Invalid) return;
|
||||
changedFallback = true;
|
||||
@ -447,10 +411,10 @@ namespace MCGalaxy.Commands.CPE {
|
||||
value = Block.Name(fallback);
|
||||
def.FallBack = fallback; break;
|
||||
default:
|
||||
Player.Message(p, "Unrecognised property: " + parts[2]); return;
|
||||
Player.Message(p, "Unrecognised property: " + arg); return;
|
||||
}
|
||||
|
||||
Player.Message(p, "Set {0} for {1} to {2}", parts[2], blockName, value);
|
||||
Player.Message(p, "Set {0} for {1} to {2}", arg, blockName, value);
|
||||
BlockDefinition.Add(def, defs, p == null ? null : p.level);
|
||||
if (changedFallback)
|
||||
BlockDefinition.UpdateFallback(global, def.BlockID, p == null ? null : p.level);
|
||||
@ -530,18 +494,17 @@ namespace MCGalaxy.Commands.CPE {
|
||||
Player.Message(p, "Type \"%T{0} list\" %Sto see a list of {1} custom blocks.", cmd, scope);
|
||||
}
|
||||
|
||||
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 arg, string propName, ref byte target, string help) {
|
||||
return EditByte(p, arg, propName, ref target, help, 0, 255);
|
||||
}
|
||||
|
||||
static bool EditByte(Player p, string value, string propName, ref byte target,
|
||||
int step, int offset, byte min, byte max) {
|
||||
string help, byte min, byte max) {
|
||||
int temp = 0;
|
||||
if (!CommandParser.GetInt(p, value, propName, ref temp, min, max)) {
|
||||
if (step != -1) SendEditHelp(p, step, offset);
|
||||
SendEditHelp(p, help);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = (byte)temp; return true;
|
||||
}
|
||||
|
||||
@ -638,7 +601,7 @@ namespace MCGalaxy.Commands.CPE {
|
||||
|
||||
static void SendStepHelp(Player p, bool global) {
|
||||
int step = GetStep(p, global);
|
||||
string[] help = stepsHelp[step];
|
||||
string[] help = helpSections[stepsHelp[step]];
|
||||
|
||||
BlockDefinition bd = GetBD(p, global);
|
||||
if (step == 4 && bd.Shape == 0)
|
||||
@ -649,59 +612,80 @@ namespace MCGalaxy.Commands.CPE {
|
||||
Player.Message(p, "%f--------------------------");
|
||||
}
|
||||
|
||||
static void SendEditHelp(Player p, int step, int offset) {
|
||||
string[] help = stepsHelp[step];
|
||||
for (int i = offset; i < help.Length; i++)
|
||||
static void SendEditHelp(Player p, string section) {
|
||||
string[] help = helpSections[section];
|
||||
for (int i = 0; i < help.Length; i++)
|
||||
Player.Message(p, help[i].Replace("Type", "Use"));
|
||||
}
|
||||
|
||||
static string[][] stepsHelp = new string[][] {
|
||||
null, // step 0
|
||||
null, // step 1
|
||||
new string[] { "Type the name for the block." },
|
||||
new string[] { "Type '0' if the block is a cube, '1' if a sprite (e.g roses)." },
|
||||
static string MapPropertyName(string prop) {
|
||||
if (prop == "side" || prop == "all" || prop == "top" || prop == "bottom"
|
||||
|| prop == "left" || prop == "right" || prop == "front" || prop == "back") return prop + "tex";
|
||||
|
||||
new string[] { "Type a number between '0' and '255' for the top texture.",
|
||||
"Textures in terrain.png are numbered from left to right, increasing downwards",
|
||||
},
|
||||
new string[] { "Type a number between '0' and '255' for the sides texture.",
|
||||
"Textures in terrain.png are numbered from left to right, increasing downwards.",
|
||||
},
|
||||
new string[] { "Type a number between '0' and '255' for the bottom texture.",
|
||||
"Textures in terrain.png are numbered from left to right, increasing downwards.",
|
||||
},
|
||||
if (prop == "sides" || prop == "sidestex") return "sidetex";
|
||||
if (prop == "light") return "blockslight";
|
||||
if (prop == "bright") return "fullbright";
|
||||
if (prop == "walksound") return "sound";
|
||||
if (prop == "draw") return "blockdraw";
|
||||
if (prop == "mincoords") return "min";
|
||||
if (prop == "maxcoords") return "max";
|
||||
if (prop == "density") return "fogdensity";
|
||||
if (prop == "col" || prop == "fogcol") return "fogcolor";
|
||||
if (prop == "fallbackid" || prop == "fallbackblock") return "fallback";
|
||||
|
||||
new string[] { "Enter the three minimum coordinates of the cube in units (separated by spaces). 1 block = 16 units.",
|
||||
"Minimum coordinates for a normal block are &40 &20 &10." },
|
||||
new string[] { "Enter the three maximum coordinates of the cube in units (separated by spaces). 1 block = 16 units.",
|
||||
"Maximum coordinates for a normal block are &416 &216 &116." },
|
||||
return prop;
|
||||
}
|
||||
|
||||
new string[] { "Type a number between '0' and '6' for collision type of this block.",
|
||||
"0 - block is walk-through (e.g. air).", "1 - block is swim-through/climable (e.g. rope).",
|
||||
"2 - block is solid (e.g. dirt).",
|
||||
|
||||
static string[] stepsHelp = new string[] {
|
||||
null, null, "name", "shape", "toptex", "sidetex", "bottomtex", "min", "max", "collide",
|
||||
"speed", "blockslight", "sound", "fullbright", "blockdraw", "fogdensity", "fogcolor", "fallback" };
|
||||
|
||||
const string texLine = "Textures in terrain.png are numbered from left to right, increasing downwards";
|
||||
static Dictionary<string, string[]> helpSections = new Dictionary<string, string[]>() {
|
||||
{ "name", new string[] { "Type the name for the block." } },
|
||||
{ "shape", new string[] { "Type '0' if the block is a cube, '1' if a sprite (e.g roses)." } },
|
||||
{ "blockslight", new string[] { "Type 'yes' if the block casts a shadow, 'no' if it doesn't." } },
|
||||
{ "fullbright", new string[] { "Type 'yes' if the block is fully lit (e.g. lava), 'no' if not." } },
|
||||
|
||||
{ "alltex", new string[] { "Type a number between '0' and '255' for all textures.", texLine } },
|
||||
{ "sidetex", new string[] { "Type a number between '0' and '255' for sides texture.", texLine } },
|
||||
{ "lefttex", new string[] { "Type a number between '0' and '255' for the left side texture.", texLine } },
|
||||
{ "righttex", new string[] { "Type a number between '0' and '255' for the right side texture.", texLine } },
|
||||
{ "fronttex", new string[] { "Type a number between '0' and '255' for the front side texture.", texLine } },
|
||||
{ "backtex", new string[] { "Type a number between '0' and '255' for the back side texture.", texLine } },
|
||||
{ "toptex", new string[] { "Type a number between '0' and '255' for the top texture.", texLine } },
|
||||
{ "bottomtex", new string[] { "Type a number between '0' and '255' for the bottom texture.", texLine } },
|
||||
|
||||
{ "min", new string[] { "Enter the three minimum coordinates of the cube in units (separated by spaces). 1 block = 16 units.",
|
||||
"Minimum coordinates for a normal block are &40 &20 &10." } },
|
||||
{ "max", new string[] { "Enter the three maximum coordinates of the cube in units (separated by spaces). 1 block = 16 units.",
|
||||
"Maximum coordinates for a normal block are &416 &216 &116." } },
|
||||
{ "collide", new string[] { "Type a number between '0' and '6' for collision type.",
|
||||
"0 - block is walk-through (e.g. air).", "1 - block is swim-through/climbable (e.g. rope).",
|
||||
"2 - block is solid (e.g. dirt).", "3 - block is solid, but slippery like ice",
|
||||
"4 - block is solid, but even slipperier than ice", "5 - block is swim-through like water",
|
||||
"6 - block is swim-through like lava" } },
|
||||
{ "speed", new string[] { "Type a number between '0.25' (25% speed) and '3.96' (396% speed).",
|
||||
"This speed is used when inside or walking on the block. Default speed is 1" }
|
||||
},
|
||||
new string[] { "Type a number between '0.25' (25% speed) and '3.96' (396% speed).",
|
||||
"This speed is used when inside or walking on the block. Default speed is 1",
|
||||
},
|
||||
new string[] { "Type 'yes' if the block casts a shadow, 'no' if it doesn't" },
|
||||
new string[] { "Type a number between '0' and '9' for the sound played when walking on it and breaking.",
|
||||
{ "sound", new string[] { "Type a number between '0' and '9' for the sound played when walking on it and breaking.",
|
||||
"0 = None, 1 = Wood, 2 = Gravel, 3 = Grass, 4 = Stone",
|
||||
"5 = Metal, 6 = Glass, 7 = Cloth, 8 = Sand, 9 = Snow",
|
||||
"5 = Metal, 6 = Glass, 7 = Cloth, 8 = Sand, 9 = Snow" }
|
||||
},
|
||||
new string[] { "Type 'yes' if the block is fully lit (e.g. lava), 'no' if not." },
|
||||
new string[] { "Enter the block's draw method.", "0 = Opaque, 1 = Transparent (Like glass)",
|
||||
"2 = Transparent (Like leaves), 3 = Translucent (Like ice), 4 = Gas (Like air)",
|
||||
{ "blockdraw", new string[] { "Enter the block's draw method.", "0 = Opaque, 1 = Transparent (Like glass)",
|
||||
"2 = Transparent (Like leaves), 3 = Translucent (Like ice), 4 = Gas (Like air)" }
|
||||
},
|
||||
|
||||
new string[] { "Enter the fog density for the block. 0 = No fog at all",
|
||||
"1 - 255 = Increasing density (e.g. water has 12, lava 255)",
|
||||
{ "fogdensity", new string[] { "Enter the fog density for the block. 0 = No fog at all",
|
||||
"1 - 255 = Increasing density (e.g. water has 12, lava 255)" }
|
||||
},
|
||||
new string[] { "Enter the fog color (hex color)", },
|
||||
new string[] { "Enter the fallback block (Block shown to players who can't see custom blocks).",
|
||||
"You can use any block name or block ID from the normal blocks.",
|
||||
{ "fogcolor", new string[] { "Enter the fog color (hex color)" } },
|
||||
{ "fallback", new string[] { "Enter the fallback block (Block shown to players who can't see custom blocks).",
|
||||
"You can use any block name or block ID from the normal blocks." }
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
internal static void Help(Player p, string cmd) {
|
||||
Player.Message(p, "%T{0} add [id] %H- begins creating a new custom block.", cmd);
|
||||
Player.Message(p, "%T{0} copy [source id] [new id] %H- clones a new custom block from an existing custom block.", cmd);
|
||||
@ -711,6 +695,18 @@ namespace MCGalaxy.Commands.CPE {
|
||||
Player.Message(p, "%T{0} info [id] %H- shows info about that custom block.", cmd);
|
||||
Player.Message(p, "%HTo see the list of editable properties, type {0} edit.", cmd);
|
||||
}
|
||||
|
||||
internal static void Help(Player p, string cmd, string args) {
|
||||
if (!args.CaselessStarts("edit ")) { Help(p, cmd); return; }
|
||||
string prop = args.Substring(args.IndexOf(' ') + 1);
|
||||
prop = MapPropertyName(prop.ToLower());
|
||||
|
||||
if (!helpSections.ContainsKey(prop)) {
|
||||
Player.Message(p, "Valid properties: " + helpSections.Keys.Join());
|
||||
} else {
|
||||
SendEditHelp(p, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CmdGlobalBlock : Command {
|
||||
@ -727,6 +723,10 @@ namespace MCGalaxy.Commands.CPE {
|
||||
public override void Help(Player p) {
|
||||
CustomBlockCommand.Help(p, "/gb");
|
||||
}
|
||||
|
||||
public override void Help(Player p, string message) {
|
||||
CustomBlockCommand.Help(p, "/gb", message);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CmdLevelBlock : Command {
|
||||
@ -744,5 +744,9 @@ namespace MCGalaxy.Commands.CPE {
|
||||
public override void Help(Player p) {
|
||||
CustomBlockCommand.Help(p, "/lb");
|
||||
}
|
||||
|
||||
public override void Help(Player p, string message) {
|
||||
CustomBlockCommand.Help(p, "/lb", message);
|
||||
}
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ namespace MCGalaxy.Commands.Fun {
|
||||
for (; y <= lvl.Height; y++) {
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (above.IsInvalid) continue;
|
||||
if (lvl.CollideType(above) != CollideType.Solid) continue;
|
||||
if (!CollideType.IsSolid(lvl.CollideType(above))) continue;
|
||||
|
||||
int posY = (y + 1) * 32 - 6;
|
||||
BlockDefinition def = lvl.GetBlockDef(above);
|
||||
|
@ -102,7 +102,7 @@ namespace MCGalaxy.Commands.Building {
|
||||
|
||||
static void PlaceMark(Player p, int x, int y, int z) {
|
||||
ExtBlock block = p.GetHeldBlock();
|
||||
p.ManualChange((ushort)x, (ushort)y, (ushort)z, 0, block, false);
|
||||
p.ManualChange((ushort)x, (ushort)y, (ushort)z, false, block, false);
|
||||
Player.Message(p, "Mark placed at &b({0}, {1}, {2})", x, y, z);
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,13 @@ namespace MCGalaxy.Commands.Misc {
|
||||
static int FindYAbove(Level lvl, ushort x, ushort y, ushort z) {
|
||||
for (; y < lvl.Height; y++) {
|
||||
ExtBlock block = lvl.GetBlock(x, y, z);
|
||||
if (!block.IsInvalid && lvl.CollideType(block) == CollideType.Solid) continue;
|
||||
if (!block.IsInvalid && CollideType.IsSolid(lvl.CollideType(block))) continue;
|
||||
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (!above.IsInvalid && lvl.CollideType(above) == CollideType.Solid) continue;
|
||||
if (!above.IsInvalid && CollideType.IsSolid(lvl.CollideType(above))) continue;
|
||||
|
||||
ExtBlock below = lvl.GetBlock(x, (ushort)(y - 1), z);
|
||||
if (!below.IsInvalid && lvl.CollideType(below) == CollideType.Solid)
|
||||
if (!below.IsInvalid && CollideType.IsSolid(lvl.CollideType(below)))
|
||||
return y;
|
||||
}
|
||||
return -1;
|
||||
|
@ -54,12 +54,13 @@ namespace MCGalaxy.Commands.Misc {
|
||||
static int FindYBelow(Level lvl, ushort x, ushort y, ushort z) {
|
||||
for (; y > 0; y--) {
|
||||
ExtBlock block = lvl.GetBlock(x, y, z);
|
||||
if (!block.IsInvalid && lvl.CollideType(block) == CollideType.Solid) continue;
|
||||
if (!block.IsInvalid && CollideType.IsSolid(lvl.CollideType(block))) continue;
|
||||
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (!above.IsInvalid && lvl.CollideType(above) == CollideType.Solid) continue;
|
||||
if (!above.IsInvalid && CollideType.IsSolid(lvl.CollideType(above))) continue;
|
||||
|
||||
ExtBlock below = lvl.GetBlock(x, (ushort)(y - 1), z);
|
||||
if (!below.IsInvalid && lvl.CollideType(below) == CollideType.Solid)
|
||||
if (!below.IsInvalid && CollideType.IsSolid(lvl.CollideType(below)))
|
||||
return y;
|
||||
}
|
||||
return -1;
|
||||
|
@ -112,13 +112,14 @@ namespace MCGalaxy.Events.PlayerEvents {
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void OnBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block);
|
||||
public delegate void SelectionBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block);
|
||||
public delegate void OnBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool placing);
|
||||
/// <summary> Called whenever a player places or deletes a block. </summary>
|
||||
public sealed class OnBlockChangeEvent : IEvent<OnBlockChange> {
|
||||
|
||||
public static void Call(Player p, ushort x, ushort y, ushort z, ExtBlock block) {
|
||||
public static void Call(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool placing) {
|
||||
if (handlers.Count == 0) return;
|
||||
CallCommon(pl => pl(p, x, y, z, block));
|
||||
CallCommon(pl => pl(p, x, y, z, block, placing));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ namespace MCGalaxy.Games {
|
||||
p.cancelchat = true;
|
||||
}
|
||||
|
||||
void HandleBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block) {
|
||||
void HandleBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool placing) {
|
||||
if (!Game.started || p.level != Game.Map) return;
|
||||
CtfTeam2 team = Game.TeamOf(p);
|
||||
if (team == null) {
|
||||
|
@ -24,12 +24,6 @@ namespace MCGalaxy.Games {
|
||||
/// <summary> Whether players are allowed to teleport to others when not in referee mode. </summary>
|
||||
public virtual bool TeleportAllowed { get { return true; } }
|
||||
|
||||
/// <summary> Returns whether this game handed the player manually placing a block. </summary>
|
||||
public virtual bool HandlesManualChange(Player p, ushort x, ushort y, ushort z,
|
||||
byte action, byte block, byte old) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary> Returns whether this game handled the player sending a chat message. </summary>
|
||||
public virtual bool HandlesChatMessage(Player p, string message) {
|
||||
return false;
|
||||
|
@ -17,6 +17,7 @@
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using MCGalaxy.Blocks;
|
||||
using MCGalaxy.Events;
|
||||
|
||||
namespace MCGalaxy.Games.ZS {
|
||||
@ -24,10 +25,10 @@ namespace MCGalaxy.Games.ZS {
|
||||
internal static class Pillaring {
|
||||
|
||||
internal static bool Handles(Player p, ushort x, ushort y, ushort z,
|
||||
byte action, byte block, byte old, ZSGame game) {
|
||||
bool placing, ExtBlock block, ExtBlock old, ZSGame game) {
|
||||
|
||||
if (action == 1 && !game.CurLevel.Config.Pillaring && !p.Game.Referee) {
|
||||
if (NotPillaring(block, old)) {
|
||||
if (placing && !game.CurLevel.Config.Pillaring && !p.Game.Referee) {
|
||||
if (NotPillaring(game.CurLevel, block, old)) {
|
||||
p.Game.BlocksStacked = 0;
|
||||
} else if (CheckCoords(p, x, y, z)) {
|
||||
p.Game.BlocksStacked++;
|
||||
@ -41,10 +42,13 @@ namespace MCGalaxy.Games.ZS {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool NotPillaring(byte b, byte old) {
|
||||
if (Block.Walkthrough(b)) return true;
|
||||
old = Block.Convert(old);
|
||||
return old >= Block.Water && old <= Block.StillLava;
|
||||
static bool NotPillaring(Level lvl, ExtBlock b, ExtBlock old) {
|
||||
byte collide = lvl.CollideType(b);
|
||||
if (collide == CollideType.WalkThrough) return true;
|
||||
|
||||
collide = lvl.CollideType(old);
|
||||
return collide == CollideType.SwimThrough || collide == CollideType.LiquidWater
|
||||
|| collide == CollideType.LiquidLava;
|
||||
}
|
||||
|
||||
static bool CheckCoords(Player p, ushort x, ushort y, ushort z) {
|
||||
|
@ -37,6 +37,7 @@ namespace MCGalaxy.Games.ZS {
|
||||
OnPlayerMoveEvent.Register(HandlePlayerMove, Priority.High);
|
||||
OnPlayerActionEvent.Register(HandlePlayerAction, Priority.High);
|
||||
OnPlayerSpawningEvent.Register(HandlePlayerSpawning, Priority.High);
|
||||
OnBlockChangeEvent.Register(HandleBlockChange, Priority.High);
|
||||
}
|
||||
|
||||
public override void Unload(bool shutdown) {
|
||||
@ -47,6 +48,7 @@ namespace MCGalaxy.Games.ZS {
|
||||
OnPlayerMoveEvent.Unregister(HandlePlayerMove);
|
||||
OnPlayerActionEvent.Unregister(HandlePlayerAction);
|
||||
OnPlayerSpawningEvent.Unregister(HandlePlayerSpawning);
|
||||
OnBlockChangeEvent.Unregister(HandleBlockChange);
|
||||
}
|
||||
|
||||
void HandleTabListEntryAdded(Entity entity, ref string tabName, ref string tabGroup, Player dst) {
|
||||
@ -119,5 +121,33 @@ namespace MCGalaxy.Games.ZS {
|
||||
Game.InfectPlayer(p, null);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool placing) {
|
||||
if (p.level != Game.CurLevel) return;
|
||||
ExtBlock old = Game.CurLevel.GetBlock(x, y, z);
|
||||
|
||||
if (Game.CurLevel.Config.BuildType == BuildType.NoModify) {
|
||||
p.RevertBlock(x, y, z); p.cancelBlock = true; return;
|
||||
}
|
||||
if (Game.CurLevel.Config.BuildType == BuildType.ModifyOnly && Game.CurLevel.BlockProps[old.Index].OPBlock) {
|
||||
p.RevertBlock(x, y, z); p.cancelBlock = true; return;
|
||||
}
|
||||
|
||||
if (Pillaring.Handles(p, x, y, z, placing, block, old, Game)) {
|
||||
p.cancelBlock = true; return;
|
||||
}
|
||||
|
||||
if (placing || (!placing && p.painting)) {
|
||||
if (p.Game.Referee) return;
|
||||
if (p.Game.BlocksLeft == 0) {
|
||||
Player.Message(p, "You have no blocks left.");
|
||||
p.RevertBlock(x, y, z); p.cancelBlock = true; return;
|
||||
}
|
||||
|
||||
p.Game.BlocksLeft--;
|
||||
if ((p.Game.BlocksLeft % 10) == 0 || (p.Game.BlocksLeft >= 0 && p.Game.BlocksLeft <= 10))
|
||||
Player.Message(p, "Blocks Left: &4" + p.Game.BlocksLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,33 +36,6 @@ namespace MCGalaxy.Games {
|
||||
HUD.UpdateAllPrimary(this);
|
||||
}
|
||||
|
||||
public override bool HandlesManualChange(Player p, ushort x, ushort y, ushort z,
|
||||
byte action, byte block, byte old) {
|
||||
if (!Running || (p.level == null || !p.level.name.CaselessEq(CurLevelName))) return false;
|
||||
if (CurLevel.Config.BuildType == BuildType.NoModify) {
|
||||
p.RevertBlock(x, y, z); return true;
|
||||
}
|
||||
if (CurLevel.Config.BuildType == BuildType.ModifyOnly && Block.Props[old].OPBlock) {
|
||||
p.RevertBlock(x, y, z); return true;
|
||||
}
|
||||
|
||||
if (Pillaring.Handles(p, x, y, z, action, block, old, this)) return true;
|
||||
|
||||
if (action == 1 || (action == 0 && p.painting)) {
|
||||
if (!p.level.name.CaselessEq(CurLevelName) || p.Game.Referee) return false;
|
||||
|
||||
if (p.Game.BlocksLeft == 0) {
|
||||
Player.Message(p, "You have no blocks left.");
|
||||
p.RevertBlock(x, y, z); return true;
|
||||
}
|
||||
|
||||
p.Game.BlocksLeft--;
|
||||
if ((p.Game.BlocksLeft % 10) == 0 || (p.Game.BlocksLeft >= 0 && p.Game.BlocksLeft <= 10))
|
||||
Player.Message(p, "Blocks Left: &4" + p.Game.BlocksLeft);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HandlesChatMessage(Player p, string message) {
|
||||
if (!Running || (p.level == null || !p.level.name.CaselessEq(CurLevelName))) return false;
|
||||
if (Server.votingforlevel && HandleVote(p, message)) return true;
|
||||
|
@ -494,7 +494,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
public void UpdateBlockHandler(ExtBlock block) {
|
||||
bool nonSolid = CollideType(block) != MCGalaxy.Blocks.CollideType.Solid;
|
||||
bool nonSolid = !MCGalaxy.Blocks.CollideType.IsSolid(CollideType(block));
|
||||
int i = block.Index;
|
||||
|
||||
deleteHandlers[i] = BlockBehaviour.GetDeleteHandler(block, BlockProps);
|
||||
|
@ -252,7 +252,7 @@ namespace MCGalaxy {
|
||||
|
||||
/// <summary> Called when a player removes or places a block.
|
||||
/// NOTE: Currently this prevents the OnBlockChange event from being called. </summary>
|
||||
public event OnBlockChange Blockchange;
|
||||
public event SelectionBlockChange Blockchange;
|
||||
|
||||
internal bool HasBlockchange { get { return Blockchange != null; } }
|
||||
public void ClearBlockchange() { ClearSelection(); }
|
||||
|
@ -47,11 +47,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
}
|
||||
|
||||
public void ManualChange(ushort x, ushort y, ushort z, byte action, ExtBlock block) {
|
||||
ManualChange(x, y, z, action, block, true);
|
||||
}
|
||||
|
||||
public void ManualChange(ushort x, ushort y, ushort z, byte action,
|
||||
public void ManualChange(ushort x, ushort y, ushort z, bool placing,
|
||||
ExtBlock block, bool checkPlaceDist) {
|
||||
ExtBlock old = level.GetBlock(x, y, z);
|
||||
if (old.IsInvalid) return;
|
||||
@ -63,20 +59,13 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
if (level.IsMuseum && Blockchange == null) return;
|
||||
if (action > 1) {
|
||||
const string msg = "Unknown block action!";
|
||||
Leave(msg, msg, true); return;
|
||||
}
|
||||
bool doDelete = !painting && action == 0;
|
||||
bool deletingBlock = !painting && !placing;
|
||||
|
||||
if (ServerConfig.verifyadmins && adminpen) {
|
||||
SendMessage("&cYou must first verify with %T/pass [Password]");
|
||||
RevertBlock(x, y, z); return;
|
||||
}
|
||||
|
||||
if (Server.zombie.Running && Server.zombie.HandlesManualChange(this, x, y, z, action, block.BlockID, old.BlockID))
|
||||
return;
|
||||
|
||||
if ( Server.lava.active && Server.lava.HasPlayer(this) && Server.lava.IsPlayerDead(this) ) {
|
||||
SendMessage("You are out of the round, and cannot build.");
|
||||
RevertBlock(x, y, z); return;
|
||||
@ -86,7 +75,7 @@ namespace MCGalaxy {
|
||||
if (Blockchange != null) {
|
||||
Blockchange(this, x, y, z, block); return;
|
||||
}
|
||||
OnBlockChangeEvent.Call(this, x, y, z, block);
|
||||
OnBlockChangeEvent.Call(this, x, y, z, block, placing);
|
||||
if (cancelBlock) { cancelBlock = false; return; }
|
||||
|
||||
if (old.BlockID >= Block.Air_Flood && old.BlockID <= Block.Door_Air_air) {
|
||||
@ -94,7 +83,7 @@ namespace MCGalaxy {
|
||||
RevertBlock(x, y, z); return;
|
||||
}
|
||||
|
||||
if (!deleteMode) {
|
||||
if (!deletingBlock) {
|
||||
PhysicsArgs args = level.foundInfo(x, y, z);
|
||||
if (args.HasWait) return;
|
||||
}
|
||||
@ -113,19 +102,19 @@ namespace MCGalaxy {
|
||||
|
||||
ExtBlock held = block;
|
||||
block = BlockBindings[block.RawID];
|
||||
if (!CheckManualChange(old, block, doDelete)) {
|
||||
if (!CheckManualChange(old, block, deletingBlock)) {
|
||||
RevertBlock(x, y, z); return;
|
||||
}
|
||||
if (!ModeBlock.IsAir) block = ModeBlock;
|
||||
|
||||
//Ignores updating blocks that are the same and revert block back only to the player
|
||||
ExtBlock newB = (painting || action == 1) ? block : ExtBlock.Air;
|
||||
ExtBlock newB = deletingBlock ? ExtBlock.Air : block;
|
||||
if (old == newB) {
|
||||
if (painting || !old.VisuallyEquals(held)) RevertBlock(x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
if (doDelete) {
|
||||
if (deletingBlock) {
|
||||
bool deleted = DeleteBlock(old, x, y, z, block);
|
||||
} else {
|
||||
bool placed = PlaceBlock(old, x, y, z, block);
|
||||
@ -280,6 +269,11 @@ namespace MCGalaxy {
|
||||
if (frozen) { RevertBlock(x, y, z); return; }
|
||||
|
||||
byte action = packet[7];
|
||||
if (action > 1) {
|
||||
const string msg = "Unknown block action!";
|
||||
Leave(msg, msg, true); return;
|
||||
}
|
||||
|
||||
ExtBlock held = ExtBlock.FromRaw(packet[8]);
|
||||
RawHeldBlock = held;
|
||||
|
||||
@ -297,7 +291,7 @@ namespace MCGalaxy {
|
||||
RevertBlock(x, y, z); return;
|
||||
}
|
||||
}
|
||||
ManualChange(x, y, z, action, held);
|
||||
ManualChange(x, y, z, action != 0, held, true);
|
||||
} catch ( Exception e ) {
|
||||
// Don't ya just love it when the server tattles?
|
||||
Chat.MessageOps(DisplayName + " has triggered a block change error");
|
||||
|
@ -65,10 +65,10 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
for (int x = min.X; x <= max.X; x++)
|
||||
{
|
||||
ExtBlock block = GetSurvivalBlock(p, x, min.Y, z);
|
||||
byte collideType = p.level.CollideType(block);
|
||||
allGas = allGas && collideType == CollideType.WalkThrough;
|
||||
byte collide = p.level.CollideType(block);
|
||||
allGas = allGas && collide == CollideType.WalkThrough;
|
||||
|
||||
if (collideType != CollideType.Solid) continue;
|
||||
if (!CollideType.IsSolid(collide)) continue;
|
||||
if (p.fallCount > p.level.Config.FallHeight)
|
||||
p.HandleDeath(ExtBlock.Air, null, false, true);
|
||||
|
||||
|
@ -158,7 +158,7 @@ namespace MCGalaxy.Maths {
|
||||
|
||||
BlockDefinition def = lvl.GetBlockDef(block);
|
||||
if (def != null) {
|
||||
if (def.CollideType == CollideType.Solid) return true;
|
||||
if (CollideType.IsSolid(def.CollideType)) return true;
|
||||
} else {
|
||||
if (block.BlockID == Block.Invalid || !Block.Walkthrough(Block.Convert(block.BlockID))) return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user