public WorldFixpos(WorldObjectUnit obj)
     : base(0x88, 10)
 {
     Write((int)(obj is Character ? (obj as Character).AccountID : obj.ID));
     Write((short)obj.Location.X);
     Write((short)obj.Location.Y);
 }
        public WorldUnitSitStand(WorldObjectUnit obj, bool sitting)
            : base(0x8a, 27)
        {
            mSitting = sitting;

            Write((int)(obj is Character ? (obj as Character).AccountID : obj.ID));
            // Go, ask gravity..
            Writer.Position = 26;
            Write((byte)(sitting == true ? 2 : 3));
        }
        private static int CalcWalkspeed(WorldObjectUnit obj)
        {
            // In final case, the speed comes from status and/or calculation..
            int speed = Global.DEFAULT_WALK_SPEED;

            if (obj.Walkpath.path_pos >= obj.Walkpath.path_len)
            {
                speed = -1;
            }
            else if ((obj.Walkpath.path[obj.Walkpath.path_pos] & EDirection.Up) > 0)
            {
            }
            else
            {
            }
            return(speed);
        }
        public static void WalkToXY(WorldObjectUnit obj, Point2D targetLoc)
        {
            // Walking in process?
            if (obj.Walkpath != null || obj.WalkTimer != null)
            {
                // Stop and reset walking
                if (obj.WalkTimer != null)
                {
                    obj.WalkTimer.Stop();
                    obj.WalkTimer = null;
                }
                obj.Walkpath = null;
            }

            obj.TargetLocation = targetLoc;
            if (obj.Location.Point == obj.TargetLocation)
            {
                return;
            }

            // Calc path
            WalkpathData wpd;

            if (PathHelper.SearchPath(out wpd, obj.Map, obj.Location.Point, obj.TargetLocation) == false)
            {
                ServerConsole.ErrorLine("Bad path, cancel moving");
                //obj.Map.DrawGat();
                return;
            }

            obj.Walkpath = wpd;
            // Player needs to notify clients about a successfull move
            if ((obj is Character))
            {
                (obj as Character).Account.Netstate.Send(new WorldResponseWalkOK(obj as Character));
            }

            // Get speed and start timer
            int speed = CalcWalkspeed(obj);

            if (speed > 0)
            {
                obj.WalkTimer = Timer.DelayCall(TimeSpan.FromMilliseconds(speed), TimeSpan.Zero, 1, new TimerStateCallback <WorldObjectUnit>(WalkToXY_Tick), obj);
            }
        }
Exemple #5
0
 private void Move(WorldObjectUnit obj, Point2D OldLocation)
 {
     this[OldLocation].DelUnit(obj);
     this[obj.Location].AddUnit(obj);
 }
Exemple #6
0
 private void Remove(WorldObjectUnit obj)
 {
     this[obj.Location].DelUnit(obj);
 }
Exemple #7
0
 private void Add(WorldObjectUnit obj)
 {
     this[obj.Location].AddUnit(obj);
 }
Exemple #8
0
        /// <summary>
        /// Locates a random spare cell around the object given, using range as max
        /// distance from that spot. Used for warping functions. Use range below 0 for whole map range.
        /// </summary>
        /// <param name="src">src can be null as long as flag&1</param>
        /// <param name="p">Source poition to use (if flag & 1), will also contain the new position</param>
        /// <param name="rx">Range width</param>
        /// <param name="ry">Range height</param>
        /// <param name="flag">
        /// <para>&1 = random cell must be around given m,x,y, not around src</para>
        /// <PARA>&2 = the target should be able to walk to the target tile</para>
        /// <para>&4 = there shouldn't be any players around the target tile (use the no_spawn_on_player setting)</para>
        /// </param>
        /// <returns></returns>
        public bool SearchFreeCell(WorldObjectUnit src, ref Point2D p, int rx, int ry, int flag)
        {
            int tries, spawn = 0;
            int bx, by;
            int rx2 = 2 * rx + 1;
            int ry2 = 2 * ry + 1;

            if (src == null && ((flag & 1) != 1 || (flag & 2) != 2))
            {
                ServerConsole.DebugLine("SearchFreeCell: Incorrect usage! When src is NULL, flag has to be &1 and can't have &2");
                return(false);
            }

            if ((flag & 1) == 1)
            {
                bx = p.X;
                by = p.Y;
            }
            else
            {
                bx = src.X;
                by = src.Y;
            }

            // No range? Return the target cell then....
            if (rx == 0 && ry == 0)
            {
                p.X = bx;
                p.Y = by;
                return(CheckCell(p, ECollisionType.Reachable));
            }

            // Calc max tries
            if (rx >= 0 && ry >= 0)
            {
                tries = rx2 * ry2;
                if (tries > 100)
                {
                    tries = 100;
                }
            }
            else
            {
                tries = Width * Height;
                if (tries > 500)
                {
                    tries = 500;
                }
            }

            Random rand = new Random();

            while (tries-- > 0)
            {
                p.X = (rx >= 0 ? (rand.Next() % rx2 - rx + bx) : (rand.Next() % (Width - 2) + 1));
                p.Y = (ry >= 0 ? (rand.Next() % ry2 - ry + by) : (rand.Next() % (Height - 2) + 1));

                // Avoid picking the same target tile
                if (p.X == bx && p.Y == by)
                {
                    continue;
                }

                if (CheckCell(p, ECollisionType.Reachable) == true)
                {
                    if ((flag & 2) == 2 && src.CanReach(p, 1) == false)
                    {
                        continue;
                    }
                    if ((flag & 4) == 4)
                    {
                        // Limit of retries reached.
                        if (spawn >= 100)
                        {
                            return(false);
                        }

                        /*
                         * if (spawn++ < battle_config.no_spawn_on_player &&
                         *      map_foreachinarea(map_count_sub, m,
                         * x-AREA_SIZE, *y-AREA_SIZE,
                         * x+AREA_SIZE, *y+AREA_SIZE, BL_PC)
                         *      )
                         *      continue;
                         */
                    }

                    return(true);
                }
            }

            p.X = bx;
            p.Y = by;
            return(false);
        }
Exemple #9
0
 public void OnMove(WorldObjectUnit obj, Point2D OldLocation)
 {
     Move(obj, OldLocation);
 }
Exemple #10
0
 public void OnLeave(WorldObjectUnit obj)
 {
     Remove(obj);
 }
Exemple #11
0
 public void OnEnter(WorldObjectUnit obj)
 {
     Add(obj);
 }
Exemple #12
0
 public static bool check_distance_blxy(WorldObjectUnit bl, int x1, int y1, int distance)
 {
     return(InRange((bl).X - (x1), (bl).Y - (y1), distance));
 }
Exemple #13
0
 public static bool check_distance_bl(WorldObjectUnit bl1, WorldObjectUnit bl2, int distance)
 {
     return(InRange((bl1).X - (bl2).X, (bl1).Y - (bl2).Y, distance));
 }
        public static void WalkToXY_Tick(WorldObjectUnit obj)
        {
            if (obj.Walkpath == null)
            {
                return;
            }
            else if (obj.Walkpath.path_pos >= obj.Walkpath.path_len)
            {
                return;
            }
            else if (obj.Walkpath.path[obj.Walkpath.path_pos] == EDirection.None)
            {
                return;
            }
            else if ((int)obj.Walkpath.path[obj.Walkpath.path_pos] > 8)
            {
                return;
            }
            else
            {
            }

            // TODO: this is the point there the client seems to look laggy
            //		 eAthena sends before any movement the WalkOk() packet
            //		 and the client animates the move to the target location.
            //		 But if we attacked by a skill or w00tever,
            //		 eAthena updates the position (i think)
            //		 AND THIS is the all-known movement/position-reset.
            //
            //		 In future, we may test to send a WalkOk() Packet in every single step
            //		 So the client maybe display it more accurate..

            EDirection dir       = obj.Walkpath.path[obj.Walkpath.path_pos];
            Point2D    targetLoc = obj.Location.Point + dir.ToPoint2D();

            ServerConsole.DebugLine("{0}: walk from {1} to {2} ({3})", obj, obj.Location.Point, targetLoc, dir);
            //obj.Map.DrawGat();
            //Mapcache.Maps[obj.Map.Name].DrawGat();
            if (obj.Map.CheckCell(targetLoc, ECollisionType.Walkable) == false)
            {
                // Target location is not walkable - recalc path!
                ServerConsole.DebugLine("WalkToXY_Tick: location {0} not walkable, recalc path..", targetLoc);
                WalkToXY(obj, obj.TargetLocation);
                return;
            }

            obj.Move(dir);

            obj.Walkpath.path_pos++;
            int speed = CalcWalkspeed(obj);

            // Next step?
            if (speed > 0)
            {
                obj.WalkTimer = Timer.DelayCall(TimeSpan.FromMilliseconds(speed), TimeSpan.Zero, 1, new TimerStateCallback <WorldObjectUnit>(WalkToXY_Tick), obj);
            }
            else
            {
                // No next step, target location reached, update target location
                // just to be sure..
                obj.TargetLocation = obj.Location.Point;
                obj.Walkpath       = null;
                ServerConsole.DebugLine("WalkToXY_Tick: finished moving to location {0}", obj.Location.Point);
            }
        }