diff --git a/Commands/other/CmdGun.cs b/Commands/other/CmdGun.cs index a3cf7ad0a..aaedb4ae2 100644 --- a/Commands/other/CmdGun.cs +++ b/Commands/other/CmdGun.cs @@ -213,7 +213,7 @@ namespace MCGalaxy.Commands { if (bp.ending == 1) { - if ((!Block.LavaKill(by) && !Block.NeedRestart(by)) && by != Block.glass) + if ((!Block.FireKill(by) && !Block.NeedRestart(by)) && by != Block.glass) { break; } diff --git a/Commands/other/CmdMissile.cs b/Commands/other/CmdMissile.cs index 5c9eaa5d7..fcb770eb7 100644 --- a/Commands/other/CmdMissile.cs +++ b/Commands/other/CmdMissile.cs @@ -218,7 +218,7 @@ namespace MCGalaxy.Commands { if (bp.ending == 1) { - if ((!Block.LavaKill(by) && !Block.NeedRestart(by)) && by != Block.glass) + if ((!Block.FireKill(by) && !Block.NeedRestart(by)) && by != Block.glass) { break; } @@ -280,7 +280,7 @@ namespace MCGalaxy.Commands { if (bp.ending == 1) { - if ((!Block.LavaKill(by) && !Block.NeedRestart(by)) && by != Block.glass) + if ((!Block.FireKill(by) && !Block.NeedRestart(by)) && by != Block.glass) { break; } diff --git a/Levels/Block.cs b/Levels/Block.cs index a3213fd29..3ddf7bb6d 100644 --- a/Levels/Block.cs +++ b/Levels/Block.cs @@ -941,10 +941,15 @@ namespace MCGalaxy return false; } + public static bool FireKill(byte type) { + return type != Block.air && LavaKill(type); + } + public static bool LavaKill(byte type) { switch (type) { + case Block.air: case Block.wood: case Block.shrub: case Block.trunk: diff --git a/Levels/Level.cs b/Levels/Level.cs index 0a8871684..38174457b 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -1377,7 +1377,6 @@ namespace MCGalaxy try { IntToPos(C.b, out x, out y, out z); - bool InnerChange = false; string foundInfo = C.extraInfo; if (PhysicsUpdate != null) PhysicsUpdate(x, y, z, C.time, C.extraInfo, this); @@ -1470,133 +1469,23 @@ namespace MCGalaxy C.time = 255; break; - case Block.water: //Active_water + case Block.water: case Block.activedeathwater: LiquidPhysics.DoWater(this, C, rand); break; case Block.WaterDown: - rand = new Random(); - - switch (GetTile(x, (ushort)(y - 1), z)) - { - case Block.air: - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.WaterDown); - if (C.extraInfo.IndexOf("wait") == -1) C.time = 255; - break; - case Block.air_flood_down: - break; - case Block.lavastill: - case Block.waterstill: - break; - default: - if (GetTile(x, (ushort)(y - 1), z) != - Block.WaterDown) - { - PhysWater( - PosToInt((ushort)(x + 1), y, z), - blocks[C.b]); - PhysWater( - PosToInt((ushort)(x - 1), y, z), - blocks[C.b]); - PhysWater( - PosToInt(x, y, (ushort)(z + 1)), - blocks[C.b]); - PhysWater( - PosToInt(x, y, (ushort)(z - 1)), - blocks[C.b]); - if (C.extraInfo.IndexOf("wait") == -1) - C.time = 255; - } - break; - } + ExtLiquidPhysics.DoWaterfall(this, C, rand); break; - case Block.LavaDown: - rand = new Random(); - - switch (GetTile(x, (ushort)(y - 1), z)) - { - case Block.air: - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.LavaDown); - if (C.extraInfo.IndexOf("wait") == -1) C.time = 255; - break; - case Block.air_flood_down: - break; - case Block.lavastill: - case Block.waterstill: - break; - default: - if (GetTile(x, (ushort)(y - 1), z) != - Block.LavaDown) - { - PhysLava( - PosToInt((ushort)(x + 1), y, z), - blocks[C.b]); - PhysLava( - PosToInt((ushort)(x - 1), y, z), - blocks[C.b]); - PhysLava( - PosToInt(x, y, (ushort)(z + 1)), - blocks[C.b]); - PhysLava( - PosToInt(x, y, (ushort)(z - 1)), - blocks[C.b]); - if (C.extraInfo.IndexOf("wait") == -1) - C.time = 255; - } - break; - } + ExtLiquidPhysics.DoLavafall(this, C, rand); break; - case Block.WaterFaucet: - //rand = new Random(); - C.time++; - if (C.time < 2) break; - - C.time = 0; - - switch (GetTile(x, (ushort)(y - 1), z)) - { - case Block.WaterDown: - case Block.air: - if (rand.Next(1, 10) > 7) - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.air_flood_down); - break; - case Block.air_flood_down: - if (rand.Next(1, 10) > 4) - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.WaterDown); - break; - } + ExtLiquidPhysics.DoFaucet(this, C, rand, Block.WaterDown); break; - case Block.LavaFaucet: - //rand = new Random(); - C.time++; - if (C.time < 2) break; - - C.time = 0; - - switch (GetTile(x, (ushort)(y - 1), z)) - { - case Block.LavaDown: - case Block.air: - if (rand.Next(1, 10) > 7) - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.air_flood_down); - break; - case Block.air_flood_down: - if (rand.Next(1, 10) > 4) - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.LavaDown); - break; - } + ExtLiquidPhysics.DoFaucet(this, C, rand, Block.LavaDown); break; - - case Block.lava: //Active_lava + case Block.lava: case Block.activedeathlava: LiquidPhysics.DoLava(this, C, rand); break; @@ -1710,144 +1599,11 @@ namespace MCGalaxy TrainPhysics.Do(this, C, rand); break; case Block.magma: - C.time++; - if (C.time < 3) break; - - if (GetTile(x, (ushort)(y - 1), z) == Block.air) - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.magma); - else if (GetTile(x, (ushort)(y - 1), z) != Block.magma) - { - PhysLava(PosToInt((ushort)(x + 1), y, z), blocks[C.b]); - PhysLava(PosToInt((ushort)(x - 1), y, z), blocks[C.b]); - PhysLava(PosToInt(x, y, (ushort)(z + 1)), blocks[C.b]); - PhysLava(PosToInt(x, y, (ushort)(z - 1)), blocks[C.b]); - } - - if (physics > 1) - { - if (C.time > 10) - { - C.time = 0; - - if (Block.LavaKill(GetTile((ushort)(x + 1), y, z))) - { - AddUpdate(PosToInt((ushort)(x + 1), y, z), - Block.magma); - InnerChange = true; - } - if (Block.LavaKill(GetTile((ushort)(x - 1), y, z))) - { - AddUpdate(PosToInt((ushort)(x - 1), y, z), - Block.magma); - InnerChange = true; - } - if (Block.LavaKill(GetTile(x, y, (ushort)(z + 1)))) - { - AddUpdate(PosToInt(x, y, (ushort)(z + 1)), - Block.magma); - InnerChange = true; - } - if (Block.LavaKill(GetTile(x, y, (ushort)(z - 1)))) - { - AddUpdate(PosToInt(x, y, (ushort)(z - 1)), - Block.magma); - InnerChange = true; - } - if (Block.LavaKill(GetTile(x, (ushort)(y - 1), z))) - { - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.magma); - InnerChange = true; - } - - if (InnerChange) - { - if ( - Block.LavaKill(GetTile(x, (ushort)(y + 1), - z))) - AddUpdate( - PosToInt(x, (ushort)(y + 1), z), - Block.magma); - } - } - } - + ExtLiquidPhysics.DoMagma(this, C, rand); break; case Block.geyser: - C.time++; - - if (GetTile(x, (ushort)(y - 1), z) == Block.air) - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.geyser); - else if (GetTile(x, (ushort)(y - 1), z) != Block.geyser) - { - PhysWater(PosToInt((ushort)(x + 1), y, z), - blocks[C.b]); - PhysWater(PosToInt((ushort)(x - 1), y, z), - blocks[C.b]); - PhysWater(PosToInt(x, y, (ushort)(z + 1)), - blocks[C.b]); - PhysWater(PosToInt(x, y, (ushort)(z - 1)), - blocks[C.b]); - } - - if (physics > 1) - { - if (C.time > 10) - { - C.time = 0; - - if ( - Block.WaterKill(GetTile((ushort)(x + 1), y, z))) - { - AddUpdate(PosToInt((ushort)(x + 1), y, z), - Block.geyser); - InnerChange = true; - } - if ( - Block.WaterKill(GetTile((ushort)(x - 1), y, z))) - { - AddUpdate(PosToInt((ushort)(x - 1), y, z), - Block.geyser); - InnerChange = true; - } - if ( - Block.WaterKill(GetTile(x, y, (ushort)(z + 1)))) - { - AddUpdate(PosToInt(x, y, (ushort)(z + 1)), - Block.geyser); - InnerChange = true; - } - if ( - Block.WaterKill(GetTile(x, y, (ushort)(z - 1)))) - { - AddUpdate(PosToInt(x, y, (ushort)(z - 1)), - Block.geyser); - InnerChange = true; - } - if ( - Block.WaterKill(GetTile(x, (ushort)(y - 1), z))) - { - AddUpdate(PosToInt(x, (ushort)(y - 1), z), - Block.geyser); - InnerChange = true; - } - - if (InnerChange) - { - if ( - Block.WaterKill(GetTile(x, - (ushort)(y + 1), - z))) - AddUpdate( - PosToInt(x, (ushort)(y + 1), z), - Block.geyser); - } - } - } + ExtLiquidPhysics.DoGeyser(this, C, rand); break; - case Block.birdblack: case Block.birdwhite: case Block.birdlava: diff --git a/Levels/Physics/ExtLiquidPhysics.cs b/Levels/Physics/ExtLiquidPhysics.cs new file mode 100644 index 000000000..0046aa61d --- /dev/null +++ b/Levels/Physics/ExtLiquidPhysics.cs @@ -0,0 +1,177 @@ +/* + 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 ExtLiquidPhysics { + + public static void DoMagma(Level lvl, Check C, Random rand) { + C.time++; + if (C.time < 3) return; + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + byte below = lvl.GetTile(x, (ushort)(y - 1), z); + + if (below == Block.air) { + lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), Block.magma); + } else if (below != Block.magma) { + byte block = lvl.blocks[C.b]; + lvl.PhysLava(lvl.PosToInt((ushort)(x + 1), y, z), block); + lvl.PhysLava(lvl.PosToInt((ushort)(x - 1), y, z), block); + lvl.PhysLava(lvl.PosToInt(x, y, (ushort)(z + 1)), block); + lvl.PhysLava(lvl.PosToInt(x, y, (ushort)(z - 1)), block); + } + + if (lvl.physics <= 1 || C.time <= 10) return; + C.time = 0; + bool flowUp = false; + + MagmaFlow(lvl, x - 1, y, z, ref flowUp); + MagmaFlow(lvl, x + 1, y, z, ref flowUp); + MagmaFlow(lvl, x, y - 1, z, ref flowUp); + MagmaFlow(lvl, x, y, z - 1, ref flowUp); + MagmaFlow(lvl, x, y, z + 1, ref flowUp); + if (flowUp) + MagmaFlow(lvl, x, y + 1, z, ref flowUp); + } + + static void MagmaFlow(Level lvl, int x, int y, int z, ref bool flowUp) { + int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); + if (index >= 0 && Block.LavaKill(lvl.blocks[index])) { + lvl.AddUpdate(index, Block.magma); + flowUp = true; + } + } + + public static void DoGeyser(Level lvl, Check C, Random rand) { + C.time++; + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + byte below = lvl.GetTile(x, (ushort)(y - 1), z); + + if (below == Block.air) { + lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), Block.geyser); + } else if (below != Block.geyser) { + byte block = lvl.blocks[C.b]; + lvl.PhysWater(lvl.PosToInt((ushort)(x + 1), y, z), block); + lvl.PhysWater(lvl.PosToInt((ushort)(x - 1), y, z), block); + lvl.PhysWater(lvl.PosToInt(x, y, (ushort)(z + 1)), block); + lvl.PhysWater(lvl.PosToInt(x, y, (ushort)(z - 1)), block); + } + + if (lvl.physics <= 1 || C.time <= 10) return; + C.time = 0; + bool flowUp = false; + + GeyserFlow(lvl, x - 1, y, z, ref flowUp); + GeyserFlow(lvl, x + 1, y, z, ref flowUp); + GeyserFlow(lvl, x, y - 1, z, ref flowUp); + GeyserFlow(lvl, x, y, z - 1, ref flowUp); + GeyserFlow(lvl, x, y, z + 1, ref flowUp); + if (flowUp) + GeyserFlow(lvl, x, y + 1, z, ref flowUp); + } + + static void GeyserFlow(Level lvl, int x, int y, int z, ref bool flowUp) { + int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); + if (index >= 0 && Block.WaterKill(lvl.blocks[index])) { + lvl.AddUpdate(index, Block.geyser); + flowUp = true; + } + } + + public static void DoWaterfall(Level lvl, Check C, Random rand) { + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + byte below = lvl.GetTile(x, (ushort)(y - 1), z); + + switch (below) + { + case Block.air: + lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), Block.WaterDown); + if (C.extraInfo.IndexOf("wait") == -1) + C.time = 255; + break; + case Block.air_flood_down: + case Block.lavastill: + case Block.waterstill: + case Block.WaterDown: + break; + default: + byte block = lvl.blocks[C.b]; + lvl.PhysWater(lvl.PosToInt((ushort)(x + 1), y, z), block); + lvl.PhysWater(lvl.PosToInt((ushort)(x - 1), y, z), block); + lvl.PhysWater(lvl.PosToInt(x, y, (ushort)(z + 1)),block); + lvl.PhysWater(lvl.PosToInt(x, y, (ushort)(z - 1)), block); + if (C.extraInfo.IndexOf("wait") == -1) + C.time = 255; + break; + } + } + + public static void DoLavafall(Level lvl, Check C, Random rand) { + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + byte below = lvl.GetTile(x, (ushort)(y - 1), z); + + switch (below) + { + case Block.air: + lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), Block.LavaDown); + if (C.extraInfo.IndexOf("wait") == -1) + C.time = 255; + break; + case Block.air_flood_down: + case Block.lavastill: + case Block.waterstill: + case Block.LavaDown: + break; + default: + byte block = lvl.blocks[C.b]; + lvl.PhysLava(lvl.PosToInt((ushort)(x + 1), y, z), block); + lvl.PhysLava(lvl.PosToInt((ushort)(x - 1), y, z), block); + lvl.PhysLava(lvl.PosToInt(x, y, (ushort)(z + 1)),block); + lvl.PhysLava(lvl.PosToInt(x, y, (ushort)(z - 1)), block); + if (C.extraInfo.IndexOf("wait") == -1) + C.time = 255; + break; + } + } + + public static void DoFaucet(Level lvl, Check C, Random rand, byte target) { + C.time++; + if (C.time < 2) return; + C.time = 0; + + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + int index = lvl.PosToInt(x, (ushort)(y - 1), z); + if (index < 0) return; + + byte block = lvl.blocks[index]; + if (block == Block.air || block == target) { + if (rand.Next(1, 10) > 7) + lvl.AddUpdate(index, Block.air_flood_down); + } else if (block == Block.air_flood_down) { + if (rand.Next(1, 10) > 4) + lvl.AddUpdate(index, target); + } + } + } +} diff --git a/Levels/Physics/FirePhysics.cs b/Levels/Physics/FirePhysics.cs index 59ffd66be..2033b9d78 100644 --- a/Levels/Physics/FirePhysics.cs +++ b/Levels/Physics/FirePhysics.cs @@ -31,7 +31,7 @@ namespace MCGalaxy.BlockPhysics { static void ExpandDiagonal(Level lvl, ushort x, ushort y, ushort z, int xOffset, int yOffset, int zOffset) { - if (!Block.LavaKill(lvl.GetTile((ushort)(x + xOffset), + if (!Block.FireKill(lvl.GetTile((ushort)(x + xOffset), (ushort)(y + yOffset), (ushort)(z + zOffset)))) return; @@ -48,7 +48,7 @@ namespace MCGalaxy.BlockPhysics { if (index < 0) return; byte block = lvl.blocks[index]; - if (Block.LavaKill(block)) + if (Block.FireKill(block)) lvl.AddUpdate(index, Block.fire); else if (block == Block.tnt) lvl.MakeExplosion((ushort)x, (ushort)y, (ushort)z, -1); diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 6bffc0e39..9bc795bfb 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -427,6 +427,7 @@ +