public static bool DoNormal(Level lvl, ref PhysInfo C) { if (!C.Data.HasWait && C.Block == Block.Air) { C.Data.ResetTypes(); } ExtraInfoArgs args = default(ExtraInfoArgs); ParseType(C.Data.Type1, ref args, C.Data.Value1); ParseType(C.Data.Type2, ref args, C.Data.Value2); args.ExtBlock = C.Data.ExtBlock; if (args.Wait) { if (C.Data.Data <= args.WaitTime) { C.Data.Data++; return(true); } if (C.Data.Type1 == PhysicsArgs.Wait) { C.Data.Type1 = 0; } if (C.Data.Type2 == PhysicsArgs.Wait) { C.Data.Type2 = 0; } } DoOther(lvl, ref C, ref args); return(false); }
static void DoOther(Level lvl, ref PhysInfo C, ref ExtraInfoArgs args) { Random rand = lvl.physRandom; if (args.Rainbow) { if (C.Data.Data < 4) { C.Data.Data++; } else { DoRainbow(lvl, ref C, rand, args.RainbowNum); } return; } if (args.Revert) { PhysicsArgs revertArgs = default(PhysicsArgs); revertArgs.ExtBlock = args.ExtBlock; lvl.AddUpdate(C.Index, args.RevertType, revertArgs); C.Data.ResetTypes(); C.Data.Data = PhysicsArgs.RemoveFromChecks; } ushort x = C.X, y = C.Y, z = C.Z; // Not setting drop = false can cause occasional leftover blocks, since C.extraInfo is emptied, so // drop can generate another block with no dissipate/explode information. if (args.Dissipate && rand.Next(1, 100) <= args.DissipateNum) { if (!lvl.listUpdateExists.Get(x, y, z)) { lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs)); C.Data.ResetTypes(); args.Drop = false; } else { lvl.AddUpdate(C.Index, C.Block, C.Data); } } if (args.Explode && rand.Next(1, 100) <= args.ExplodeNum) { lvl.MakeExplosion(x, y, z, 0); C.Data.ResetTypes(); args.Drop = false; } if (args.Drop && rand.Next(1, 100) <= args.DropNum) { DoDrop(lvl, ref C, rand, args.DropNum, x, y, z); } }
public static bool DoNormal(Level lvl, ref Check C) { if (C.data.Type1 == PhysicsArgs.Custom) { return(true); } if (!C.data.HasWait && lvl.blocks[C.b] == Block.air) { C.data.ResetTypes(); } ExtraInfoArgs args = default(ExtraInfoArgs); ParseType(C.data.Type1, ref args, C.data.Value1); ParseType(C.data.Type2, ref args, C.data.Value2); args.ExtBlock = C.data.ExtBlock; 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; } if (tdoor) { DoorPhysics.tDoor(lvl, ref C); } else { DoorPhysics.Door(lvl, ref C); } } if (C.data.Data <= args.WaitTime) { C.data.Data++; return(true); } if (C.data.Type1 == PhysicsArgs.Wait) { C.data.Type1 = 0; } if (C.data.Type2 == PhysicsArgs.Wait) { C.data.Type2 = 0; } } DoOther(lvl, ref C, ref args); return(false); }
static void DoOther(Level lvl, ref Check C, ref ExtraInfoArgs args) { Random rand = lvl.physRandom; if (args.Rainbow) { if (C.data.Data < 4) { C.data.Data++; } else { DoRainbow(lvl, ref C, rand, args.RainbowNum); } return; } if (args.Revert) { lvl.AddUpdate(C.b, args.RevertType); C.data.ResetTypes(); } ushort x, y, z; lvl.IntToPos(C.b, out x, out y, out z); // Not setting drop = false can cause occasional leftover blocks, since C.extraInfo is emptied, so // drop can generate another block with no dissipate/explode information. if (args.Dissipate && rand.Next(1, 100) <= args.DissipateNum) { if (!lvl.listUpdateExists.Get(x, y, z)) { lvl.AddUpdate(C.b, Block.air); C.data.ResetTypes(); args.Drop = false; } else { lvl.AddUpdate(C.b, lvl.blocks[C.b], false, C.data); } } if (args.Explode && rand.Next(1, 100) <= args.ExplodeNum) { lvl.MakeExplosion(x, y, z, 0); C.data.ResetTypes(); args.Drop = false; } if (args.Drop && rand.Next(1, 100) <= args.DropNum) { DoDrop(lvl, ref C, rand, args.DropNum, x, y, z); } }
public static bool DoComplex(Level lvl, ref Check C) { if (!C.data.HasWait && lvl.blocks[C.b] == Block.air) { C.data.ResetTypes(); } if (C.data.Type1 == PhysicsArgs.TntWars) { return(true); } ExtraInfoArgs args = default(ExtraInfoArgs); args.Door = C.data.Door; ParseType(C.data.Type1, ref args, C.data.Value1); ParseType(C.data.Type2, ref args, C.data.Value2); if (args.Wait) { if (args.Door && C.data.Data < 2) { Checktdoor(lvl, lvl.IntOffset(C.b, -1, 0, 0)); Checktdoor(lvl, lvl.IntOffset(C.b, 1, 0, 0)); Checktdoor(lvl, lvl.IntOffset(C.b, 0, -1, 0)); Checktdoor(lvl, lvl.IntOffset(C.b, 0, 1, 0)); Checktdoor(lvl, lvl.IntOffset(C.b, 0, 0, -1)); Checktdoor(lvl, lvl.IntOffset(C.b, 0, 0, 1)); } if (C.data.Data > args.WaitTime) { if (C.data.Type1 == PhysicsArgs.Wait) { C.data.Type1 = 0; } if (C.data.Type2 == PhysicsArgs.Wait) { C.data.Type2 = 0; } DoOther(lvl, ref C, ref args); return(false); } C.data.Data++; return(true); } DoOther(lvl, ref C, ref args); return(false); }
static void ParseType(byte type, ref ExtraInfoArgs args, byte value) { switch (type) { case PhysicsArgs.Wait: args.Wait = true; args.WaitTime = value; break; case PhysicsArgs.Drop: args.Drop = true; args.DropNum = value; break; case PhysicsArgs.Dissipate: args.Dissipate = true; args.DissipateNum = value; break; case PhysicsArgs.Revert: args.Revert = true; args.RevertType = value; break; case PhysicsArgs.Explode: args.Explode = true; args.ExplodeNum = value; break; case PhysicsArgs.Rainbow: args.Rainbow = true; args.RainbowNum = value; break; } }