diff --git a/Blocks/Behaviour/Block.Behaviour.cs b/Blocks/Behaviour/Block.Behaviour.cs
new file mode 100644
index 000000000..54e9ad206
--- /dev/null
+++ b/Blocks/Behaviour/Block.Behaviour.cs
@@ -0,0 +1,57 @@
+/*
+ Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
+
+ Dual-licensed under the Educational Community License, Version 2.0 and
+ the GNU General Public License, Version 3 (the "Licenses"); you may
+ not use this file except in compliance with the Licenses. You may
+ obtain a copy of the Licenses at
+
+ http://www.opensource.org/licenses/ecl2.php
+ http://www.gnu.org/licenses/gpl-3.0.html
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the Licenses are distributed on an "AS IS"
+ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ or implied. See the Licenses for the specific language governing
+ permissions and limitations under the Licenses.
+ */
+using System;
+using MCGalaxy.BlockBehaviour;
+
+namespace MCGalaxy {
+
+ public sealed partial class Block {
+
+ /// Returns whether this block handles the player placing a block at the given coordinates.
+ /// If this returns true, the usual 'dirt/grass below' behaviour and 'adding to the BlockDB' is skipped.
+ public delegate bool HandleDelete(Player p, byte block, ushort x, ushort y, ushort z);
+ internal static HandleDelete[] deleteHandlers = new HandleDelete[256];
+
+ /// Returns whether this block handles the player deleting a block at the given coordinates.
+ /// If this returns true, the usual 'checking dirt/grass below' and 'adding to the BlockDB' is skipped.
+ public delegate bool HandlePlace(Player p, byte block, ushort x, ushort y, ushort z);
+ internal static HandlePlace[] placeHandlers = new Block.HandlePlace[256];
+
+ /// Returns whether this block handles the player walking through this block at the given coordinates.
+ /// If this returns true, the usual 'checking dirt/grass below' behaviour is skipped.
+ public delegate bool HandleWalkthrough(Player p, byte block, ushort x, ushort y, ushort z);
+ internal static HandleWalkthrough[] walkthroughHandlers = new Block.HandleWalkthrough[256];
+
+ static void SetupCoreHandlers() {
+ deleteHandlers[Block.rocketstart] = DeleteBehaviour.RocketStart;
+ deleteHandlers[Block.firework] = DeleteBehaviour.Firework;
+ walkthroughHandlers[Block.checkpoint] = WalkthroughBehaviour.Checkpoint;
+ deleteHandlers[Block.c4det] = DeleteBehaviour.C4Det;
+
+ for (int i = 0; i < 256; i++) {
+ if (Block.mb((byte)i)) {
+ walkthroughHandlers[i] = WalkthroughBehaviour.MessageBlock;
+ deleteHandlers[i] = WalkthroughBehaviour.MessageBlock;
+ } else if (Block.portal((byte)i)) {
+ walkthroughHandlers[i] = WalkthroughBehaviour.Portal;
+ deleteHandlers[i] = WalkthroughBehaviour.Portal;
+ }
+ }
+ }
+ }
+}
diff --git a/Blocks/Block.Behaviour.cs b/Blocks/Behaviour/DeleteBehaviour.cs
similarity index 71%
rename from Blocks/Block.Behaviour.cs
rename to Blocks/Behaviour/DeleteBehaviour.cs
index 2df1b94f6..1c17f1b49 100644
--- a/Blocks/Block.Behaviour.cs
+++ b/Blocks/Behaviour/DeleteBehaviour.cs
@@ -17,30 +17,15 @@
*/
using System;
-namespace MCGalaxy {
+namespace MCGalaxy.BlockBehaviour {
- public sealed partial class Block {
-
- /// Returns whether this block handles the player placing a block at the given coordinates.
- /// If this returns true, the usual 'checking dirt/grass below' behaviour is skipped.
- public delegate bool HandleDelete(Player p, byte block, ushort x, ushort y, ushort z);
- internal static HandleDelete[] deleteHandlers = new HandleDelete[256];
-
- /// Returns whether this block handles the player deleting a block at the given coordinates.
- /// If this returns true, the usual 'checking dirt/grass below' behaviour is skipped.
- public delegate bool HandlePlace(Player p, byte block, ushort x, ushort y, ushort z);
- internal static HandlePlace[] placeHandlers = new Block.HandlePlace[256];
-
- static void SetupCoreHandlers() {
- deleteHandlers[Block.rocketstart] = RocketStartDelete;
- deleteHandlers[Block.firework] = FireworkDelete;
- }
+ internal static class DeleteBehaviour {
- static bool RocketStartDelete(Player p, byte block, ushort x, ushort y, ushort z) {
+ internal static bool RocketStart(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics < 2 || p.level.physics == 5) { p.RevertBlock(x, y, z); return true; }
int newZ = 0, newX = 0, newY = 0;
- p.SendBlockchange(x, y, z, Block.rocketstart);
+ p.RevertBlock(x, y, z);
if ( p.rot[0] < 48 || p.rot[0] > ( 256 - 48 ) )
newZ = -1;
else if ( p.rot[0] > ( 128 - 48 ) && p.rot[0] < ( 128 + 48 ) )
@@ -68,7 +53,7 @@ namespace MCGalaxy {
return false;
}
- static bool FireworkDelete(Player p, byte block, ushort x, ushort y, ushort z) {
+ internal static bool Firework(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics == 0 || p.level.physics == 5) { p.RevertBlock(x, y, z); return true; }
Random rand = new Random();
@@ -84,5 +69,11 @@ namespace MCGalaxy {
}
p.RevertBlock(x, y, z); return false;
}
+
+ internal static bool C4Det(Player p, byte block, ushort x, ushort y, ushort z) {
+ Level.C4.BlowUp(new ushort[] { x, y, z }, p.level);
+ p.level.UpdateBlock(p, x, y, z, Block.air, 0);
+ return false;
+ }
}
}
diff --git a/Blocks/Behaviour/WalkthroughBehaviour.cs b/Blocks/Behaviour/WalkthroughBehaviour.cs
new file mode 100644
index 000000000..8942c57dd
--- /dev/null
+++ b/Blocks/Behaviour/WalkthroughBehaviour.cs
@@ -0,0 +1,92 @@
+/*
+ Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
+
+ Dual-licensed under the Educational Community License, Version 2.0 and
+ the GNU General Public License, Version 3 (the "Licenses"); you may
+ not use this file except in compliance with the Licenses. You may
+ obtain a copy of the Licenses at
+
+ http://www.opensource.org/licenses/ecl2.php
+ http://www.gnu.org/licenses/gpl-3.0.html
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the Licenses are distributed on an "AS IS"
+ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ or implied. See the Licenses for the specific language governing
+ permissions and limitations under the Licenses.
+ */
+using System;
+using System.Data;
+using MCGalaxy.SQL;
+
+namespace MCGalaxy.BlockBehaviour {
+
+ internal static class WalkthroughBehaviour {
+
+ internal static bool Portal(Player p, byte block, ushort x, ushort y, ushort z) {
+ p.RevertBlock(x, y, z);
+ try {
+ //safe against SQL injections because no user input is given here
+ DataTable Portals = Database.fillData("SELECT * FROM `Portals" + p.level.name + "` WHERE EntryX=" + (int)x + " AND EntryY=" + (int)y + " AND EntryZ=" + (int)z);
+ int last = Portals.Rows.Count - 1;
+ if (last == -1) { Portals.Dispose(); return true; }
+
+ DataRow row = Portals.Rows[last];
+ if (p.level.name != row["ExitMap"].ToString()) {
+ if (p.level.permissionvisit > p.group.Permission) {
+ Player.SendMessage(p, "You do not have the adequate rank to visit this map!"); return true;
+ }
+
+ p.ignorePermission = true;
+ Level curLevel = p.level;
+ Command.all.Find("goto").Use(p, row["ExitMap"].ToString());
+ if (curLevel == p.level) { Player.SendMessage(p, "The map the portal goes to isn't loaded."); return true; }
+ p.ignorePermission = false;
+ }
+ p.BlockUntilLoad(10);
+ Command.all.Find("move").Use(p, p.name + " " + row["ExitX"].ToString() + " " + row["ExitY"].ToString() + " " + row["ExitZ"].ToString());
+ Portals.Dispose();
+ } catch {
+ Player.SendMessage(p, "Portal had no exit.");
+ }
+ return true;
+ }
+
+ static char[] trimChars = { ' ' };
+ internal static bool MessageBlock(Player p, byte block, ushort x, ushort y, ushort z) {
+ p.RevertBlock(x, y, z);
+ try {
+ //safe against SQL injections because no user input is given here
+ DataTable Messages = Database.fillData("SELECT * FROM `Messages" + p.level.name + "` WHERE X=" + (int)x + " AND Y=" + (int)y + " AND Z=" + (int)z);
+ int last = Messages.Rows.Count - 1;
+ if (last == -1) { Messages.Dispose(); return true; }
+
+ string message = Messages.Rows[last]["Message"].ToString().Trim();
+ message = message.Replace("\\'", "\'");
+ if ( message != p.prevMsg || Server.repeatMessage ) {
+ if ( message.StartsWith("/") ) {
+ string[] parts = message.Remove(0, 1).Split(trimChars, 2);
+ p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
+ } else {
+ Player.SendMessage(p, message);
+ }
+ p.prevMsg = message;
+ }
+ } catch {
+ Player.SendMessage(p, "No message was stored.");
+ }
+ return true;
+ }
+
+ internal static bool Checkpoint(Player p, byte block, ushort x, ushort y, ushort z) {
+ p.useCheckpointSpawn = true;
+ p.checkpointX = x; p.checkpointY = y; p.checkpointZ = z;
+ int index = p.level.PosToInt(x, y, z);
+ if (index != p.lastCheckpointIndex) {
+ p.SendSpawn(0xFF, p.color + p.truename, p.pos[0], (ushort)((y - 1) * 32 + 51), p.pos[2], p.rot[0], p.rot[1]);
+ p.lastCheckpointIndex = index;
+ }
+ return true;
+ }
+ }
+}
diff --git a/Blocks/Block.Convert.cs b/Blocks/Block.Convert.cs
index 0ec83e5ad..743211117 100644
--- a/Blocks/Block.Convert.cs
+++ b/Blocks/Block.Convert.cs
@@ -232,7 +232,7 @@ namespace MCGalaxy
//Blocks after this are converted before saving
case air_flood: return "air_flood";
- case door_tree__air: return "door_air";
+ case door_tree_air: return "door_air";
case air_flood_layer: return "air_flood_layer";
case air_flood_down: return "air_flood_down";
case air_flood_up: return "air_flood_up";
@@ -550,7 +550,7 @@ namespace MCGalaxy
case "air_flood_layer": return air_flood_layer;
case "air_flood_down": return air_flood_down;
case "air_flood_up": return air_flood_up;
- case "door_air": return door_tree__air;
+ case "door_air": return door_tree_air;
case "door2_air": return door_obsidian_air;
case "door3_air": return door_glass_air;
case "door4_air": return door_stone_air;
@@ -762,7 +762,7 @@ namespace MCGalaxy
case Block.checkpoint: return Block.air;
case air_flood:
- case door_tree__air:
+ case door_tree_air:
case air_flood_layer:
case air_flood_down:
case air_flood_up:
@@ -845,7 +845,7 @@ namespace MCGalaxy
case air_flood_down:
case air_flood_up:
return air; //air_flood must be converted to air on save to prevent issues
- case door_tree__air: return door_tree;
+ case door_tree_air: return door_tree;
case door_obsidian_air: return door_obsidian;
case door_glass_air: return door_glass;
case door_stone_air: return door_stone;
diff --git a/Blocks/Block.ID.cs b/Blocks/Block.ID.cs
index 291e42753..dd5612611 100644
--- a/Blocks/Block.ID.cs
+++ b/Blocks/Block.ID.cs
@@ -255,7 +255,7 @@ namespace MCGalaxy
public const byte checkpoint = (byte)197;
public const byte air_flood = (byte)200;
- public const byte door_tree__air = (byte)201;
+ public const byte door_tree_air = (byte)201;
public const byte air_flood_layer = (byte)202;
public const byte air_flood_down = (byte)203;
public const byte air_flood_up = (byte)204;
diff --git a/Blocks/Block.Permissions.cs b/Blocks/Block.Permissions.cs
index d0aa274bc..f77bada8d 100644
--- a/Blocks/Block.Permissions.cs
+++ b/Blocks/Block.Permissions.cs
@@ -117,7 +117,7 @@ namespace MCGalaxy
case wood_float:
case lava_sponge:
- case door_tree__air:
+ case door_tree_air:
case door_obsidian_air:
case door_glass_air:
case door_stone_air:
diff --git a/Blocks/Block.cs b/Blocks/Block.cs
index 16071d2ee..b36b7841d 100644
--- a/Blocks/Block.cs
+++ b/Blocks/Block.cs
@@ -472,7 +472,7 @@ namespace MCGalaxy
{
switch (b)
{
- case door_tree: return door_tree__air;
+ case door_tree: return door_tree_air;
case door_obsidian: return door_obsidian_air;
case door_glass: return door_glass_air;
case door_stone: return door_stone_air;
diff --git a/Levels/Level.Physics.cs b/Levels/Level.Physics.cs
index b448435c4..7efa1858f 100644
--- a/Levels/Level.Physics.cs
+++ b/Levels/Level.Physics.cs
@@ -567,7 +567,7 @@ namespace MCGalaxy {
case Block.air_flood_down:
case Block.air_flood_up:
blocks[C.b] = 0; break;
- case Block.door_tree__air:
+ case Block.door_tree_air:
//blocks[C.b] = 111;
Blockchange(x, y, z, Block.door_tree); break;
case Block.door_obsidian_air:
diff --git a/Levels/Physics/DoorPhysics.cs b/Levels/Physics/DoorPhysics.cs
index 6f24d0b68..6aa6abb8f 100644
--- a/Levels/Physics/DoorPhysics.cs
+++ b/Levels/Physics/DoorPhysics.cs
@@ -29,7 +29,7 @@ namespace MCGalaxy.BlockPhysics {
switch (lvl.blocks[C.b]) {
//Change any door blocks nearby into door_air
- case Block.door_tree__air:
+ case Block.door_tree_air:
case Block.door_obsidian_air:
case Block.door_glass_air:
case Block.door_stone_air:
diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj
index be9d5458d..f3ba948c5 100644
--- a/MCGalaxy_.csproj
+++ b/MCGalaxy_.csproj
@@ -101,7 +101,9 @@
-
+
+
+
@@ -719,6 +721,7 @@
+
diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs
index 62e76cb15..70fe0b088 100644
--- a/Player/Player.Handlers.cs
+++ b/Player/Player.Handlers.cs
@@ -126,13 +126,9 @@ namespace MCGalaxy {
}
//else
if ( !painting && action == 0 ) {
- if ( !deleteMode ) {
- if ( Block.portal(b) ) { HandlePortal(this, x, y, z, b); return; }
- if ( Block.mb(b) ) { HandleMsgBlock(this, x, y, z, b); return; }
- }
- bP.flags |= 1;
- level.blockCache.Add(bP);
- DeleteBlock(b, x, y, z, type, extType);
+ bP.flags |= 1;
+ if (DeleteBlock(b, x, y, z, type, extType))
+ level.blockCache.Add(bP);
} else {
level.blockCache.Add(bP);
PlaceBlock(b, x, y, z, type, extType);
@@ -672,77 +668,18 @@ namespace MCGalaxy {
}
}
- void HandlePortal(Player p, ushort x, ushort y, ushort z, byte b) {
- try {
- //safe against SQL injections because no user input is given here
- DataTable Portals = Database.fillData("SELECT * FROM `Portals" + level.name + "` WHERE EntryX=" + (int)x + " AND EntryY=" + (int)y + " AND EntryZ=" + (int)z);
-
- int LastPortal = Portals.Rows.Count - 1;
- if ( LastPortal > -1 ) {
- if ( level.name != Portals.Rows[LastPortal]["ExitMap"].ToString() ) {
- if ( level.permissionvisit > this.group.Permission ) {
- Player.SendMessage(this, "You do not have the adequate rank to visit this map!");
- return;
- }
- ignorePermission = true;
- Level thisLevel = level;
- Command.all.Find("goto").Use(this, Portals.Rows[LastPortal]["ExitMap"].ToString());
- if ( thisLevel == level ) { Player.SendMessage(p, "The map the portal goes to isn't loaded."); return; }
- ignorePermission = false;
- }
- else SendBlockchange(x, y, z, b);
-
- p.BlockUntilLoad(10);
- Command.all.Find("move").Use(this, this.name + " " + Portals.Rows[LastPortal]["ExitX"].ToString() + " " + Portals.Rows[LastPortal]["ExitY"].ToString() + " " + Portals.Rows[LastPortal]["ExitZ"].ToString());
- }
- else {
- Blockchange(this, x, y, z, Block.air, 0);
- }
- Portals.Dispose();
- }
- catch { Player.SendMessage(p, "Portal had no exit."); return; }
- }
-
static char[] trimChars = { ' ' };
- void HandleMsgBlock(Player p, ushort x, ushort y, ushort z, byte b) {
- try {
- //safe against SQL injections because no user input is given here
- DataTable Messages = Database.fillData("SELECT * FROM `Messages" + level.name + "` WHERE X=" + (int)x + " AND Y=" + (int)y + " AND Z=" + (int)z);
-
- int LastMsg = Messages.Rows.Count - 1;
- if ( LastMsg > -1 ) {
- string message = Messages.Rows[LastMsg]["Message"].ToString().Trim();
- message = message.Replace("\\'", "\'");
- if ( message != prevMsg || Server.repeatMessage ) {
- if ( message.StartsWith("/") ) {
- string[] parts = message.Remove(0, 1).Split(trimChars, 2);
- HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
- } else {
- Player.SendMessage(p, message);
- }
- prevMsg = message;
- }
- SendBlockchange(x, y, z, b);
- } else {
- Blockchange(this, x, y, z, Block.air, 0);
- }
- Messages.Dispose();
- } catch {
- Player.SendMessage(p, "No message was stored.");
- RevertBlock(x, y, z); return;
- }
- }
- void DeleteBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
- if ( deleteMode && b != Block.c4det ) { ChangeBlock(x, y, z, Block.air, 0); return; }
+ bool DeleteBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
+ if (deleteMode) { ChangeBlock(x, y, z, Block.air, 0); return true; }
- if ( Block.tDoor(b) ) { RevertBlock(x, y, z); return; }
+ if ( Block.tDoor(b) ) { RevertBlock(x, y, z); return true; }
if ( Block.DoorAirs(b) != 0 ) {
if ( level.physics != 0 )
level.Blockchange(x, y, z, Block.DoorAirs(b));
else
RevertBlock(x, y, z);
- return;
+ return true;
}
if ( Block.odoor(b) != Block.Zero ) {
if ( b == Block.odoor8 || b == Block.odoor8_air ) {
@@ -750,11 +687,11 @@ namespace MCGalaxy {
} else {
RevertBlock(x, y, z);
}
- return;
+ return true;
}
switch ( b ) {
- case Block.door_tree__air: //Door_air
+ case Block.door_tree_air: //Door_air
case Block.door_obsidian_air:
case Block.door_glass_air:
case Block.door_stone_air:
@@ -779,15 +716,10 @@ namespace MCGalaxy {
case Block.door_book_air:
break;
- case Block.c4det:
- Level.C4.BlowUp(new ushort[] { x, y, z }, level);
- level.Blockchange(x, y, z, Block.air);
- break;
-
default:
Block.HandleDelete handler = Block.deleteHandlers[b];
if (handler != null) {
- if (handler(this, b, x, y, z)) return;
+ if (handler(this, b, x, y, z)) return false;
} else {
ChangeBlock(x, y, z, Block.air, 0);
}
@@ -795,6 +727,7 @@ namespace MCGalaxy {
}
if ((level.physics == 0 || level.physics == 5) && level.GetTile(x, (ushort)(y - 1), z) == Block.dirt)
ChangeBlock(x, (ushort)(y - 1), z, Block.grass, 0);
+ return true;
}
void PlaceBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
@@ -941,33 +874,10 @@ return;
level.Blockchange(x, (ushort)(y - 1), z, Block.DoorAirs(b1));
if ( level.PosToInt( x, y, z ) != oldIndex ) {
- if ( b == Block.air_portal || b == Block.water_portal || b == Block.lava_portal ) {
- HandlePortal(this, x, y, z, b);
- } else if ( b1 == Block.air_portal || b1 == Block.water_portal || b1 == Block.lava_portal ) {
- HandlePortal(this, x, (ushort)(y - 1), z, b1);
- }
-
- if ( b == Block.MsgAir || b == Block.MsgWater || b == Block.MsgLava ) {
- HandleMsgBlock(this, x, y, z, b);
- } else if ( b1 == Block.MsgAir || b1 == Block.MsgWater || b1 == Block.MsgLava ) {
- HandleMsgBlock(this, x, (ushort)(y - 1), z, b1);
- } else if ( b == Block.checkpoint ) {
- useCheckpointSpawn = true;
- checkpointX = x; checkpointY = y; checkpointZ = z;
- int index = level.PosToInt(x, y, z);
- if (index != lastCheckpointIndex) {
- SendSpawn(0xFF, color + truename, pos[0], (ushort)((y - 1) * 32 + 51), pos[2], rot[0], rot[1]);
- lastCheckpointIndex = index;
- }
- } else if ( b1 == Block.checkpoint ) {
- useCheckpointSpawn = true;
- checkpointX = x; checkpointY = (ushort)(y + 1); checkpointZ = z;
- int index = level.PosToInt(x, (ushort)(y - 1), z);
- if (index != lastCheckpointIndex) {
- SendSpawn(0xFF, color + truename, pos[0], (ushort)((y - 1) * 32 + 51), pos[2], rot[0], rot[1]);
- lastCheckpointIndex = index;
- }
- }
+ Block.HandleWalkthrough handler = Block.walkthroughHandlers[b];
+ if (handler != null && handler(this, b, x, y, z)) return;
+ handler = Block.walkthroughHandlers[b1];
+ if (handler != null && handler(this, b, x, y, z)) return;
}
}
if ( ( b == Block.tntexplosion || b1 == Block.tntexplosion ) && PlayingTntWars ) { }