mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-26 14:54:12 -04:00
Majorly optimise block physics performance, also reduce memory usage of level physics undo buffer.
This commit is contained in:
parent
0543cb1dd3
commit
db2b4646ff
@ -192,8 +192,8 @@ namespace MCGalaxy.Commands
|
||||
|
||||
bool CheckBlockPhysics(Player p, long seconds, int i, Level.UndoPos undo) {
|
||||
byte b = p.level.GetTile(undo.location);
|
||||
if (undo.timePerformed.AddSeconds(seconds) < DateTime.Now)
|
||||
return false;
|
||||
DateTime time = Server.StartTime.AddSeconds(undo.timeDelta);
|
||||
if (time.AddSeconds(seconds) < DateTime.UtcNow) return false;
|
||||
|
||||
if (b == undo.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
||||
ushort x, y, z;
|
||||
|
@ -392,7 +392,7 @@ namespace MCGalaxy {
|
||||
uP.location = b;
|
||||
uP.newType = type; uP.newExtType = extType;
|
||||
uP.oldType = oldBlock; uP.oldExtType = oldExtType;
|
||||
uP.timePerformed = DateTime.Now;
|
||||
uP.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
|
||||
|
||||
if (currentUndo > Server.physUndo) {
|
||||
currentUndo = 0;
|
||||
|
@ -128,16 +128,17 @@ namespace MCGalaxy {
|
||||
if (physics == 5) {
|
||||
for (int i = 0; i < ListCheck.Count; i++) {
|
||||
Check C = ListCheck.Items[i];
|
||||
try {
|
||||
IntToPos(C.b, out x, out y, out z);
|
||||
try {
|
||||
string info = C.data as string;
|
||||
if (info == null) info = "";
|
||||
IntToPos(C.b, out x, out y, out z);
|
||||
if (info == null) info = "";
|
||||
|
||||
if (PhysicsUpdate != null)
|
||||
PhysicsUpdate(x, y, z, C.time, info, this);
|
||||
if (info == "" || ExtraInfoPhysics.DoDoorsOnly(this, C, null))
|
||||
DoorPhysics.Do(this, C);
|
||||
} catch {
|
||||
listCheckExists.Set(x, y, z, false);
|
||||
ListCheck.Remove(C);
|
||||
}
|
||||
}
|
||||
@ -145,23 +146,25 @@ namespace MCGalaxy {
|
||||
Random rand = new Random();
|
||||
for (int i = 0; i < ListCheck.Count; i++) {
|
||||
Check C = ListCheck.Items[i];
|
||||
try {
|
||||
IntToPos(C.b, out x, out y, out z);
|
||||
IntToPos(C.b, out x, out y, out z);
|
||||
try {
|
||||
string info = C.data as string;
|
||||
if (info == null) info = "";
|
||||
|
||||
if (PhysicsUpdate != null)
|
||||
PhysicsUpdate(x, y, z, C.time, info, this);
|
||||
OnPhysicsUpdateEvent.Call(x, y, z, C.time, info, this);
|
||||
if (OnPhysicsUpdateEvent.events.Count > 0)
|
||||
OnPhysicsUpdateEvent.Call(x, y, z, C.time, info, this);
|
||||
if (info == "" || ExtraInfoPhysics.DoComplex(this, C, rand))
|
||||
DoNormalPhysics(x, y, z, rand, C);
|
||||
} catch {
|
||||
listCheckExists.Set(x, y, z, false);
|
||||
ListCheck.Remove(C);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RemoveExpiredChecks();
|
||||
|
||||
ListCheck.RemoveAll(C => C.time == 255); //Remove all that are finished with 255 time
|
||||
lastUpdate = ListUpdate.Count;
|
||||
for (int i = 0; i < ListUpdate.Count; i++) {
|
||||
Update C = ListUpdate.Items[i];
|
||||
@ -173,7 +176,7 @@ namespace MCGalaxy {
|
||||
Server.s.Log("Phys update issue");
|
||||
}
|
||||
}
|
||||
ListUpdate.Clear();
|
||||
ListUpdate.Clear(); listUpdateExists.Clear();
|
||||
} catch (Exception e) {
|
||||
Server.s.Log("Level physics error");
|
||||
Server.ErrorLog(e);
|
||||
@ -415,7 +418,6 @@ namespace MCGalaxy {
|
||||
ZombiePhysics.Do(this, C, rand); break;
|
||||
|
||||
case Block.c4:
|
||||
Server.s.Log("Processing 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;
|
||||
@ -425,7 +427,6 @@ namespace MCGalaxy {
|
||||
break;
|
||||
|
||||
case Block.c4det:
|
||||
Server.s.Log("Processing C4 det");
|
||||
C4.C4s c = C4.Find(this, ((Player)C.data).c4circuitNumber);
|
||||
if (c != null) {
|
||||
c.detenator[0] = x;
|
||||
@ -440,16 +441,25 @@ namespace MCGalaxy {
|
||||
DoorPhysics.Do(this, C); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddCheck(int b, bool overRide = false) { AddCheck(b, overRide, ""); }
|
||||
|
||||
public void AddCheck(int b, bool overRide, object data) {
|
||||
try {
|
||||
int index = ListCheck.IndexOf(C => C.b == b);
|
||||
if (index < 0) {
|
||||
try {
|
||||
ushort x, y, z;
|
||||
IntToPos(b, out x, out y, out z);
|
||||
if (x >= Width || y >= Height || z >= Length) return;
|
||||
|
||||
if (!listCheckExists.Get(x, y, z)) {
|
||||
ListCheck.Add(new Check(b, data)); //Adds block to list to be updated
|
||||
listCheckExists.Set(x, y, z, true);
|
||||
} else if (overRide) {
|
||||
ListCheck.Items[index].data = data; return;
|
||||
Check[] items = ListCheck.Items;
|
||||
int count = ListCheck.Count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (items[i].b != b) continue;
|
||||
items[i].data = data; return;
|
||||
}
|
||||
//Dont need to check physics here because if the list is active, then physics is active :)
|
||||
}
|
||||
if (!physicssate && physics > 0)
|
||||
@ -464,23 +474,25 @@ namespace MCGalaxy {
|
||||
|
||||
internal bool AddUpdate(int b, int type, bool overRide, object data) {
|
||||
try {
|
||||
if (overRide) {
|
||||
ushort x, y, z;
|
||||
IntToPos(b, out x, out y, out z);
|
||||
AddCheck(b, true, data); //Dont need to check physics here....AddCheck will do that
|
||||
|
||||
ushort x, y, z;
|
||||
IntToPos(b, out x, out y, out z);
|
||||
if (x >= Width || y >= Height || z >= Length) return false;
|
||||
|
||||
if (overRide) {
|
||||
AddCheck(b, true, data); //Dont need to check physics here....AddCheck will do that
|
||||
string info = data as string;
|
||||
if (info == null) info = "";
|
||||
Blockchange(x, y, z, (byte)type, true, info);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ListUpdate.Exists(C => C.b == b)) {
|
||||
if (!listUpdateExists.Get(x, y, z)) {
|
||||
listUpdateExists.Set(x, y, z, true);
|
||||
} else if (type == Block.sand || type == Block.gravel) {
|
||||
ListUpdate.RemoveAll(C => C.b == b);
|
||||
RemoveUpdatesAtPos(b);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ListUpdate.Add(new Update(b, (byte)type, data));
|
||||
if (!physicssate && physics > 0)
|
||||
@ -492,12 +504,41 @@ namespace MCGalaxy {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RemoveExpiredChecks() {
|
||||
Check[] items = ListCheck.Items;
|
||||
int j = 0, count = ListCheck.Count;
|
||||
ushort x, y, z;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (items[i].time == 255) {
|
||||
IntToPos(items[i].b, out x, out y, out z);
|
||||
listCheckExists.Set(x, y, z, false);
|
||||
continue;
|
||||
}
|
||||
items[j] = items[i]; j++;
|
||||
}
|
||||
ListCheck.Items = items;
|
||||
ListCheck.Count = j;
|
||||
}
|
||||
|
||||
void RemoveUpdatesAtPos(int b) {
|
||||
Update[] items = ListUpdate.Items;
|
||||
int j = 0, count = ListUpdate.Count;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (items[j].b == b) continue;
|
||||
items[j] = items[i]; j++;
|
||||
}
|
||||
ListUpdate.Items = items;
|
||||
ListUpdate.Count = j;
|
||||
}
|
||||
|
||||
public void ClearPhysics() {
|
||||
for (int i = 0; i < ListCheck.Count; i++ )
|
||||
RevertPhysics(ListCheck.Items[i]);
|
||||
ListCheck.Clear();
|
||||
ListUpdate.Clear();
|
||||
ListCheck.Clear(); listCheckExists.Clear();
|
||||
ListUpdate.Clear(); listUpdateExists.Clear();
|
||||
}
|
||||
|
||||
void RevertPhysics(Check C) {
|
||||
@ -541,22 +582,21 @@ namespace MCGalaxy {
|
||||
|
||||
internal void PhysAir(int b) { AirPhysics.PhysAir(this, b); }
|
||||
|
||||
internal void PhysWater(int b, byte type) {
|
||||
if (b == -1) return;
|
||||
ushort x, y, z;
|
||||
IntToPos(b, out x, out y, out z);
|
||||
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 (!PhysSpongeCheck(b)) AddUpdate(b, type);
|
||||
if (!CheckSpongeWater(x, y, z)) AddUpdate(b, type);
|
||||
break;
|
||||
|
||||
case Block.lava:
|
||||
case Block.lava_fast:
|
||||
case Block.activedeathlava:
|
||||
if (!PhysSpongeCheck(b)) AddUpdate(b, Block.rock);
|
||||
if (!CheckSpongeWater(x, y, z)) AddUpdate(b, Block.rock);
|
||||
break;
|
||||
|
||||
case Block.shrub:
|
||||
@ -564,7 +604,7 @@ namespace MCGalaxy {
|
||||
case Block.redflower:
|
||||
case Block.mushroom:
|
||||
case Block.redmushroom:
|
||||
if (physics > 1 && physics != 5 && !PhysSpongeCheck(b))
|
||||
if (physics > 1 && physics != 5 && !CheckSpongeWater(x, y, z))
|
||||
AddUpdate(b, 0); //Adv physics kills flowers and mushrooms in water
|
||||
break;
|
||||
|
||||
@ -577,25 +617,24 @@ namespace MCGalaxy {
|
||||
}
|
||||
}
|
||||
|
||||
internal void PhysLava(int b, byte type) {
|
||||
if (b == -1) return;
|
||||
ushort x, y, z;
|
||||
IntToPos(b, out x, out y, out z);
|
||||
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;
|
||||
|
||||
if (physics > 1 && physics != 5 && !PhysSpongeCheck(b, true) && blocks[b] >= 21 && blocks[b] <= 36) {
|
||||
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
|
||||
} // Adv physics destroys cloth
|
||||
|
||||
switch (blocks[b]) {
|
||||
case Block.air:
|
||||
if (!PhysSpongeCheck(b, true)) AddUpdate(b, type);
|
||||
if (!CheckSpongeLava(x, y, z)) AddUpdate(b, type);
|
||||
break;
|
||||
|
||||
case Block.water:
|
||||
case Block.activedeathwater:
|
||||
if (!PhysSpongeCheck(b, true)) AddUpdate(b, Block.rock); break;
|
||||
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
|
||||
@ -616,7 +655,7 @@ namespace MCGalaxy {
|
||||
case Block.mushroom:
|
||||
case Block.redmushroom:
|
||||
if (physics > 1 && physics != 5) //Adv physics kills flowers and mushrooms plus wood in lava
|
||||
if (!PhysSpongeCheck(b, true)) AddUpdate(b, Block.air);
|
||||
if (!CheckSpongeLava(x, y, z)) AddUpdate(b, Block.air);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -716,16 +755,33 @@ namespace MCGalaxy {
|
||||
AddUpdate(bBelow, Block.stone);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool PhysSpongeCheck(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)
|
||||
{
|
||||
byte block = GetTile(IntOffset(b, x, y, z));
|
||||
if (block == Block.Zero) continue;
|
||||
if ((!lava && block == Block.sponge) || (lava && block == Block.lava_sponge))
|
||||
return true;
|
||||
|
||||
internal bool CheckSpongeWater(ushort x, ushort y, ushort z) {
|
||||
for (int yy = y - 2; yy <= y + 2; ++yy) {
|
||||
if (yy < 0 || yy >= Height) continue;
|
||||
for (int zz = z - 2; zz <= z + 2; ++zz) {
|
||||
if (zz < 0 || zz >= Length) continue;
|
||||
for (int xx = x - 2; xx <= x + 2; ++xx) {
|
||||
if (xx < 0 || xx >= Width) continue;
|
||||
if (blocks[xx + Width * (zz + yy * Length)] == Block.sponge)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool CheckSpongeLava(ushort x, ushort y, ushort z) {
|
||||
for (int yy = y - 2; yy <= y + 2; ++yy) {
|
||||
if (yy < 0 || yy >= Height) continue;
|
||||
for (int zz = z - 2; zz <= z + 2; ++zz) {
|
||||
if (zz < 0 || zz >= Length) continue;
|
||||
for (int xx = x - 2; xx <= x + 2; ++xx) {
|
||||
if (xx < 0 || xx >= Width) continue;
|
||||
if (blocks[xx + Width * (zz + yy * Length)] == Block.lava_sponge)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ namespace MCGalaxy
|
||||
public static bool cancelphysics;
|
||||
internal readonly FastList<Check> ListCheck = new FastList<Check>(); //A list of blocks that need to be updated
|
||||
internal readonly FastList<Update> ListUpdate = new FastList<Update>(); //A list of block to change after calculation
|
||||
internal readonly SparseBitSet listCheckExists, listUpdateExists;
|
||||
|
||||
internal readonly Dictionary<int, sbyte> leaves = new Dictionary<int, sbyte>();
|
||||
// Holds block state for leaf decay
|
||||
@ -236,6 +237,8 @@ namespace MCGalaxy
|
||||
spawnz = (ushort)(Length / 2);
|
||||
rotx = 0;
|
||||
roty = 0;
|
||||
listCheckExists = new SparseBitSet(Width, Height, Length);
|
||||
listUpdateExists = new SparseBitSet(Width, Height, Length);
|
||||
//season = new SeasonsCore(this);
|
||||
}
|
||||
|
||||
@ -251,8 +254,8 @@ namespace MCGalaxy
|
||||
Extras.Clear();
|
||||
liquids.Clear();
|
||||
leaves.Clear();
|
||||
ListCheck.Clear();
|
||||
ListUpdate.Clear();
|
||||
ListCheck.Clear(); listCheckExists.Clear();
|
||||
ListUpdate.Clear(); listUpdateExists.Clear();
|
||||
UndoBuffer.Clear();
|
||||
blockCache.Clear();
|
||||
ZoneList.Clear();
|
||||
@ -429,10 +432,8 @@ namespace MCGalaxy
|
||||
|
||||
// Returns true if ListCheck does not already have an check in the position.
|
||||
// Useful for fireworks, which depend on two physics blocks being checked, one with extraInfo.
|
||||
public bool CheckClear(ushort x, ushort y, ushort z)
|
||||
{
|
||||
int b = PosToInt(x, y, z);
|
||||
return !ListCheck.Exists(C => C.b == b);
|
||||
public bool CheckClear(ushort x, ushort y, ushort z) {
|
||||
return x >= Width || y >= Height || z >= Length || !listCheckExists.Get(x, y, z);
|
||||
}
|
||||
|
||||
public void Save(bool Override = false, bool clearPhysics = false)
|
||||
@ -744,7 +745,7 @@ namespace MCGalaxy
|
||||
public int location;
|
||||
public byte newType, newExtType;
|
||||
public byte oldType, oldExtType;
|
||||
public DateTime timePerformed;
|
||||
public int timeDelta;
|
||||
}
|
||||
|
||||
public struct Zone {
|
||||
|
@ -151,8 +151,8 @@ namespace MCGalaxy.BlockPhysics {
|
||||
int b1 = lvl.IntOffset(C.b, xx * 3, yy * 3, zz * 3);
|
||||
int b2 = lvl.IntOffset(C.b, xx * 2, yy * 2, zz * 2);
|
||||
bool unblocked = lvl.GetTile(b1) == Block.air && lvl.GetTile(b2) == Block.air &&
|
||||
!lvl.ListUpdate.Exists(u => u.b == b1) &&
|
||||
!lvl.ListUpdate.Exists(u => u.b == b2);
|
||||
!lvl.listUpdateExists.Get(x + xx * 3, y + yy * 3, z + zz * 3) &&
|
||||
!lvl.listUpdateExists.Get(x + xx * 2, y + yy * 2, z + zz * 2);
|
||||
|
||||
if (unblocked) {
|
||||
lvl.AddUpdate(b1, Block.rockethead);
|
||||
@ -166,8 +166,8 @@ namespace MCGalaxy.BlockPhysics {
|
||||
int b1 = lvl.IntOffset(C.b, xx, yy + 1, zz);
|
||||
int b2 = lvl.IntOffset(C.b, xx, yy + 2, zz);
|
||||
bool unblocked = lvl.GetTile(b1) == Block.air && lvl.GetTile(b2) == Block.air &&
|
||||
!lvl.ListUpdate.Exists(u => u.b == b1) &&
|
||||
!lvl.ListUpdate.Exists(u => u.b == b2);
|
||||
!lvl.listUpdateExists.Get(x + xx, y + yy + 1, z + zz) &&
|
||||
!lvl.listUpdateExists.Get(x + xx, y + yy + 2, z + zz);
|
||||
|
||||
if (unblocked) {
|
||||
lvl.AddUpdate(b2, Block.firework);
|
||||
|
@ -33,10 +33,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(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);
|
||||
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);
|
||||
}
|
||||
|
||||
if (lvl.physics <= 1 || C.time <= 10) return;
|
||||
@ -70,10 +70,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(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);
|
||||
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);
|
||||
}
|
||||
|
||||
if (lvl.physics <= 1 || C.time <= 10) return;
|
||||
@ -116,10 +116,10 @@ namespace MCGalaxy.BlockPhysics {
|
||||
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);
|
||||
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);
|
||||
if (!(C.data is string) || !((string)C.data).Contains("wait"))
|
||||
C.time = 255;
|
||||
break;
|
||||
@ -145,10 +145,10 @@ namespace MCGalaxy.BlockPhysics {
|
||||
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);
|
||||
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);
|
||||
if (!(C.data is string) || !((string)C.data).Contains("wait"))
|
||||
C.time = 255;
|
||||
break;
|
||||
|
@ -152,7 +152,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
// Not setting drop = false can cause occasional leftover blocks, since C.extraInfo is emptied, so
|
||||
// drop can generate another block with no dissipate/explode information.
|
||||
if (args.Dissipate && rand.Next(1, 100) <= args.DissipateNum) {
|
||||
if (!lvl.ListUpdate.Exists(Update => Update.b == C.b)) {
|
||||
if (!lvl.listUpdateExists.Get(x, y, z)) {
|
||||
lvl.AddUpdate(C.b, Block.air);
|
||||
C.data = "";
|
||||
args.Drop = false;
|
||||
|
@ -36,7 +36,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
|
||||
if (keepGoing) {
|
||||
int bAbove = lvl.PosToInt(x, (ushort)(y + 1), z);
|
||||
bool unblocked = !lvl.ListUpdate.Exists(u => u.b == bAbove);
|
||||
bool unblocked = bAbove < 0 || !lvl.listUpdateExists.Get(x, y + 1, z);
|
||||
if (unblocked) {
|
||||
lvl.AddUpdate(bAbove, Block.firework, false);
|
||||
lvl.AddUpdate(C.b, Block.lavastill, false, "wait 1 dissipate 100");
|
||||
|
@ -22,6 +22,7 @@ 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);
|
||||
@ -65,7 +66,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
ushort x, y, z;
|
||||
lvl.IntToPos(C.b, out x, out y, out z);
|
||||
|
||||
if (!lvl.PhysSpongeCheck(C.b)) {
|
||||
if (!lvl.CheckSpongeWater(x, y, z)) {
|
||||
if (!lvl.liquids.TryGetValue(C.b, out blocked)) {
|
||||
blocked = new bool[5];
|
||||
lvl.liquids.Add(C.b, blocked);
|
||||
@ -77,23 +78,23 @@ namespace MCGalaxy.BlockPhysics {
|
||||
}
|
||||
|
||||
if (!blocked[0] && rand.Next(4) == 0) {
|
||||
lvl.PhysWater(lvl.PosToInt((ushort)(x + 1), y, z), block);
|
||||
lvl.PhysWater((ushort)(x + 1), y, z, block);
|
||||
blocked[0] = true;
|
||||
}
|
||||
if (!blocked[1] && rand.Next(4) == 0) {
|
||||
lvl.PhysWater(lvl.PosToInt((ushort)(x - 1), y, z), block);
|
||||
lvl.PhysWater((ushort)(x - 1), y, z, block);
|
||||
blocked[1] = true;
|
||||
}
|
||||
if (!blocked[2] && rand.Next(4) == 0) {
|
||||
lvl.PhysWater(lvl.PosToInt(x, y, (ushort)(z + 1)), block);
|
||||
lvl.PhysWater(x, y, (ushort)(z + 1), block);
|
||||
blocked[2] = true;
|
||||
}
|
||||
if (!blocked[3] && rand.Next(4) == 0) {
|
||||
lvl.PhysWater(lvl.PosToInt(x, y, (ushort)(z - 1)), block);
|
||||
lvl.PhysWater(x, y, (ushort)(z - 1), block);
|
||||
blocked[3] = true;
|
||||
}
|
||||
if (!blocked[4] && rand.Next(4) == 0) {
|
||||
lvl.PhysWater(lvl.PosToInt(x, (ushort)(y - 1), z), block);
|
||||
lvl.PhysWater(x, (ushort)(y - 1), z, block);
|
||||
blocked[4] = true;
|
||||
}
|
||||
|
||||
@ -111,11 +112,11 @@ namespace MCGalaxy.BlockPhysics {
|
||||
lvl.liquids.TryGetValue(C.b, out blocked);
|
||||
lvl.AddUpdate(C.b, Block.air);
|
||||
|
||||
if (((string)C.data).IndexOf("wait") == -1)
|
||||
if (((string)C.data).IndexOf("wait", comp) == -1)
|
||||
C.time = 255;
|
||||
}
|
||||
|
||||
if (((string)C.data).IndexOf("wait") == -1 && blocked != null)
|
||||
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);
|
||||
@ -128,21 +129,21 @@ namespace MCGalaxy.BlockPhysics {
|
||||
ushort x, y, z;
|
||||
lvl.IntToPos(C.b, out x, out y, out z);
|
||||
|
||||
if (!lvl.PhysSpongeCheck(C.b)) {
|
||||
if (!lvl.CheckSpongeWater(x, y, z)) {
|
||||
byte block = lvl.blocks[C.b];
|
||||
if (lvl.GetTile(x, (ushort)(y + 1), z) != Block.Zero) {
|
||||
lvl.PhysSandCheck(lvl.PosToInt(x, (ushort)(y + 1), z));
|
||||
}
|
||||
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);
|
||||
lvl.PhysWater(lvl.PosToInt(x, (ushort)(y - 1), z), block);
|
||||
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") == -1)
|
||||
if (((string)C.data).IndexOf("wait", comp) == -1)
|
||||
C.time = 255;
|
||||
}
|
||||
|
||||
@ -158,7 +159,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
case Block.lava:
|
||||
case Block.lava_fast:
|
||||
case Block.activedeathlava:
|
||||
if (!lvl.PhysSpongeCheck(b)) return false;
|
||||
if (!lvl.CheckSpongeWater(x, y, z)) return false;
|
||||
break;
|
||||
|
||||
case Block.shrub:
|
||||
@ -166,7 +167,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
case Block.redflower:
|
||||
case Block.mushroom:
|
||||
case Block.redmushroom:
|
||||
if (lvl.physics > 1 && !lvl.PhysSpongeCheck(b)) return false;
|
||||
if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z)) return false;
|
||||
break;
|
||||
|
||||
case Block.sand:
|
||||
@ -182,7 +183,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
ushort x, y, z;
|
||||
lvl.IntToPos(C.b, out x, out y, out z);
|
||||
|
||||
if (!lvl.PhysSpongeCheck(C.b, true)) {
|
||||
if (!lvl.CheckSpongeLava(x, y, z)) {
|
||||
C.time = (byte)rand.Next(3);
|
||||
if (!lvl.liquids.TryGetValue(C.b, out blocked)) {
|
||||
blocked = new bool[5];
|
||||
@ -191,23 +192,23 @@ namespace MCGalaxy.BlockPhysics {
|
||||
byte block = lvl.blocks[C.b];
|
||||
|
||||
if (!blocked[0] && rand.Next(4) == 0) {
|
||||
lvl.PhysLava(lvl.PosToInt((ushort)(x + 1), y, z), block);
|
||||
lvl.PhysLava((ushort)(x + 1), y, z, block);
|
||||
blocked[0] = true;
|
||||
}
|
||||
if (!blocked[1] && rand.Next(4) == 0) {
|
||||
lvl.PhysLava(lvl.PosToInt((ushort)(x - 1), y, z), block);
|
||||
lvl.PhysLava((ushort)(x - 1), y, z, block);
|
||||
blocked[1] = true;
|
||||
}
|
||||
if (!blocked[2] && rand.Next(4) == 0) {
|
||||
lvl.PhysLava(lvl.PosToInt(x, y, (ushort)(z + 1)), block);
|
||||
lvl.PhysLava(x, y, (ushort)(z + 1), block);
|
||||
blocked[2] = true;
|
||||
}
|
||||
if (!blocked[3] && rand.Next(4) == 0) {
|
||||
lvl.PhysLava(lvl.PosToInt(x, y, (ushort)(z - 1)), block);
|
||||
lvl.PhysLava(x, y, (ushort)(z - 1), block);
|
||||
blocked[3] = true;
|
||||
}
|
||||
if (!blocked[4] && rand.Next(4) == 0) {
|
||||
lvl.PhysLava(lvl.PosToInt(x, (ushort)(y - 1), z), block);
|
||||
lvl.PhysLava(x, (ushort)(y - 1), z, block);
|
||||
blocked[4] = true;
|
||||
}
|
||||
|
||||
@ -224,11 +225,11 @@ namespace MCGalaxy.BlockPhysics {
|
||||
} 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") == -1)
|
||||
if (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1)
|
||||
C.time = 255;
|
||||
}
|
||||
|
||||
if (blocked != null && (!checkWait || ((string)C.data).IndexOf("wait") == -1))
|
||||
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);
|
||||
@ -241,18 +242,18 @@ namespace MCGalaxy.BlockPhysics {
|
||||
ushort x, y, z;
|
||||
lvl.IntToPos(C.b, out x, out y, out z);
|
||||
|
||||
if (!lvl.PhysSpongeCheck(C.b, true)) {
|
||||
if (!lvl.CheckSpongeLava(x, y, z)) {
|
||||
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);
|
||||
lvl.PhysLava(lvl.PosToInt(x, (ushort)(y - 1), z), block);
|
||||
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") == -1)
|
||||
if (!checkWait || ((string)C.data).IndexOf("wait", comp) == -1)
|
||||
C.time = 255;
|
||||
}
|
||||
|
||||
@ -264,7 +265,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
return true;
|
||||
|
||||
if (lvl.physics > 1 && lvl.blocks[b] >= Block.red && lvl.blocks[b] <= Block.white
|
||||
&& !lvl.PhysSpongeCheck(b, true))
|
||||
&& !lvl.CheckSpongeLava(x, y, z))
|
||||
return false; // Adv physics destroys cloth
|
||||
|
||||
switch (lvl.blocks[b]) {
|
||||
@ -273,7 +274,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
|
||||
case Block.water:
|
||||
case Block.activedeathwater:
|
||||
if (!lvl.PhysSpongeCheck(b, true)) return false;
|
||||
if (!lvl.CheckSpongeLava(x, y, z)) return false;
|
||||
break;
|
||||
|
||||
case Block.sand:
|
||||
@ -288,7 +289,7 @@ namespace MCGalaxy.BlockPhysics {
|
||||
case Block.redflower:
|
||||
case Block.mushroom:
|
||||
case Block.redmushroom:
|
||||
if (lvl.physics > 1 && !lvl.PhysSpongeCheck(b, true)) return false;
|
||||
if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z)) return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
@ -38,7 +38,8 @@ namespace MCGalaxy.BlockPhysics {
|
||||
|
||||
int headIndex = lvl.PosToInt((ushort)(x - cx), (ushort)(y - cy), (ushort)(z - cz));
|
||||
byte rocketHead = headIndex < 0 ? Block.Zero : lvl.blocks[headIndex];
|
||||
bool unblocked = !lvl.ListUpdate.Exists(u => u.b == headIndex || u.b == C.b);
|
||||
bool unblocked = !lvl.listUpdateExists.Get(x, y, z) &&
|
||||
(headIndex < 0 || !lvl.listUpdateExists.Get(x - cx, y - cy, z - cz));
|
||||
|
||||
if (unblocked && (rocketHead == Block.air || rocketHead == Block.rocketstart)) {
|
||||
lvl.AddUpdate(headIndex, Block.rockethead);
|
||||
|
@ -62,6 +62,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Galaxy.ico" />
|
||||
<Content Include="ProfilingSessions\Session20160228_124429.sdps" />
|
||||
<Content Include="ProfilingSessions\Session20160228_131348.sdps" />
|
||||
<Content Include="ProfilingSessions\Session20160228_135632.sdps" />
|
||||
<Content Include="ProfilingSessions\Session20160228_135946.sdps" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
Loading…
x
Reference in New Issue
Block a user