From a28d0d38e22da52c4ca224997afbbad865a7b212 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 2 Apr 2016 22:34:27 +1100 Subject: [PATCH] First stage of final physics refactoring (in preparation for making them extensible). --- Blocks/Block.Convert.cs | 22 ++--- Levels/Level.Physics.cs | 157 +++----------------------------- Levels/Physics/AirPhysics.cs | 6 +- Levels/Physics/OtherPhysics.cs | 153 +++++++++++++++++++++++++++++++ Levels/Physics/SimplePhysics.cs | 75 --------------- Levels/Physics/SnakePhysics.cs | 8 ++ Levels/Physics/TntPhysics.cs | 5 + Levels/Physics/ZombiePhysics.cs | 6 ++ MCGalaxy_.csproj | 2 +- 9 files changed, 198 insertions(+), 236 deletions(-) create mode 100644 Levels/Physics/OtherPhysics.cs delete mode 100644 Levels/Physics/SimplePhysics.cs diff --git a/Blocks/Block.Convert.cs b/Blocks/Block.Convert.cs index 743211117..44d405faf 100644 --- a/Blocks/Block.Convert.cs +++ b/Blocks/Block.Convert.cs @@ -642,24 +642,24 @@ namespace MCGalaxy case op_water: return waterstill; case op_lava: return lavastill; - case griefer_stone: return stone; //Griefer_stone + case griefer_stone: return stone; case lava_sponge: return sponge; - case wood_float: return wood; //wood_float + case wood_float: return wood; case lava_fast: return lava; case 71: case 72: return Block.white; - case door_tree: return trunk;//door show by treetype - case door_obsidian: return obsidian;//door show by obsidian - case door_glass: return glass;//door show by glass - case door_stone: return rock;//door show by stone - case door_leaves: return leaf;//door show by leaves - case door_sand: return sand;//door show by sand - case door_wood: return wood;//door show by wood + case door_tree: return trunk; + case door_obsidian: return obsidian; + case door_glass: return glass; + case door_stone: return rock; + case door_leaves: return leaf; + case door_sand: return sand; + case door_wood: return wood; case door_green: return green; - case door_tnt: return tnt;//door show by TNT - case door_stair: return staircasestep;//door show by Stair + case door_tnt: return tnt; + case door_stair: return staircasestep; case door_iron: return iron; case door_dirt: return dirt; case door_grass: return grass; diff --git a/Levels/Level.Physics.cs b/Levels/Level.Physics.cs index 7efa1858f..9fb9abffb 100644 --- a/Levels/Level.Physics.cs +++ b/Levels/Level.Physics.cs @@ -239,7 +239,7 @@ namespace MCGalaxy { if (rand.Next(10) == 0) C.time++; break; } - if (StandardPhysics.DoLeafDecay(this, C)) + if (OtherPhysics.DoLeafDecay(this, C)) AddUpdate(C.b, Block.air); C.time = 255; break; @@ -295,15 +295,7 @@ namespace MCGalaxy { FinitePhysics.DoFaucet(this, C, rand); break; case Block.sand: case Block.gravel: - if (PhysSand(C.b, blocks[C.b])) - { - PhysAir(PosToInt((ushort)(x + 1), y, z)); - PhysAir(PosToInt((ushort)(x - 1), y, z)); - PhysAir(PosToInt(x, y, (ushort)(z + 1))); - PhysAir(PosToInt(x, y, (ushort)(z - 1))); - PhysAir(PosToInt(x, (ushort)(y + 1), z)); - } - C.time = 255; + OtherPhysics.DoFalling(this, C, blocks[C.b]); break; case Block.sponge: //SPONGE PhysSponge(C.b); @@ -352,18 +344,12 @@ namespace MCGalaxy { case Block.staircasestep: case Block.cobblestoneslab: - PhysStair(C.b); - C.time = 255; - break; - case Block.wood_float: //wood_float - PhysFloatwood(C.b); - C.time = 255; - break; - case Block.lava_fast: //lava_fast + OtherPhysics.DoStairs(this, C); break; + case Block.wood_float: + OtherPhysics.DoFloatwood(this, C); break; + case Block.lava_fast: case Block.fastdeathlava: - LiquidPhysics.DoFastLava(this, C, rand); - break; - + LiquidPhysics.DoFastLava(this, C, rand); break; //Special blocks that are not saved case Block.air_flood: AirPhysics.DoFlood(this, C, rand, AirFlood.Full, Block.air_flood); break; @@ -376,15 +362,11 @@ namespace MCGalaxy { case Block.smalltnt: TntPhysics.DoSmallTnt(this, C, rand); break; case Block.bigtnt: - TntPhysics.DoLargeTnt(this, C, rand, 1); - break; + TntPhysics.DoLargeTnt(this, C, rand, 1); break; case Block.nuketnt: - TntPhysics.DoLargeTnt(this, C, rand, 4); - break; + TntPhysics.DoLargeTnt(this, C, rand, 4); break; case Block.tntexplosion: - if (rand.Next(1, 11) <= 7) - AddUpdate(C.b, Block.air); - break; + TntPhysics.DoTntExplosion(this, C, rand); break; case Block.train: TrainPhysics.Do(this, C, rand); break; case Block.magma: @@ -397,12 +379,7 @@ namespace MCGalaxy { case Block.birdwater: BirdPhysics.Do(this, C, rand); break; case Block.snaketail: - if (GetTile(IntOffset(C.b, -1, 0, 0)) != Block.snake || - GetTile(IntOffset(C.b, 1, 0, 0)) != Block.snake || - GetTile(IntOffset(C.b, 0, 0, 1)) != Block.snake || - GetTile(IntOffset(C.b, 0, 0, -1)) != Block.snake) - C.data = "revert 0"; - break; + SnakePhysics.DoTail(this, C); break; case Block.snake: SnakePhysics.Do(this, C, rand); break; case Block.birdred: @@ -423,14 +400,9 @@ namespace MCGalaxy { case Block.firework: FireworkPhysics.Do(this, C, rand); break; case Block.zombiehead: - if (GetTile(IntOffset(C.b, 0, -1, 0)) != Block.zombiebody && - GetTile(IntOffset(C.b, 0, -1, 0)) != Block.creeper) - C.data = "revert 0"; - break; - case Block.zombiebody: + ZombiePhysics.DoHead(this, C); break; case Block.creeper: ZombiePhysics.Do(this, C, rand); break; - case Block.c4: C4.C4s c4 = C4.Find(this, ((Player)C.data).c4circuitNumber); if (c4 != null) { @@ -677,87 +649,6 @@ namespace MCGalaxy { break; } } - - bool PhysSand(int b, byte type) { //also does gravel - if (b == -1 || physics == 0 || physics == 5) return false; - - int tempb = b; - bool blocked = false, moved = false; - - do - { - tempb = IntOffset(tempb, 0, -1, 0); //Get block below each loop - if (GetTile(tempb) != Block.Zero) - { - switch (blocks[tempb]) - { - case 0: //air lava water - case 8: - case 10: - moved = true; - break; - - case 6: - case 37: - case 38: - case 39: - case 40: - if (physics > 1 && physics != 5) //Adv physics crushes plants with sand - { - moved = true; - } - else - { - blocked = true; - } - break; - - default: - blocked = true; - break; - } - if (physics > 1) - { - if (physics != 5) - { - blocked = true; - } - } - } - else - { - blocked = true; - } - } while (!blocked); - - if (moved) - { - AddUpdate(b, 0); - if (physics > 1) - { - AddUpdate(tempb, type); - } - else - { - AddUpdate(IntOffset(tempb, 0, 1, 0), type); - } - } - - return moved; - } - - void PhysStair(int b) { - int bBelow = IntOffset(b, 0, -1, 0); - byte tile = GetTile(bBelow); - - if (tile == Block.staircasestep) { - AddUpdate(b, Block.air); - AddUpdate(bBelow, Block.staircasefull); - } else if (tile == Block.cobblestoneslab) { - AddUpdate(b, Block.air); - AddUpdate(bBelow, Block.stone); - } - } internal bool CheckSpongeWater(ushort x, ushort y, ushort z) { for (int yy = y - 2; yy <= y + 2; ++yy) { @@ -819,30 +710,6 @@ namespace MCGalaxy { } } } - - void PhysFloatwood(int b) { - int tempb = IntOffset(b, 0, -1, 0); //Get block below - if (GetTile(tempb) != Block.Zero) - { - if (GetTile(tempb) == Block.air) - { - AddUpdate(b, Block.air); - AddUpdate(tempb, Block.wood_float); - return; - } - } - - tempb = IntOffset(b, 0, 1, 0); //Get block above - if (GetTile(tempb) != Block.Zero) - { - if (Block.Convert(GetTile(tempb)) == Block.water) - { - AddUpdate(b, Block.water); - AddUpdate(tempb, Block.wood_float); - return; - } - } - } public void MakeExplosion(ushort x, ushort y, ushort z, int size, bool force = false, TntWarsGame CheckForExplosionZone = null) { TntPhysics.MakeExplosion(this, x, y, z, size, force, CheckForExplosionZone); diff --git a/Levels/Physics/AirPhysics.cs b/Levels/Physics/AirPhysics.cs index 9c7cb8798..2ebff0288 100644 --- a/Levels/Physics/AirPhysics.cs +++ b/Levels/Physics/AirPhysics.cs @@ -80,16 +80,14 @@ namespace MCGalaxy.BlockPhysics { } static void FloodAir(Level lvl, int b, byte type) { - if (b == -1) - return; + if (b == -1) return; byte block = Block.Convert(lvl.blocks[b]); if (block == Block.water || block == Block.lava) lvl.AddUpdate(b, type); } internal static void PhysAir(Level lvl, int b) { - if (b == -1) - return; + if (b == -1) return; byte block = lvl.blocks[b]; byte convBlock = Block.Convert(block); if (convBlock == Block.water || convBlock == Block.lava || diff --git a/Levels/Physics/OtherPhysics.cs b/Levels/Physics/OtherPhysics.cs new file mode 100644 index 000000000..f431615ab --- /dev/null +++ b/Levels/Physics/OtherPhysics.cs @@ -0,0 +1,153 @@ +/* + Copyright 2015 MCGalaxy + Original level physics 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; + +namespace MCGalaxy.BlockPhysics { + + public static class OtherPhysics { + + public static bool DoLeafDecay(Level lvl, Check C) { + const int dist = 4; + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + + for (int xx = -dist; xx <= dist; xx++) + for (int yy = -dist; yy <= dist; yy++) + for (int zz = -dist; zz <= dist; zz++) + { + int index = lvl.PosToInt((ushort)(x + xx), (ushort)(y + yy), (ushort)(z + zz)); + if (index < 0) continue; + byte type = lvl.blocks[index]; + + if (type == Block.trunk) + lvl.leaves[index] = 0; + else if (type == Block.leaf) + lvl.leaves[index] = -2; + else + lvl.leaves[index] = -1; + } + + for (int i = 1; i <= dist; i++) + for (int xx = -dist; xx <= dist; xx++) + for (int yy = -dist; yy <= dist; yy++) + for (int zz = -dist; zz <= dist; zz++) + { + int index = lvl.PosToInt((ushort)(x + xx), (ushort)(y + yy), (ushort)(z + zz)); + if (index < 0) continue; + + if (lvl.leaves[index] == i - 1) { + CheckLeaf(lvl, i, x + xx - 1, y + yy, z + zz); + CheckLeaf(lvl, i, x + xx + 1, y + yy, z + zz); + CheckLeaf(lvl, i, x + xx, y + yy - 1, z + zz); + CheckLeaf(lvl, i, x + xx, y + yy + 1, z + zz); + CheckLeaf(lvl, i, x + xx, y + yy, z + zz - 1); + CheckLeaf(lvl, i, x + xx, y + yy, z + zz + 1); + } + } + return lvl.leaves[C.b] < 0; + } + + static void CheckLeaf(Level lvl, int i, int x, int y, int z) { + int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); + if (index < 0) return; + + sbyte type; + if (lvl.leaves.TryGetValue(index, out type) && type == -2) + lvl.leaves[index] = (sbyte)i; + } + + public static void DoFalling(Level lvl, Check C, byte type) { + if (lvl.physics == 0 || lvl.physics == 5) { C.time = 255; return; } + ushort x, y, z; + lvl.IntToPos(C.b, out x, out y, out z); + int index = C.b; + bool movedDown = false; + + do { + index = lvl.IntOffset(index, 0, -1, 0); //Get block below each loop + if (lvl.GetTile(index) == Block.Zero) break; + bool hitBlock = false; + + switch (lvl.blocks[index]) { + case Block.air: + case Block.water: + case Block.lava: + movedDown = true; + break; + //Adv physics crushes plants with sand + case Block.shrub: + case Block.yellowflower: + case Block.redflower: + case Block.mushroom: + case Block.redmushroom: + if (lvl.physics > 1) movedDown = true; + break; + default: + hitBlock = true; + break; + } + if (hitBlock || lvl.physics > 1) break; + } while (true); + + if (movedDown) { + lvl.AddUpdate(C.b, Block.air); + if (lvl.physics > 1) + lvl.AddUpdate(index, type); + else + lvl.AddUpdate(lvl.IntOffset(index, 0, 1, 0), type); + + AirPhysics.PhysAir(lvl, lvl.PosToInt((ushort)(x + 1), y, z)); + AirPhysics.PhysAir(lvl, lvl.PosToInt((ushort)(x - 1), y, z)); + AirPhysics.PhysAir(lvl, lvl.PosToInt(x, y, (ushort)(z + 1))); + AirPhysics.PhysAir(lvl, lvl.PosToInt(x, y, (ushort)(z - 1))); + AirPhysics.PhysAir(lvl, lvl.PosToInt(x, (ushort)(y + 1), z)); + } + C.time = 255; + } + + public static void DoStairs(Level lvl, Check C) { + int bBelow = lvl.IntOffset(C.b, 0, -1, 0); + byte tile = lvl.GetTile(bBelow); + + if (tile == Block.staircasestep) { + lvl.AddUpdate(C.b, Block.air); + lvl.AddUpdate(bBelow, Block.staircasefull); + } else if (tile == Block.cobblestoneslab) { + lvl.AddUpdate(C.b, Block.air); + lvl.AddUpdate(bBelow, Block.stone); + } + C.time = 255; + } + + public static void DoFloatwood(Level lvl, Check C) { + int index = lvl.IntOffset(C.b, 0, -1, 0); + if (lvl.GetTile(index) == Block.air) { + lvl.AddUpdate(C.b, Block.air); + lvl.AddUpdate(index, Block.wood_float); + } else { + index = lvl.IntOffset(C.b, 0, 1, 0); + if (Block.Convert(lvl.GetTile(index)) == Block.water) { + lvl.AddUpdate(C.b, lvl.blocks[index]); + lvl.AddUpdate(index, Block.wood_float); + } + } + C.time = 255; + } + } +} diff --git a/Levels/Physics/SimplePhysics.cs b/Levels/Physics/SimplePhysics.cs deleted file mode 100644 index be7e8b097..000000000 --- a/Levels/Physics/SimplePhysics.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright 2015 MCGalaxy - Original level physics 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; - -namespace MCGalaxy.BlockPhysics { - - public static class StandardPhysics { - - public static bool DoLeafDecay(Level lvl, Check C) { - const int dist = 4; - ushort x, y, z; - lvl.IntToPos(C.b, out x, out y, out z); - - for (int xx = -dist; xx <= dist; xx++) - for (int yy = -dist; yy <= dist; yy++) - for (int zz = -dist; zz <= dist; zz++) - { - int index = lvl.PosToInt((ushort)(x + xx), (ushort)(y + yy), (ushort)(z + zz)); - if (index < 0) continue; - byte type = lvl.blocks[index]; - - if (type == Block.trunk) - lvl.leaves[index] = 0; - else if (type == Block.leaf) - lvl.leaves[index] = -2; - else - lvl.leaves[index] = -1; - } - - for (int i = 1; i <= dist; i++) - for (int xx = -dist; xx <= dist; xx++) - for (int yy = -dist; yy <= dist; yy++) - for (int zz = -dist; zz <= dist; zz++) - { - int index = lvl.PosToInt((ushort)(x + xx), (ushort)(y + yy), (ushort)(z + zz)); - if (index < 0) continue; - - if (lvl.leaves[index] == i - 1) { - CheckLeaf(lvl, i, x + xx - 1, y + yy, z + zz); - CheckLeaf(lvl, i, x + xx + 1, y + yy, z + zz); - CheckLeaf(lvl, i, x + xx, y + yy - 1, z + zz); - CheckLeaf(lvl, i, x + xx, y + yy + 1, z + zz); - CheckLeaf(lvl, i, x + xx, y + yy, z + zz - 1); - CheckLeaf(lvl, i, x + xx, y + yy, z + zz + 1); - } - } - return lvl.leaves[C.b] < 0; - } - - static void CheckLeaf(Level lvl, int i, int x, int y, int z) { - int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); - if (index < 0) return; - - sbyte type; - if (lvl.leaves.TryGetValue(index, out type) && type == -2) - lvl.leaves[index] = (sbyte)i; - } - } -} diff --git a/Levels/Physics/SnakePhysics.cs b/Levels/Physics/SnakePhysics.cs index 888fadc8e..f9fb30de2 100644 --- a/Levels/Physics/SnakePhysics.cs +++ b/Levels/Physics/SnakePhysics.cs @@ -102,6 +102,14 @@ namespace MCGalaxy.BlockPhysics { } } + public static void DoTail(Level lvl, Check C) { + if (lvl.GetTile(lvl.IntOffset(C.b, -1, 0, 0)) != Block.snake + || lvl.GetTile(lvl.IntOffset(C.b, 1, 0, 0)) != Block.snake + || lvl.GetTile(lvl.IntOffset(C.b, 0, 0, 1)) != Block.snake + || lvl.GetTile(lvl.IntOffset(C.b, 0, 0, -1)) != Block.snake) + C.data = "revert 0"; + } + static bool MoveSnake(Level lvl, Check C, int index) { if ( lvl.GetTile(lvl.IntOffset(index, 0, -1, 0)) == Block.air && diff --git a/Levels/Physics/TntPhysics.cs b/Levels/Physics/TntPhysics.cs index bfe40504f..fbefa7721 100644 --- a/Levels/Physics/TntPhysics.cs +++ b/Levels/Physics/TntPhysics.cs @@ -33,6 +33,11 @@ namespace MCGalaxy.BlockPhysics { lvl.Blockchange(x, y, (ushort)(z - 1), lvl.GetTile(x, y, (ushort)(z - 1)) == Block.lavastill ? Block.air : Block.lavastill); } + public static void DoTntExplosion(Level lvl, Check C, Random rand) { + if (rand.Next(1, 11) <= 7) + lvl.AddUpdate(C.b, Block.air); + } + public static void DoLargeTnt(Level lvl, Check C, Random rand, int power) { ushort x, y, z; lvl.IntToPos(C.b, out x, out y, out z); diff --git a/Levels/Physics/ZombiePhysics.cs b/Levels/Physics/ZombiePhysics.cs index 5c0e160fe..329994987 100644 --- a/Levels/Physics/ZombiePhysics.cs +++ b/Levels/Physics/ZombiePhysics.cs @@ -105,6 +105,12 @@ namespace MCGalaxy.BlockPhysics { lvl.AddUpdate(lvl.IntOffset(C.b, 0, 1, 0), Block.air); } + public static void DoHead(Level lvl, Check C) { + if (lvl.GetTile(lvl.IntOffset(C.b, 0, -1, 0)) != Block.zombiebody + && lvl.GetTile(lvl.IntOffset(C.b, 0, -1, 0)) != Block.creeper) + C.data = "revert 0"; + } + static bool MoveZombie(Level lvl, Check C, int index) { if( lvl.GetTile(lvl.IntOffset(index, 0, -1, 0)) == Block.air && diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 87d511e60..d7b9d0352 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -480,7 +480,7 @@ - +