From 4d15eed40597e7a489e55adcabd46f690f8e6bd3 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 24 Jul 2017 23:13:46 +1000 Subject: [PATCH] Add extended collide types to lb/gb, and document lb/gb properties. Fixes #464 and fixes #465 --- MCGalaxy/Blocks/Block.Convert.cs | 2 +- MCGalaxy/Blocks/Block.ID.cs | 2 +- MCGalaxy/Blocks/DefaultSet.cs | 14 +- MCGalaxy/Commands/CPE/CustomBlockCommand.cs | 236 +++++++++--------- MCGalaxy/Commands/Fun/CmdSlap.cs | 2 +- MCGalaxy/Commands/building/CmdMark.cs | 2 +- MCGalaxy/Commands/other/CmdAscend.cs | 7 +- MCGalaxy/Commands/other/CmdDescend.cs | 7 +- MCGalaxy/Events/PlayerEvents.cs | 7 +- MCGalaxy/Games/CTF/CtfPlugin.cs | 2 +- MCGalaxy/Games/IGame.cs | 6 - MCGalaxy/Games/ZombieSurvival/Pillaring.cs | 18 +- MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs | 32 ++- .../Games/ZombieSurvival/ZombieGame.Game.cs | 27 -- MCGalaxy/Levels/Level.cs | 2 +- MCGalaxy/Player/Player.Fields.cs | 2 +- MCGalaxy/Player/Player.Handlers.cs | 36 ++- MCGalaxy/Player/PlayerPhysics.cs | 6 +- MCGalaxy/util/Math/AABB.cs | 2 +- 19 files changed, 211 insertions(+), 201 deletions(-) diff --git a/MCGalaxy/Blocks/Block.Convert.cs b/MCGalaxy/Blocks/Block.Convert.cs index 6f7801612..21904fd82 100644 --- a/MCGalaxy/Blocks/Block.Convert.cs +++ b/MCGalaxy/Blocks/Block.Convert.cs @@ -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: diff --git a/MCGalaxy/Blocks/Block.ID.cs b/MCGalaxy/Blocks/Block.ID.cs index de258af05..b9338dc7a 100644 --- a/MCGalaxy/Blocks/Block.ID.cs +++ b/MCGalaxy/Blocks/Block.ID.cs @@ -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; diff --git a/MCGalaxy/Blocks/DefaultSet.cs b/MCGalaxy/Blocks/DefaultSet.cs index f28be83ee..4df10a79b 100644 --- a/MCGalaxy/Blocks/DefaultSet.cs +++ b/MCGalaxy/Blocks/DefaultSet.cs @@ -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 { diff --git a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs index 43fb1c417..656bf31d2 100644 --- a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs +++ b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs @@ -148,7 +148,7 @@ namespace MCGalaxy.Commands.CPE { bool tinted = (def.FogR != 0 || def.FogG != 0 || def.FogB != 0) && def.Name.IndexOf('#') >= 0; if (tinted) { - Player.Message(p, " Tint color: {0}", Utils.Hex(def.FogR, def.FogG, def.FogB)); + Player.Message(p, " Tint color: {0}", Utils.Hex(def.FogR, def.FogG, def.FogB)); } if (def.Shape == 0) { @@ -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); } @@ -307,7 +307,7 @@ namespace MCGalaxy.Commands.CPE { } ExtBlock block; - if (!CheckBlock(p, parts[1], out block)) return; + if (!CheckBlock(p, parts[1], out block)) return; BlockDefinition[] defs = global ? BlockDefinition.GlobalDefs : p.level.CustomBlockDefs; BlockDefinition def = defs[block.RawID]; @@ -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); @@ -480,7 +444,7 @@ namespace MCGalaxy.Commands.CPE { string scope = global ? "global" : "level"; Player.Message(p, "Created a new " + scope + " custom block " + def.Name + "(" + def.BlockID + ")"); - block = ExtBlock.FromRaw(def.BlockID); + block = ExtBlock.FromRaw(def.BlockID); BlockDefinition.Add(def, defs, p == null ? null : p.level); UpdateBlockProps(global, p, block, props); return true; @@ -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; } @@ -573,14 +536,14 @@ namespace MCGalaxy.Commands.CPE { p.level.BlockProps[block.Index] = props; p.level.UpdateBlockHandler(block); return; - } - + } + BlockDefinition.GlobalProps[block.Index] = props; Level[] loaded = LevelInfo.Loaded.Items; byte raw = block.RawID; foreach (Level lvl in loaded) { - if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw]) continue; + if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw]) continue; lvl.BlockProps[block.Index] = props; lvl.UpdateBlockHandler(block); } @@ -595,7 +558,7 @@ namespace MCGalaxy.Commands.CPE { } BlockProps props = BlockProps.MakeDefault(); - BlockDefinition.GlobalProps[block.Index] = props; + BlockDefinition.GlobalProps[block.Index] = props; Level[] loaded = LevelInfo.Loaded.Items; byte raw = block.RawID; if (!block.IsCustomType) props = Block.Props[raw]; @@ -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; + } + + + 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 helpSections = new Dictionary() { + { "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." } }, - 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).", + { "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", + { "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" } }, - 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.", - "0 = None, 1 = Wood, 2 = Gravel, 3 = Grass, 4 = Stone", - "5 = Metal, 6 = Glass, 7 = Cloth, 8 = Sand, 9 = Snow", + { "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[] { "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)", + { "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 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); + } } } \ No newline at end of file diff --git a/MCGalaxy/Commands/Fun/CmdSlap.cs b/MCGalaxy/Commands/Fun/CmdSlap.cs index 85535818d..187cef3ef 100644 --- a/MCGalaxy/Commands/Fun/CmdSlap.cs +++ b/MCGalaxy/Commands/Fun/CmdSlap.cs @@ -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); diff --git a/MCGalaxy/Commands/building/CmdMark.cs b/MCGalaxy/Commands/building/CmdMark.cs index a89c6b9c9..ea0f92c20 100644 --- a/MCGalaxy/Commands/building/CmdMark.cs +++ b/MCGalaxy/Commands/building/CmdMark.cs @@ -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); } diff --git a/MCGalaxy/Commands/other/CmdAscend.cs b/MCGalaxy/Commands/other/CmdAscend.cs index 74f76a7b7..87dd3057b 100644 --- a/MCGalaxy/Commands/other/CmdAscend.cs +++ b/MCGalaxy/Commands/other/CmdAscend.cs @@ -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; diff --git a/MCGalaxy/Commands/other/CmdDescend.cs b/MCGalaxy/Commands/other/CmdDescend.cs index d4dea21f4..ccd9106b3 100644 --- a/MCGalaxy/Commands/other/CmdDescend.cs +++ b/MCGalaxy/Commands/other/CmdDescend.cs @@ -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; diff --git a/MCGalaxy/Events/PlayerEvents.cs b/MCGalaxy/Events/PlayerEvents.cs index 7d5a82feb..0c2e169ee 100644 --- a/MCGalaxy/Events/PlayerEvents.cs +++ b/MCGalaxy/Events/PlayerEvents.cs @@ -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); /// Called whenever a player places or deletes a block. public sealed class OnBlockChangeEvent : IEvent { - 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)); } } diff --git a/MCGalaxy/Games/CTF/CtfPlugin.cs b/MCGalaxy/Games/CTF/CtfPlugin.cs index 7ae23ddd6..e0041456a 100644 --- a/MCGalaxy/Games/CTF/CtfPlugin.cs +++ b/MCGalaxy/Games/CTF/CtfPlugin.cs @@ -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) { diff --git a/MCGalaxy/Games/IGame.cs b/MCGalaxy/Games/IGame.cs index 734c170e8..d04e1d20c 100644 --- a/MCGalaxy/Games/IGame.cs +++ b/MCGalaxy/Games/IGame.cs @@ -24,12 +24,6 @@ namespace MCGalaxy.Games { /// Whether players are allowed to teleport to others when not in referee mode. public virtual bool TeleportAllowed { get { return true; } } - /// Returns whether this game handed the player manually placing a block. - public virtual bool HandlesManualChange(Player p, ushort x, ushort y, ushort z, - byte action, byte block, byte old) { - return false; - } - /// Returns whether this game handled the player sending a chat message. public virtual bool HandlesChatMessage(Player p, string message) { return false; diff --git a/MCGalaxy/Games/ZombieSurvival/Pillaring.cs b/MCGalaxy/Games/ZombieSurvival/Pillaring.cs index 6e0660bd5..a52722cc0 100644 --- a/MCGalaxy/Games/ZombieSurvival/Pillaring.cs +++ b/MCGalaxy/Games/ZombieSurvival/Pillaring.cs @@ -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) { diff --git a/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs b/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs index 6eb2c2fe0..46566242b 100644 --- a/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs +++ b/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs @@ -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) { @@ -116,7 +118,35 @@ namespace MCGalaxy.Games.ZS { if (p.level != Game.CurLevel) return; if (!p.Game.Referee && !p.Game.Infected && Game.RoundInProgress) { - Game.InfectPlayer(p, null); + 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); } } } diff --git a/MCGalaxy/Games/ZombieSurvival/ZombieGame.Game.cs b/MCGalaxy/Games/ZombieSurvival/ZombieGame.Game.cs index 6076d5137..d8429f47b 100644 --- a/MCGalaxy/Games/ZombieSurvival/ZombieGame.Game.cs +++ b/MCGalaxy/Games/ZombieSurvival/ZombieGame.Game.cs @@ -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; diff --git a/MCGalaxy/Levels/Level.cs b/MCGalaxy/Levels/Level.cs index 43a7b0df8..1a13e4c48 100644 --- a/MCGalaxy/Levels/Level.cs +++ b/MCGalaxy/Levels/Level.cs @@ -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); diff --git a/MCGalaxy/Player/Player.Fields.cs b/MCGalaxy/Player/Player.Fields.cs index 87b900ef6..021d70722 100644 --- a/MCGalaxy/Player/Player.Fields.cs +++ b/MCGalaxy/Player/Player.Fields.cs @@ -252,7 +252,7 @@ namespace MCGalaxy { /// Called when a player removes or places a block. /// NOTE: Currently this prevents the OnBlockChange event from being called. - public event OnBlockChange Blockchange; + public event SelectionBlockChange Blockchange; internal bool HasBlockchange { get { return Blockchange != null; } } public void ClearBlockchange() { ClearSelection(); } diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index 8b5dafaa2..bb2e6f7de 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -46,12 +46,8 @@ 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; @@ -62,21 +58,14 @@ namespace MCGalaxy { RevertBlock(x, y, z); return; } - 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; + if (level.IsMuseum && Blockchange == null) return; + 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"); diff --git a/MCGalaxy/Player/PlayerPhysics.cs b/MCGalaxy/Player/PlayerPhysics.cs index 6d4c8232a..843c9289b 100644 --- a/MCGalaxy/Player/PlayerPhysics.cs +++ b/MCGalaxy/Player/PlayerPhysics.cs @@ -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); diff --git a/MCGalaxy/util/Math/AABB.cs b/MCGalaxy/util/Math/AABB.cs index 12ff0e0c1..152e8a3af 100644 --- a/MCGalaxy/util/Math/AABB.cs +++ b/MCGalaxy/util/Math/AABB.cs @@ -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; }