mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
Redesign BlockQueue/PhysicsArgs for future extensibility
This commit is contained in:
parent
08286625f3
commit
ecec7a9843
@ -89,6 +89,10 @@ namespace MCGalaxy.Blocks {
|
|||||||
/// <summary> Retrieves the default physics block handler for the given block. </summary>
|
/// <summary> Retrieves the default physics block handler for the given block. </summary>
|
||||||
internal static HandlePhysics GetPhysicsHandler(BlockID block, BlockProps[] props) {
|
internal static HandlePhysics GetPhysicsHandler(BlockID block, BlockProps[] props) {
|
||||||
switch (block) {
|
switch (block) {
|
||||||
|
case Block.Door_Log_air: return DoorPhysics.Do;
|
||||||
|
case Block.Door_TNT_air: return DoorPhysics.Do;
|
||||||
|
case Block.Door_Green_air: return DoorPhysics.Do;
|
||||||
|
|
||||||
case Block.SnakeTail: return SnakePhysics.DoTail;
|
case Block.SnakeTail: return SnakePhysics.DoTail;
|
||||||
case Block.Snake: return SnakePhysics.Do;
|
case Block.Snake: return SnakePhysics.Do;
|
||||||
case Block.RocketHead: return RocketPhysics.Do;
|
case Block.RocketHead: return RocketPhysics.Do;
|
||||||
@ -166,6 +170,10 @@ namespace MCGalaxy.Blocks {
|
|||||||
|
|
||||||
/// <summary> Retrieves the default physics block handler for the given block. </summary>
|
/// <summary> Retrieves the default physics block handler for the given block. </summary>
|
||||||
internal static HandlePhysics GetPhysicsDoorsHandler(BlockID block, BlockProps[] props) {
|
internal static HandlePhysics GetPhysicsDoorsHandler(BlockID block, BlockProps[] props) {
|
||||||
|
if (block == Block.Air) return DoorPhysics.Do;
|
||||||
|
if (block == Block.Door_Log_air) return DoorPhysics.Do;
|
||||||
|
if (block == Block.Door_TNT_air) return DoorPhysics.Do;
|
||||||
|
if (block == Block.Door_Green_air) return DoorPhysics.Do;
|
||||||
if (props[block].oDoorBlock != Block.Invalid) return DoorPhysics.oDoor;
|
if (props[block].oDoorBlock != Block.Invalid) return DoorPhysics.oDoor;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -84,9 +84,8 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
|
|
||||||
internal static PhysicsArgs GetDoorArgs(BlockID block, out BlockID physForm) {
|
internal static PhysicsArgs GetDoorArgs(BlockID block, out BlockID physForm) {
|
||||||
PhysicsArgs args = default(PhysicsArgs);
|
PhysicsArgs args = default(PhysicsArgs);
|
||||||
args.Type1 = PhysicsArgs.Wait; args.Value1 = 16 - 1;
|
args.Type1 = PhysicsArgs.Custom; args.Value1 = 16 - 1;
|
||||||
args.Type2 = PhysicsArgs.Revert; args.Value2 = (BlockRaw)block;
|
args.Type2 = PhysicsArgs.Revert; args.Value2 = (BlockRaw)block;
|
||||||
args.Door = true;
|
|
||||||
args.ExtBlock = block >= Block.Extended;
|
args.ExtBlock = block >= Block.Extended;
|
||||||
|
|
||||||
physForm = Block.Door_Log_air; // air
|
physForm = Block.Door_Log_air; // air
|
||||||
@ -102,9 +101,8 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
|
|
||||||
internal static PhysicsArgs GetTDoorArgs(BlockID block) {
|
internal static PhysicsArgs GetTDoorArgs(BlockID block) {
|
||||||
PhysicsArgs args = default(PhysicsArgs);
|
PhysicsArgs args = default(PhysicsArgs);
|
||||||
args.Type1 = PhysicsArgs.Wait; args.Value1 = 16;
|
args.Type1 = PhysicsArgs.Custom; args.Value1 = 16;
|
||||||
args.Type2 = PhysicsArgs.Revert; args.Value2 = (BlockRaw)block;
|
args.Type2 = PhysicsArgs.Revert; args.Value2 = (BlockRaw)block;
|
||||||
args.Door = true;
|
|
||||||
args.ExtBlock = block >= Block.Extended;
|
args.ExtBlock = block >= Block.Extended;
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,10 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
public static class AirPhysics {
|
public static class AirPhysics {
|
||||||
|
|
||||||
public static void DoAir(Level lvl, ref PhysInfo C) {
|
public static void DoAir(Level lvl, ref PhysInfo C) {
|
||||||
|
if (C.Data.Type1 == PhysicsArgs.Custom) {
|
||||||
|
DoorPhysics.Do(lvl, ref C); return;
|
||||||
|
}
|
||||||
|
|
||||||
ushort x = C.X, y = C.Y, z = C.Z;
|
ushort x = C.X, y = C.Y, z = C.Z;
|
||||||
ActivateablePhysics.CheckNeighbours(lvl, x, y, z);
|
ActivateablePhysics.CheckNeighbours(lvl, x, y, z);
|
||||||
ActivateablePhysics.CheckAt(lvl, x, (ushort)(y - 1), z);
|
ActivateablePhysics.CheckAt(lvl, x, (ushort)(y - 1), z);
|
||||||
|
@ -21,8 +21,28 @@ using BlockID = System.UInt16;
|
|||||||
namespace MCGalaxy.Blocks.Physics {
|
namespace MCGalaxy.Blocks.Physics {
|
||||||
public static class DoorPhysics {
|
public static class DoorPhysics {
|
||||||
|
|
||||||
|
public static void Do(Level lvl, ref PhysInfo C) {
|
||||||
|
if (C.Data.Type1 != PhysicsArgs.Custom) return;
|
||||||
|
if (C.Data.Data == 0) {
|
||||||
|
BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0));
|
||||||
|
bool tdoor = lvl.Props[block].IsTDoor;
|
||||||
|
|
||||||
|
if (tdoor) tDoor(lvl, ref C);
|
||||||
|
else Door(lvl, ref C);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (C.Data.Data <= C.Data.Value1) { // value1 for wait time
|
||||||
|
C.Data.Data++;
|
||||||
|
} else {
|
||||||
|
PhysicsArgs dArgs = default(PhysicsArgs);
|
||||||
|
dArgs.ExtBlock = C.Data.ExtBlock;
|
||||||
|
lvl.AddUpdate(C.Index, C.Data.Value2, dArgs);
|
||||||
|
C.Data.Data = PhysicsArgs.RemoveFromChecks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Change anys door blocks nearby into air forms
|
// Change anys door blocks nearby into air forms
|
||||||
public static void Door(Level lvl, ref PhysInfo C) {
|
static void Door(Level lvl, ref PhysInfo C) {
|
||||||
ushort x = C.X, y = C.Y, z = C.Z;
|
ushort x = C.X, y = C.Y, z = C.Z;
|
||||||
BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0));
|
BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0));
|
||||||
bool instant = block == Block.Door_Air || block == Block.Door_AirActivatable;
|
bool instant = block == Block.Door_Air || block == Block.Door_AirActivatable;
|
||||||
@ -62,8 +82,7 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tDoor(Level lvl, ref PhysInfo C) {
|
||||||
public static void tDoor(Level lvl, ref PhysInfo C) {
|
|
||||||
ushort x = C.X, y = C.Y, z = C.Z;
|
ushort x = C.X, y = C.Y, z = C.Z;
|
||||||
ActivateTDoor(lvl, (ushort)(x - 1), y, z);
|
ActivateTDoor(lvl, (ushort)(x - 1), y, z);
|
||||||
ActivateTDoor(lvl, (ushort)(x + 1), y, z);
|
ActivateTDoor(lvl, (ushort)(x + 1), y, z);
|
||||||
|
@ -25,19 +25,10 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
public static class ExtraInfoPhysics {
|
public static class ExtraInfoPhysics {
|
||||||
|
|
||||||
public static bool DoDoorsOnly(Level lvl, ref PhysInfo C) {
|
public static bool DoDoorsOnly(Level lvl, ref PhysInfo C) {
|
||||||
if (C.Data.Type1 == PhysicsArgs.Custom) return true;
|
|
||||||
if (!C.Data.HasWait && C.Block == Block.Air)
|
if (!C.Data.HasWait && C.Block == Block.Air)
|
||||||
C.Data.ResetTypes();
|
C.Data.ResetTypes();
|
||||||
if (!C.Data.HasWait) return false;
|
if (!C.Data.HasWait) return false;
|
||||||
|
|
||||||
if (C.Data.Door && C.Data.Data == 0) {
|
|
||||||
BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0));
|
|
||||||
bool tdoor = lvl.Props[block].IsTDoor;
|
|
||||||
|
|
||||||
if (tdoor) DoorPhysics.tDoor(lvl, ref C);
|
|
||||||
else DoorPhysics.Door(lvl, ref C);
|
|
||||||
}
|
|
||||||
|
|
||||||
int waitTime = 0;
|
int waitTime = 0;
|
||||||
if (C.Data.Type1 == PhysicsArgs.Wait) waitTime = C.Data.Value1;
|
if (C.Data.Type1 == PhysicsArgs.Wait) waitTime = C.Data.Value1;
|
||||||
if (C.Data.Type2 == PhysicsArgs.Wait) waitTime = C.Data.Value2;
|
if (C.Data.Type2 == PhysicsArgs.Wait) waitTime = C.Data.Value2;
|
||||||
@ -46,19 +37,10 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
if (C.Data.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 0;
|
if (C.Data.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 0;
|
||||||
if (C.Data.Type2 == PhysicsArgs.Wait) C.Data.Type2 = 0;
|
if (C.Data.Type2 == PhysicsArgs.Wait) C.Data.Type2 = 0;
|
||||||
|
|
||||||
if (C.Data.Door) {
|
|
||||||
PhysicsArgs dArgs = default(PhysicsArgs);
|
|
||||||
dArgs.ExtBlock = C.Data.ExtBlock;
|
|
||||||
lvl.AddUpdate(C.Index, C.Data.Value2, dArgs);
|
|
||||||
|
|
||||||
C.Data.ResetTypes();
|
|
||||||
C.Data.Data = PhysicsArgs.RemoveFromChecks;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool DoNormal(Level lvl, ref PhysInfo C) {
|
public static bool DoNormal(Level lvl, ref PhysInfo C) {
|
||||||
if (C.Data.Type1 == PhysicsArgs.Custom) return true;
|
|
||||||
if (!C.Data.HasWait && C.Block == Block.Air)
|
if (!C.Data.HasWait && C.Block == Block.Air)
|
||||||
C.Data.ResetTypes();
|
C.Data.ResetTypes();
|
||||||
|
|
||||||
@ -68,14 +50,6 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
args.ExtBlock = C.Data.ExtBlock;
|
args.ExtBlock = C.Data.ExtBlock;
|
||||||
|
|
||||||
if (args.Wait) {
|
if (args.Wait) {
|
||||||
if (C.Data.Door && C.Data.Data == 0) {
|
|
||||||
BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0));
|
|
||||||
bool tdoor = lvl.Props[block].IsTDoor;
|
|
||||||
|
|
||||||
if (tdoor) DoorPhysics.tDoor(lvl, ref C);
|
|
||||||
else DoorPhysics.Door(lvl, ref C);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (C.Data.Data <= args.WaitTime) { C.Data.Data++; return true; }
|
if (C.Data.Data <= args.WaitTime) { C.Data.Data++; return true; }
|
||||||
if (C.Data.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 0;
|
if (C.Data.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 0;
|
||||||
if (C.Data.Type2 == PhysicsArgs.Wait) C.Data.Type2 = 0;
|
if (C.Data.Type2 == PhysicsArgs.Wait) C.Data.Type2 = 0;
|
||||||
|
@ -27,7 +27,7 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
public const uint TypeMask = 0x3F;
|
public const uint TypeMask = 0x3F;
|
||||||
public const uint TypeBitsMask = 0x07;
|
public const uint TypeBitsMask = 0x07;
|
||||||
public const uint ValueBitsMask = 0xFF;
|
public const uint ValueBitsMask = 0xFF;
|
||||||
public const uint ExtBit = 1u << 31;
|
public const uint ExtBit = 1u << 30;
|
||||||
|
|
||||||
/// <summary> Indicates that this physics entry should be removed from the list of
|
/// <summary> Indicates that this physics entry should be removed from the list of
|
||||||
/// entries that are checked for physics, at the end of the current tick. </summary>
|
/// entries that are checked for physics, at the end of the current tick. </summary>
|
||||||
@ -58,11 +58,6 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
set { Raw &= ~(ValueBitsMask << 22); Raw |= (uint)value << 22; }
|
set { Raw &= ~(ValueBitsMask << 22); Raw |= (uint)value << 22; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Door {
|
|
||||||
get { return (Raw & (1u << 30)) != 0; }
|
|
||||||
set { Raw &= ~(1u << 30); Raw |= (value ? 1u : 0u) << 30; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ExtBlock {
|
public bool ExtBlock {
|
||||||
get { return (Raw & ExtBit) != 0; }
|
get { return (Raw & ExtBit) != 0; }
|
||||||
set { Raw &= ~ExtBit; Raw |= value ? ExtBit : 0u; }
|
set { Raw &= ~ExtBit; Raw |= value ? ExtBit : 0u; }
|
||||||
|
@ -176,7 +176,7 @@ namespace MCGalaxy.Commands.Info {
|
|||||||
Player.Message(p, "Water level: &b{0}%S, Bedrock offset: &b{1}%S, Clouds height: &b{2}%S, Max fog distance: &b{3}",
|
Player.Message(p, "Water level: &b{0}%S, Bedrock offset: &b{1}%S, Clouds height: &b{2}%S, Max fog distance: &b{3}",
|
||||||
cfg.EdgeLevel,cfg.SidesOffset, cfg.CloudsHeight, cfg.MaxFogDistance);
|
cfg.EdgeLevel,cfg.SidesOffset, cfg.CloudsHeight, cfg.MaxFogDistance);
|
||||||
Player.Message(p, "Edge Block: &b{0}%S, Horizon Block: &b{1}",
|
Player.Message(p, "Edge Block: &b{0}%S, Horizon Block: &b{1}",
|
||||||
cfg.EdgeBlock, cfg.HorizonBlock);
|
Block.GetName(p, cfg.EdgeBlock), Block.GetName(p, cfg.HorizonBlock));
|
||||||
Player.Message(p, "Clouds speed: &b{0}%%S, Weather speed: &b{1}%",
|
Player.Message(p, "Clouds speed: &b{0}%%S, Weather speed: &b{1}%",
|
||||||
(cfg.CloudsSpeed / 256f).ToString("F2"),
|
(cfg.CloudsSpeed / 256f).ToString("F2"),
|
||||||
(cfg.WeatherSpeed / 256f).ToString("F2"));
|
(cfg.WeatherSpeed / 256f).ToString("F2"));
|
||||||
|
@ -38,8 +38,7 @@ namespace MCGalaxy.Commands.Building {
|
|||||||
p.DefaultBrushArgs = "";
|
p.DefaultBrushArgs = "";
|
||||||
p.Transform = NoTransform.Instance;
|
p.Transform = NoTransform.Instance;
|
||||||
|
|
||||||
lock (p.level.queueLock)
|
BlockQueue.RemoveAll(p);
|
||||||
p.level.blockqueue.RemoveAll(b => (int)((b >> 9) & Player.SessionIDMask) == p.SessionID);
|
|
||||||
Player.Message(p, "Every toggle or action was aborted.");
|
Player.Message(p, "Every toggle or action was aborted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,10 @@ namespace MCGalaxy {
|
|||||||
public static int Interval = 100;
|
public static int Interval = 100;
|
||||||
public static int UpdatesPerTick = 750;
|
public static int UpdatesPerTick = 750;
|
||||||
static BufferedBlockSender bulkSender = new BufferedBlockSender();
|
static BufferedBlockSender bulkSender = new BufferedBlockSender();
|
||||||
public const int BlockMask = 0x1FF;
|
|
||||||
|
const int posShift = 32;
|
||||||
|
const int idShift = 12;
|
||||||
|
const int blockMask = 0x7FF;
|
||||||
|
|
||||||
public static void Loop(SchedulerTask task) {
|
public static void Loop(SchedulerTask task) {
|
||||||
Level[] loaded = LevelInfo.Loaded.Items;
|
Level[] loaded = LevelInfo.Loaded.Items;
|
||||||
@ -44,15 +47,21 @@ namespace MCGalaxy {
|
|||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
// Bit packing format
|
// Bit packing format
|
||||||
// 32-63: index
|
// 32-63: index
|
||||||
// 9-31: session ID
|
// 12-31: session ID
|
||||||
// 8: is ext block or not
|
// 0-11: block type
|
||||||
// 0-7: raw type
|
ulong flags = (ulong)index << posShift;
|
||||||
ulong flags = (ulong)index << 32;
|
flags |= (ulong)p.SessionID << idShift;
|
||||||
flags |= (ulong)p.SessionID << 9;
|
flags |= (ulong)block & blockMask;
|
||||||
flags |= (ulong)block & BlockMask;
|
|
||||||
|
|
||||||
lock (p.level.queueLock)
|
lock (p.level.queueLock) {
|
||||||
p.level.blockqueue.Add(flags);
|
p.level.blockqueue.Add(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveAll(Player p) {
|
||||||
|
lock (p.level.queueLock) {
|
||||||
|
p.level.blockqueue.RemoveAll(b => (int)((b >> idShift) & Player.SessionIDMask) == p.SessionID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessLevelBlocks(Level lvl) {
|
static void ProcessLevelBlocks(Level lvl) {
|
||||||
@ -67,8 +76,8 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
ulong flags = lvl.blockqueue[i];
|
ulong flags = lvl.blockqueue[i];
|
||||||
int index = (int)(flags >> 32);
|
int index = (int)(flags >> posShift);
|
||||||
BlockID block = (BlockID)(flags & BlockMask);
|
BlockID block = (BlockID)(flags & blockMask);
|
||||||
bulkSender.Add(index, block);
|
bulkSender.Add(index, block);
|
||||||
}
|
}
|
||||||
bulkSender.Send(true);
|
bulkSender.Send(true);
|
||||||
|
@ -156,7 +156,7 @@ namespace MCGalaxy {
|
|||||||
C.Block = (BlockID)(Block.Extended | GetExtTileNoCheck(C.X, C.Y, C.Z));
|
C.Block = (BlockID)(Block.Extended | GetExtTileNoCheck(C.X, C.Y, C.Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((C.Data.Raw & mask) == 0 || extraHandler(this, ref C)) {
|
if ((C.Data.Raw & mask) == 0 || C.Data.Type1 == PhysicsArgs.Custom || extraHandler(this, ref C)) {
|
||||||
HandlePhysics handler = handlers[C.Block];
|
HandlePhysics handler = handlers[C.Block];
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
handler(this, ref C);
|
handler(this, ref C);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user