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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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;
            }
        }