mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
Stage 2 of rewriting physics/props to properly support custom blocks
This commit is contained in:
parent
59c6953104
commit
4ab173104a
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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()")]
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(" ", "");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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); }
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user