Esempio n. 1
0
		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);
			}
		}
Esempio n. 2
0
		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);
			}
		}
Esempio n. 3
0
		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;
		}
Esempio n. 4
0
		public static bool check_distance_blxy(WorldObjectUnit bl, int x1, int y1, int distance) {
			return InRange((bl).X - (x1), (bl).Y - (y1), distance);
		}
Esempio n. 5
0
 public bool InRange(WorldObjectUnit obj, int range)
 {
     return(PathHelper.InRange(X - obj.X, Y - obj.Y, range));
 }
Esempio n. 6
0
		private void Move(WorldObjectUnit obj, Point2D OldLocation) {
			this[OldLocation].DelUnit(obj);
			this[obj.Location].AddUnit(obj);
		}
Esempio n. 7
0
		public static bool check_distance_bl(WorldObjectUnit bl1, WorldObjectUnit bl2, int distance) {
			return InRange((bl1).X - (bl2).X, (bl1).Y - (bl2).Y, distance);
		}
Esempio n. 8
0
		private void Add(WorldObjectUnit obj) {
			this[obj.Location].AddUnit(obj);
		}
Esempio n. 9
0
		private void Remove(WorldObjectUnit obj) {
			this[obj.Location].DelUnit(obj);
		}
Esempio n. 10
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;
		}
Esempio n. 11
0
		public void OnMove(WorldObjectUnit obj, Point2D OldLocation) {
			Move(obj, OldLocation);
		}
Esempio n. 12
0
		public void OnLeave(WorldObjectUnit obj) {
			Remove(obj);
		}
Esempio n. 13
0
		public void OnEnter(WorldObjectUnit obj) {
			Add(obj);
		}
Esempio n. 14
0
		public bool InRange(WorldObjectUnit obj, int range) {
			return PathHelper.InRange(X - obj.X, Y - obj.Y, range);
		}