コード例 #1
0
ファイル: Creature.cs プロジェクト: moseleyc/server
        public Creature GetDirectionalTarget(Xml.Direction direction)
        {
            VisibleObject obj;

            switch (direction)
            {
            case Xml.Direction.East:
            {
                obj = Map.EntityTree.FirstOrDefault(x => x.X == X + 1 && x.Y == Y && x is Creature);
            }
            break;

            case Xml.Direction.West:
            {
                obj = Map.EntityTree.FirstOrDefault(x => x.X == X - 1 && x.Y == Y && x is Creature);
            }
            break;

            case Xml.Direction.North:
            {
                obj = Map.EntityTree.FirstOrDefault(x => x.X == X && x.Y == Y - 1 && x is Creature);
            }
            break;

            case Xml.Direction.South:
            {
                obj = Map.EntityTree.FirstOrDefault(x => x.X == X && x.Y == Y + 1 && x is Creature);
            }
            break;

            default:
                throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
            }

            if (obj is Creature)
            {
                return(obj as Creature);
            }
            return(null);
        }
コード例 #2
0
        public void AssailAttack(Xml.Direction direction, Creature target = null)
        {
            if (target == null)
            {
                var obj     = GetDirectionalTarget(direction);
                var monster = obj as Monster;
                if (monster != null)
                {
                    target = monster;
                }
                var user = obj as User;
                if (user != null)
                {
                    target = user;
                }
                var npc = obj as Merchant;
                if (npc != null)
                {
                    target = npc;
                }
                //try to get the creature we're facing and set it as the target.
            }

            // A monster's assail is just a straight attack, no skills involved.
            SimpleAttack(target);

            //animation handled here as to not repeatedly send assails.
            var assail = new ServerPacketStructures.PlayerAnimation()
            {
                Animation = 1, Speed = 20, UserId = this.Id
            };

            //Enqueue(assail.Packet());
            //Enqueue(sound.Packet());
            SendAnimation(assail.Packet());
            PlaySound(1);
        }
コード例 #3
0
        public virtual bool Walk(Xml.Direction direction)
        {
            lock (_lock)
            {
                int       oldX = X, oldY = Y, newX = X, newY = Y;
                Rectangle arrivingViewport  = Rectangle.Empty;
                Rectangle departingViewport = Rectangle.Empty;
                Rectangle commonViewport    = Rectangle.Empty;
                var       halfViewport      = Constants.VIEWPORT_SIZE / 2;
                Warp      targetWarp;

                switch (direction)
                {
                // Calculate the differences (which are, in all cases, rectangles of height 12 / width 1 or vice versa)
                // between the old and new viewpoints. The arrivingViewport represents the objects that need to be notified
                // of this object's arrival (because it is now within the viewport distance), and departingViewport represents
                // the reverse. We later use these rectangles to query the quadtree to locate the objects that need to be
                // notified of an update to their AOI (area of interest, which is the object's viewport calculated from its
                // current position).

                case Xml.Direction.North:
                    --newY;
                    arrivingViewport  = new Rectangle(oldX - halfViewport, newY - halfViewport, Constants.VIEWPORT_SIZE, 1);
                    departingViewport = new Rectangle(oldX - halfViewport, oldY + halfViewport, Constants.VIEWPORT_SIZE, 1);
                    break;

                case Xml.Direction.South:
                    ++newY;
                    arrivingViewport  = new Rectangle(oldX - halfViewport, oldY + halfViewport, Constants.VIEWPORT_SIZE, 1);
                    departingViewport = new Rectangle(oldX - halfViewport, newY - halfViewport, Constants.VIEWPORT_SIZE, 1);
                    break;

                case Xml.Direction.West:
                    --newX;
                    arrivingViewport  = new Rectangle(newX - halfViewport, oldY - halfViewport, 1, Constants.VIEWPORT_SIZE);
                    departingViewport = new Rectangle(oldX + halfViewport, oldY - halfViewport, 1, Constants.VIEWPORT_SIZE);
                    break;

                case Xml.Direction.East:
                    ++newX;
                    arrivingViewport  = new Rectangle(oldX + halfViewport, oldY - halfViewport, 1, Constants.VIEWPORT_SIZE);
                    departingViewport = new Rectangle(oldX - halfViewport, oldY - halfViewport, 1, Constants.VIEWPORT_SIZE);
                    break;
                }
                var isWarp = Map.Warps.TryGetValue(new Tuple <byte, byte>((byte)newX, (byte)newY), out targetWarp);

                // Now that we know where we are going, perform some sanity checks.
                // Is the player trying to walk into a wall, or off the map?

                if (newX >= Map.X || newY >= Map.Y || newX < 0 || newY < 0)
                {
                    Refresh();
                    return(false);
                }
                if (Map.IsWall[newX, newY])
                {
                    Refresh();
                    return(false);
                }
                else
                {
                    // Is the player trying to walk into an occupied tile?
                    foreach (var obj in Map.GetTileContents((byte)newX, (byte)newY))
                    {
                        GameLog.DebugFormat("Collsion check: found obj {0}", obj.Name);
                        if (obj is Creature)
                        {
                            GameLog.DebugFormat("Walking prohibited: found {0}", obj.Name);
                            Refresh();
                            return(false);
                        }
                    }
                    // Is this user entering a forbidden (by level or otherwise) warp?
                    if (isWarp)
                    {
                        if (targetWarp.MinimumLevel > Stats.Level)
                        {
                            Refresh();
                            return(false);
                        }
                        else if (targetWarp.MaximumLevel < Stats.Level)
                        {
                            Refresh();
                            return(false);
                        }
                    }
                }

                // Calculate the common viewport between the old and new position

                commonViewport = new Rectangle(oldX - halfViewport, oldY - halfViewport, Constants.VIEWPORT_SIZE, Constants.VIEWPORT_SIZE);
                commonViewport.Intersect(new Rectangle(newX - halfViewport, newY - halfViewport, Constants.VIEWPORT_SIZE, Constants.VIEWPORT_SIZE));
                GameLog.DebugFormat("Moving from {0},{1} to {2},{3}", oldX, oldY, newX, newY);
                GameLog.DebugFormat("Arriving viewport is a rectangle starting at {0}, {1}", arrivingViewport.X, arrivingViewport.Y);
                GameLog.DebugFormat("Departing viewport is a rectangle starting at {0}, {1}", departingViewport.X, departingViewport.Y);
                GameLog.DebugFormat("Common viewport is a rectangle starting at {0}, {1} of size {2}, {3}", commonViewport.X,
                                    commonViewport.Y, commonViewport.Width, commonViewport.Height);

                X         = (byte)newX;
                Y         = (byte)newY;
                Direction = direction;

                // Objects in the common viewport receive a "walk" (0x0C) packet
                // Objects in the arriving viewport receive a "show to" (0x33) packet
                // Objects in the departing viewport receive a "remove object" (0x0E) packet

                foreach (var obj in Map.EntityTree.GetObjects(commonViewport))
                {
                    if (obj != this && obj is User)
                    {
                        var user = obj as User;
                        GameLog.DebugFormat("Sending walk packet for {0} to {1}", Name, user.Name);
                        var x0C = new ServerPacket(0x0C);
                        x0C.WriteUInt32(Id);
                        x0C.WriteUInt16((byte)oldX);
                        x0C.WriteUInt16((byte)oldY);
                        x0C.WriteByte((byte)direction);
                        x0C.WriteByte(0x00);
                        user.Enqueue(x0C);
                    }
                }
                Map.EntityTree.Move(this);

                foreach (var obj in Map.EntityTree.GetObjects(arrivingViewport).Distinct())
                {
                    obj.AoiEntry(this);
                    AoiEntry(obj);
                }

                foreach (var obj in Map.EntityTree.GetObjects(departingViewport).Distinct())
                {
                    obj.AoiDeparture(this);
                    AoiDeparture(obj);
                }
            }
            HasMoved = true;
            return(true);
        }