Stage 2 of rewriting physics/props to properly support custom blocks

This commit is contained in:
UnknownShadow200 2017-06-11 17:13:56 +10:00
parent 59c6953104
commit 4ab173104a
31 changed files with 265 additions and 371 deletions

View File

@ -36,32 +36,7 @@ namespace MCGalaxy.Blocks {
public delegate void HandlePhysics(Level lvl, ref Check C);
public static class BlockBehaviour {
internal static HandleDelete[] deleteHandlers = new HandleDelete[Block.Count];
internal static HandlePlace[] placeHandlers = new HandlePlace[Block.Count];
internal static HandleWalkthrough[] walkthroughHandlers = new HandleWalkthrough[Block.Count];
internal static HandlePhysics[] physicsHandlers = new HandlePhysics[Block.Count];
internal static HandlePhysics[] physicsDoorsHandlers = new HandlePhysics[Block.Count];
/// <summary> Initalises default deleting, placing, and walkthrough handling behaviour for the core blocks. </summary>
internal static void SetDefaultHandlers() {
for (int i = 0; i < Block.Count; i++) {
SetDefaultHandler(i);
}
}
internal static void SetDefaultHandler(int i) {
ExtBlock block = new ExtBlock((byte)i, 0);
deleteHandlers[i] = GetDeleteHandler(block, Block.Props);
placeHandlers[i] = GetPlaceHandler(block, Block.Props);
bool nonSolid = Block.Walkthrough(Block.Convert((byte)i));
walkthroughHandlers[i] = GetWalkthroughHandler(block, Block.Props, nonSolid);
physicsHandlers[i] = GetPhysicsHandler(block, Block.Props);
physicsDoorsHandlers[i] = GetPhysicsDoorsHandler(block, Block.Props);
}
/// <summary> Retrieves the default place block handler for the given block. </summary>
internal static HandlePlace GetPlaceHandler(ExtBlock block, BlockProps[] props) {
switch (block.BlockID) {
@ -81,7 +56,6 @@ namespace MCGalaxy.Blocks {
case Block.rocketstart: return DeleteBehaviour.RocketStart;
case Block.firework: return DeleteBehaviour.Firework;
case Block.c4det: return DeleteBehaviour.C4Det;
case Block.custom_block: return DeleteBehaviour.CustomBlock;
case Block.door_tree_air: return DeleteBehaviour.RevertDoor;
case Block.door_tnt_air: return DeleteBehaviour.RevertDoor;
case Block.door_green_air: return DeleteBehaviour.RevertDoor;
@ -106,7 +80,6 @@ namespace MCGalaxy.Blocks {
case Block.water_door: return WalkthroughBehaviour.Door;
case Block.lava_door: return WalkthroughBehaviour.Door;
case Block.train: return WalkthroughBehaviour.Train;
case Block.custom_block: return WalkthroughBehaviour.CustomBlock;
}
int i = block.Index;

View File

@ -91,7 +91,7 @@ namespace MCGalaxy.Blocks {
internal static void ODoor(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
if (block.BlockID == Block.odoor8 || block.BlockID == Block.odoor8_air) {
p.level.Blockchange(x, y, z, (ExtBlock)Block.Props[block.BlockID].ODoorId);
p.level.Blockchange(x, y, z, (ExtBlock)p.level.BlockProps[block.Index].ODoorId);
} else {
p.RevertBlock(x, y, z);
}
@ -112,20 +112,5 @@ namespace MCGalaxy.Blocks {
p.ChangeBlock(x, y, z, ExtBlock.Air);
}
}
internal static void CustomBlock(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
byte extBlock = p.level.GetExtTile(x, y, z);
if (p.level.CustomBlockProps[extBlock].IsPortal) {
DoPortal(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) {
DoMessageBlock(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsTDoor) {
RevertDoor(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsDoor) {
Door(p, block, x, y, z);
} else {
p.ChangeBlock(x, y, z, ExtBlock.Air);
}
}
}
}

View File

@ -37,24 +37,7 @@ namespace MCGalaxy.Blocks {
internal static bool Train(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
if (!p.trainInvincible) p.HandleDeath((ExtBlock)Block.train);
return true;
}
internal static bool CustomBlock(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
byte extBlock = p.level.GetExtTile(x, y, z);
BlockDefinition def = p.level.CustomBlockDefs[extBlock];
if (def == null) return false; // custom block was removed
if (def.CollideType == CollideType.Solid) return false;
if (p.level.CustomBlockProps[extBlock].IsPortal) {
return DoPortal(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) {
return DoMessageBlock(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsDoor) {
return Door(p, block, x, y, z);
}
return false;
}
}
internal static bool DoPortal(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
if (p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true;

View File

@ -95,12 +95,6 @@ namespace MCGalaxy {
return block >= water && block <= lavastill;
}
[Obsolete]
public static bool OPBlocks(byte block) { return Props[block].OPBlock; }
[Obsolete]
public static bool Death(byte block) { return Props[block].KillerBlock; }
public static bool BuildIn(byte block) {
if (block == op_water || block == op_lava
|| Props[block].IsPortal || Props[block].IsMessageBlock) return false;
@ -108,16 +102,9 @@ namespace MCGalaxy {
return block >= water && block <= lavastill;
}
public static bool Mover(byte block) { return BlockBehaviour.walkthroughHandlers[block] != null; }
[Obsolete]
public static bool FireKill(byte block) { return block != air && Props[block].LavaKills; }
[Obsolete]
public static bool LavaKill(byte block) { return Props[block].LavaKills; }
[Obsolete]
public static bool WaterKill(byte block) { return Props[block].WaterKills; }
public static bool Mover(byte block) {
return BlockBehaviour.GetWalkthroughHandler(new ExtBlock(block, 0), Block.Props, Walkthrough(Convert(block))) != null;
}
public static bool LightPass(byte block) {
switch (Convert(block)) {
@ -178,12 +165,6 @@ namespace MCGalaxy {
return false;
}
[Obsolete]
public static bool portal(byte block) { return Props[block].IsPortal; }
[Obsolete]
public static bool mb(byte block) { return Props[block].IsMessageBlock; }
public static bool Physics(byte block) { //returns false if placing block cant actualy cause any physics to happen
if (Props[block].IsMessageBlock || Props[block].IsPortal) return false;
if (Props[block].IsDoor || Props[block].IsTDoor) return false;
@ -218,12 +199,6 @@ namespace MCGalaxy {
return true;
}
}
[Obsolete]
public static bool tDoor(byte block) { return Props[block].IsTDoor; }
[Obsolete]
public static byte odoor(byte block) { return Props[block].ODoorId; }
public static AABB BlockAABB(ExtBlock block, Level lvl) {
BlockDefinition def = lvl.GetBlockDef(block);
@ -242,8 +217,12 @@ namespace MCGalaxy {
public static void SetBlocks() {
SetCoreProperties();
BlockProps.Load("core", Block.Props);
BlockPerms.Load();
BlockBehaviour.SetDefaultHandlers();
BlockPerms.Load();
Level[] loaded = LevelInfo.Loaded.Items;
foreach (Level lvl in loaded) {
lvl.SetBlockHandlers();
}
}
[Obsolete("Use BlockPerms.CanModify()")]

View File

@ -146,7 +146,7 @@ namespace MCGalaxy {
for (int i = 0; i < lvl.CustomBlockDefs.Length; i++) {
if (lvl.CustomBlockDefs[i] != oldGlobalDefs[i]) continue;
lvl.CustomBlockDefs[i] = GlobalDefs[i];
lvl.CustomBlockProps[i] = GlobalProps[i];
lvl.BlockProps[i] = GlobalProps[i];
}
}
}
@ -160,11 +160,14 @@ namespace MCGalaxy {
foreach (Level lvl in loaded) {
if (lvl.CustomBlockDefs[block] == null) {
lvl.CustomBlockDefs[block] = def;
lvl.SetBlockHandler(ExtBlock.FromRaw(block));
}
}
}
defs[block] = def;
if (global) Block.SetDefaultNames();
if (!global) level.SetBlockHandler(ExtBlock.FromRaw(block));
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
@ -194,11 +197,13 @@ namespace MCGalaxy {
foreach (Level lvl in loaded) {
if (lvl.CustomBlockDefs[block] == GlobalDefs[block]) {
lvl.CustomBlockDefs[block] = null;
lvl.SetBlockHandler(ExtBlock.FromRaw(block));
}
}
}
defs[block] = null;
if (global) Block.SetDefaultNames();
if (!global) level.SetBlockHandler(ExtBlock.FromRaw(block));
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {

View File

@ -59,31 +59,21 @@ namespace MCGalaxy.Blocks.Physics {
/// <summary> Activates doors, tdoors and toggles odoors at (x, y, z) </summary>
public static void DoDoors(Level lvl, ushort x, ushort y, ushort z, bool instant) {
int index = lvl.PosToInt(x, y, z);
if (index < 0) return;
int index;
ExtBlock block = lvl.GetBlock(x, y, z, out index);
if (index == -1) return;
byte block = lvl.blocks[index];
bool ext = block == Block.custom_block;
BlockProps[] props = Block.Props;
ExtBlock block2 = default(ExtBlock); // TODO: temp hack
block2.BlockID = block;
if (ext) {
block = lvl.GetExtTile(x, y, z);
block2.ExtID = block;
props = lvl.CustomBlockProps;
}
if (props[block].IsDoor) {
int i = block.Index;
if (lvl.BlockProps[i].IsDoor) {
byte physForm;
PhysicsArgs args = GetDoorArgs(block2, out physForm);
PhysicsArgs args = GetDoorArgs(block, out physForm);
if (!instant) lvl.AddUpdate(index, physForm, false, args);
else lvl.Blockchange(index, (ExtBlock)physForm, false, args);
} else if (props[block].IsTDoor) {
PhysicsArgs args = GetTDoorArgs(block, ext);
} else if (lvl.BlockProps[i].IsTDoor) {
PhysicsArgs args = GetTDoorArgs(block);
lvl.AddUpdate(index, Block.air, false, args);
} else {
byte oDoor = props[block].ODoorId;
byte oDoor = lvl.BlockProps[i].ODoorId;
if (oDoor != Block.Invalid)
lvl.AddUpdate(index, oDoor, true);
}
@ -108,12 +98,12 @@ namespace MCGalaxy.Blocks.Physics {
return args;
}
internal static PhysicsArgs GetTDoorArgs(byte raw, bool isExt) {
internal static PhysicsArgs GetTDoorArgs(ExtBlock block) {
PhysicsArgs args = default(PhysicsArgs);
args.Type1 = PhysicsArgs.Wait; args.Value1 = 16;
args.Type2 = PhysicsArgs.Revert; args.Value2 = raw;
args.Type2 = PhysicsArgs.Revert; args.Value2 = block.RawID;
args.Door = true;
args.ExtBlock = isExt;
args.ExtBlock = block.BlockID == Block.custom_block;
return args;
}

View File

@ -67,28 +67,22 @@ namespace MCGalaxy.Blocks.Physics {
lvl.IntToPos(C.b, out x, out y, out z);
int oneY = lvl.Width * lvl.Length;
if (x > 0) ActivateTDoor(lvl, C.b - 1);
if (x < lvl.Width - 1) ActivateTDoor(lvl, C.b + 1);
if (y > 0) ActivateTDoor(lvl, C.b - oneY);
if (y < lvl.Height - 1) ActivateTDoor(lvl, C.b + oneY);
if (z > 0) ActivateTDoor(lvl, C.b - lvl.Width);
if (z < lvl.Length - 1) ActivateTDoor(lvl, C.b + lvl.Width);
ActivateTDoor(lvl, (ushort)(x - 1), y, z);
ActivateTDoor(lvl, (ushort)(x + 1), y, z);
ActivateTDoor(lvl, x, (ushort)(y - 1), z);
ActivateTDoor(lvl, x, (ushort)(y + 1), z);
ActivateTDoor(lvl, x, y, (ushort)(z -1));
ActivateTDoor(lvl, x, y, (ushort)(z + 1));
}
static void ActivateTDoor(Level lvl, int index) {
byte block = lvl.blocks[index];
if (block != Block.custom_block) {
if (!Block.Props[block].IsTDoor) return;
PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block, false);
static void ActivateTDoor(Level lvl, ushort x, ushort y, ushort z) {
int index;
ExtBlock block = lvl.GetBlock(x, y, z, out index);
if (index >= 0 && lvl.BlockProps[block.Index].IsTDoor) {
PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block);
lvl.AddUpdate(index, Block.air, false, args);
} else {
block = lvl.GetExtTile(index);
if (!lvl.CustomBlockProps[block].IsTDoor) return;
PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block, true);
lvl.AddUpdate(index, Block.air, false, args);
}
}
}
}
}

View File

@ -52,8 +52,10 @@ namespace MCGalaxy.Blocks.Physics {
}
static void MagmaFlow(Level lvl, int x, int y, int z, ref bool flowUp) {
int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z);
if (index >= 0 && Block.LavaKill(lvl.blocks[index])) {
int index;
ExtBlock block = lvl.GetBlock((ushort)x, (ushort)y, (ushort)z, out index);
if (index >= 0 && lvl.BlockProps[block.Index].LavaKills) {
lvl.AddUpdate(index, Block.magma);
flowUp = true;
}
@ -89,8 +91,10 @@ namespace MCGalaxy.Blocks.Physics {
}
static void GeyserFlow(Level lvl, int x, int y, int z, ref bool flowUp) {
int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z);
if (index >= 0 && Block.WaterKill(lvl.blocks[index])) {
int index;
ExtBlock block = lvl.GetBlock((ushort)x, (ushort)y, (ushort)z, out index);
if (index >= 0 && lvl.BlockProps[block.Index].WaterKills) {
lvl.AddUpdate(index, Block.geyser);
flowUp = true;
}

View File

@ -30,9 +30,8 @@ namespace MCGalaxy.Blocks.Physics {
if (!C.data.HasWait) return false;
if (C.data.Door && C.data.Data == 0) {
bool tdoor = false;
if (!C.data.ExtBlock) tdoor = Block.Props[C.data.Value2].IsTDoor;
else tdoor = lvl.CustomBlockProps[C.data.Value2].IsTDoor;
int i = C.data.Value2 + (C.data.ExtBlock ? 256 : 0);
bool tdoor = lvl.BlockProps[i].IsTDoor;
if (tdoor) DoorPhysics.tDoor(lvl, ref C);
else DoorPhysics.Door(lvl, ref C);
@ -69,9 +68,8 @@ namespace MCGalaxy.Blocks.Physics {
if (args.Wait) {
if (C.data.Door && C.data.Data == 0) {
bool tdoor = false;
if (!C.data.ExtBlock) tdoor = Block.Props[C.data.Value2].IsTDoor;
else tdoor = lvl.CustomBlockProps[C.data.Value2].IsTDoor;
int i = C.data.Value2 + (C.data.ExtBlock ? 256 : 0);
bool tdoor = lvl.BlockProps[i].IsTDoor;
if (tdoor) DoorPhysics.tDoor(lvl, ref C);
else DoorPhysics.Door(lvl, ref C);

View File

@ -31,15 +31,9 @@ namespace MCGalaxy.Blocks.Physics {
static void ExpandDiagonal(Level lvl, ushort x, ushort y, ushort z,
int dx, int dy, int dz) {
byte block = lvl.GetTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
if (block == Block.air) return;
if (block == Block.custom_block) {
block = lvl.GetExtTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
if (!lvl.CustomBlockProps[block].LavaKills) return;
} else {
if (!Block.Props[block].LavaKills) return;
}
ExtBlock block = lvl.GetBlock((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
if (block.BlockID == Block.air) return;
if (!lvl.BlockProps[block.Index].LavaKills) return;
if (dx != 0)
lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), y, z), Block.fire);
@ -50,19 +44,13 @@ namespace MCGalaxy.Blocks.Physics {
}
static void ExpandAvanced(Level lvl, int x, int y, int z) {
int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z);
if (index < 0) return;
int index;
ExtBlock block = lvl.GetBlock((ushort)x, (ushort)y, (ushort)z, out index);
if (index < 0 || block.BlockID == Block.air) return;
byte block = lvl.blocks[index];
if (block == Block.air) return;
if (block == Block.tnt) {
if (block.BlockID == Block.tnt) {
lvl.MakeExplosion((ushort)x, (ushort)y, (ushort)z, -1);
} else if (block == Block.custom_block) {
block = lvl.GetExtTileNoCheck((ushort)x, (ushort)y, (ushort)z);
if (lvl.CustomBlockProps[block].LavaKills)
lvl.AddUpdate(index, Block.fire);
} else if (Block.Props[block].LavaKills) {
} else if (lvl.BlockProps[block.Index].LavaKills) {
lvl.AddUpdate(index, Block.fire);
}
}

View File

@ -22,12 +22,13 @@ namespace MCGalaxy.Blocks.Physics {
public static class LiquidPhysics {
public static void PhysWater(Level lvl, ushort x, ushort y, ushort z, byte type) {
int b = lvl.PosToInt(x, y, z);
int b;
ExtBlock block = lvl.GetBlock(x, y, z, out b);
if (b == -1) return;
if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z))
return;
switch (lvl.blocks[b]) {
switch (block.BlockID) {
case Block.air:
if (!lvl.CheckSpongeWater(x, y, z)) lvl.AddUpdate(b, type);
break;
@ -44,14 +45,8 @@ namespace MCGalaxy.Blocks.Physics {
lvl.AddCheck(b); break;
default:
// //Adv physics kills flowers and mushrooms in water
byte block = lvl.blocks[b];
if (block != Block.custom_block) {
if (!Block.Props[block].WaterKills) break;
} else {
block = lvl.GetExtTile(x, y, z);
if (!lvl.CustomBlockProps[block].WaterKills) break;
}
// Adv physics kills flowers and mushrooms in water
if (!lvl.BlockProps[block.Index].WaterKills) break;
if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z))
lvl.AddUpdate(b, Block.air);
@ -60,12 +55,13 @@ namespace MCGalaxy.Blocks.Physics {
}
public static void PhysLava(Level lvl, ushort x, ushort y, ushort z, byte type) {
int b = lvl.PosToInt(x, y, z);
int b;
ExtBlock block = lvl.GetBlock(x, y, z, out b);
if (b == -1) return;
if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z))
return;
switch (lvl.blocks[b]) {
switch (block.BlockID) {
case Block.air:
if (!lvl.CheckSpongeLava(x, y, z)) lvl.AddUpdate(b, type);
break;
@ -87,13 +83,7 @@ namespace MCGalaxy.Blocks.Physics {
default:
//Adv physics kills flowers, wool, mushrooms, and wood type blocks in lava
byte block = lvl.blocks[b];
if (block != Block.custom_block) {
if (!Block.Props[block].LavaKills) break;
} else {
block = lvl.GetExtTile(x, y, z);
if (!lvl.CustomBlockProps[block].LavaKills) break;
}
if (!lvl.BlockProps[block.Index].LavaKills) break;
if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z))
lvl.AddUpdate(b, Block.air);

View File

@ -138,13 +138,13 @@ namespace MCGalaxy.Blocks.Physics {
}
static bool WaterBlocked(Level lvl, ushort x, ushort y, ushort z) {
int b = lvl.PosToInt(x, y, z);
if (b == -1)
return true;
int b;
ExtBlock block = lvl.GetBlock(x, y, z, out b);
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]) {
switch (block.BlockID) {
case Block.air:
case Block.lava:
case Block.lava_fast:
@ -158,14 +158,8 @@ namespace MCGalaxy.Blocks.Physics {
return false;
default:
//Adv physics kills flowers, mushroom blocks in water
byte block = lvl.blocks[b];
if (block != Block.custom_block) {
if (!Block.Props[block].WaterKills) return true;
} else {
block = lvl.GetExtTile(x, y, z);
if (!lvl.CustomBlockProps[block].WaterKills) return true;
}
// Adv physics kills flowers, mushroom blocks in water
if (!lvl.BlockProps[block.Index].WaterKills) break;
if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z)) return false;
break;
@ -256,12 +250,13 @@ namespace MCGalaxy.Blocks.Physics {
}
static bool LavaBlocked(Level lvl, ushort x, ushort y, ushort z) {
int b = lvl.PosToInt(x, y, z);
int b;
ExtBlock block = lvl.GetBlock(x, y, z, out b);
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]) {
switch (block.BlockID) {
case Block.air:
return false;
@ -275,14 +270,8 @@ namespace MCGalaxy.Blocks.Physics {
return false;
default:
//Adv physics kills flowers, wool, mushrooms, and wood type blocks in lava
byte block = lvl.blocks[b];
if (block != Block.custom_block) {
if (!Block.Props[block].LavaKills) return true;
} else {
block = lvl.GetExtTile(x, y, z);
if (!lvl.CustomBlockProps[block].LavaKills) return true;
}
// Adv physics kills flowers, wool, mushrooms, and wood type blocks in lava
if (!lvl.BlockProps[block.Index].LavaKills) break;
if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z)) return false;
break;

View File

@ -121,8 +121,10 @@ namespace MCGalaxy.Blocks.Physics {
bool force = false, TntWarsGame game = null) {
Random rand = new Random();
if ((lvl.physics < 2 || lvl.physics == 5) && !force) return;
int index = lvl.PosToInt(x, y, z);
if (index >= 0 && !Block.Props[lvl.blocks[index]].OPBlock)
int index;
ExtBlock block = lvl.GetBlock(x, y, z, out index);
if (index >= 0 && !lvl.BlockProps[block.Index].OPBlock)
lvl.AddUpdate(index, Block.tntexplosion, true);
Explode(lvl, x, y, z, size + 1, rand, -1, game);

View File

@ -33,33 +33,22 @@ namespace MCGalaxy.Blocks.Physics {
for (int dy = -dirY; dy != 2 * dirY; dy += dirY)
for (int dz = -dirZ; dz != 2 * dirZ; dz += dirZ)
{
byte tileBelow = lvl.GetTile((ushort)(x + dx),(ushort)(y + dy - 1), (ushort)(z + dz));
byte tile = lvl.GetTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
ExtBlock below = lvl.GetBlock((ushort)(x + dx),(ushort)(y + dy - 1), (ushort)(z + dz));
ExtBlock block = lvl.GetBlock((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz));
bool isRails = lvl.BlockProps[below.BlockID].IsRails;
bool isRails = false;
if (tileBelow != Block.custom_block) {
isRails = Block.Props[tileBelow].IsRails;
} else {
byte extBelow = lvl.GetExtTile((ushort)(x + dx), (ushort)(y + dy - 1), (ushort)(z + dz));
isRails = lvl.CustomBlockProps[extBelow].IsRails;
}
if (isRails && (tile == Block.air || tile == Block.water)
if (isRails && (block.BlockID == Block.air || block.BlockID == Block.water)
&& !lvl.listUpdateExists.Get(x + dx, y + dy, z + dz)) {
lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx),
(ushort)(y + dy), (ushort)(z + dz)), Block.train);
lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)), Block.train);
lvl.AddUpdate(C.b, Block.air);
byte newBlock = tileBelow == Block.op_air ? Block.glass : Block.obsidian;
byte newBlock = below.BlockID == Block.op_air ? Block.glass : Block.obsidian;
tileBelow = lvl.GetTile(x, (ushort)(y - 1), z);
below = lvl.GetBlock(x, (ushort)(y - 1), z);
PhysicsArgs args = default(PhysicsArgs);
args.Type1 = PhysicsArgs.Wait; args.Value1 = 5;
args.Type2 = PhysicsArgs.Revert; args.Value2 = tileBelow;
args.Type2 = PhysicsArgs.Revert; args.Value2 = below.RawID;
args.ExtBlock = below.BlockID == Block.custom_block;
if (tileBelow == Block.custom_block) {
args.Value2 = lvl.GetExtTile(x, (ushort)(y - 1), z);
args.ExtBlock = true;
}
lvl.AddUpdate(lvl.IntOffset(C.b, 0, -1, 0), newBlock, true, args);
return;
}

View File

@ -115,7 +115,7 @@ namespace MCGalaxy.Commands.CPE {
if (src == null) { MessageNoBlock(p, srcId, global, cmd); return; }
if (ExistsInScope(dst, dstId, global)) { MessageAlreadyBlock(p, dstId, global, cmd); return; }
BlockProps props = global ? BlockDefinition.GlobalProps[srcId] : p.level.CustomBlockProps[srcId];
BlockProps props = global ? BlockDefinition.GlobalProps[srcId] : p.level.BlockProps[srcId];
dst = src.Copy();
props.BlockId = (byte)dstId;
dst.BlockID = (byte)dstId;
@ -550,14 +550,14 @@ namespace MCGalaxy.Commands.CPE {
static void UpdateBlockProps(bool global, Player p, BlockProps props) {
byte block = props.BlockId;
if (!global) {
p.level.CustomBlockProps[block] = props;
p.level.BlockProps[block] = props;
} else {
BlockDefinition.GlobalProps[block] = props;
Level[] loaded = LevelInfo.Loaded.Items;
foreach (Level lvl in loaded) {
if (lvl.CustomBlockDefs[block] != null) continue;
lvl.CustomBlockProps[block] = props;
lvl.BlockProps[block] = props;
}
}
}
@ -565,16 +565,16 @@ namespace MCGalaxy.Commands.CPE {
static void RemoveBlockProps(bool global, byte id, Player p) {
// Level block reverts to using global block
if (!global && BlockDefinition.GlobalDefs[id] != null) {
p.level.CustomBlockProps[id] = BlockDefinition.GlobalProps[id];
p.level.BlockProps[id] = BlockDefinition.GlobalProps[id];
} else if (!global) {
p.level.CustomBlockProps[id] = new BlockProps((byte)id);
p.level.BlockProps[id] = new BlockProps((byte)id);
} else {
BlockDefinition.GlobalProps[id] = new BlockProps((byte)id);
Level[] loaded = LevelInfo.Loaded.Items;
foreach (Level lvl in loaded) {
if (lvl.CustomBlockDefs[id] != BlockDefinition.GlobalDefs[id]) continue;
lvl.CustomBlockProps[id] = new BlockProps((byte)id);
lvl.BlockProps[id] = new BlockProps((byte)id);
}
}
}

View File

@ -55,8 +55,8 @@ namespace MCGalaxy.Commands.Fun {
pos.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * t));
pos.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * t));
byte by = p.level.GetTile(pos.X, pos.Y, pos.Z);
if (by != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, by, bp.ending, pos, true))
ExtBlock cur = p.level.GetBlock(pos.X, pos.Y, pos.Z);
if (cur.BlockID != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, cur, bp.ending, pos, true))
break;
p.level.Blockchange(pos.X, pos.Y, pos.Z, block);

View File

@ -95,10 +95,10 @@ namespace MCGalaxy.Commands.Fun {
target.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i));
target.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i));
byte tile = p.level.GetTile(target.X, target.Y, target.Z);
if (tile == Block.Invalid) break;
ExtBlock block = p.level.GetBlock(target.X, target.Y, target.Z);
if (block.BlockID == Block.Invalid) break;
if (tile != Block.air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, tile, args.ending, target, false))
if (block.BlockID != Block.air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, block, args.ending, target, false))
break;
Player hit = GetPlayer(p, target, true);
@ -113,8 +113,8 @@ namespace MCGalaxy.Commands.Fun {
static bool MoveMissile(MissileArgs args, Vec3U16 pos, Vec3U16 target) {
Player p = args.player;
byte tile = p.level.GetTile(pos.X, pos.Y, pos.Z);
if (tile != Block.air && !args.allBlocks.Contains(pos) && HandlesHitBlock(p, tile, args.ending, pos, true))
ExtBlock block = p.level.GetBlock(pos.X, pos.Y, pos.Z);
if (block.BlockID != Block.air && !args.allBlocks.Contains(pos) && HandlesHitBlock(p, block, args.ending, pos, true))
return false;
p.level.Blockchange(pos.X, pos.Y, pos.Z, args.block);

View File

@ -161,15 +161,16 @@ namespace MCGalaxy.Commands.Fun {
}
}
protected static bool HandlesHitBlock(Player p, byte type, EndType ending, Vec3U16 pos, bool doExplode) {
protected static bool HandlesHitBlock(Player p, ExtBlock block, EndType ending, Vec3U16 pos, bool doExplode) {
if (p.level.physics < 2 || ending == EndType.Teleport || ending == EndType.Normal) return true;
if (ending == EndType.Destroy) {
if ((!Block.FireKill(type) && !Block.NeedRestart(type)) && type != Block.glass) {
bool fireKills = block.BlockID != Block.air && p.level.BlockProps[block.Index].LavaKills;
if ((!fireKills && !Block.NeedRestart(block.BlockID)) && block.BlockID != Block.glass) {
return true;
}
} else if (p.level.physics >= 3) {
if (type != Block.glass && doExplode) {
if (block.BlockID != Block.glass && doExplode) {
p.level.MakeExplosion(pos.X, pos.Y, pos.Z, 1);
return true;
}

View File

@ -32,10 +32,10 @@ namespace MCGalaxy.Commands.World {
if (args.Length < 3) { Help(p); return; }
BlockProps[] scope = GetScope(p, args[0]);
if (scope == null) return;
if (scope == null) return;
ExtBlock block = GetBlock(p, scope, args[1]);
if (block.IsInvalid) return;
byte block = GetBlock(p, scope, args[1]);
if (block == Block.Invalid) return;
string prop = args[2].ToLower();
SetProperty(p, scope, block, prop, args);
}
@ -50,79 +50,82 @@ namespace MCGalaxy.Commands.World {
Player.Message(p, "Cannot use level scope from {0}.", src);
return null;
}
return p.level.CustomBlockProps;
return p.level.BlockProps;
}
Player.Message(p, "&cScope must \"core\", \"global\", or \"level\"");
return null;
}
byte GetBlock(Player p, BlockProps[] scope, string input) {
byte block = 0;
ExtBlock GetBlock(Player p, BlockProps[] scope, string input) {
if (scope == Block.Props) {
if (!byte.TryParse(input, out block))
block = Block.Byte(input);
byte raw;
if (!byte.TryParse(input, out raw))
raw = Block.Byte(input);
if (Block.Name(block).CaselessEq("unknown")) {
if (Block.Name(raw).CaselessEq("unknown")) {
Player.Message(p, "&cThere is no block with id or name \"{0}\"", input);
block = Block.Invalid;
return ExtBlock.Invalid;
}
return new ExtBlock(raw, 0);
} else if (scope == BlockDefinition.GlobalProps) {
block = BlockDefinition.GetBlock(input, BlockDefinition.GlobalDefs);
if (block == Block.Invalid)
byte raw = BlockDefinition.GetBlock(input, BlockDefinition.GlobalDefs);
if (raw == Block.Invalid)
Player.Message(p, "&cThere is no global custom block with id or name \"{0}\"", input);
return ExtBlock.FromRaw(raw);
} else {
block = BlockDefinition.GetBlock(input, p.level.CustomBlockDefs);
if (block == Block.Invalid)
byte raw = BlockDefinition.GetBlock(input, p.level.CustomBlockDefs);
if (raw == Block.Invalid)
Player.Message(p, "&cThere is no level custom block with id or name \"{0}\"", input);
if (p.level.CustomBlockDefs[block] == BlockDefinition.GlobalDefs[block]) {
Player.Message(p, "&cUse %T/blockprops global &cto modify this custom block."); return Block.Invalid;
if (p.level.CustomBlockDefs[raw] == BlockDefinition.GlobalDefs[raw]) {
Player.Message(p, "&cUse %T/blockprops global &cto modify this custom block."); return ExtBlock.Invalid;
}
return ExtBlock.FromRaw(raw);
}
return block;
}
void SetProperty(Player p, BlockProps[] scope, byte id,
void SetProperty(Player p, BlockProps[] scope, ExtBlock block,
string prop, string[] args) {
if (prop == "portal") {
Toggle(p, scope, id, "a portal",
Toggle(p, scope, block, "a portal",
(ref BlockProps props) => props.IsPortal = !props.IsPortal,
(BlockProps props) => props.IsPortal);
} else if (prop == "mb" || prop == "messageblock") {
Toggle(p, scope, id, "a message block",
Toggle(p, scope, block, "a message block",
(ref BlockProps props) => props.IsMessageBlock = !props.IsMessageBlock,
(BlockProps props) => props.IsMessageBlock);
} else if (prop == "rails") {
Toggle(p, scope, id, "train rails",
Toggle(p, scope, block, "train rails",
(ref BlockProps props) => props.IsRails = !props.IsRails,
(BlockProps props) => props.IsRails);
} else if (prop == "waterkills") {
Toggle(p, scope, id, "killed by water",
Toggle(p, scope, block, "killed by water",
(ref BlockProps props) => props.WaterKills = !props.WaterKills,
(BlockProps props) => props.WaterKills);
} else if (prop == "lavakills") {
Toggle(p, scope, id, "killed by lava",
Toggle(p, scope, block, "killed by lava",
(ref BlockProps props) => props.LavaKills = !props.LavaKills,
(BlockProps props) => props.LavaKills);
} else if (prop == "door") {
Toggle(p, scope, id, "a door",
Toggle(p, scope, block, "a door",
(ref BlockProps props) => props.IsDoor = !props.IsDoor,
(BlockProps props) => props.IsDoor);
} else if (prop == "tdoor") {
Toggle(p, scope, id, "a tdoor",
Toggle(p, scope, block, "a tdoor",
(ref BlockProps props) => props.IsTDoor = !props.IsTDoor,
(BlockProps props) => props.IsTDoor);
} else if (prop == "killer" || prop == "death") {
Toggle(p, scope, id, "a killer block",
Toggle(p, scope, block, "a killer block",
(ref BlockProps props) => props.KillerBlock = !props.KillerBlock,
(BlockProps props) => props.KillerBlock);
} else if (prop == "deathmsg" || prop == "deathmessage") {
string msg = args.Length > 3 ? args[3] : null;
SetDeathMessage(p, scope, id, msg);
SetDeathMessage(p, scope, block, msg);
} else if (prop == "animalai" || prop == "animal") {
string msg = args.Length > 3 ? args[3] : null;
SetEnum(p, scope, id, msg);
SetEnum(p, scope, block, msg);
} else {
Help(p);
}
@ -130,73 +133,82 @@ namespace MCGalaxy.Commands.World {
delegate void BoolSetter(ref BlockProps props);
static void Toggle(Player p, BlockProps[] scope, byte id, string type,
static void Toggle(Player p, BlockProps[] scope, ExtBlock block, string type,
BoolSetter setter, Func<BlockProps, bool> getter) {
BlockProps props = scope[id];
BlockProps props = scope[block.Index];
setter(ref props);
scope[id] = props;
scope[block.Index] = props;
Level lvl = Player.IsSuper(p) ? null : p.level;
Player.Message(p, "Block {0} is {1}: {2}",
BlockName(scope, lvl, id),
BlockName(scope, lvl, block),
type, getter(props) ? "&aYes" : "&cNo");
OnPropsChanged(scope, lvl, id, false);
OnPropsChanged(scope, lvl, block, false);
}
static void SetEnum(Player p, BlockProps[] scope, byte id, string msg) {
static void SetEnum(Player p, BlockProps[] scope, ExtBlock block, string msg) {
Level lvl = Player.IsSuper(p) ? null : p.level;
AnimalAI ai = AnimalAI.None;
if (!CommandParser.GetEnum(p, msg, "Animal AI", ref ai)) return;
scope[id].AnimalAI = ai;
scope[block.Index].AnimalAI = ai;
Player.Message(p, "Animal AI for {0} set to: {1}",
BlockName(scope, lvl, id), ai);
OnPropsChanged(scope, lvl, id, true);
BlockName(scope, lvl, block), ai);
OnPropsChanged(scope, lvl, block, true);
}
static void SetDeathMessage(Player p, BlockProps[] scope, byte id, string msg) {
scope[id].DeathMessage = msg;
static void SetDeathMessage(Player p, BlockProps[] scope, ExtBlock block, string msg) {
scope[block.Index].DeathMessage = msg;
Level lvl = Player.IsSuper(p) ? null : p.level;
if (msg == null) {
Player.Message(p, "Death message for {0} removed.",
BlockName(scope, lvl, id));
BlockName(scope, lvl, block));
} else {
Player.Message(p, "Death message for {0} set to: {1}",
BlockName(scope, lvl, id), msg);
BlockName(scope, lvl, block), msg);
}
OnPropsChanged(scope, lvl, id, false);
OnPropsChanged(scope, lvl, block, false);
}
static void OnPropsChanged(BlockProps[] scope, Level level, byte id, bool physics) {
scope[id].Changed = true;
static void OnPropsChanged(BlockProps[] scope, Level level, ExtBlock block, bool physics) {
scope[block.Index].Changed = true;
if (scope == Block.Props) {
BlockBehaviour.SetDefaultHandler(id);
BlockProps.Save("core", scope);
BlockProps.Save("core", scope);
Level[] loaded = LevelInfo.Loaded.Items;
foreach (Level lvl in loaded) {
lvl.SetBlockHandler(block);
lvl.BlockProps[block.Index] = BlockDefinition.GlobalProps[block.Index];
}
} else if (scope == BlockDefinition.GlobalProps) {
Level[] loaded = LevelInfo.Loaded.Items;
foreach (Level lvl in loaded) {
if (lvl.CustomBlockDefs[id] != BlockDefinition.GlobalDefs[id]) continue;
lvl.CustomBlockProps[id] = BlockDefinition.GlobalProps[id];
}
BlockProps.Save("global", scope);
byte raw = block.RawID;
foreach (Level lvl in loaded) {
if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw]) continue;
lvl.BlockProps[block.Index] = BlockDefinition.GlobalProps[block.Index];
lvl.SetBlockHandler(block);
}
} else {
BlockProps.Save("lvl_" + level.name, scope);
level.SetBlockHandler(block);
}
}
static string BlockName(BlockProps[] scope, Level lvl, byte raw) {
if (scope == Block.Props) return Block.Name(raw);
static string BlockName(BlockProps[] scope, Level lvl, ExtBlock block) {
if (scope == Block.Props) return Block.Name(block.RawID);
BlockDefinition def = null;
if (scope == BlockDefinition.GlobalProps) {
def = BlockDefinition.GlobalDefs[raw];
def = BlockDefinition.GlobalDefs[block.RawID];
} else {
def = lvl.CustomBlockDefs[raw];
def = lvl.CustomBlockDefs[block.RawID];
}
return def == null ? raw.ToString() : def.Name.Replace(" ", "");
return def == null ? block.RawID.ToString() : def.Name.Replace(" ", "");
}

View File

@ -55,7 +55,7 @@ namespace MCGalaxy.Commands.Building {
ExtBlock old = p.level.GetBlock(P.X, P.Y, P.Z);
if (!p.CheckManualChange(old, ExtBlock.Air, false)) return;
HandleDelete handler = BlockBehaviour.deleteHandlers[old.BlockID];
HandleDelete handler = p.level.deleteHandlers[old.Index];
if (handler != null) {
handler(p, old, P.X, P.Y, P.Z);
} else {

View File

@ -70,7 +70,7 @@ namespace MCGalaxy.Commands.Building {
if (name == "show") { ShowMessageBlocks(p); return ExtBlock.Invalid; }
block = BlockDefinition.GetBlock(name, p);
if (p.level.CustomBlockProps[block].IsMessageBlock)
if (p.level.BlockProps[block].IsMessageBlock)
return ExtBlock.FromRaw(block);
// Hardcoded aliases for backwards compatibility
@ -214,7 +214,7 @@ namespace MCGalaxy.Commands.Building {
string blocks = Block.Props.Join(props => Format(props));
if (!Player.IsSuper(p)) {
string custom = p.level.CustomBlockProps.Join(props => FormatCustom(p.level, props));
string custom = p.level.BlockProps.Join(props => FormatCustom(p.level, props));
if (blocks != "" && custom != "")
blocks = blocks + ", " + custom;
}

View File

@ -60,7 +60,7 @@ namespace MCGalaxy.Commands.Building {
if (name == "show") { ShowPortals(p); return ExtBlock.Invalid; }
block = BlockDefinition.GetBlock(name, p);
if (p.level.CustomBlockProps[block].IsPortal)
if (p.level.BlockProps[block].IsPortal)
return ExtBlock.FromRaw(block);
// Hardcoded aliases for backwards compatibility
@ -218,7 +218,7 @@ namespace MCGalaxy.Commands.Building {
string blocks = Block.Props.Join(props => Format(props));
if (!Player.IsSuper(p)) {
string custom = p.level.CustomBlockProps.Join(props => FormatCustom(p.level, props));
string custom = p.level.BlockProps.Join(props => FormatCustom(p.level, props));
if (blocks != "" && custom != "")
blocks = blocks + ", " + custom;
}

View File

@ -93,16 +93,10 @@ namespace MCGalaxy.Core {
byte entity, ushort x, ushort y, ushort z, TargetBlockFace face) {
if (p.level.Deletable || action != MouseAction.Pressed || !p.level.IsValidPos(x, y, z)) return;
byte block = p.level.GetTile(x, y, z);
bool isMB = Block.Props[block].IsMessageBlock;
bool isPortal = Block.Props[block].IsPortal;
if (block == Block.custom_block) {
block = p.level.GetExtTile(x, y, z);
isMB = p.level.CustomBlockProps[block].IsMessageBlock;
isPortal = p.level.CustomBlockProps[block].IsMessageBlock;
}
ExtBlock block = p.level.GetBlock(x, y, z);
bool isMB = p.level.BlockProps[block.Index].IsMessageBlock;
bool isPortal = p.level.BlockProps[block.Index].IsPortal;
if (isMB) { MessageBlock.Handle(p, x, y, z, true); }
if (isPortal) { Portal.Handle(p, x, y, z); }
}

View File

@ -47,11 +47,7 @@ namespace MCGalaxy.DB {
public static void OutputMessageBlock(Player p, ExtBlock block,
ushort x, ushort y, ushort z) {
if (block.BlockID == Block.custom_block) {
if (!p.level.CustomBlockProps[block.ExtID].IsMessageBlock) return;
} else {
if (!Block.Props[block.BlockID].IsMessageBlock) return;
}
if (!p.level.BlockProps[block.Index].IsMessageBlock) return;
try {
if (!Database.Backend.TableExists("Messages" + p.level.name)) return;
@ -69,11 +65,7 @@ namespace MCGalaxy.DB {
public static void OutputPortal(Player p, ExtBlock block,
ushort x, ushort y, ushort z) {
if (block.BlockID == Block.custom_block) {
if (!p.level.CustomBlockProps[block.ExtID].IsPortal) return;
} else {
if (!Block.Props[block.BlockID].IsPortal) return;
}
if (!p.level.BlockProps[block.Index].IsPortal) return;
try {
if (!Database.Backend.TableExists("Portals" + p.level.name)) return;

View File

@ -129,10 +129,10 @@ namespace MCGalaxy.Games
if (mapOn.GetBlock(x, y, z) != (ExtBlock)Block.flagbase) {
mapOn.Blockchange(x, y, z, (ExtBlock)Block.flagbase);
}
if (mapOn.GetBlock(x, y + 1, z) != (ExtBlock)Block.mushroom) {
if (mapOn.GetBlock(x, (ushort)(y + 1), z) != (ExtBlock)Block.mushroom) {
mapOn.Blockchange(x, (ushort)(y + 1), z, (ExtBlock)Block.mushroom);
}
if (mapOn.GetBlock(x, y + 2, z) != (ExtBlock)GetColorBlock(color)) {
if (mapOn.GetBlock(x, (ushort)(y + 2), z) != (ExtBlock)GetColorBlock(color)) {
mapOn.Blockchange(x, (ushort)(y + 2), z, (ExtBlock)GetColorBlock(color));
}

View File

@ -54,8 +54,19 @@ namespace MCGalaxy {
ExtBlock block;
block.BlockID = blocks[x + Width * (z + y * Length)];
block.ExtID = block.BlockID == Block.custom_block
? GetExtTileNoCheck(x, y, z) : Block.air;
block.ExtID = block.BlockID == Block.custom_block ? GetExtTileNoCheck(x, y, z) : Block.air;
return block;
}
/// <summary> Gets the block at the given coordinates. </summary>
/// <returns> Block.Invalid if coordinates outside map. </returns>
public ExtBlock GetBlock(ushort x, ushort y, ushort z, out int index) {
if (x >= Width || y >= Height || z >= Length || blocks == null) { index = -1; return ExtBlock.Invalid; }
ExtBlock block;
index = x + Width * (z + y * Length);
block.BlockID = blocks[index];
block.ExtID = block.BlockID == Block.custom_block ? GetExtTileNoCheck(x, y, z) : Block.air;
return block;
}
@ -354,9 +365,10 @@ namespace MCGalaxy {
try
{
if (!overRide)
if (Block.Props[old.BlockID].OPBlock || (Block.Props[block.BlockID].OPBlock && data.Raw != 0))
if (!overRide) {
if (BlockProps[old.Index].OPBlock || (BlockProps[block.Index].OPBlock && data.Raw != 0))
return false;
}
if (old.BlockID == Block.sponge && physics > 0 && block.BlockID != Block.sponge)
OtherPhysics.DoSpongeRemoved(this, b, false);

View File

@ -49,9 +49,15 @@ namespace MCGalaxy {
public Orientation SpawnRot { get { return new Orientation(rotx, roty); } }
public BlockDefinition[] CustomBlockDefs;
public BlockProps[] CustomBlockProps;
public BlockProps[] BlockProps;
public ExtrasCollection Extras = new ExtrasCollection();
internal HandleDelete[] deleteHandlers = new HandleDelete[Block.Count * 2];
internal HandlePlace[] placeHandlers = new HandlePlace[Block.Count * 2];
internal HandleWalkthrough[] walkthroughHandlers = new HandleWalkthrough[Block.Count * 2];
internal HandlePhysics[] physicsHandlers = new HandlePhysics[Block.Count * 2];
internal HandlePhysics[] physicsDoorsHandlers = new HandlePhysics[Block.Count * 2];
public ushort Width, Height, Length;
// NOTE: These are for legacy code only, you should use upper case Width/Height/Length
// as these correctly map Y to being Height

View File

@ -137,10 +137,10 @@ namespace MCGalaxy {
lastCheck = ListCheck.Count;
const uint mask = PhysicsArgs.TypeMask;
HandlePhysics[] handlers = BlockBehaviour.physicsHandlers;
HandlePhysics[] handlers = physicsHandlers;
ExtraInfoHandler extraHandler = ExtraInfoPhysics.DoNormal;
if (physics == 5) {
handlers = BlockBehaviour.physicsDoorsHandlers;
handlers = physicsDoorsHandlers;
extraHandler = ExtraInfoPhysics.DoDoorsOnly;
}
@ -350,11 +350,10 @@ namespace MCGalaxy {
if (block.BlockID != Block.custom_block)
return Block.Physics(block.BlockID);
BlockProps[] props = CustomBlockProps;
byte extBlock = block.ExtID;
if (props[extBlock].IsMessageBlock || props[extBlock].IsPortal) return false;
if (props[extBlock].IsDoor || props[extBlock].IsTDoor) return false;
if (props[extBlock].OPBlock) return false;
int i = block.Index;
if (BlockProps[i].IsMessageBlock || BlockProps[i].IsPortal) return false;
if (BlockProps[i].IsDoor || BlockProps[i].IsTDoor) return false;
if (BlockProps[i].OPBlock) return false;
return true;
}

View File

@ -72,9 +72,9 @@ namespace MCGalaxy {
CustomBlockDefs = new BlockDefinition[256];
for (int i = 0; i < CustomBlockDefs.Length; i++)
CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i];
CustomBlockProps = new BlockProps[256];
for (int i = 0; i < CustomBlockProps.Length; i++)
CustomBlockProps[i] = BlockDefinition.GlobalProps[i];
BlockProps = new BlockProps[256];
for (int i = 0; i < BlockProps.Length; i++)
BlockProps[i] = BlockDefinition.GlobalProps[i];
name = n; MapName = n.ToLower();
BlockDB = new BlockDB(this);
@ -91,6 +91,7 @@ namespace MCGalaxy {
spawny = (ushort)(Height * 0.75f);
spawnz = (ushort)(Length / 2);
rotx = 0; roty = 0;
SetBlockHandlers();
ZoneList = new List<Zone>();
VisitAccess = new LevelAccessController(this, true);
@ -401,9 +402,9 @@ namespace MCGalaxy {
for (int i = 0; i < defs.Length; i++) {
if (defs[i] == null) continue;
lvl.CustomBlockDefs[i] = defs[i];
lvl.CustomBlockProps[i] = new BlockProps((byte)i);
lvl.BlockProps[i] = new BlockProps((byte)i);
}
BlockProps.Load("lvl_" + lvl.MapName, lvl.CustomBlockProps);
MCGalaxy.Blocks.BlockProps.Load("lvl_" + lvl.MapName, lvl.BlockProps);
}
public static bool CheckLoadOnGoto(string givenName) {
@ -499,5 +500,31 @@ namespace MCGalaxy {
public ushort bigX, bigY, bigZ;
public ushort smallX, smallY, smallZ;
}
public void SetBlockHandlers() {
for (int i = 0; i < Block.Count; i++) {
SetBlockHandler(new ExtBlock((byte)i, 0));
SetBlockHandler(new ExtBlock(Block.custom_block, (byte)i));
}
}
public void SetBlockHandler(ExtBlock block) {
bool notCustom = !block.IsCustomType &&
(block.BlockID >= Block.CpeCount || CustomBlockDefs[block.BlockID] == null);
bool nonSolid;
if (notCustom) {
nonSolid = Block.Walkthrough(Block.Convert(block.BlockID));
} else {
nonSolid = CustomBlockDefs[block.BlockID].CollideType != CollideType.Solid;
}
int i = block.Index;
deleteHandlers[i] = BlockBehaviour.GetDeleteHandler(block, BlockProps);
placeHandlers[i] = BlockBehaviour.GetPlaceHandler(block, BlockProps);
walkthroughHandlers[i] = BlockBehaviour.GetWalkthroughHandler(block, BlockProps, nonSolid);
physicsHandlers[i] = BlockBehaviour.GetPhysicsHandler(block, BlockProps);
physicsDoorsHandlers[i] = BlockBehaviour.GetPhysicsDoorsHandler(block, BlockProps);
}
}
}

View File

@ -65,13 +65,8 @@ namespace MCGalaxy {
ushort y = ushort.Parse(row["EntryY"].ToString());
ushort z = ushort.Parse(row["EntryZ"].ToString());
byte block = level.GetTile(x, y, z);
if (block == Block.custom_block) {
block = level.GetExtTile(x, y, z);
if (level.CustomBlockProps[block].IsPortal) continue;
} else {
if (Block.Props[block].IsPortal) continue;
}
ExtBlock block = level.GetBlock(x, y, z);
if (level.BlockProps[block.Index].IsPortal) continue;
Database.Backend.DeleteRows("Portals" + name, "WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z);
}
@ -88,13 +83,8 @@ namespace MCGalaxy {
ushort y = ushort.Parse(row["Y"].ToString());
ushort z = ushort.Parse(row["Z"].ToString());
byte block = level.GetTile(x, y, z);
if (block == Block.custom_block) {
block = level.GetExtTile(x, y, z);
if (level.CustomBlockProps[block].IsMessageBlock) continue;
} else {
if (Block.Props[block].IsMessageBlock) continue;
}
ExtBlock block = level.GetBlock(x, y, z);
if (level.BlockProps[block.Index].IsMessageBlock) continue;
Database.Backend.DeleteRows("Messages" + name, "WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
}

View File

@ -142,7 +142,7 @@ namespace MCGalaxy {
bool DeleteBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block) {
if (deleteMode) { return ChangeBlock(x, y, z, ExtBlock.Air) == 2; }
HandleDelete handler = BlockBehaviour.deleteHandlers[old.BlockID];
HandleDelete handler = level.deleteHandlers[old.Index];
if (handler != null) {
handler(this, old, x, y, z);
return true;
@ -151,7 +151,7 @@ namespace MCGalaxy {
}
bool PlaceBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block) {
HandlePlace handler = BlockBehaviour.placeHandlers[block.BlockID];
HandlePlace handler = level.placeHandlers[block.Index];
if (handler != null) {
handler(this, old, x, y, z);
return true;
@ -426,7 +426,7 @@ namespace MCGalaxy {
// We can activate only one walkthrough block per movement
if (!hitWalkthrough) {
HandleWalkthrough handler = BlockBehaviour.walkthroughHandlers[block.BlockID];
HandleWalkthrough handler = level.walkthroughHandlers[block.Index];
if (handler != null && handler(this, block, xP, yP, zP)) {
lastWalkthrough = level.PosToInt(xP, yP, zP);
hitWalkthrough = true;
@ -434,12 +434,9 @@ namespace MCGalaxy {
}
// Some blocks will cause death of players
byte coreID = block.BlockID;
if (coreID != Block.custom_block && !Block.Props[coreID].KillerBlock) continue;
if (coreID == Block.custom_block && !level.CustomBlockProps[block.ExtID].KillerBlock) continue;
if (coreID == Block.tntexplosion && PlayingTntWars) continue; // TODO: hardcoded behaviour is icky
if (coreID == Block.train && trainInvincible) continue;
if (!level.BlockProps[block.Index].KillerBlock) continue;
if (block.BlockID == Block.tntexplosion && PlayingTntWars) continue; // TODO: hardcoded behaviour is icky
if (block.BlockID == Block.train && trainInvincible) continue;
HandleDeath(block);
}
@ -463,12 +460,7 @@ namespace MCGalaxy {
onTrain = false; trainInvincible = false; trainGrab = false;
ushort x = (ushort)Pos.BlockX, y = (ushort)Pos.BlockY, z = (ushort)Pos.BlockZ;
string deathMsg = null;
if (block.BlockID != Block.custom_block) {
deathMsg = Block.Props[block.BlockID].DeathMessage;
} else {
deathMsg = level.CustomBlockProps[block.ExtID].DeathMessage;
}
string deathMsg = level.BlockProps[block.Index].DeathMessage;
if (deathMsg != null) {
Chat.MessageLevel(this, deathMsg.Replace("@p", ColoredName), false, level);
}