Add extended collide types to lb/gb, and document lb/gb properties. Fixes #464 and fixes #465

This commit is contained in:
UnknownShadow200 2017-07-24 23:13:46 +10:00
parent 2b5f0406af
commit 4d15eed405
19 changed files with 211 additions and 201 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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 {

View File

@ -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).",
},
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.",
"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 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)",
},
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)",
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[] { "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.",
{ "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" }
},
{ "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)" }
},
{ "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)" }
},
{ "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);
}
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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(); }

View File

@ -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");

View File

@ -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);

View File

@ -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;
}