Пример #1
0
        protected override void PlacedMark(Player p, ushort x, ushort y, ushort z, BlockID block)
        {
            p.RevertBlock(x, y, z);
            if (!p.level.Config.Guns)
            {
                p.ClearBlockchange(); return;
            }
            if (!CommandParser.IsBlockAllowed(p, "use", block))
            {
                return;
            }

            WeaponArgs args = new WeaponArgs();

            args.player     = p;
            args.block      = block;
            args.weaponType = (WeaponType)p.blockchangeObject;

            args.start      = MakePos(p);
            args.dir        = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX);
            args.pos        = args.PosAt(3);
            args.iterations = 4;

            SchedulerTask task = new SchedulerTask(GunCallback, args, TimeSpan.Zero, true);

            p.CriticalTasks.Add(task);
        }
Пример #2
0
        static Vec3U16 MissileTarget(WeaponArgs args)
        {
            Player p = args.player;

            args.start = MakePos(p);
            args.dir   = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX);
            int i;

            for (i = 1; ; i++)
            {
                Vec3U16 target = args.PosAt(i);
                BlockID block  = p.level.GetBlock(target.X, target.Y, target.Z);
                if (block == Block.Invalid)
                {
                    break;
                }

                if (block != Block.Air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, block, args.weaponType, target, false))
                {
                    break;
                }

                Player hit = GetPlayer(p, target, true);
                if (hit != null)
                {
                    return(MakePos(hit));
                }
            }
            return(args.PosAt(i - 1));
        }
Пример #3
0
        void DoAim(Player p)
        {
            List <Vec3U16> lastSent = new List <Vec3U16>(), toSend = new List <Vec3U16>();

            while (p.aiming)
            {
                Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]);
                try {
                    ushort x = (ushort)Math.Round((ushort)(p.pos[0] / 32) + dir.X * 3);
                    ushort y = (ushort)Math.Round((ushort)(p.pos[1] / 32) + dir.Y * 3);
                    ushort z = (ushort)Math.Round((ushort)(p.pos[2] / 32) + dir.Z * 3);

                    int signX = Math.Sign(dir.X) >= 0 ? 1 : -1, signZ = Math.Sign(dir.Z) >= 0 ? 1 : -1;
                    CheckTile(p.level, toSend, x, y, z);
                    CheckTile(p.level, toSend, x + signX, y, z);
                    CheckTile(p.level, toSend, x, y, z + signZ);
                    CheckTile(p.level, toSend, x + signX, y, z + signZ);

                    // Revert all glass blocks now not in the ray from the player's direction
                    for (int i = 0; i < lastSent.Count; i++)
                    {
                        Vec3U16 cP = lastSent[i];
                        if (toSend.Contains(cP))
                        {
                            continue;
                        }

                        if (p.level.IsValidPos(cP))
                        {
                            p.RevertBlock(cP.X, cP.Y, cP.Z);
                        }
                        lastSent.RemoveAt(i); i--;
                    }

                    // Place the new glass blocks that are in the ray from the player's direction
                    foreach (Vec3U16 cP in toSend)
                    {
                        if (lastSent.Contains(cP))
                        {
                            continue;
                        }
                        lastSent.Add(cP);
                        p.SendBlockchange(cP.X, cP.Y, cP.Z, Block.glass);
                    }
                    toSend.Clear();
                }
                catch { }
                Thread.Sleep(20);
            }

            foreach (Vec3U16 cP in lastSent)
            {
                if (p.level.IsValidPos(cP))
                {
                    p.RevertBlock(cP.X, cP.Y, cP.Z);
                }
            }
        }
Пример #4
0
        static void DoAim(AimState state)
        {
            Player  p   = state.player;
            Vec3F32 dir = DirUtils.GetFlatDirVector(p.Rot.RotY, p.Rot.HeadX);
            ushort  x   = (ushort)Math.Round(p.Pos.BlockX + dir.X * 3);
            ushort  y   = (ushort)Math.Round(p.Pos.BlockY + dir.Y * 3);
            ushort  z   = (ushort)Math.Round(p.Pos.BlockZ + dir.Z * 3);

            int signX = Math.Sign(dir.X) >= 0 ? 1 : -1, signZ = Math.Sign(dir.Z) >= 0 ? 1 : -1;

            CheckTile(p.level, state.glassCoords, x, y, z);
            CheckTile(p.level, state.glassCoords, x + signX, y, z);
            CheckTile(p.level, state.glassCoords, x, y, z + signZ);
            CheckTile(p.level, state.glassCoords, x + signX, y, z + signZ);

            // Revert all glass blocks now not in the ray from the player's direction
            for (int i = 0; i < state.lastGlass.Count; i++)
            {
                Vec3U16 pos = state.lastGlass[i];
                if (state.glassCoords.Contains(pos))
                {
                    continue;
                }

                if (p.level.IsValidPos(pos))
                {
                    p.RevertBlock(pos.X, pos.Y, pos.Z);
                }
                state.lastGlass.RemoveAt(i); i--;
            }

            // Place the new glass blocks that are in the ray from the player's direction
            foreach (Vec3U16 pos in state.glassCoords)
            {
                if (state.lastGlass.Contains(pos))
                {
                    continue;
                }
                state.lastGlass.Add(pos);
                p.SendBlockchange(pos.X, pos.Y, pos.Z, (ExtBlock)Block.Glass);
            }
            state.glassCoords.Clear();
        }
Пример #5
0
        void DoShoot(Player p, byte type, byte extType)
        {
            CatchPos       bp = (CatchPos)p.blockchangeObject;
            List <Vec3U16> previous = new List <Vec3U16>(), allBlocks = new List <Vec3U16>();
            Vec3U16        pos = MakePos(p);

            int            total  = 0;
            List <Vec3U16> buffer = new List <Vec3U16>(2);

            while (true)
            {
                Vec3U16 start = MakePos(p);
                total++;
                Vec3F32 dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]);

                Vec3U16 lookedAt;
                int     i;
                for (i = 1; ; i++)
                {
                    lookedAt.X = (ushort)Math.Round(start.X + (double)(dir.X * i));
                    lookedAt.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i));
                    lookedAt.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i));

                    byte tile = p.level.GetTile(lookedAt.X, lookedAt.Y, lookedAt.Z);
                    if (tile == Block.Invalid)
                    {
                        break;
                    }

                    if (tile != Block.air && !allBlocks.Contains(lookedAt) && HandlesHitBlock(p, tile, bp, pos, false))
                    {
                        break;
                    }

                    Player hit = GetPlayer(p, lookedAt, true);
                    if (hit != null)
                    {
                        lookedAt = MakePos(hit); break;
                    }
                }

                lookedAt.X = (ushort)Math.Round(start.X + (double)(dir.X * (i - 1)));
                lookedAt.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * (i - 1)));
                lookedAt.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * (i - 1)));
                FindNext(lookedAt, ref pos, buffer);

                byte by = p.level.GetTile(pos.X, pos.Y, pos.Z);
                if (total > 3)
                {
                    if (by != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, by, bp, pos, true))
                    {
                        break;
                    }

                    p.level.Blockchange(pos.X, pos.Y, pos.Z, type, extType);
                    previous.Add(pos);
                    allBlocks.Add(pos);

                    Player hitP = GetPlayer(p, pos, true);
                    if (hitP != null)
                    {
                        if (p.level.physics >= 3 && bp.ending >= EndType.Explode)
                        {
                            hitP.HandleDeath(Block.stone, 0, " was blown up by " + p.ColoredName, true);
                        }
                        else
                        {
                            hitP.HandleDeath(Block.stone, 0, " was hit a missile from " + p.ColoredName);
                        }
                        break;
                    }

                    if (pos.X == lookedAt.X && pos.Y == lookedAt.Y && pos.Z == lookedAt.Z)
                    {
                        if (p.level.physics >= 3 && bp.ending >= EndType.Explode && p.allowTnt)
                        {
                            p.level.MakeExplosion(lookedAt.X, lookedAt.Y, lookedAt.Z, 2);
                            break;
                        }
                    }

                    if (previous.Count > 12)
                    {
                        p.level.Blockchange(previous[0].X, previous[0].Y, previous[0].Z, Block.air, true);
                        previous.RemoveAt(0);
                    }
                    Thread.Sleep(100);
                }
            }

            if (bp.ending == EndType.Teleport)
            {
                int index = previous.Count - 3;
                if (index >= 0 && index < previous.Count)
                {
                    DoTeleport(p, previous[index]);
                }
            }
            foreach (Vec3U16 pos1 in previous)
            {
                p.level.Blockchange(pos1.X, pos1.Y, pos1.Z, Block.air, true);
                Thread.Sleep(100);
            }
        }
Пример #6
0
        void DoShoot(Player p, byte type, byte extType)
        {
            CatchPos bp  = (CatchPos)p.blockchangeObject;
            Vec3F32  dir = DirUtils.GetFlatDirVector(p.rot[0], p.rot[1]);

            double bigDiag = Math.Sqrt(Math.Sqrt(p.level.Width * p.level.Width + p.level.Length * p.level.Length)
                                       + p.level.Height * p.level.Height + p.level.Width * p.level.Width);

            List <Vec3U16> previous  = new List <Vec3U16>();
            List <Vec3U16> allBlocks = new List <Vec3U16>();
            Vec3U16        pos;

            ushort startX = (ushort)(p.pos[0] / 32);
            ushort startY = (ushort)(p.pos[1] / 32);
            ushort startZ = (ushort)(p.pos[2] / 32);

            pos.X = (ushort)Math.Round(startX + dir.X * 3);
            pos.Y = (ushort)Math.Round(startY + dir.Y * 3);
            pos.Z = (ushort)Math.Round(startZ + dir.Z * 3);

            for (double t = 4; bigDiag > t; t++)
            {
                pos.X = (ushort)Math.Round(startX + (double)(dir.X * t));
                pos.Y = (ushort)Math.Round(startY + (double)(dir.Y * t));
                pos.Z = (ushort)Math.Round(startZ + (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, pos, true))
                {
                    break;
                }

                p.level.Blockchange(pos.X, pos.Y, pos.Z, type, extType);
                previous.Add(pos);
                allBlocks.Add(pos);

                if (HandlesPlayers(p, bp, pos))
                {
                    break;
                }

                if (t > 12 && bp.ending != EndType.Laser)
                {
                    pos = previous[0];
                    p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.air, true);
                    previous.RemoveAt(0);
                }

                if (bp.ending != EndType.Laser)
                {
                    Thread.Sleep(20);
                }
            }

            if (bp.ending == EndType.Teleport)
            {
                int index = previous.Count - 3;
                if (index >= 0 && index < previous.Count)
                {
                    DoTeleport(p, previous[index]);
                }
            }
            if (bp.ending == EndType.Laser)
            {
                Thread.Sleep(400);
            }

            foreach (Vec3U16 pos1 in previous)
            {
                p.level.Blockchange(pos1.X, pos1.Y, pos1.Z, Block.air, true);
                if (bp.ending != EndType.Laser)
                {
                    Thread.Sleep(20);
                }
            }
        }