public static void Do(Level lvl, ref PhysInfo C)
        {
            if (C.Data.Type1 != PhysicsArgs.Custom)
            {
                return;
            }
            if (C.Data.Data == 0)
            {
                BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock << Block.ExtendedShift));
                bool    tdoor = lvl.Props[block].IsTDoor;

                if (tdoor)
                {
                    tDoor(lvl, ref C);
                }
                else
                {
                    Door(lvl, ref C);
                }
            }

            if (C.Data.Data <= C.Data.Value1)   // value1 for wait time
            {
                C.Data.Data++;
            }
            else
            {
                PhysicsArgs dArgs = default(PhysicsArgs);
                dArgs.ExtBlock = C.Data.ExtBlock;
                lvl.AddUpdate(C.Index, C.Data.Value2, dArgs);
                C.Data.Data = PhysicsArgs.RemoveFromChecks;
            }
        }
示例#2
0
        static bool MoveSnake(Level lvl, ref PhysInfo C, ushort x, ushort y, ushort z)
        {
            int index;

            // Move snake up or down blocks
            if (lvl.IsAirAt(x, (ushort)(y - 1), z, out index) && lvl.IsAirAt(x, y, z))
            {
            }
            else if (lvl.IsAirAt(x, y, z, out index) && lvl.IsAirAt(x, (ushort)(y + 1), z))
            {
            }
            else if (lvl.IsAirAt(x, (ushort)(y + 1), z, out index) && lvl.IsAirAt(x, (ushort)(y + 2), z))
            {
            }
            else
            {
                return(false);
            }

            if (lvl.AddUpdate(index, C.Block))
            {
                PhysicsArgs args = default(PhysicsArgs);
                args.Type1 = PhysicsArgs.Wait; args.Value1 = 5;
                args.Type2 = PhysicsArgs.Revert; args.Value2 = Block.Air;
                lvl.AddUpdate(C.Index, Block.SnakeTail, args, true);
                return(true);
            }
            return(false);
        }
示例#3
0
        public static void DoLeaf(Level lvl, ref PhysInfo C)
        {
            // Decaying disabled? Then just remove from the physics list
            if (!lvl.Config.LeafDecay)
            {
                C.Data.Data = PhysicsArgs.RemoveFromChecks; return;
            }

            // Delay checking for leaf decay for a random amount of time
            if (C.Data.Data < 5)
            {
                Random rand = lvl.physRandom;
                if (rand.Next(10) == 0)
                {
                    C.Data.Data++;
                }
                return;
            }

            // Perform actual leaf decay, then remove from physics list
            if (DoLeafDecay(lvl, ref C))
            {
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
                if (lvl.physics > 1)
                {
                    ActivateablePhysics.CheckNeighbours(lvl, C.X, C.Y, C.Z);
                }
            }
            C.Data.Data = PhysicsArgs.RemoveFromChecks;
        }
        public static void DoFlood(Level lvl, ref PhysInfo C, AirFlood mode, BlockID block)
        {
            if (C.Data.Data >= 1)
            {
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
                C.Data.Data = PhysicsArgs.RemoveFromChecks; return;
            }

            ushort x = C.X, y = C.Y, z = C.Z;

            FloodAir(lvl, (ushort)(x + 1), y, z, block);
            FloodAir(lvl, (ushort)(x - 1), y, z, block);
            FloodAir(lvl, x, y, (ushort)(z + 1), block);
            FloodAir(lvl, x, y, (ushort)(z - 1), block);

            switch (mode)
            {
            case AirFlood.Full:
                FloodAir(lvl, x, (ushort)(y - 1), z, block);
                FloodAir(lvl, x, (ushort)(y + 1), z, block);
                break;

            case AirFlood.Layer:
                break;

            case AirFlood.Down:
                FloodAir(lvl, x, (ushort)(y - 1), z, block);
                break;

            case AirFlood.Up:
                FloodAir(lvl, x, (ushort)(y + 1), z, block);
                break;
            }
            C.Data.Data++;
        }
        public static void DoAir(Level lvl, ref PhysInfo C)
        {
            if (C.Data.Type1 == PhysicsArgs.Custom)
            {
                DoorPhysics.Do(lvl, ref C); return;
            }

            ushort x = C.X, y = C.Y, z = C.Z;

            ActivateablePhysics.CheckNeighbours(lvl, x, y, z);
            ActivateablePhysics.CheckAt(lvl, x, (ushort)(y - 1), z);

            //Edge of map water
            if (lvl.Config.EdgeWater && (y < lvl.Config.EdgeLevel && y >= (lvl.Config.EdgeLevel + lvl.Config.SidesOffset)))
            {
                if (x == 0 || x == lvl.Width - 1 || z == 0 || z == lvl.Length - 1)
                {
                    BlockID horizon = lvl.Config.HorizonBlock;
                    lvl.AddUpdate(C.Index, horizon == Block.Invalid ? Block.Water : horizon);
                }
            }
            if (!C.Data.HasWait)
            {
                C.Data.Data = PhysicsArgs.RemoveFromChecks;
            }
        }
示例#6
0
 public static void DoWater(Level lvl, ref PhysInfo C)
 {
     if (lvl.Config.FiniteLiquids)
     {
         if (lvl.Config.FiniteHighWater)
         {
             ushort y = C.Y;
             if (y >= lvl.Config.EdgeLevel)
             {
                 FinitePhysics.DoWaterOrLava(lvl, ref C);
                 return;
             }
         }
         else
         {
             FinitePhysics.DoWaterOrLava(lvl, ref C);
             return;
         }
     }
     if (lvl.Config.RandomFlow)
     {
         DoWaterRandowFlow(lvl, ref C);
     }
     else
     {
         DoWaterUniformFlow(lvl, ref C);
     }
 }
示例#7
0
        public static void DoFaucet(Level lvl, ref PhysInfo C, BlockID target)
        {
            C.Data.Data++;
            if (C.Data.Data < 2)
            {
                return;
            }
            C.Data.Data = 0;

            Random  rand = lvl.physRandom;
            int     index;
            BlockID below = lvl.GetBlock(C.X, (ushort)(C.Y - 1), C.Z, out index);

            if (below == Block.Air || below == target)
            {
                if (rand.Next(1, 10) > 7)
                {
                    lvl.AddUpdate(index, Block.Air_FloodDown, default(PhysicsArgs));
                }
            }
            else if (below == Block.Air_FloodDown)
            {
                if (rand.Next(1, 10) > 4)
                {
                    lvl.AddUpdate(index, target);
                }
            }
        }
示例#8
0
        public static void DoLeaf(Level lvl, ref PhysInfo C)
        {
            if (lvl.physics > 1)   //Adv physics kills flowers and mushroos in water/lava
            {
                ActivateablePhysics.CheckNeighbours(lvl, C.X, C.Y, C.Z);
            }

            // Just immediately remove from physics list
            if (!lvl.Config.LeafDecay)
            {
                lvl.leaves.Clear();
                C.Data.Data = PhysicsArgs.RemoveFromChecks; return;
            }

            // Delay checking for decay for a random amount of time
            if (C.Data.Data < 5)
            {
                Random rand = lvl.physRandom;
                if (rand.Next(10) == 0)
                {
                    C.Data.Data++;
                }
                return;
            }

            // Perform actual leaf decay, then remove from physics list
            if (DoLeafDecay(lvl, ref C))
            {
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
            }
            C.Data.Data = PhysicsArgs.RemoveFromChecks;
        }
示例#9
0
        public static void DoLargeTnt(Level lvl, ref PhysInfo C, int power)
        {
            ushort x = C.X, y = C.Y, z = C.Z;

            if (lvl.physics < 3)
            {
                lvl.Blockchange(x, y, z, Block.Air);
            }
            else
            {
                if (C.Data.Data < 5 && lvl.physics == 3)
                {
                    C.Data.Data++;

                    ToggleFuse(lvl, x, (ushort)(y + 1), z);
                    ToggleFuse(lvl, x, (ushort)(y - 1), z);
                    ToggleFuse(lvl, (ushort)(x + 1), y, z);
                    ToggleFuse(lvl, (ushort)(x - 1), y, z);
                    ToggleFuse(lvl, x, y, (ushort)(z + 1));
                    ToggleFuse(lvl, x, y, (ushort)(z - 1));
                    return;
                }
                MakeExplosion(lvl, x, y, z, power);
            }
        }
示例#10
0
        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);
        }
示例#11
0
        static void DoWaterUniformFlow(Level lvl, ref PhysInfo C)
        {
            ushort x = C.X, y = C.Y, z = C.Z;

            if (!lvl.CheckSpongeWater(x, y, z))
            {
                BlockID block = C.Block;
                if (y < lvl.Height - 1)
                {
                    CheckFallingBlocks(lvl, C.Index + lvl.Width * lvl.Length);
                }

                LiquidPhysics.PhysWater(lvl, (ushort)(x + 1), y, z, block);
                LiquidPhysics.PhysWater(lvl, (ushort)(x - 1), y, z, block);
                LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z + 1), block);
                LiquidPhysics.PhysWater(lvl, x, y, (ushort)(z - 1), block);
                LiquidPhysics.PhysWater(lvl, x, (ushort)(y - 1), z, block);
            }
            else     //was placed near sponge
            {
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
            }
            if (!C.Data.HasWait)
            {
                C.Data.Data = PhysicsArgs.RemoveFromChecks;
            }
        }
示例#12
0
        public static void DoLavafall(Level lvl, ref PhysInfo C)
        {
            ushort  x = C.X, y = C.Y, z = C.Z;
            int     index;
            BlockID below = lvl.GetBlock(x, (ushort)(y - 1), z, out index);

            switch (below)
            {
            case Block.Air:
                lvl.AddUpdate(index, Block.LavaDown, default(PhysicsArgs));
                if (!C.Data.HasWait)
                {
                    C.Data.Data = PhysicsArgs.RemoveFromChecks;
                }
                break;

            case Block.Air_FloodDown:
            case Block.StillLava:
            case Block.StillWater:
            case Block.LavaDown:
                break;

            default:
                BlockID block = C.Block;
                LiquidPhysics.PhysLava(lvl, (ushort)(x + 1), y, z, block);
                LiquidPhysics.PhysLava(lvl, (ushort)(x - 1), y, z, block);
                LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z + 1), block);
                LiquidPhysics.PhysLava(lvl, x, y, (ushort)(z - 1), block);
                if (!C.Data.HasWait)
                {
                    C.Data.Data = PhysicsArgs.RemoveFromChecks;
                }
                break;
            }
        }
示例#13
0
        static void Firework(ref PhysInfo C, int size, Level lvl, Random rand)
        {
            int rand1 = rand.Next(Block.Red, Block.White);
            int rand2 = rand.Next(Block.Red, Block.White);
            int min = Math.Min(rand1, rand2), max = Math.Max(rand1, rand2);

            // Not using override, since override = true makes it more likely that a colored block will be
            // generated with no extraInfo, because it sets a Check for that position with no extraInfo.
            lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));

            int    index;
            ushort x = C.X, y = C.Y, z = C.Z;

            for (int yy = y - (size + 1); yy <= y + (size + 1); ++yy)
            {
                for (int zz = z - (size + 1); zz <= z + (size + 1); ++zz)
                {
                    for (int xx = x - (size + 1); xx <= x + (size + 1); ++xx)
                    {
                        if (lvl.IsAirAt((ushort)xx, (ushort)yy, (ushort)zz, out index) && rand.Next(1, 40) < 2)
                        {
                            PhysicsArgs args = default(PhysicsArgs);
                            args.Type1 = PhysicsArgs.Drop; args.Value1 = 100;
                            args.Type2 = PhysicsArgs.Dissipate; args.Value2 = 25;
                            lvl.AddUpdate(index, (byte)rand.Next(min, max), args);
                        }
                    }
                }
            }
        }
示例#14
0
        static void FlyTo(Level lvl, ref PhysInfo C, ushort x, ushort y, ushort z, BlockID block)
        {
            int     index;
            BlockID neighbour = lvl.GetBlock(x, y, z, out index);

            if (neighbour == Block.Invalid)
            {
                return;
            }

            switch (neighbour)
            {
            case Block.Air:
                lvl.AddUpdate(index, block);
                break;

            case Block.Op_Air:
                break;

            default:
                // bird died by hitting a block
                PhysicsArgs args = default(PhysicsArgs);
                args.Type1 = PhysicsArgs.Dissipate; args.Value1 = 25;
                lvl.AddUpdate(C.Index, Block.Red, args);
                break;
            }
        }
示例#15
0
        static bool MoveZombie(Level lvl, ref PhysInfo C, ushort x, ushort y, ushort z)
        {
            int index;

            // Move zombie up or down blocks
            if (lvl.IsAirAt(x, (ushort)(y - 1), z, out index) && lvl.IsAirAt(x, y, z))
            {
            }
            else if (lvl.IsAirAt(x, y, z, out index) && lvl.IsAirAt(x, (ushort)(y + 1), z))
            {
            }
            else if (lvl.IsAirAt(x, (ushort)(y + 1), z, out index) && lvl.IsAirAt(x, (ushort)(y + 2), z))
            {
            }
            else
            {
                return(false);
            }

            if (lvl.AddUpdate(index, C.Block))
            {
                lvl.AddUpdate(lvl.IntOffset(index, 0, 1, 0), Block.ZombieHead, default(PhysicsArgs));
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
                lvl.AddUpdate(lvl.IntOffset(C.Index, 0, 1, 0), Block.Air, default(PhysicsArgs));
                return(true);
            }
            return(false);
        }
示例#16
0
        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);
            }
        }
示例#17
0
        public static void DoTntExplosion(Level lvl, ref PhysInfo C)
        {
            Random rand = lvl.physRandom;

            if (rand.Next(1, 11) <= 7)
            {
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
            }
        }
示例#18
0
        public static void DoHead(Level lvl, ref PhysInfo C)
        {
            BlockID below = lvl.GetBlock(C.X, (ushort)(C.Y - 1), C.Z);

            if (below != Block.ZombieBody && below != Block.Creeper)
            {
                C.Data.Type1 = PhysicsArgs.Revert; C.Data.Value1 = Block.Air;
            }
        }
示例#19
0
        public static void Do(Level lvl, ref PhysInfo C)
        {
            Random  rand = lvl.physRandom;
            ushort  x = C.X, y = C.Y, z = C.Z;
            BlockID block = lvl.GetBlock(x, y, z);
            int     index;

            switch (rand.Next(1, 15))
            {
            case 1:
                if (lvl.IsAirAt(x, (ushort)(y - 1), z, out index))
                {
                    lvl.AddUpdate(index, block);
                }
                else
                {
                    goto case 3;
                }
                break;

            case 2:
                if (lvl.IsAirAt(x, (ushort)(y + 1), z, out index))
                {
                    lvl.AddUpdate(index, block);
                }
                else
                {
                    goto case 6;
                }
                break;

            case 3:
            case 4:
            case 5:
                FlyTo(lvl, ref C, (ushort)(x - 1), y, z, block);
                break;

            case 6:
            case 7:
            case 8:
                FlyTo(lvl, ref C, (ushort)(x + 1), y, z, block);
                break;

            case 9:
            case 10:
            case 11:
                FlyTo(lvl, ref C, x, y, (ushort)(z - 1), block);
                break;

            default:
                FlyTo(lvl, ref C, x, y, (ushort)(z + 1), block);
                break;
            }
            lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
            C.Data.Data = PhysicsArgs.RemoveFromChecks;
        }
示例#20
0
        public static void DoOther(Level lvl, ref PhysInfo C)
        {
            if (lvl.physics <= 1)
            {
                C.Data.Data = PhysicsArgs.RemoveFromChecks; return;
            }

            //Adv physics kills flowers and mushroos in water/lava
            ActivateablePhysics.CheckNeighbours(lvl, C.X, C.Y, C.Z);
            C.Data.Data = PhysicsArgs.RemoveFromChecks;
        }
示例#21
0
        static void tDoor(Level lvl, ref PhysInfo C)
        {
            ushort x = C.X, y = C.Y, z = C.Z;

            ActivateTDoor(lvl, (ushort)(x - 1), y, z);
            ActivateTDoor(lvl, (ushort)(x + 1), y, z);
            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));
        }
示例#22
0
        void HandleTNTPhysics(Level lvl, ref PhysInfo C)
        {
            ushort x = C.X, y = C.Y, z = C.Z;
            Player p = GetPlayer(ref C.Data);

            if (p == null)
            {
                C.Data.Data = PhysicsArgs.RemoveFromChecks; return;
            }

            int power = 2, threshold = 3;

            switch (Config.Difficulty)
            {
            case TWDifficulty.Easy: threshold = 7; break;

            case TWDifficulty.Normal: threshold = 5; break;

            case TWDifficulty.Extreme: power = 3; break;
            }

            if ((C.Data.Data >> 4) < threshold)
            {
                C.Data.Data += (1 << 4);
                TntPhysics.ToggleFuse(lvl, x, (ushort)(y + 1), z);
                return;
            }

            TWData data = Get(p);

            if (data.KillStreak >= cfg.StreakTwoAmount && cfg.Streaks)
            {
                power++;
            }
            TntPhysics.MakeExplosion(Map, x, y, z, power - 2, true, this);

            List <Player> inRange = new List <Player>();

            Player[] all = allPlayers.Items;

            foreach (Player pl in all)
            {
                if (pl == p)
                {
                    continue;
                }
                if (Math.Abs(pl.Pos.BlockX - x) + Math.Abs(pl.Pos.BlockY - y) + Math.Abs(pl.Pos.BlockZ - z) < ((power * 3) + 1))
                {
                    inRange.Add(pl);
                }
            }

            KillPlayers(p, data, inRange);
        }
        static bool MoveTo(Level lvl, ref PhysInfo C, BlockID target, ushort x, ushort y, ushort z)
        {
            int     index;
            BlockID block = lvl.GetBlock(x, y, z, out index);

            if (block == target && lvl.AddUpdate(index, C.Block))
            {
                lvl.AddUpdate(C.Index, target);
                return(true);
            }
            return(false);
        }
示例#24
0
        public static void oDoor(Level lvl, ref PhysInfo C)
        {
            ushort  x = C.X, y = C.Y, z = C.Z;
            BlockID block = C.Block;

            ActivateODoor(lvl, block, (ushort)(x - 1), y, z);
            ActivateODoor(lvl, block, (ushort)(x + 1), y, z);
            ActivateODoor(lvl, block, x, (ushort)(y - 1), z);
            ActivateODoor(lvl, block, x, (ushort)(y + 1), z);
            ActivateODoor(lvl, block, x, y, (ushort)(z - 1));
            ActivateODoor(lvl, block, x, y, (ushort)(z + 1));
            C.Data.Data = PhysicsArgs.RemoveFromChecks;
        }
示例#25
0
        public static void DoTail(Level lvl, ref PhysInfo C)
        {
            ushort x = C.X, y = C.Y, z = C.Z;
            bool   revert =
                lvl.GetBlock((ushort)(x - 1), y, z) != Block.Snake ||
                lvl.GetBlock((ushort)(x + 1), y, z) != Block.Snake ||
                lvl.GetBlock(x, y, (ushort)(z - 1)) != Block.Snake ||
                lvl.GetBlock(x, y, (ushort)(z + 1)) != Block.Snake;

            if (revert)
            {
                C.Data.Type1 = PhysicsArgs.Revert; C.Data.Value1 = Block.Air;
            }
        }
示例#26
0
 public static void DoFastLava(Level lvl, ref PhysInfo C)
 {
     if (lvl.Config.RandomFlow)
     {
         DoLavaRandowFlow(lvl, ref C, false);
         if (C.Data.Data != PhysicsArgs.RemoveFromChecks)
         {
             C.Data.Data = 0; // no lava delay
         }
     }
     else
     {
         DoLavaUniformFlow(lvl, ref C, false);
     }
 }
示例#27
0
 public static void DoWater(Level lvl, ref PhysInfo C)
 {
     if (lvl.Config.FiniteLiquids)
     {
         FinitePhysics.DoWaterOrLava(lvl, ref C);
     }
     else if (lvl.Config.RandomFlow)
     {
         DoWaterRandowFlow(lvl, ref C);
     }
     else
     {
         DoWaterUniformFlow(lvl, ref C);
     }
 }
示例#28
0
        static void DoDrop(Level lvl, ref PhysInfo C, Random rand, int dropnum, ushort x, ushort y, ushort z)
        {
            int     index;
            BlockID below = lvl.GetBlock(x, (ushort)(y - 1), z, out index);

            if (!(below == Block.Air || below == Block.Lava || below == Block.Water))
            {
                return;
            }

            if (rand.Next(1, 100) < dropnum && lvl.AddUpdate(index, C.Block, C.Data))
            {
                lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs));
                C.Data.ResetTypes();
            }
        }
示例#29
0
        public static void Do(Level lvl, ref PhysInfo C)
        {
            Random rand = lvl.physRandom;
            int    dirX = rand.Next(1, 10) <= 5 ? 1 : -1;
            int    dirY = rand.Next(1, 10) <= 5 ? 1 : -1;
            int    dirZ = rand.Next(1, 10) <= 5 ? 1 : -1;
            ushort x = C.X, y = C.Y, z = C.Z;

            for (int cx = -dirX; cx != 2 * dirX; cx += dirX)
            {
                for (int cy = -dirY; cy != 2 * dirY; cy += dirY)
                {
                    for (int cz = -dirZ; cz != 2 * dirZ; cz += dirZ)
                    {
                        BlockID rocketTail = lvl.GetBlock((ushort)(x + cx), (ushort)(y + cy), (ushort)(z + cz));
                        if (rocketTail != Block.LavaFire)
                        {
                            continue;
                        }

                        int     headIndex;
                        BlockID rocketHead = lvl.GetBlock((ushort)(x - cx), (ushort)(y - cy), (ushort)(z - cz), out headIndex);
                        bool    unblocked  = !lvl.listUpdateExists.Get(x, y, z) && (headIndex < 0 || !lvl.listUpdateExists.Get(x - cx, y - cy, z - cz));

                        if (unblocked && (rocketHead == Block.Air || rocketHead == Block.RocketStart))
                        {
                            lvl.AddUpdate(headIndex, Block.RocketHead, default(PhysicsArgs));
                            lvl.AddUpdate(C.Index, Block.LavaFire, default(PhysicsArgs));
                        }
                        else if (rocketHead == Block.LavaFire)
                        {
                        }
                        else
                        {
                            if (lvl.physics > 2)
                            {
                                lvl.MakeExplosion(x, y, z, 2);
                            }
                            else
                            {
                                lvl.AddUpdate(C.Index, Block.LavaFire, default(PhysicsArgs));
                            }
                        }
                    }
                }
            }
        }
示例#30
0
        // Change anys door blocks nearby into air forms
        static void Door(Level lvl, ref PhysInfo C)
        {
            ushort  x = C.X, y = C.Y, z = C.Z;
            BlockID block   = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock << Block.ExtendedShift));
            bool    instant = block == Block.Door_Air || block == Block.Door_AirActivatable;

            ActivateablePhysics.DoDoors(lvl, (ushort)(x + 1), y, z, instant);
            ActivateablePhysics.DoDoors(lvl, (ushort)(x - 1), y, z, instant);
            ActivateablePhysics.DoDoors(lvl, x, y, (ushort)(z + 1), instant);
            ActivateablePhysics.DoDoors(lvl, x, y, (ushort)(z - 1), instant);
            ActivateablePhysics.DoDoors(lvl, x, (ushort)(y - 1), z, instant);
            ActivateablePhysics.DoDoors(lvl, x, (ushort)(y + 1), z, instant);

            if (block == Block.Door_Green && lvl.physics != 5)
            {
                ActivateablePhysics.DoNeighbours(lvl, x, y, z);
            }
        }