diff --git a/Commands/building/CmdRestartPhysics.cs b/Commands/building/CmdRestartPhysics.cs
index 28cad7c48..26d4446e4 100644
--- a/Commands/building/CmdRestartPhysics.cs
+++ b/Commands/building/CmdRestartPhysics.cs
@@ -47,11 +47,8 @@ namespace MCGalaxy.Commands
switch (s)
{
case "drop":
- case "explode":
case "dissipate":
- case "finite":
case "wait":
- case "rainbow":
break;
case "revert":
if (skip) break;
@@ -96,7 +93,7 @@ namespace MCGalaxy.Commands
{
Player.SendMessage(p, "/restartphysics ([type] [num]) ([type2] [num2]) (...) - Restarts every physics block in an area");
Player.SendMessage(p, "[type] will set custom physics for selected blocks");
- Player.SendMessage(p, "Possible [types]: drop, explode, dissipate, finite, wait, rainbow, revert");
+ Player.SendMessage(p, "Possible [types]: drop, dissipate, wait, revert");
Player.SendMessage(p, "/rp revert takes block names");
}
public void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type)
diff --git a/Levels/Level.cs b/Levels/Level.cs
index 1a4a77ce9..a661dfd6d 100644
--- a/Levels/Level.cs
+++ b/Levels/Level.cs
@@ -1329,112 +1329,13 @@ namespace MCGalaxy
try
{
IntToPos(C.b, out x, out y, out z);
- string foundInfo = C.extraInfo;
if (PhysicsUpdate != null)
- {
PhysicsUpdate(x, y, z, C.time, C.extraInfo, this);
- }
- newPhysic:
- if (foundInfo != "")
- {
- int currentLoop = 0;
- if (!foundInfo.Contains("wait"))
- if (blocks[C.b] == Block.air) C.extraInfo = "";
-
- bool wait = false;
- int waitnum = 0;
- bool door = false;
-
- foreach (string s in C.extraInfo.Split(' '))
- {
- if (currentLoop % 2 == 0)
- {
- //Type of code
- switch (s)
- {
- case "wait":
- wait = true;
- waitnum =
- int.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
- case "door":
- door = true;
- break;
- }
- }
- currentLoop++;
- }
-
- startCheck:
- if (wait)
- {
- int storedInt = 0;
- if (door && C.time < 2)
- {
- storedInt = IntOffset(C.b, -1, 0, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 1, 0, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, 1, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, -1, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, 0, 1);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, 0, -1);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- }
-
- if (waitnum <= C.time)
- {
- wait = false;
- C.extraInfo =
- C.extraInfo.Substring(0, C.extraInfo.IndexOf("wait ")) +
- C.extraInfo.Substring(
- C.extraInfo.IndexOf(' ',
- C.extraInfo.IndexOf("wait ") +
- 5) + 1);
- //C.extraInfo = C.extraInfo.Substring(8);
- goto startCheck;
- }
- C.time++;
- foundInfo = "";
- goto newPhysic;
- }
- }
- else
- {
+
+ if (C.extraInfo != "") {
+ if (ExtraInfoPhysics.DoDoorsOnly(this, C, null))
+ DoorPhysics.Do(this, C);
+ } else {
DoorPhysics.Do(this, C);
}
}
@@ -1491,227 +1392,10 @@ namespace MCGalaxy
PhysicsUpdate(x, y, z, C.time, C.extraInfo, this);
OnPhysicsUpdateEvent.Call(x, y, z, C.time, C.extraInfo, this);
newPhysic:
- if (foundInfo != "")
- {
- int currentLoop = 0;
- if (!foundInfo.Contains("wait"))
- if (blocks[C.b] == Block.air) C.extraInfo = "";
-
- bool drop = false;
- int dropnum = 0;
- bool wait = false;
- int waitnum = 0;
- bool dissipate = false;
- int dissipatenum = 0;
- bool revert = false;
- byte reverttype = 0;
- bool explode = false;
- int explodenum = 0;
- bool finiteWater = false;
- bool rainbow = false;
- int rainbownum = 0;
- bool door = false;
-
- foreach (string s in C.extraInfo.Split(' '))
- {
- if (currentLoop % 2 == 0)
- {
- //Type of code
- switch (s)
- {
- case "wait":
- wait = true;
- waitnum =
- int.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
- case "drop":
- drop = true;
- dropnum =
- int.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
- case "dissipate":
- dissipate = true;
- dissipatenum =
- int.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
- case "revert":
- revert = true;
- reverttype =
- byte.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
- case "explode":
- explode = true;
- explodenum =
- int.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
-
- case "finite":
- finiteWater = true;
- break;
-
- case "rainbow":
- rainbow = true;
- rainbownum =
- int.Parse(
- C.extraInfo.Split(' ')[currentLoop + 1]);
- break;
-
- case "door":
- door = true;
- break;
- }
- }
- currentLoop++;
- }
-
- startCheck:
- if (wait)
- {
- int storedInt = 0;
- if (door && C.time < 2)
- {
- storedInt = IntOffset(C.b, -1, 0, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 1, 0, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, 1, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, -1, 0);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, 0, 1);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- storedInt = IntOffset(C.b, 0, 0, -1);
- if (Block.tDoor(blocks[storedInt]))
- {
- AddUpdate(storedInt, Block.air, false,
- "wait 10 door 1 revert " +
- blocks[storedInt].ToString());
- }
- }
-
- if (waitnum <= C.time)
- {
- wait = false;
- C.extraInfo =
- C.extraInfo.Substring(0, C.extraInfo.IndexOf("wait ")) +
- C.extraInfo.Substring(
- C.extraInfo.IndexOf(' ',
- C.extraInfo.IndexOf("wait ") +
- 5) + 1);
- //C.extraInfo = C.extraInfo.Substring(8);
- goto startCheck;
- }
- C.time++;
- foundInfo = "";
- goto newPhysic;
- }
- if (finiteWater)
- FinitePhysics.DoWaterOrLava(this, C, rand);
- else if (rainbow)
- if (C.time < 4)
- {
- C.time++;
- }
- else
- {
- if (rainbownum > 2)
- {
- if (blocks[C.b] < Block.red ||
- blocks[C.b] > Block.darkpink)
- {
- AddUpdate(C.b, Block.red, true);
- }
- else
- {
- if (blocks[C.b] == Block.darkpink)
- AddUpdate(C.b, Block.red);
- else AddUpdate(C.b, (blocks[C.b] + 1));
- }
- }
- else
- {
- AddUpdate(C.b, rand.Next(21, 33));
- }
- }
- else
- {
- if (revert)
- {
- AddUpdate(C.b, reverttype);
- C.extraInfo = "";
- }
- // Not setting drop = false can cause occasional leftover blocks, since C.extraInfo is emptied, so
- // drop can generate another block with no dissipate/explode information.
- if (dissipate)
- if (rand.Next(1, 100) <= dissipatenum)
- {
- if (!ListUpdate.Exists(Update => Update.b == C.b))
- {
- AddUpdate(C.b, Block.air);
- C.extraInfo = "";
- drop = false;
- }
- else
- {
- AddUpdate(C.b, blocks[C.b], false, C.extraInfo);
- }
- }
- if (explode)
- if (rand.Next(1, 100) <= explodenum)
- {
- MakeExplosion(x, y, z, 0);
- C.extraInfo = "";
- drop = false;
- }
- if (drop)
- if (rand.Next(1, 100) <= dropnum)
- if (GetTile(x, (ushort)(y - 1), z) == Block.air ||
- GetTile(x, (ushort)(y - 1), z) == Block.lava ||
- GetTile(x, (ushort)(y - 1), z) == Block.water)
- {
- if (rand.Next(1, 100) <
- int.Parse(C.extraInfo.Split(' ')[1]))
- {
- if (
- AddUpdate(
- PosToInt(x, (ushort)(y - 1), z),
- blocks[C.b], false, C.extraInfo))
- {
- AddUpdate(C.b, Block.air);
- C.extraInfo = "";
- }
- }
- }
+ if (foundInfo != "") {
+ if (ExtraInfoPhysics.DoComplex(this, C, rand)) {
+ foundInfo = "";
+ goto newPhysic;
}
}
else
diff --git a/Levels/Physics/ExtraInfoPhysics.cs b/Levels/Physics/ExtraInfoPhysics.cs
new file mode 100644
index 000000000..ef0599b1b
--- /dev/null
+++ b/Levels/Physics/ExtraInfoPhysics.cs
@@ -0,0 +1,170 @@
+/*
+ Copyright 2015 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;
+
+namespace MCGalaxy.BlockPhysics {
+
+ public static class ExtraInfoPhysics {
+
+ public static bool DoDoorsOnly(Level lvl, Check C, Random rand) {
+ if (!C.extraInfo.Contains("wait") && lvl.blocks[C.b] == Block.air)
+ C.extraInfo = "";
+
+ bool wait = false, door = false;
+ int waitTime = 0;
+ string[] parts = C.extraInfo.Split(' ');
+ for (int i = 0; i < parts.Length; i++) {
+ if (i % 2 != 0) continue;
+
+ switch (parts[i]) {
+ case "wait":
+ waitTime = int.Parse(parts[i + 1]);
+ wait = true; break;
+ case "door":
+ door = true; break;
+ }
+ }
+ if (!wait)
+ return false;
+
+ if (door && C.time < 2) {
+ // TODO: perhaps do proper bounds checking
+ Checktdoor(lvl, lvl.IntOffset(C.b, -1, 0, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 1, 0, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, -1, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, 1, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, 0, -1));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, 0, 1));
+ }
+
+ if (C.time > waitTime) {
+ int waitIndex = C.extraInfo.IndexOf("wait ");
+ C.extraInfo =
+ C.extraInfo.Substring(0, waitIndex) +
+ C.extraInfo.Substring(C.extraInfo.IndexOf(' ', waitIndex + 5) + 1);
+ return false;
+ }
+ C.time++;
+ return true;
+ }
+
+ static void Checktdoor(Level lvl, int index) {
+ if (index < 0 || index >= lvl.blocks.Length) return;
+ byte block = lvl.blocks[index];
+
+ if (Block.tDoor(block)) {
+ lvl.AddUpdate(index, Block.air, false,
+ "wait 10 door 1 revert " + block.ToString());
+ }
+ }
+
+ public static bool DoComplex(Level lvl, Check C, Random rand) {
+ if (!C.extraInfo.Contains("wait") && lvl.blocks[C.b] == Block.air)
+ C.extraInfo = "";
+
+ bool wait = false, drop = false, dissipate = false, revert = false, door = false;
+ int waitTime = 0, dropnum = 0, dissipatenum = 0; byte reverttype = 0;
+ string[] parts = C.extraInfo.Split(' ');
+
+ for (int i = 0; i < parts.Length; i++) {
+ if (i % 2 != 0) continue;
+
+ switch (parts[i]) {
+ case "wait":
+ waitTime = int.Parse(parts[i + 1]);
+ wait = true; break;
+ case "drop":
+ dropnum = int.Parse(parts[i + 1]);
+ drop = true; break;
+ case "dissipate":
+ dissipatenum = int.Parse(parts[i + 1]);
+ dissipate = true; break;
+ case "revert":
+ reverttype = byte.Parse(parts[i + 1]);
+ revert = true; break;
+ case "door":
+ door = true; break;
+ }
+ }
+
+ if (wait) {
+ if (door && C.time < 2) {
+ Checktdoor(lvl, lvl.IntOffset(C.b, -1, 0, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 1, 0, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, -1, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, 1, 0));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, 0, -1));
+ Checktdoor(lvl, lvl.IntOffset(C.b, 0, 0, 1));
+ }
+
+ if (C.time > waitTime) {
+ int waitIndex = C.extraInfo.IndexOf("wait ");
+ C.extraInfo =
+ C.extraInfo.Substring(0, waitIndex) +
+ C.extraInfo.Substring(C.extraInfo.IndexOf(' ', waitIndex + 5) + 1);
+ DoOther(lvl, C, rand, revert, dissipate, drop, reverttype, dissipatenum, dropnum);
+ return false;
+ }
+ C.time++;
+ return true;
+ }
+ DoOther(lvl, C, rand, revert, dissipate, drop, reverttype, dissipatenum, dropnum);
+ return false;
+ }
+
+ static void DoOther(Level lvl, Check C, Random rand, bool revert, bool dissipate,
+ bool drop, byte reverttype, int dissipatenum, int dropnum) {
+ ushort x, y, z;
+ lvl.IntToPos(C.b, out x, out y, out z);
+ if (revert) {
+ lvl.AddUpdate(C.b, reverttype);
+ C.extraInfo = "";
+ }
+
+ // Not setting drop = false can cause occasional leftover blocks, since C.extraInfo is emptied, so
+ // drop can generate another block with no dissipate/explode information.
+ if (dissipate && rand.Next(1, 100) <= dissipatenum) {
+ if (!lvl.ListUpdate.Exists(Update => Update.b == C.b)) {
+ lvl.AddUpdate(C.b, Block.air);
+ C.extraInfo = "";
+ drop = false;
+ } else {
+ lvl.AddUpdate(C.b, lvl.blocks[C.b], false, C.extraInfo);
+ }
+ }
+
+ if (drop && rand.Next(1, 100) <= dropnum)
+ DoDrop(lvl, C, rand, dropnum, x, y, z);
+ }
+
+ static void DoDrop(Level lvl, Check C, Random rand, int dropnum, ushort x, ushort y, ushort z) {
+ int index = lvl.PosToInt(x, (ushort)(y - 1), z);
+ if (index < 0)
+ return;
+
+ byte below = lvl.blocks[index];
+ if (!(below == Block.air || below == Block.lava || below == Block.water))
+ return;
+
+ if (rand.Next(1, 100) < dropnum && lvl.AddUpdate(index, lvl.blocks[C.b], false, C.extraInfo)) {
+ lvl.AddUpdate(C.b, Block.air);
+ C.extraInfo = "";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj
index 402ea3a9e..2c65d650c 100644
--- a/MCGalaxy_.csproj
+++ b/MCGalaxy_.csproj
@@ -426,6 +426,7 @@
+