From e83824975496e3480dea71ca5bd99a36d75d02b2 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 8 Dec 2015 10:19:43 +1100 Subject: [PATCH] Move physics for blocks with extrainfo into their own class. Remove explode/rainbow/finite extrainfo as they are unused in the core. --- Commands/building/CmdRestartPhysics.cs | 5 +- Levels/Level.cs | 334 +------------------------ Levels/Physics/ExtraInfoPhysics.cs | 170 +++++++++++++ MCGalaxy_.csproj | 1 + 4 files changed, 181 insertions(+), 329 deletions(-) create mode 100644 Levels/Physics/ExtraInfoPhysics.cs 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 @@ +