First stage of final physics refactoring (in preparation for making them extensible).

This commit is contained in:
UnknownShadow200 2016-04-02 22:34:27 +11:00
parent 2029ee0c94
commit a28d0d38e2
9 changed files with 198 additions and 236 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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 ||

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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 &&

View File

@ -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);

View File

@ -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 &&

View File

@ -480,7 +480,7 @@
<Compile Include="Levels\Physics\HunterPhysics.cs" />
<Compile Include="Levels\Physics\LiquidPhysics.cs" />
<Compile Include="Levels\Physics\RocketPhysics.cs" />
<Compile Include="Levels\Physics\SimplePhysics.cs" />
<Compile Include="Levels\Physics\OtherPhysics.cs" />
<Compile Include="Levels\Physics\SnakePhysics.cs" />
<Compile Include="Levels\Physics\TrainPhysics.cs" />
<Compile Include="Levels\Physics\TntPhysics.cs" />