Second stage of physics refactoring - now all physics call separate functions. (So they can eventually be extended)

This commit is contained in:
UnknownShadow200 2016-04-03 00:19:55 +11:00
parent a28d0d38e2
commit 2924d8d969
26 changed files with 728 additions and 688 deletions

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.BlockPhysics;
namespace MCGalaxy.BlockBehaviour {
@ -71,7 +72,7 @@ namespace MCGalaxy.BlockBehaviour {
}
internal static bool C4Det(Player p, byte block, ushort x, ushort y, ushort z) {
Level.C4.BlowUp(new ushort[] { x, y, z }, p.level);
C4Physics.BlowUp(new ushort[] { x, y, z }, p.level);
p.ChangeBlock(x, y, z, Block.air, 0);
return false;
}

View File

@ -1,20 +1,22 @@
/*
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.
*/
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 MCGalaxy.BlockPhysics;
namespace MCGalaxy.Commands
{
public sealed class CmdC4 : Command
@ -27,11 +29,11 @@ namespace MCGalaxy.Commands
public CmdC4() { }
public override void Use(Player p, string message) {
if (p == null) { MessageInGameOnly(p); return; }
if (p == null) { MessageInGameOnly(p); return; }
if (p.level.physics >= 1 && p.level.physics < 5) {
sbyte numb = Level.C4.NextCircuit(p.level);
Level.C4.C4s c4 = new Level.C4.C4s(numb);
sbyte numb = C4Physics.NextCircuit(p.level);
C4Physics.C4Data c4 = new C4Physics.C4Data(numb);
p.level.C4list.Add(c4);
p.c4circuitNumber = numb;
Player.SendMessage(p, "Place any block for c4 and place a " + Colors.red + "red" + Server.DefaultColor + " block for the detonator!");
@ -40,28 +42,23 @@ namespace MCGalaxy.Commands
Player.SendMessage(p, "To use c4, the physics level must be 1, 2, 3 or 4");
}
}
public override void Help(Player p)
{
Player.SendMessage(p, "/c4 - Place c4!");
}
public void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
{
void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
p.ClearBlockchange();
if (type == Block.red) { Blockchange2(p, x, y, z, type, extType); return; }
if (type != Block.air)
{
p.level.Blockchange(p, x, y, z, Block.c4);
}
if (type != Block.air) { p.level.Blockchange(p, x, y, z, Block.c4); }
p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1);
}
public void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
{
void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
p.ClearBlockchange();
byte b = p.level.GetTile(x, y, z);
p.level.Blockchange(p, x, y, z, Block.c4det);
Player.SendMessage(p, "Placed detonator block!");
}
public override void Help(Player p) {
Player.SendMessage(p, "/c4 - Place c4!");
}
}
}

View File

@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MCGalaxy.BlockPhysics;
using MCGalaxy.Games;
using MCGalaxy.SQL;
@ -137,12 +138,12 @@ namespace MCGalaxy {
changed = true;
if (oldType == Block.custom_block) {
oldExtType = GetExtTile(x, y, z);
if (type != Block.custom_block)
RevertExtTileNoCheck(x, y, z);
oldExtType = GetExtTile(x, y, z);
if (type != Block.custom_block)
RevertExtTileNoCheck(x, y, z);
}
if (type == Block.custom_block)
SetExtTileNoCheck(x, y, z, extType);
SetExtTileNoCheck(x, y, z, extType);
if (p == null)
return;
@ -297,7 +298,7 @@ namespace MCGalaxy {
}
public void Blockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) {
if (DoBlockchange(p, x, y, z, type, extType))
if (DoBlockchange(p, x, y, z, type, extType))
Player.GlobalBlockchange(this, x, y, z, type, extType);
}
@ -317,9 +318,9 @@ namespace MCGalaxy {
}
if (b == Block.sponge && physics > 0 && type != Block.sponge)
PhysSpongeRemoved(PosToInt(x, y, z));
OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z));
if (b == Block.lava_sponge && physics > 0 && type != Block.lava_sponge)
PhysSpongeRemoved(PosToInt(x, y, z), true);
OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true);
errorLocation = "Undo buffer filling";
Player.UndoPos Pos;
@ -364,7 +365,7 @@ namespace MCGalaxy {
}
public void Blockchange(int b, byte type, bool overRide = false, string extraInfo = "", byte extType = 0, bool addUndo = true) { //Block change made by physics
if (DoPhysicsBlockchange(b, type, overRide, extraInfo, extType, addUndo))
if (DoPhysicsBlockchange(b, type, overRide, extraInfo, extType, addUndo))
Player.GlobalBlockchange(this, b, type, extType);
}
@ -379,7 +380,7 @@ namespace MCGalaxy {
internal bool DoPhysicsBlockchange(int b, byte type, bool overRide = false,
string extraInfo = "", byte extType = 0, bool addUndo = true) {
if (b < 0 || b >= blocks.Length || blocks == null) return false;
if (b < 0 || b >= blocks.Length || blocks == null) return false;
byte oldBlock = blocks[b];
byte oldExtType = oldBlock == Block.custom_block ? GetExtTile(b) : (byte)0;
try
@ -388,13 +389,13 @@ namespace MCGalaxy {
if (Block.OPBlocks(oldBlock) || (Block.OPBlocks(type) && extraInfo != "")) return false;
if (b == Block.sponge && physics > 0 && type != Block.sponge)
PhysSpongeRemoved(b);
OtherPhysics.DoSpongeRemoved(this, b);
if (b == Block.lava_sponge && physics > 0 && type != Block.lava_sponge)
PhysSpongeRemoved(b, true);
OtherPhysics.DoSpongeRemoved(this, b, true);
if (addUndo) {
UndoPos uP = default(UndoPos);
UndoPos uP = default(UndoPos);
uP.index = b;
uP.SetData(oldBlock, oldExtType, type, extType);
@ -412,13 +413,13 @@ namespace MCGalaxy {
blocks[b] = type;
if (type == Block.custom_block) {
ushort x, y, z;
IntToPos(b, out x, out y, out z);
SetExtTileNoCheck(x, y, z, extType);
ushort x, y, z;
IntToPos(b, out x, out y, out z);
SetExtTileNoCheck(x, y, z, extType);
} else if (oldBlock == Block.custom_block) {
ushort x, y, z;
IntToPos(b, out x, out y, out z);
RevertExtTileNoCheck(x, y, z);
ushort x, y, z;
IntToPos(b, out x, out y, out z);
RevertExtTileNoCheck(x, y, z);
}
if (physics > 0 && ((Block.Physics(type) || extraInfo != "")))
AddCheck(b, false, extraInfo);
@ -426,7 +427,7 @@ namespace MCGalaxy {
// Save bandwidth sending identical looking blocks, like air/op_air changes.
bool diffBlock = Block.Convert(oldBlock) != Block.Convert(type);
if (!diffBlock && oldBlock == Block.custom_block)
diffBlock = oldExtType != extType;
diffBlock = oldExtType != extType;
return diffBlock;
} catch {
blocks[b] = type;

View File

@ -96,9 +96,9 @@ namespace MCGalaxy {
wait = speedPhysics;
} else {
Player[] online = PlayerInfo.Online.Items;
Player[] online = PlayerInfo.Online.Items;
foreach (Player p in online) {
if (p.level != this) continue;
if (p.level != this) continue;
Player.SendMessage(p, "Physics warning!");
}
Server.s.Log("Physics warning on " + name);
@ -172,7 +172,7 @@ namespace MCGalaxy {
lastUpdate = ListUpdate.Count;
if (ListUpdate.Count > 0 && bulkSender == null)
bulkSender = new BufferedBlockSender(this);
bulkSender = new BufferedBlockSender(this);
for (int i = 0; i < ListUpdate.Count; i++) {
Update C = ListUpdate.Items[i];
@ -180,7 +180,7 @@ namespace MCGalaxy {
string info = C.data as string;
if (info == null) info = "";
if (DoPhysicsBlockchange(C.b, C.type, false, info, 0, true))
bulkSender.Add(C.b, C.type, 0);
bulkSender.Add(C.b, C.type, 0);
} catch {
Server.s.Log("Phys update issue");
}
@ -196,85 +196,18 @@ namespace MCGalaxy {
}
void DoNormalPhysics(ushort x, ushort y, ushort z, Random rand, Check C) {
switch (blocks[C.b])
{
case Block.air: //Placed air
AirPhysics.DoAir(this, C, rand);
break;
case Block.dirt: //Dirt
if (!GrassGrow) { C.time = 255; break; }
if (C.time > 20) {
byte type = GetTile(x, (ushort)(y + 1), z), extType = 0;
if (type == Block.custom_block)
extType = GetExtTile(x, (ushort)(y + 1), z);
if (Block.LightPass(type, extType, CustomBlockDefs))
AddUpdate(C.b, Block.grass);
C.time = 255;
} else {
C.time++;
}
break;
switch (blocks[C.b]) {
case Block.air:
AirPhysics.DoAir(this, C, rand); break;
case Block.dirt:
OtherPhysics.DoDirt(this, C); break;
case Block.leaf:
if (physics > 1)
//Adv physics kills flowers and mushroos in water/lava
{
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));
//Check block above
}
if (!leafDecay) {
C.time = 255;
leaves.Clear();
break;
}
if (C.time < 5)
{
if (rand.Next(10) == 0) C.time++;
break;
}
if (OtherPhysics.DoLeafDecay(this, C))
AddUpdate(C.b, Block.air);
C.time = 255;
break;
LeafPhysics.DoLeaf(this, C, rand); break;
case Block.shrub:
if (physics > 1)
//Adv physics kills flowers and mushroos in water/lava
{
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));
//Check block above
}
if (!growTrees) {
C.time = 255;
break;
}
if (C.time < 20) {
if (rand.Next(20) == 0) C.time++;
break;
}
TreeDrawOp op = new TreeDrawOp();
op.random = rand;
op.method = DrawOp.M_BlockChange;
op.Perform(new [] { new Vec3U16(x, y, z) }, null, this, null);
C.time = 255;
break;
OtherPhysics.DoShrub(this, C, rand); break;
case Block.water:
case Block.activedeathwater:
LiquidPhysics.DoWater(this, C, rand); break;
SimpleLiquidPhysics.DoWater(this, C, rand); break;
case Block.WaterDown:
ExtLiquidPhysics.DoWaterfall(this, C, rand); break;
case Block.LavaDown:
@ -285,7 +218,7 @@ namespace MCGalaxy {
ExtLiquidPhysics.DoFaucet(this, C, rand, Block.LavaDown); break;
case Block.lava:
case Block.activedeathlava:
LiquidPhysics.DoLava(this, C, rand); break;
SimpleLiquidPhysics.DoLava(this, C, rand); break;
case Block.fire:
FirePhysics.Do(this, C, rand); break;
case Block.finiteWater:
@ -295,25 +228,20 @@ namespace MCGalaxy {
FinitePhysics.DoFaucet(this, C, rand); break;
case Block.sand:
case Block.gravel:
OtherPhysics.DoFalling(this, C, blocks[C.b]);
break;
case Block.sponge: //SPONGE
PhysSponge(C.b);
C.time = 255;
break;
case Block.lava_sponge: //SPONGE
PhysSponge(C.b, true);
C.time = 255;
break;
//Adv physics updating anything placed next to water or lava
OtherPhysics.DoFalling(this, C, blocks[C.b]); break;
case Block.sponge:
OtherPhysics.DoSponge(this, C, false); break;
case Block.lava_sponge:
OtherPhysics.DoSponge(this, C, true); break;
//Adv physics updating anything placed next to water or lava
case Block.wood: //Wood to die in lava
case Block.trunk: //Wood to die in lava
case Block.yellowflower:
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
case Block.bookcase: //bookcase
case Block.red: //Shitload of cloth
case Block.bookcase:
case Block.red:
case Block.orange:
case Block.yellow:
case Block.lightgreen:
@ -329,19 +257,7 @@ namespace MCGalaxy {
case Block.darkgrey:
case Block.lightgrey:
case Block.white:
if (physics > 1)
//Adv physics kills flowers and mushroos in water/lava
{
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));
//Check block above
}
C.time = 255;
break;
OtherPhysics.DoOther(this, C); break;
case Block.staircasestep:
case Block.cobblestoneslab:
OtherPhysics.DoStairs(this, C); break;
@ -349,8 +265,8 @@ namespace MCGalaxy {
OtherPhysics.DoFloatwood(this, C); break;
case Block.lava_fast:
case Block.fastdeathlava:
LiquidPhysics.DoFastLava(this, C, rand); break;
//Special blocks that are not saved
SimpleLiquidPhysics.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;
case Block.air_flood_layer:
@ -404,25 +320,9 @@ namespace MCGalaxy {
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) {
FillPos pos; pos.X = x; pos.Y = y; pos.Z = z;
c4.list.Add(pos);
}
C.time = 255;
break;
C4Physics.DoC4(this, C, rand); break;
case Block.c4det:
C4.C4s c = C4.Find(this, ((Player)C.data).c4circuitNumber);
if (c != null) {
c.detenator[0] = x;
c.detenator[1] = y;
c.detenator[2] = z;
}
((Player)C.data).c4circuitNumber = -1;
C.time = 255;
break;
C4Physics.DoC4Det(this, C, rand); break;
default:
DoorPhysics.Do(this, C); break;
}
@ -567,88 +467,6 @@ namespace MCGalaxy {
Server.ErrorLog(e);
}
}
internal void PhysAir(int b) { AirPhysics.PhysAir(this, b); }
internal void PhysWater(ushort x, ushort y, ushort z, byte type) {
if (x >= Width || y >= Height || z >= Length) return;
if (Server.lava.active && Server.lava.map == this && Server.lava.InSafeZone(x, y, z))
return;
int b = x + (z * Width) + (y * Width * Length);
switch (blocks[b]) {
case Block.air:
if (!CheckSpongeWater(x, y, z)) AddUpdate(b, type);
break;
case Block.lava:
case Block.lava_fast:
case Block.activedeathlava:
if (!CheckSpongeWater(x, y, z)) AddUpdate(b, Block.rock);
break;
case Block.shrub:
case Block.yellowflower:
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
if (physics > 1 && physics != 5 && !CheckSpongeWater(x, y, z))
AddUpdate(b, Block.air); //Adv physics kills flowers and mushrooms in water
break;
case Block.sand:
case Block.gravel:
case Block.wood_float:
AddCheck(b); break;
default:
break;
}
}
internal void PhysLava(ushort x, ushort y, ushort z, byte type) {
if (x >= Width || y >= Height || z >= Length) return;
if (Server.lava.active && Server.lava.map == this && Server.lava.InSafeZone(x, y, z))
return;
int b = x + Width * (z + y * Length);
if (physics > 1 && physics != 5 && !CheckSpongeLava(x, y, z) && blocks[b] >= 21 && blocks[b] <= 36) {
AddUpdate(b, Block.air); return;
} // Adv physics destroys cloth
switch (blocks[b]) {
case Block.air:
if (!CheckSpongeLava(x, y, z)) AddUpdate(b, type);
break;
case Block.water:
case Block.activedeathwater:
if (!CheckSpongeLava(x, y, z)) AddUpdate(b, Block.rock); break;
case Block.sand:
if (physics > 1) { //Adv physics changes sand to glass next to lava
if (physics != 5) AddUpdate(b, Block.glass);
} else {
AddCheck(b);
} break;
case Block.gravel:
AddCheck(b); break;
case Block.wood:
case Block.shrub:
case Block.trunk:
case Block.leaf:
case Block.yellowflower:
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
if (physics > 1 && physics != 5) //Adv physics kills flowers and mushrooms plus wood in lava
if (!CheckSpongeLava(x, y, z)) AddUpdate(b, Block.air);
break;
default:
break;
}
}
internal bool CheckSpongeWater(ushort x, ushort y, ushort z) {
for (int yy = y - 2; yy <= y + 2; ++yy) {
@ -680,82 +498,9 @@ namespace MCGalaxy {
return false;
}
void PhysSponge(int b, bool lava = false) {
for (int y = -2; y <= +2; ++y)
for (int z = -2; z <= +2; ++z)
for (int x = -2; x <= +2; ++x)
{
int index = IntOffset(b, x, y, z);
byte block = GetTile(index);
if (block == Block.Zero) continue;
if ((!lava && Block.Convert(block) == Block.water) || (lava && Block.Convert(block) == Block.lava))
AddUpdate(index, Block.air);
}
}
void PhysSpongeRemoved(int b, bool lava = false) {
for (int y = -3; y <= +3; ++y)
for (int z = -3; z <= +3; ++z)
for (int x = -3; x <= +3; ++x)
{
if (Math.Abs(x) == 3 || Math.Abs(y) == 3 || Math.Abs(z) == 3) //Calc only edge
{
int index = IntOffset(b, x, y, z);
byte block = GetTile(index);
if (block == Block.Zero) continue;
if ((!lava && Block.Convert(block) == Block.water) || (lava && Block.Convert(block) == Block.lava))
AddCheck(index);
}
}
}
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);
}
public static class C4 {
public static void BlowUp(ushort[] detenator, Level lvl) {
try {
foreach (C4s c4 in lvl.C4list) {
if (c4.detenator[0] == detenator[0] && c4.detenator[1] == detenator[1] && c4.detenator[2] == detenator[2]) {
foreach (FillPos c in c4.list)
lvl.MakeExplosion(c.X, c.Y, c.Z, 0);
lvl.C4list.Remove(c4);
}
}
} catch { }
}
public static sbyte NextCircuit(Level lvl) {
sbyte number = 1;
foreach (C4s c4 in lvl.C4list)
number++;
return number;
}
public static C4s Find(Level lvl, sbyte CircuitNumber) {
foreach (C4s c4 in lvl.C4list) {
if (c4.CircuitNumb == CircuitNumber)
return c4;
}
return null;
}
public class C4s {
public sbyte CircuitNumb;
public ushort[] detenator;
public List<FillPos> list;
public C4s(sbyte num) {
CircuitNumb = num;
list = new List<FillPos>();
detenator = new ushort[3];
}
}
}
}
public class Check {

View File

@ -200,7 +200,7 @@ namespace MCGalaxy
private readonly object physThreadLock = new object();
BufferedBlockSender bulkSender;
public List<C4.C4s> C4list = new List<C4.C4s>();
public List<C4Physics.C4Data> C4list = new List<C4Physics.C4Data>();
// Games fields
public int Likes, Dislikes;
public string Authors = "";

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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
@ -20,12 +19,7 @@ using System;
namespace MCGalaxy.BlockPhysics {
public enum AirFlood {
Full,
Layer,
Down,
Up,
}
public enum AirFlood { Full, Layer, Down, Up, }
public static class AirPhysics {
public static void DoAir(Level lvl, Check C, Random rand) {

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -0,0 +1,78 @@
/*
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;
using System.Collections.Generic;
namespace MCGalaxy.BlockPhysics {
public static class C4Physics {
public static void DoC4(Level lvl, Check C, Random rand) {
C4Data c4 = Find(lvl, ((Player)C.data).c4circuitNumber);
if (c4 != null) c4.list.Add(C.b);
C.time = 255;
}
public static void DoC4Det(Level lvl, Check C, Random rand) {
C4Data c4 = Find(lvl, ((Player)C.data).c4circuitNumber);
if (c4 != null) c4.detIndex = C.b;
((Player)C.data).c4circuitNumber = -1;
C.time = 255;
}
public static void BlowUp(ushort[] pos, Level lvl) {
int srcIndex = lvl.PosToInt(pos[0], pos[1], pos[2]);
try {
foreach (C4Data c4 in lvl.C4list) {
if (c4.detIndex != srcIndex) continue;
foreach (int index in c4.list) {
ushort x, y, z;
lvl.IntToPos(index, out x, out y, out z);
lvl.MakeExplosion(x, y, z, 0);
}
lvl.C4list.Remove(c4);
}
} catch { }
}
public static sbyte NextCircuit(Level lvl) {
sbyte number = 1;
foreach (C4Data c4 in lvl.C4list)
number++;
return number;
}
public static C4Data Find(Level lvl, sbyte circuitId) {
foreach (C4Data c4 in lvl.C4list) {
if (c4.CircuitID == circuitId) return c4;
}
return null;
}
public class C4Data {
public sbyte CircuitID;
public int detIndex = -1;
public List<int> list = new List<int>();
public C4Data(sbyte num) {
CircuitID = num;
}
}
}
}

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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
@ -23,9 +22,6 @@ namespace MCGalaxy.BlockPhysics {
public static class DoorPhysics {
public static void Do(Level lvl, Check C) {
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
switch (lvl.blocks[C.b]) {
//Change any door blocks nearby into door_air
@ -53,15 +49,12 @@ namespace MCGalaxy.BlockPhysics {
case Block.door_grass_air:
case Block.door_blue_air:
case Block.door_book_air:
AnyDoor(lvl, C, x, y, z, 16);
break;
AnyDoor(lvl, C, 16); break;
case Block.air_switch_air:
case Block.air_door_air:
AnyDoor(lvl, C, x, y, z, 4, true);
break;
AnyDoor(lvl, C, 4, true); break;
case Block.door_tnt_air:
AnyDoor(lvl, C, x, y, z, 4);
break;
AnyDoor(lvl, C, 4); break;
case Block.odoor1_air:
case Block.odoor2_air:
@ -121,10 +114,13 @@ namespace MCGalaxy.BlockPhysics {
lvl.AddUpdate(index, block, true);
}
static void AnyDoor(Level lvl, Check C, ushort x, ushort y, ushort z, int timer, bool instaUpdate = false) {
static void AnyDoor(Level lvl, Check C, int timer, bool instaUpdate = false) {
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (C.time != 0) {
CheckDoorRevert(lvl, C, timer); return;
}
PhysDoor(lvl, (ushort)(x + 1), y, z, instaUpdate);
PhysDoor(lvl, (ushort)(x - 1), y, z, instaUpdate);
PhysDoor(lvl, x, y, (ushort)(z + 1), instaUpdate);

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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
@ -33,10 +32,10 @@ namespace MCGalaxy.BlockPhysics {
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), Block.magma);
} else if (below != Block.magma) {
byte block = lvl.blocks[C.b];
lvl.PhysLava((ushort)(x + 1), y, z, block);
lvl.PhysLava((ushort)(x - 1), y, z, block);
lvl.PhysLava(x, y, (ushort)(z + 1), block);
lvl.PhysLava(x, y, (ushort)(z - 1), block);
LiquidPhysics.PhysLava(lvl, (ushort)(x + 1), y, z, block);
LiquidPhysics.PhysLava(lvl, (ushort)(x - 1), y, z, block);
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z + 1), block);
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z - 1), block);
}
if (lvl.physics <= 1 || C.time <= 10) return;
@ -70,10 +69,10 @@ namespace MCGalaxy.BlockPhysics {
lvl.AddUpdate(lvl.PosToInt(x, (ushort)(y - 1), z), Block.geyser);
} else if (below != Block.geyser) {
byte block = lvl.blocks[C.b];
lvl.PhysWater((ushort)(x + 1), y, z, block);
lvl.PhysWater((ushort)(x - 1), y, z, block);
lvl.PhysWater(x, y, (ushort)(z + 1), block);
lvl.PhysWater(x, y, (ushort)(z - 1), block);
LiquidPhysics.PhysWater(lvl, (ushort)(x + 1), y, z, block);
LiquidPhysics.PhysWater(lvl, (ushort)(x - 1), y, z, block);
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z + 1), block);
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z - 1), block);
}
if (lvl.physics <= 1 || C.time <= 10) return;
@ -116,10 +115,10 @@ namespace MCGalaxy.BlockPhysics {
break;
default:
byte block = lvl.blocks[C.b];
lvl.PhysWater((ushort)(x + 1), y, z, block);
lvl.PhysWater((ushort)(x - 1), y, z, block);
lvl.PhysWater(x, y, (ushort)(z + 1),block);
lvl.PhysWater(x, y, (ushort)(z - 1), block);
LiquidPhysics.PhysWater(lvl, (ushort)(x + 1), y, z, block);
LiquidPhysics.PhysWater(lvl, (ushort)(x - 1), y, z, block);
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z + 1),block);
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z - 1), block);
if (!(C.data is string) || !((string)C.data).Contains("wait"))
C.time = 255;
break;
@ -145,10 +144,10 @@ namespace MCGalaxy.BlockPhysics {
break;
default:
byte block = lvl.blocks[C.b];
lvl.PhysLava((ushort)(x + 1), y, z, block);
lvl.PhysLava((ushort)(x - 1), y, z, block);
lvl.PhysLava(x, y, (ushort)(z + 1),block);
lvl.PhysLava(x, y, (ushort)(z - 1), block);
LiquidPhysics.PhysLava(lvl, (ushort)(x + 1), y, z, block);
LiquidPhysics.PhysLava(lvl, (ushort)(x - 1), y, z, block);
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z + 1),block);
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z - 1), block);
if (!(C.data is string) || !((string)C.data).Contains("wait"))
C.time = 255;
break;

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -0,0 +1,97 @@
/*
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 LeafPhysics {
public static void DoLeaf(Level lvl, Check C, Random rand) {
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (lvl.physics > 1) { //Adv physics kills flowers and mushroos in water/lava
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));
}
if (!lvl.leafDecay) {
lvl.leaves.Clear();
C.time = 255; return;
}
if (C.time < 5) {
if (rand.Next(10) == 0) C.time++;
return;
}
if (DoLeafDecay(lvl, C)) lvl.AddUpdate(C.b, Block.air);
C.time = 255;
}
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

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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
@ -22,142 +21,21 @@ namespace MCGalaxy.BlockPhysics {
public static class LiquidPhysics {
const StringComparison comp = StringComparison.Ordinal;
public static void DoWater(Level lvl, Check C, Random rand) {
if (lvl.finite) {
lvl.liquids.Remove(C.b);
FinitePhysics.DoWaterOrLava(lvl, C, rand);
return;
}
if (lvl.randomFlow)
DoWaterRandowFlow(lvl, C, rand);
else
DoWaterUniformFlow(lvl, C, rand);
}
public static void DoLava(Level lvl, Check C, Random rand) {
if (C.time < 4) {
C.time++; return;
}
if (lvl.finite) {
lvl.liquids.Remove(C.b);
FinitePhysics.DoWaterOrLava(lvl, C, rand);
return;
}
if (lvl.randomFlow)
DoLavaRandowFlow(lvl, C, rand, true);
else
DoLavaUniformFlow(lvl, C, rand, true);
}
public static void DoFastLava(Level lvl, Check C, Random rand) {
if (lvl.randomFlow) {
byte oldTime = C.time;
DoLavaRandowFlow(lvl, C, rand, false);
if (C.time != 255)
C.time = oldTime;
} else {
DoLavaUniformFlow(lvl, C, rand, false);
}
}
static void DoWaterRandowFlow(Level lvl, Check C, Random rand) {
bool[] blocked = null;
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeWater(x, y, z)) {
if (!lvl.liquids.TryGetValue(C.b, out blocked)) {
blocked = new bool[5];
lvl.liquids.Add(C.b, blocked);
}
byte block = lvl.blocks[C.b];
if (y < lvl.Height - 1)
CheckFallingBlocks(lvl, C.b + lvl.Width * lvl.Length);
if (!blocked[0] && rand.Next(4) == 0) {
lvl.PhysWater((ushort)(x + 1), y, z, block);
blocked[0] = true;
}
if (!blocked[1] && rand.Next(4) == 0) {
lvl.PhysWater((ushort)(x - 1), y, z, block);
blocked[1] = true;
}
if (!blocked[2] && rand.Next(4) == 0) {
lvl.PhysWater(x, y, (ushort)(z + 1), block);
blocked[2] = true;
}
if (!blocked[3] && rand.Next(4) == 0) {
lvl.PhysWater(x, y, (ushort)(z - 1), block);
blocked[3] = true;
}
if (!blocked[4] && rand.Next(4) == 0) {
lvl.PhysWater(x, (ushort)(y - 1), z, block);
blocked[4] = true;
}
if (!blocked[0] && WaterBlocked(lvl, (ushort)(x + 1), y, z))
blocked[0] = true;
if (!blocked[1] && WaterBlocked(lvl, (ushort)(x - 1), y, z))
blocked[1] = true;
if (!blocked[2] && WaterBlocked(lvl, x, y, (ushort)(z + 1)))
blocked[2] = true;
if (!blocked[3] && WaterBlocked(lvl, x, y, (ushort)(z - 1)))
blocked[3] = true;
if (!blocked[4] && WaterBlocked(lvl, x, (ushort)(y - 1), z))
blocked[4] = true;
} else { //was placed near sponge
lvl.liquids.TryGetValue(C.b, out blocked);
lvl.AddUpdate(C.b, Block.air);
if (((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
if (((string)C.data).IndexOf("wait", comp) == -1 && blocked != null)
if (blocked[0] && blocked[1] && blocked[2] && blocked[3] && blocked[4])
{
lvl.liquids.Remove(C.b);
C.time = 255;
}
}
static void DoWaterUniformFlow(Level lvl, Check C, Random rand) {
lvl.liquids.Remove(C.b);
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeWater(x, y, z)) {
byte block = lvl.blocks[C.b];
if (y < lvl.Height - 1)
CheckFallingBlocks(lvl, C.b + lvl.Width * lvl.Length);
lvl.PhysWater((ushort)(x + 1), y, z, block);
lvl.PhysWater((ushort)(x - 1), y, z, block);
lvl.PhysWater(x, y, (ushort)(z + 1), block);
lvl.PhysWater(x, y, (ushort)(z - 1), block);
lvl.PhysWater(x, (ushort)(y - 1), z, block);
} else { //was placed near sponge
lvl.AddUpdate(C.b, Block.air);
}
if (((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
static bool WaterBlocked(Level lvl, ushort x, ushort y, ushort z) {
int b = lvl.PosToInt(x, y, z);
if (b == -1)
return true;
public static void PhysWater(Level lvl, ushort x, ushort y, ushort z, byte type) {
if (x >= lvl.Width || y >= lvl.Height || z >= lvl.Length) return;
if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z))
return true;
return;
int b = x + (z * lvl.Width) + (y * lvl.Width * lvl.Length);
switch (lvl.blocks[b]) {
case Block.air:
if (!lvl.CheckSpongeWater(x, y, z)) lvl.AddUpdate(b, type);
break;
case Block.lava:
case Block.lava_fast:
case Block.activedeathlava:
if (!lvl.CheckSpongeWater(x, y, z)) return false;
if (!lvl.CheckSpongeWater(x, y, z)) lvl.AddUpdate(b, Block.rock);
break;
case Block.shrub:
@ -165,119 +43,48 @@ namespace MCGalaxy.BlockPhysics {
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z)) return false;
if (lvl.physics > 1 && lvl.physics != 5 && !lvl.CheckSpongeWater(x, y, z))
lvl.AddUpdate(b, Block.air); //Adv physics kills flowers and mushrooms in water
break;
case Block.sand:
case Block.gravel:
case Block.wood_float:
return false;
}
return true;
}
static void DoLavaRandowFlow(Level lvl, Check C, Random rand, bool checkWait) {
bool[] blocked = null;
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeLava(x, y, z)) {
C.time = (byte)rand.Next(3);
if (!lvl.liquids.TryGetValue(C.b, out blocked)) {
blocked = new bool[5];
lvl.liquids.Add(C.b, blocked);
}
byte block = lvl.blocks[C.b];
if (!blocked[0] && rand.Next(4) == 0) {
lvl.PhysLava((ushort)(x + 1), y, z, block);
blocked[0] = true;
}
if (!blocked[1] && rand.Next(4) == 0) {
lvl.PhysLava((ushort)(x - 1), y, z, block);
blocked[1] = true;
}
if (!blocked[2] && rand.Next(4) == 0) {
lvl.PhysLava(x, y, (ushort)(z + 1), block);
blocked[2] = true;
}
if (!blocked[3] && rand.Next(4) == 0) {
lvl.PhysLava(x, y, (ushort)(z - 1), block);
blocked[3] = true;
}
if (!blocked[4] && rand.Next(4) == 0) {
lvl.PhysLava(x, (ushort)(y - 1), z, block);
blocked[4] = true;
}
if (!blocked[0] && LavaBlocked(lvl, (ushort)(x + 1), y, z))
blocked[0] = true;
if (!blocked[1] && LavaBlocked(lvl, (ushort)(x - 1), y, z))
blocked[1] = true;
if (!blocked[2] && LavaBlocked(lvl, x, y, (ushort)(z + 1)))
blocked[2] = true;
if (!blocked[3] && LavaBlocked(lvl, x, y, (ushort)(z - 1)))
blocked[3] = true;
if (!blocked[4] && LavaBlocked(lvl, x, (ushort)(y - 1), z))
blocked[4] = true;
} else { //was placed near sponge
lvl.liquids.TryGetValue(C.b, out blocked);
lvl.AddUpdate(C.b, Block.air);
if (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
if (blocked != null && (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1))
if (blocked[0] && blocked[1] && blocked[2] && blocked[3] && blocked[4])
{
lvl.liquids.Remove(C.b);
C.time = 255;
lvl.AddCheck(b); break;
default:
break;
}
}
static void DoLavaUniformFlow(Level lvl, Check C, Random rand, bool checkWait) {
lvl.liquids.Remove(C.b);
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeLava(x, y, z)) {
byte block = lvl.blocks[C.b];
lvl.PhysLava((ushort)(x + 1), y, z, block);
lvl.PhysLava((ushort)(x - 1), y, z, block);
lvl.PhysLava(x, y, (ushort)(z + 1), block);
lvl.PhysLava(x, y, (ushort)(z - 1), block);
lvl.PhysLava(x, (ushort)(y - 1), z, block);
} else { //was placed near sponge
lvl.AddUpdate(C.b, Block.air);
}
if (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
static bool LavaBlocked(Level lvl, ushort x, ushort y, ushort z) {
int b = lvl.PosToInt(x, y, z);
if (b == -1)
return true;
public static void PhysLava(Level lvl, ushort x, ushort y, ushort z, byte type) {
if (x >= lvl.Width || y >= lvl.Height || z >= lvl.Length) return;
if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z))
return true;
return;
if (lvl.physics > 1 && lvl.blocks[b] >= Block.red && lvl.blocks[b] <= Block.white
&& !lvl.CheckSpongeLava(x, y, z))
return false; // Adv physics destroys cloth
int b = x + lvl.Width * (z + y * lvl.Length);
if (lvl.physics > 1 && lvl.physics != 5 && !lvl.CheckSpongeLava(x, y, z) && lvl.blocks[b] >= 21 && lvl.blocks[b] <= 36) {
lvl.AddUpdate(b, Block.air); return;
} // Adv physics destroys cloth
switch (lvl.blocks[b]) {
case Block.air:
return false;
if (!lvl.CheckSpongeLava(x, y, z)) lvl.AddUpdate(b, type);
break;
case Block.water:
case Block.activedeathwater:
if (!lvl.CheckSpongeLava(x, y, z)) return false;
if (!lvl.CheckSpongeLava(x, y, z)) lvl.AddUpdate(b, Block.rock);
break;
case Block.sand:
if (lvl.physics > 1) { //Adv physics changes sand to glass next to lava
if (lvl.physics != 5) lvl.AddUpdate(b, Block.glass);
} else {
lvl.AddCheck(b);
} break;
case Block.gravel:
return false;
lvl.AddCheck(b); break;
case Block.wood:
case Block.shrub:
@ -287,19 +94,8 @@ namespace MCGalaxy.BlockPhysics {
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z)) return false;
break;
}
return true;
}
static void CheckFallingBlocks(Level lvl, int b) {
switch (lvl.blocks[b]) {
case Block.sand:
case Block.gravel:
case Block.wood_float:
lvl.AddCheck(b); break;
default:
if (lvl.physics > 1 && lvl.physics != 5) //Adv physics kills flowers and mushrooms plus wood in lava
if (!lvl.CheckSpongeLava(x, y, z)) lvl.AddUpdate(b, Block.air);
break;
}
}

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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
@ -17,61 +16,13 @@
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.Drawing;
using MCGalaxy.Drawing.Ops;
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;
@ -149,5 +100,93 @@ namespace MCGalaxy.BlockPhysics {
}
C.time = 255;
}
public static void DoShrub(Level lvl, Check C, Random rand) {
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (lvl.physics > 1) { //Adv physics kills flowers and mushroos in water/lava
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));
}
if (!lvl.growTrees) { C.time = 255; return; }
if (C.time < 20) {
if (rand.Next(20) == 0) C.time++;
return;
}
TreeDrawOp op = new TreeDrawOp();
op.random = rand;
op.method = DrawOp.M_BlockChange;
op.Perform(new [] { new Vec3U16(x, y, z) }, null, lvl, null);
C.time = 255;
}
public static void DoDirt(Level lvl, Check C) {
if (!lvl.GrassGrow) { C.time = 255; return; }
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (C.time > 20) {
byte type = lvl.GetTile(x, (ushort)(y + 1), z), extType = 0;
if (type == Block.custom_block)
extType = lvl.GetExtTile(x, (ushort)(y + 1), z);
if (Block.LightPass(type, extType, lvl.CustomBlockDefs))
lvl.AddUpdate(C.b, Block.grass);
C.time = 255;
} else {
C.time++;
}
}
public static void DoSponge(Level lvl, Check C, bool lava) {
for (int y = -2; y <= +2; ++y)
for (int z = -2; z <= +2; ++z)
for (int x = -2; x <= +2; ++x)
{
int index = lvl.IntOffset(C.b, x, y, z);
byte block = lvl.GetTile(index);
if (block == Block.Zero) continue;
if ((!lava && Block.Convert(block) == Block.water) || (lava && Block.Convert(block) == Block.lava))
lvl.AddUpdate(index, Block.air);
}
C.time = 255;
}
public static void DoSpongeRemoved(Level lvl, int b, bool lava = false) {
for (int y = -3; y <= +3; ++y)
for (int z = -3; z <= +3; ++z)
for (int x = -3; x <= +3; ++x)
{
if (Math.Abs(x) == 3 || Math.Abs(y) == 3 || Math.Abs(z) == 3) //Calc only edge
{
int index = lvl.IntOffset(b, x, y, z);
byte block = lvl.GetTile(index);
if (block == Block.Zero) continue;
if ((!lava && Block.Convert(block) == Block.water) || (lava && Block.Convert(block) == Block.lava))
lvl.AddCheck(index);
}
}
}
public static void DoOther(Level lvl, Check C) {
if (lvl.physics <= 1) { C.time = 255; return; }
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
//Adv physics kills flowers and mushroos in water/lava
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;
}
}
}

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -0,0 +1,306 @@
/*
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 SimpleLiquidPhysics {
const StringComparison comp = StringComparison.Ordinal;
public static void DoWater(Level lvl, Check C, Random rand) {
if (lvl.finite) {
lvl.liquids.Remove(C.b);
FinitePhysics.DoWaterOrLava(lvl, C, rand);
return;
}
if (lvl.randomFlow)
DoWaterRandowFlow(lvl, C, rand);
else
DoWaterUniformFlow(lvl, C, rand);
}
public static void DoLava(Level lvl, Check C, Random rand) {
if (C.time < 4) {
C.time++; return;
}
if (lvl.finite) {
lvl.liquids.Remove(C.b);
FinitePhysics.DoWaterOrLava(lvl, C, rand);
return;
}
if (lvl.randomFlow)
DoLavaRandowFlow(lvl, C, rand, true);
else
DoLavaUniformFlow(lvl, C, rand, true);
}
public static void DoFastLava(Level lvl, Check C, Random rand) {
if (lvl.randomFlow) {
byte oldTime = C.time;
DoLavaRandowFlow(lvl, C, rand, false);
if (C.time != 255)
C.time = oldTime;
} else {
DoLavaUniformFlow(lvl, C, rand, false);
}
}
static void DoWaterRandowFlow(Level lvl, Check C, Random rand) {
bool[] blocked = null;
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeWater(x, y, z)) {
if (!lvl.liquids.TryGetValue(C.b, out blocked)) {
blocked = new bool[5];
lvl.liquids.Add(C.b, blocked);
}
byte block = lvl.blocks[C.b];
if (y < lvl.Height - 1)
CheckFallingBlocks(lvl, C.b + lvl.Width * lvl.Length);
if (!blocked[0] && rand.Next(4) == 0) {
LiquidPhysics.PhysWater(lvl, (ushort)(x + 1), y, z, block);
blocked[0] = true;
}
if (!blocked[1] && rand.Next(4) == 0) {
LiquidPhysics.PhysWater(lvl, (ushort)(x - 1), y, z, block);
blocked[1] = true;
}
if (!blocked[2] && rand.Next(4) == 0) {
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z + 1), block);
blocked[2] = true;
}
if (!blocked[3] && rand.Next(4) == 0) {
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z - 1), block);
blocked[3] = true;
}
if (!blocked[4] && rand.Next(4) == 0) {
LiquidPhysics.PhysWater(lvl, x, (ushort)(y - 1), z, block);
blocked[4] = true;
}
if (!blocked[0] && WaterBlocked(lvl, (ushort)(x + 1), y, z))
blocked[0] = true;
if (!blocked[1] && WaterBlocked(lvl, (ushort)(x - 1), y, z))
blocked[1] = true;
if (!blocked[2] && WaterBlocked(lvl, x, y, (ushort)(z + 1)))
blocked[2] = true;
if (!blocked[3] && WaterBlocked(lvl, x, y, (ushort)(z - 1)))
blocked[3] = true;
if (!blocked[4] && WaterBlocked(lvl, x, (ushort)(y - 1), z))
blocked[4] = true;
} else { //was placed near sponge
lvl.liquids.TryGetValue(C.b, out blocked);
lvl.AddUpdate(C.b, Block.air);
if (((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
if (((string)C.data).IndexOf("wait", comp) == -1 && blocked != null)
if (blocked[0] && blocked[1] && blocked[2] && blocked[3] && blocked[4])
{
lvl.liquids.Remove(C.b);
C.time = 255;
}
}
static void DoWaterUniformFlow(Level lvl, Check C, Random rand) {
lvl.liquids.Remove(C.b);
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeWater(x, y, z)) {
byte block = lvl.blocks[C.b];
if (y < lvl.Height - 1)
CheckFallingBlocks(lvl, C.b + lvl.Width * lvl.Length);
LiquidPhysics.PhysWater(lvl, (ushort)(x + 1), y, z, block);
LiquidPhysics.PhysWater(lvl, (ushort)(x - 1), y, z, block);
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z + 1), block);
LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z - 1), block);
LiquidPhysics.PhysWater(lvl, x, (ushort)(y - 1), z, block);
} else { //was placed near sponge
lvl.AddUpdate(C.b, Block.air);
}
if (((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
static bool WaterBlocked(Level lvl, ushort x, ushort y, ushort z) {
int b = lvl.PosToInt(x, y, z);
if (b == -1)
return true;
if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z))
return true;
switch (lvl.blocks[b]) {
case Block.air:
case Block.lava:
case Block.lava_fast:
case Block.activedeathlava:
if (!lvl.CheckSpongeWater(x, y, z)) return false;
break;
case Block.shrub:
case Block.yellowflower:
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z)) return false;
break;
case Block.sand:
case Block.gravel:
case Block.wood_float:
return false;
}
return true;
}
static void DoLavaRandowFlow(Level lvl, Check C, Random rand, bool checkWait) {
bool[] blocked = null;
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeLava(x, y, z)) {
C.time = (byte)rand.Next(3);
if (!lvl.liquids.TryGetValue(C.b, out blocked)) {
blocked = new bool[5];
lvl.liquids.Add(C.b, blocked);
}
byte block = lvl.blocks[C.b];
if (!blocked[0] && rand.Next(4) == 0) {
LiquidPhysics.PhysLava(lvl, (ushort)(x + 1), y, z, block);
blocked[0] = true;
}
if (!blocked[1] && rand.Next(4) == 0) {
LiquidPhysics.PhysLava(lvl, (ushort)(x - 1), y, z, block);
blocked[1] = true;
}
if (!blocked[2] && rand.Next(4) == 0) {
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z + 1), block);
blocked[2] = true;
}
if (!blocked[3] && rand.Next(4) == 0) {
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z - 1), block);
blocked[3] = true;
}
if (!blocked[4] && rand.Next(4) == 0) {
LiquidPhysics.PhysLava(lvl, x, (ushort)(y - 1), z, block);
blocked[4] = true;
}
if (!blocked[0] && LavaBlocked(lvl, (ushort)(x + 1), y, z))
blocked[0] = true;
if (!blocked[1] && LavaBlocked(lvl, (ushort)(x - 1), y, z))
blocked[1] = true;
if (!blocked[2] && LavaBlocked(lvl, x, y, (ushort)(z + 1)))
blocked[2] = true;
if (!blocked[3] && LavaBlocked(lvl, x, y, (ushort)(z - 1)))
blocked[3] = true;
if (!blocked[4] && LavaBlocked(lvl, x, (ushort)(y - 1), z))
blocked[4] = true;
} else { //was placed near sponge
lvl.liquids.TryGetValue(C.b, out blocked);
lvl.AddUpdate(C.b, Block.air);
if (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
if (blocked != null && (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1))
if (blocked[0] && blocked[1] && blocked[2] && blocked[3] && blocked[4])
{
lvl.liquids.Remove(C.b);
C.time = 255;
}
}
static void DoLavaUniformFlow(Level lvl, Check C, Random rand, bool checkWait) {
lvl.liquids.Remove(C.b);
ushort x, y, z;
lvl.IntToPos(C.b, out x, out y, out z);
if (!lvl.CheckSpongeLava(x, y, z)) {
byte block = lvl.blocks[C.b];
LiquidPhysics.PhysLava(lvl, (ushort)(x + 1), y, z, block);
LiquidPhysics.PhysLava(lvl, (ushort)(x - 1), y, z, block);
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z + 1), block);
LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z - 1), block);
LiquidPhysics.PhysLava(lvl, x, (ushort)(y - 1), z, block);
} else { //was placed near sponge
lvl.AddUpdate(C.b, Block.air);
}
if (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1)
C.time = 255;
}
static bool LavaBlocked(Level lvl, ushort x, ushort y, ushort z) {
int b = lvl.PosToInt(x, y, z);
if (b == -1)
return true;
if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z))
return true;
if (lvl.physics > 1 && lvl.blocks[b] >= Block.red && lvl.blocks[b] <= Block.white
&& !lvl.CheckSpongeLava(x, y, z))
return false; // Adv physics destroys cloth
switch (lvl.blocks[b]) {
case Block.air:
return false;
case Block.water:
case Block.activedeathwater:
if (!lvl.CheckSpongeLava(x, y, z)) return false;
break;
case Block.sand:
case Block.gravel:
return false;
case Block.wood:
case Block.shrub:
case Block.trunk:
case Block.leaf:
case Block.yellowflower:
case Block.redflower:
case Block.mushroom:
case Block.redmushroom:
if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z)) return false;
break;
}
return true;
}
static void CheckFallingBlocks(Level lvl, int b) {
switch (lvl.blocks[b]) {
case Block.sand:
case Block.gravel:
case Block.wood_float:
lvl.AddCheck(b); break;
default:
break;
}
}
}
}

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -1,6 +1,5 @@
/*
Copyright 2015 MCGalaxy
Original level physics copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
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

View File

@ -471,6 +471,7 @@
<Compile Include="Levels\Physics\AIPhysics.cs" />
<Compile Include="Levels\Physics\AirPhysics.cs" />
<Compile Include="Levels\Physics\BirdPhysics.cs" />
<Compile Include="Levels\Physics\C4Physics.cs" />
<Compile Include="Levels\Physics\DoorPhysics.cs" />
<Compile Include="Levels\Physics\ExtLiquidPhysics.cs" />
<Compile Include="Levels\Physics\ExtraInfoPhysics.cs" />
@ -478,7 +479,9 @@
<Compile Include="Levels\Physics\FirePhysics.cs" />
<Compile Include="Levels\Physics\FireworkPhysics.cs" />
<Compile Include="Levels\Physics\HunterPhysics.cs" />
<Compile Include="Levels\Physics\LeafPhysics.cs" />
<Compile Include="Levels\Physics\LiquidPhysics.cs" />
<Compile Include="Levels\Physics\SimpleLiquidPhysics.cs" />
<Compile Include="Levels\Physics\RocketPhysics.cs" />
<Compile Include="Levels\Physics\OtherPhysics.cs" />
<Compile Include="Levels\Physics\SnakePhysics.cs" />