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); } }
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); //} }
public static bool check_distance_blxy(WorldObjectUnit bl, int x1, int y1, int distance) { return(InRange((bl).X - (x1), (bl).Y - (y1), distance)); }
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; }
private void Remove(WorldObjectUnit obj) { this[obj.Location].DelUnit(obj); }
public static bool check_distance_bl(WorldObjectUnit bl1, WorldObjectUnit bl2, int distance) { return InRange((bl1).X - (bl2).X, (bl1).Y - (bl2).Y, distance); }
/// <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; }
/* public void DrawGat() { System.Drawing.Pen pBlack = new System.Drawing.Pen(System.Drawing.Color.Black); System.Drawing.Pen pRed = new System.Drawing.Pen(System.Drawing.Color.Red); System.Drawing.Pen pPink = new System.Drawing.Pen(System.Drawing.Color.Pink); System.Drawing.Font font = new System.Drawing.Font("Tahoma", 7); int scale = 25; using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Width * scale, Height * scale)) { using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp)) { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { int xs = x * scale; int ys = y * scale; if (CheckCell(x, y, ECollisionType.Walkable) == true) { g.DrawRectangle(pPink, xs, ys, scale, scale); g.DrawString(x.ToString(), font, System.Drawing.Brushes.Black, xs + 1, ys + 1); g.DrawString(y.ToString(), font, System.Drawing.Brushes.Black, xs + 1, ys + 1 + (scale / 2f)); } else { g.DrawRectangle(pBlack, xs, ys, scale, scale); g.DrawString(x.ToString(), font, System.Drawing.Brushes.White, xs + 1, ys + 1); g.DrawString(y.ToString(), font, System.Drawing.Brushes.White, xs + 1, ys + 1 + (scale / 2f)); } */ /* g.DrawLine(pRed, new System.Drawing.Point(xs, ys), new System.Drawing.Point(xs + scale, ys)); g.DrawLine(pRed, new System.Drawing.Point(xs + scale, ys), new System.Drawing.Point(xs + scale, ys + scale)); g.DrawLine(pRed, new System.Drawing.Point(xs, ys), new System.Drawing.Point(xs, ys + scale)); g.DrawLine(pRed, new System.Drawing.Point(xs, ys + scale), new System.Drawing.Point(xs + scale, ys + scale)); */ /* } } string filename = "mapdebug_" + Name.ToLower() + ".png"; if (System.IO.File.Exists(filename) == true) { System.IO.File.Delete(filename); } bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png); } } } */ private void Add(WorldObjectUnit obj) { this[obj.Location].AddUnit(obj); }
public void OnMove(WorldObjectUnit obj, Point2D OldLocation) { Move(obj, OldLocation); }
public void OnLeave(WorldObjectUnit obj) { Remove(obj); }
public void OnEnter(WorldObjectUnit obj) { Add(obj); }
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); } }
private void Move(WorldObjectUnit obj, Point2D OldLocation) { this[OldLocation].DelUnit(obj); this[obj.Location].AddUnit(obj); }
public bool InRange(WorldObjectUnit obj, int range) { return(PathHelper.InRange(X - obj.X, Y - obj.Y, range)); }
public bool InRange(WorldObjectUnit obj, int range) { return PathHelper.InRange(X - obj.X, Y - obj.Y, range); }
public static bool check_distance_blxy(WorldObjectUnit bl, int x1, int y1, int distance) { return InRange((bl).X - (x1), (bl).Y - (y1), distance); }
public static bool check_distance_bl(WorldObjectUnit bl1, WorldObjectUnit bl2, int distance) { return(InRange((bl1).X - (bl2).X, (bl1).Y - (bl2).Y, distance)); }