mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -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>
|
||||
internal static HandlePhysics GetPhysicsHandler(BlockID block, BlockProps[] props) {
|
||||
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.Snake: return SnakePhysics.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>
|
||||
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;
|
||||
return null;
|
||||
}
|
||||
|
@ -84,9 +84,8 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
|
||||
internal static PhysicsArgs GetDoorArgs(BlockID block, out BlockID physForm) {
|
||||
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.Door = true;
|
||||
args.ExtBlock = block >= Block.Extended;
|
||||
|
||||
physForm = Block.Door_Log_air; // air
|
||||
@ -102,9 +101,8 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
|
||||
internal static PhysicsArgs GetTDoorArgs(BlockID block) {
|
||||
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.Door = true;
|
||||
args.ExtBlock = block >= Block.Extended;
|
||||
return args;
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
public static class AirPhysics {
|
||||
|
||||
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;
|
||||
ActivateablePhysics.CheckNeighbours(lvl, x, y, z);
|
||||
ActivateablePhysics.CheckAt(lvl, x, (ushort)(y - 1), z);
|
||||
@ -42,7 +46,7 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
|
||||
C.Data.Data = PhysicsArgs.RemoveFromChecks; return;
|
||||
}
|
||||
|
||||
|
||||
ushort x = C.X, y = C.Y, z = C.Z;
|
||||
FloodAir(lvl, (ushort)(x + 1), y, z, block);
|
||||
FloodAir(lvl, (ushort)(x - 1), y, z, block);
|
||||
|
@ -20,9 +20,29 @@ using BlockID = System.UInt16;
|
||||
|
||||
namespace MCGalaxy.Blocks.Physics {
|
||||
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
|
||||
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;
|
||||
BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0));
|
||||
bool instant = block == Block.Door_Air || block == Block.Door_AirActivatable;
|
||||
@ -42,7 +62,7 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
public static void oDoor(Level lvl, ref PhysInfo C) {
|
||||
ushort x = C.X, y = C.Y, z = C.Z;
|
||||
BlockID block = C.Block;
|
||||
|
||||
|
||||
ActivateODoor(lvl, block, (ushort)(x - 1), y, z);
|
||||
ActivateODoor(lvl, block, (ushort)(x + 1), y, z);
|
||||
ActivateODoor(lvl, block, x, (ushort)(y - 1), z);
|
||||
@ -60,10 +80,9 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
if (index >= 0 && block == target) {
|
||||
lvl.AddUpdate(index, target, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void tDoor(Level lvl, ref PhysInfo C) {
|
||||
static void tDoor(Level lvl, ref PhysInfo C) {
|
||||
ushort x = C.X, y = C.Y, z = C.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 bool DoDoorsOnly(Level lvl, ref PhysInfo C) {
|
||||
if (C.Data.Type1 == PhysicsArgs.Custom) return true;
|
||||
if (!C.Data.HasWait && C.Block == Block.Air)
|
||||
C.Data.ResetTypes();
|
||||
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;
|
||||
if (C.Data.Type1 == PhysicsArgs.Wait) waitTime = C.Data.Value1;
|
||||
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.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;
|
||||
}
|
||||
|
||||
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)
|
||||
C.Data.ResetTypes();
|
||||
|
||||
@ -68,14 +50,6 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
args.ExtBlock = C.Data.ExtBlock;
|
||||
|
||||
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.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 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 TypeBitsMask = 0x07;
|
||||
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
|
||||
/// 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; }
|
||||
}
|
||||
|
||||
public bool Door {
|
||||
get { return (Raw & (1u << 30)) != 0; }
|
||||
set { Raw &= ~(1u << 30); Raw |= (value ? 1u : 0u) << 30; }
|
||||
}
|
||||
|
||||
public bool ExtBlock {
|
||||
get { return (Raw & ExtBit) != 0; }
|
||||
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}",
|
||||
cfg.EdgeLevel,cfg.SidesOffset, cfg.CloudsHeight, cfg.MaxFogDistance);
|
||||
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}%",
|
||||
(cfg.CloudsSpeed / 256f).ToString("F2"),
|
||||
(cfg.WeatherSpeed / 256f).ToString("F2"));
|
||||
|
@ -38,8 +38,7 @@ namespace MCGalaxy.Commands.Building {
|
||||
p.DefaultBrushArgs = "";
|
||||
p.Transform = NoTransform.Instance;
|
||||
|
||||
lock (p.level.queueLock)
|
||||
p.level.blockqueue.RemoveAll(b => (int)((b >> 9) & Player.SessionIDMask) == p.SessionID);
|
||||
BlockQueue.RemoveAll(p);
|
||||
Player.Message(p, "Every toggle or action was aborted.");
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,10 @@ namespace MCGalaxy {
|
||||
public static int Interval = 100;
|
||||
public static int UpdatesPerTick = 750;
|
||||
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) {
|
||||
Level[] loaded = LevelInfo.Loaded.Items;
|
||||
@ -44,15 +47,21 @@ namespace MCGalaxy {
|
||||
if (index == -1) return;
|
||||
// Bit packing format
|
||||
// 32-63: index
|
||||
// 9-31: session ID
|
||||
// 8: is ext block or not
|
||||
// 0-7: raw type
|
||||
ulong flags = (ulong)index << 32;
|
||||
flags |= (ulong)p.SessionID << 9;
|
||||
flags |= (ulong)block & BlockMask;
|
||||
// 12-31: session ID
|
||||
// 0-11: block type
|
||||
ulong flags = (ulong)index << posShift;
|
||||
flags |= (ulong)p.SessionID << idShift;
|
||||
flags |= (ulong)block & blockMask;
|
||||
|
||||
lock (p.level.queueLock)
|
||||
lock (p.level.queueLock) {
|
||||
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) {
|
||||
@ -67,8 +76,8 @@ namespace MCGalaxy {
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
ulong flags = lvl.blockqueue[i];
|
||||
int index = (int)(flags >> 32);
|
||||
BlockID block = (BlockID)(flags & BlockMask);
|
||||
int index = (int)(flags >> posShift);
|
||||
BlockID block = (BlockID)(flags & blockMask);
|
||||
bulkSender.Add(index, block);
|
||||
}
|
||||
bulkSender.Send(true);
|
||||
|
@ -156,7 +156,7 @@ namespace MCGalaxy {
|
||||
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];
|
||||
if (handler != null) {
|
||||
handler(this, ref C);
|
||||
|
Loading…
x
Reference in New Issue
Block a user