/// <summary> /// Attempts to use an item on a world location. /// </summary> /// <param name="itemid">The item's ID.</param> /// <param name="loc">The world location to use the item on.</param> public void HotkeyUseItemOnLocation(ushort itemid, Objects.Location loc) { if (itemid == 0 || !loc.IsValid()) { return; } }
/// <summary> /// Attempts to use an item on a world location. /// If possible, use UseItemOnTile instead, as it provides better performance. /// </summary> /// <param name="itemLocation">The item's location.</param> /// <param name="loc">The world location to use the item on.</param> public void UseItemOnLocation(Objects.ItemLocation itemLocation, Objects.Location loc) { if (itemLocation == null || !loc.IsValid()) { return; } this.UseItemOnTile(itemLocation, this.Client.Map.GetTile(loc, null)); }
/// <summary> /// Gets a memory location based on a world location. /// </summary> /// <param name="memoryLocation">The memory location to use as reference.</param> /// <param name="playerTile">The player's tile to use as reference.</param> /// <returns></returns> private Objects.Location MemoryLocationToWorldLocation(Objects.Location memoryLocation, Map.Tile playerTile) { if (playerTile == null || !memoryLocation.IsValid()) { return(Objects.Location.Invalid); } Objects.Location playerMemLoc = playerTile.MemoryLocation; return(playerTile.WorldLocation.Offset(memoryLocation.X - playerMemLoc.X, memoryLocation.Y - playerMemLoc.Y, memoryLocation.Z - playerMemLoc.Z)); /*Objects.Location loc = Objects.Location.Invalid; * if (playerTile == null) return loc; * * // get the center of a "screen" * // keep in mind that memory locations are zero-based * int centerX = Constants.Map.MaxX / 2 - 1, * centerY = Constants.Map.MaxY / 2 - 1; * * loc = new Objects.Location(memoryLocation.X, memoryLocation.Y, memoryLocation.Z); * Objects.Location playerMemLoc = playerTile.MemoryLocation; * * // get and apply diffs * int diffX = centerX - playerMemLoc.X; * int diffY = centerY - playerMemLoc.Y; * loc.X += diffX; * loc.Y += diffY; * * // re-align values if they are out of range * int maxX = Constants.Map.MaxX - 1; * int maxY = Constants.Map.MaxY - 1; * if (loc.X > maxX) loc.X -= Constants.Map.MaxX; * else if (loc.X < 0) loc.X += Constants.Map.MaxX; * if (loc.Y > maxY) loc.Y -= Constants.Map.MaxY; * else if (loc.Y < 0) loc.Y += Constants.Map.MaxY; * * // finally align to the player's world location * Objects.Location playerLoc = playerTile.WorldLocation; * return playerLoc.Offset(loc.X - centerX, loc.Y - centerY, loc.Z - playerMemLoc.Z);*/ }
/// <summary> /// Attempts to get the best location to move to. Returns Objects.Location.Invalid if unsuccessful. /// </summary> /// <param name="setting">The setting to use.</param> /// <param name="tileCollection">The tiles that are visible on screen.</param> /// <param name="creaturesOnScreen">The creatures that are visible on screen.</param> /// <returns></returns> public Objects.Location GetBestLocation(Target.Setting setting, Map.TileCollection tileCollection, IEnumerable <Objects.Creature> creaturesOnScreen, Stack <Objects.Location> backtrackedLocations = null) { if (this.Creature == null) { return(null); } Map.Tile playerTile = tileCollection.GetTile(count: this.Parent.Client.Player.ID), targetTile = tileCollection.GetTile(count: this.Creature.ID); if (playerTile == null || targetTile == null) { return(null); } Map.TileCollection adjacentTiles = tileCollection.GetAdjacentTileCollection(targetTile); List <Objects.PathFinder.Node> pfNodes = null; int closest = 15; Objects.Location bestLocation = Objects.Location.Invalid; switch (setting.FightStance) { case Enums.FightStance.FollowDiagonalOnly: if (playerTile.WorldLocation.IsAdjacentDiagonalOnly(targetTile.WorldLocation)) { break; } int closestNonDiagonal = 15; Objects.Location bestNonDiagonalLocation = Objects.Location.Invalid; foreach (Map.Tile tile in adjacentTiles.GetTiles()) { if (!tile.IsWalkable()) { continue; } //if (!tile.WorldLocation.IsAdjacentDiagonalOnly(targetTile.WorldLocation)) continue; pfNodes = playerTile.WorldLocation.GetTilesToLocation(this.Parent.Client, tile.WorldLocation, tileCollection, this.Parent.PathFinder, true).ToList <Objects.PathFinder.Node>(); if (pfNodes.Count > 0) { if (this.Parent.CurrentSettings.AllowDiagonalMovement && playerTile.WorldLocation.IsAdjacentDiagonalOnly(targetTile.WorldLocation)) { continue; } if (pfNodes.Count - 1 < closest && tile.WorldLocation.IsAdjacentDiagonalOnly(targetTile.WorldLocation)) { closest = pfNodes.Count - 1; bestLocation = tile.WorldLocation; } else if (pfNodes.Count - 1 < closestNonDiagonal && tile.WorldLocation.IsAdjacentNonDiagonalOnly(targetTile.WorldLocation)) { closestNonDiagonal = pfNodes.Count - 1; bestNonDiagonalLocation = tile.WorldLocation; } } } if (!bestLocation.IsValid()) { bestLocation = bestNonDiagonalLocation; } break; case Enums.FightStance.FollowStrike: if (playerTile.WorldLocation.IsAdjacentNonDiagonalOnly(targetTile.WorldLocation)) { break; } foreach (Map.Tile tile in adjacentTiles.GetTiles()) { if (!tile.WorldLocation.IsAdjacentNonDiagonalOnly(targetTile.WorldLocation)) { continue; } pfNodes = playerTile.WorldLocation.GetTilesToLocation(this.Parent.Client, tile.WorldLocation, tileCollection, this.Parent.PathFinder, true).ToList <Objects.PathFinder.Node>(); if (pfNodes.Count > 0 && pfNodes.Count - 1 < closest && (!this.Parent.CurrentSettings.AllowDiagonalMovement || playerTile.WorldLocation.IsAdjacentDiagonalOnly(targetTile.WorldLocation))) { closest = pfNodes.Count - 1; bestLocation = tile.WorldLocation; } } break; case Enums.FightStance.DistanceFollow: case Enums.FightStance.DistanceWait: // map creature tiles and the path nodes to them from the player Dictionary <Map.Tile, List <Objects.PathFinder.Node> > creatureTiles = new Dictionary <Map.Tile, List <Objects.PathFinder.Node> >(); // add the current target creatureTiles.Add(targetTile, this.Creature.GetTilesToCreature(tileCollection, this.Parent.PathFinder).ToList <Objects.PathFinder.Node>()); // check whether to add other monsters as well if (this.Parent.CurrentSettings.ConsiderAllMonstersWhenKeepingAway) { foreach (Objects.Creature c in creaturesOnScreen) { Map.Tile t = tileCollection.GetTile(count: c.ID); if (t != null && !creatureTiles.ContainsKey(t)) { creatureTiles.Add(t, c.GetTilesToCreature(tileCollection, this.Parent.PathFinder).ToList <Objects.PathFinder.Node>()); } } } // check if the player needs to move // also set the player's location as default location to return bool needToMove = false; bestLocation = playerTile.WorldLocation; foreach (var keypair in creatureTiles) { // check if creature can reach the player if (keypair.Value.Count == 0) { continue; } if (keypair.Value.Count < setting.DistanceRange || (setting.FightStance == Enums.FightStance.DistanceFollow && keypair.Value.Count > setting.DistanceRange)) { needToMove = true; } } if (!needToMove) { break; } int bestRange = 1; Map.Tile bestTile = playerTile; // calculate distance to the player's tile foreach (var keypair in creatureTiles) { pfNodes = keypair.Value; if (pfNodes.Count == 0) { continue; } int count = pfNodes.Count; bestRange += Math.Abs(setting.DistanceRange - count) * (count < setting.DistanceRange ? 2 : 1); } if (backtrackedLocations != null && backtrackedLocations.Count > 0) { Objects.Location peekLoc = backtrackedLocations.Peek(); if (peekLoc.IsOnScreen(playerTile.WorldLocation)) { bestLocation = peekLoc; break; } } // calculate and set foreach (Map.Tile t in tileCollection.GetAdjacentTileCollection(playerTile).GetTiles()) { if (t == null || !t.IsWalkable()) { continue; } if (this.Parent.CurrentSettings.AllowDiagonalMovement && playerTile.WorldLocation.IsAdjacentDiagonalOnly(t.WorldLocation)) { continue; } // calculate distance for creatures int distance = 0; foreach (var keypair in creatureTiles) { pfNodes = keypair.Key.WorldLocation.GetTilesToLocation(this.Parent.Client, t.WorldLocation, tileCollection, this.Parent.PathFinder, true).ToList <Objects.PathFinder.Node>(); if (pfNodes.Count == 0) { continue; } int count = pfNodes.Count - 1; distance += Math.Abs(setting.DistanceRange - count) * (count < setting.DistanceRange ? 2 : 1); } // get next tile in same general direction bool good = false; int directionX = playerTile.WorldLocation.X - t.WorldLocation.X, directionY = playerTile.WorldLocation.Y - t.WorldLocation.Y; foreach (Map.Tile nextTile in tileCollection.GetAdjacentTileCollection(t).GetTiles()) { if (nextTile == null || !nextTile.IsWalkable()) { continue; } if (t.WorldLocation.X - nextTile.WorldLocation.X != directionX && t.WorldLocation.Y - nextTile.WorldLocation.Y != directionY) { continue; } if (nextTile == playerTile) { continue; } good = true; break; } if (!good) { continue; } // check of tile is better than previous tile if (bestRange > distance) { bestRange = distance; bestLocation = t.WorldLocation; } } break; case Enums.FightStance.FollowEconomic: break; } return(bestLocation); }
private void Run() { while (true) { try { this.ResetEvent.Wait(); if (this.TargetExecutedBegin != null) { this.TargetExecutedBegin(this.CurrentTarget); } Objects.Client client = this.Parent.Client; Objects.Creature oldCreature = null; while (!this.Cancel) { this.ResetEventCacheUpdated.WaitOne(); if (this.Cancel) { break; } // get best setting Target.Setting setting = this.CurrentTarget.GetBestSetting(this.CachedCreatures, this.CachedPlayers, this.CachedTiles, true); if (setting == null) { break; } // check if we should revert to older creature if sticky is on // or if new creature is in no better position if (oldCreature != null && oldCreature != this.CurrentTarget.Creature && oldCreature.IsVisible && client.Player.Location.IsOnScreen(oldCreature.Location)) { if (this.Parent.CurrentSettings.StickToCreature) { this.CurrentTarget.Creature = oldCreature; } else { int oldDist = (int)client.Player.Location.DistanceTo(oldCreature.Location), newDist = this.CurrentTarget.Creature != null ? (int)client.Player.Location.DistanceTo(this.CurrentTarget.Creature.Location) : 100; if (oldDist < newDist + 2) { this.CurrentTarget.Creature = oldCreature; } } } oldCreature = this.CurrentTarget.Creature; Objects.Location playerLoc = client.Player.Location, targetLoc = this.CurrentTarget.Creature.Location; #region targeting checks and whatnot // check if the creature is dead if (this.CurrentTarget.Creature.IsDead) { break; } // check if creature is about to become a corpse if (this.CurrentTarget.Creature.IsVisible && this.CurrentTarget.Creature.HealthPercent == 0) { continue; } // check if creature is still on screen, stop attacking and looping if so if (!playerLoc.IsOnScreen(targetLoc)) { this.CancelAttack(); break; } // check if creature if reachable and/or shootable // stop attacking and break if settings says they must be if ((setting.MustBeReachable && !this.CurrentTarget.Creature.IsReachable(this.CachedTiles, this.Parent.PathFinder)) || (setting.MustBeShootable && !this.CurrentTarget.Creature.IsShootable(this.CachedTiles))) { this.CancelAttack(); break; } // check if player is attacking the wrong target if (client.Player.Target != this.CurrentTarget.Creature.ID) { this.CurrentTarget.Creature.Attack(); Thread.Sleep(100); } // set fight stance+mode and move accordingly Map.Tile playerTile = this.CachedTiles.GetTile(count: client.Player.ID), creatureTile = this.CachedTiles.GetTile(count: this.CurrentTarget.Creature.ID); if (playerTile == null || creatureTile == null) { this.CancelAttack(); break; } switch (setting.FightStance) { case Enums.FightStance.Stand: if (client.Player.FightStance != Enums.FightStance.Stand) { client.Player.FightStance = Enums.FightStance.Stand; } break; case Enums.FightStance.Follow: if (client.Player.FightStance != Enums.FightStance.Follow) { client.Player.FightStance = Enums.FightStance.Follow; } break; case Enums.FightStance.FollowDiagonalOnly: case Enums.FightStance.DistanceFollow: case Enums.FightStance.DistanceWait: case Enums.FightStance.FollowStrike: if (client.Player.FightStance != Enums.FightStance.Stand) { client.Player.FightStance = Enums.FightStance.Stand; } if (client.Player.IsWalking) { break; } Objects.Location bestLoc = this.CurrentTarget.GetBestLocation(setting, this.CachedTiles, this.CachedCreatures); if (bestLoc.IsValid() && client.Player.GoTo != bestLoc) { client.Player.GoTo = bestLoc; } break; } // shoot rune or spell if (client.Player.HealthPercent >= this.Parent.CurrentSettings.MinimumHealthToShoot && this.CurrentTarget.Creature.HealthPercent > 0) { ushort runeID = 0; if ((runeID = setting.GetRuneID()) != 0) { Objects.Item rune = client.Inventory.GetItem(runeID); if (rune != null) { if (!this.StopwatchExhaust.IsRunning || this.StopwatchExhaust.ElapsedMilliseconds >= this.Parent.CurrentSettings.Exhaust) { if (setting.RuneIsAoE()) // todo: test this { Map.Tile aoeTile = this.Parent.GetAreaEffectTile(setting.GetAreaEffect(), this.CachedTiles, this.CurrentTarget.Creature); if (aoeTile != null) { rune.UseOnTile(aoeTile); this.StopwatchExhaust.Restart(); } } else if (this.CurrentTarget.Creature.IsShootable(this.CachedTiles)) { rune.UseOnBattleList(this.CurrentTarget.Creature); this.StopwatchExhaust.Restart(); } } } } else if (!string.IsNullOrEmpty(setting.Spell)) { // todo: add aoe spells if (playerLoc.IsAdjacentNonDiagonalOnly(targetLoc)) { Enums.Direction direction = Enums.Direction.Down; int diffX = playerLoc.X - targetLoc.X, diffY = playerLoc.Y - targetLoc.Y; if (diffX > 0) { direction = Enums.Direction.Left; } else if (diffX < 0) { direction = Enums.Direction.Right; } else if (diffY > 0) { direction = Enums.Direction.Up; } else if (diffY < 0) { direction = Enums.Direction.Down; } if (client.Player.Direction != direction) { client.Packets.Turn(direction); for (int i = 0; i < 6; i++) { Thread.Sleep(50); if ((Enums.Direction)client.Player.Direction == direction) { break; } } } if (client.Player.Direction == direction && (!this.StopwatchExhaust.IsRunning || this.StopwatchExhaust.ElapsedMilliseconds > this.Parent.CurrentSettings.Exhaust)) { client.Packets.Say(setting.Spell); this.StopwatchExhaust.Restart(); } } } } #endregion } if (this.TargetExecutedEnd != null) { this.TargetExecutedEnd(this.CurrentTarget); } this.ResetEvent.Reset(); this.Cancel = false; } catch (Exception ex) { if (this.ErrorOccurred != null) { this.ErrorOccurred(ex); } } } }
private void Run() { while (true) { try { this.ResetEvent.Wait(); if (this.WaypointExecutedBegin != null) { this.WaypointExecutedBegin(this.CurrentWaypoint); } bool success = false, firstRun = true; Objects.Location currentSubNode = Objects.Location.Invalid; while (!this.Cancel) { this.ResetEventTilesUpdated.WaitOne(); if (this.Cancel) { break; } Objects.Player player = this.Parent.Client.Player; Objects.Location playerLoc = player.Location; if (player.Z != this.CurrentWaypoint.Location.Z) { break; } if (firstRun) { firstRun = false; } else { if (this.Parent.Client.Window.StatusBar.GetText() == Enums.StatusBar.ThereIsNoWay) { this.Parent.Client.Window.StatusBar.SetText(string.Empty); success = false; break; } } bool isOnScreen = playerLoc.IsOnScreen(this.CurrentWaypoint.Location), doBreak = false; var tilesToLocation = isOnScreen ? playerLoc.GetTilesToLocation(this.Parent.Client, this.CurrentWaypoint.Location, this.CachedTiles, this.Parent.PathFinder) .ToList <Objects.PathFinder.Node>() : new List <Objects.PathFinder.Node>(); switch (this.CurrentWaypoint.Type) { case Waypoint.Types.Walk: #region walk if (playerLoc == this.CurrentWaypoint.Location) { doBreak = true; success = true; break; } if (isOnScreen && tilesToLocation.Count == 0) { doBreak = true; success = false; break; } if (!player.IsWalking || player.GoTo != this.CurrentWaypoint.Location) { player.GoTo = this.CurrentWaypoint.Location; } #endregion break; case Waypoint.Types.Node: #region node if (playerLoc == this.CurrentWaypoint.Location) { doBreak = true; success = true; break; } if (isOnScreen && tilesToLocation.Count == 0) { doBreak = true; success = false; break; } // check if the player is already walking to a node if (player.IsWalking) { int range = this.Parent.CurrentSettings.NodeRadius; Objects.Location currentGoTo = player.GoTo; bool found = false; for (int x = -range; x <= range; x++) { for (int y = -range; y <= range; y++) { Objects.Location subNode = this.CurrentWaypoint.Location.Offset(x, y); if (currentGoTo != subNode) { continue; } // check distance to node if (isOnScreen) { var tilesToSubNode = playerLoc.GetTilesToLocation(this.Parent.Client, subNode, this.CachedTiles, this.Parent.PathFinder, true).ToArray(); if (tilesToSubNode.Length <= this.Parent.CurrentSettings.NodeSkipRange) { success = true; doBreak = true; break; } } found = true; break; } if (found) { break; } } if (found) { break; } } else if (playerLoc.DistanceTo(this.CurrentWaypoint.Location) <= this.Parent.CurrentSettings.NodeSkipRange) { success = true; doBreak = true; break; } // find new node to walk to if (isOnScreen) { Map.Tile tile = this.CachedTiles.GetTile(this.CurrentWaypoint.Location); if (tile == null) { doBreak = true; success = false; break; } Map.TileCollection nearbyTiles = this.CachedTiles.GetNearbyTileCollection(tile, this.Parent.CurrentSettings.NodeRadius); Objects.Location loc = tilesToLocation.Count != 0 ? tile.WorldLocation : Objects.Location.Invalid; List <Map.Tile> goodTiles = new List <Map.Tile>(); foreach (Map.Tile nearbyTile in nearbyTiles.GetTiles()) { bool isReachable = playerLoc.CanReachLocation(this.Parent.Client, nearbyTile.WorldLocation, this.CachedTiles, this.Parent.PathFinder); if (isReachable) { goodTiles.Add(nearbyTile); } } if (goodTiles.Count > 0) { loc = goodTiles[new Random().Next(goodTiles.Count)].WorldLocation; } if (loc.IsValid()) { player.GoTo = loc; } else { doBreak = true; success = false; break; } } else if (this.Parent.CurrentSettings.UseAlternateNodeFinder) { int range = this.Parent.CurrentSettings.NodeRadius; Random rand = new Random(); Objects.Location loc = this.CurrentWaypoint.Location; for (int x = -range; x <= range; x++) { for (int y = -range; y <= range; y++) { Objects.Location subNode = this.CurrentWaypoint.Location.Offset( rand.Next(-range, range + 1), rand.Next(-range, range + 1)); if (!this.Parent.Client.Modules.MapViewer.IsWalkable(subNode)) { continue; } loc = subNode; break; } if (loc != this.CurrentWaypoint.Location) { break; } } player.GoTo = loc; } else // use stored subnodes { Objects.Location loc = this.CurrentWaypoint.Location; if (this.CurrentWaypoint.NodeLocations.Count > 0) { int index = -1, newIndex = new Random().Next(-1, this.CurrentWaypoint.NodeLocations.Count); if (newIndex != index) { loc = this.CurrentWaypoint.NodeLocations[newIndex]; } } player.GoTo = loc; } #endregion break; case Waypoint.Types.Machete: case Waypoint.Types.Pick: case Waypoint.Types.Rope: case Waypoint.Types.Shovel: #region tools // check if we're adjacent to the waypoint if (playerLoc.IsAdjacentTo(this.CurrentWaypoint.Location)) { Objects.Item tool = null; switch (this.CurrentWaypoint.Type) { case Waypoint.Types.Machete: tool = this.Parent.Client.Inventory.GetItem(this.Parent.Client.ItemList.Tools.Machete); break; case Waypoint.Types.Pick: tool = this.Parent.Client.Inventory.GetItem(this.Parent.Client.ItemList.Tools.Pick); break; case Waypoint.Types.Rope: tool = this.Parent.Client.Inventory.GetItem(this.Parent.Client.ItemList.Tools.Rope); break; case Waypoint.Types.Shovel: tool = this.Parent.Client.Inventory.GetItem(this.Parent.Client.ItemList.Tools.Shovel); break; } if (tool == null) { doBreak = true; success = false; break; } Map.Tile tile = this.CachedTiles.GetTile(this.CurrentWaypoint.Location); if (tile == null) { success = false; doBreak = true; break; } Map.TileObject topItem = tile.GetTopUseItem(true); if (this.CurrentWaypoint.Type != Waypoint.Types.Rope) { tool.UseOnTileObject(topItem); success = true; doBreak = true; } else { if (topItem.StackIndex != 0) { // find a non-blocking adjacent tile var adjacentTiles = this.CachedTiles.GetAdjacentTileCollection(tile).GetTiles() .ToList <Map.Tile>(); Map.Tile bestTile = tile; foreach (Map.Tile t in adjacentTiles.ToArray()) { if (!t.IsWalkable()) { adjacentTiles.Remove(t); } } if (adjacentTiles.Count > 0) { bestTile = adjacentTiles[new Random().Next(adjacentTiles.Count)]; } topItem.Move(bestTile.ToItemLocation()); } else { tool.UseOnTileObject(topItem); for (int i = 0; i < 3; i++) { Thread.Sleep(100); if (player.Z != this.CurrentWaypoint.Location.Z) { doBreak = true; success = true; break; } } } } break; } else if (isOnScreen) { Map.Tile tile = this.CachedTiles.GetTile(this.CurrentWaypoint.Location); if (tile == null) { success = false; doBreak = true; break; } Map.TileCollection adjacentTiles = this.CachedTiles.GetAdjacentTileCollection(tile); Objects.Location bestLoc = Objects.Location.Invalid; int distance = int.MaxValue; foreach (Map.Tile adjTile in adjacentTiles.GetTiles()) { if (!adjTile.IsWalkable()) { continue; } var tilesToAdjTile = playerLoc.GetTilesToLocation(this.Parent.Client, adjTile.WorldLocation, this.CachedTiles, this.Parent.PathFinder, true) .ToArray <Objects.PathFinder.Node>(); if (tilesToAdjTile.Length == 0) { continue; } if (tilesToAdjTile.Length < distance) { bestLoc = adjTile.WorldLocation; distance = tilesToAdjTile.Length; } } if (bestLoc.IsValid()) { player.GoTo = bestLoc; } else { doBreak = true; success = false; break; } } else if (!player.IsWalking) { player.GoTo = this.CurrentWaypoint.Location; } #endregion break; case Waypoint.Types.Ladder: #region ladder if (player.IsWalking) { break; } if (isOnScreen) { Map.Tile tile = this.CachedTiles.GetTile(this.CurrentWaypoint.Location); if (tile == null) { doBreak = true; success = false; break; } if (playerLoc.DistanceTo(this.CurrentWaypoint.Location) < 2) { Map.TileObject topItem = tile.GetTopUseItem(false); if (topItem == null) { doBreak = true; success = false; break; } for (int i = 0; i < 3; i++) { topItem.Use(); Thread.Sleep(300); if (player.Z != this.CurrentWaypoint.Location.Z) { doBreak = true; success = true; break; } } break; } // find suitable loc to walk to int distance = int.MaxValue; Objects.Location bestLoc = Objects.Location.Invalid; foreach (Map.Tile adjTile in this.CachedTiles.GetAdjacentTileCollection(tile).GetTiles()) { if (!adjTile.IsWalkable()) { continue; } var tilesToAdjTile = playerLoc.GetTilesToLocation(this.Parent.Client, adjTile.WorldLocation, this.CachedTiles, this.Parent.PathFinder, true) .ToArray <Objects.PathFinder.Node>(); if (tilesToAdjTile.Length == 0) { continue; } if (tilesToAdjTile.Length < distance) { distance = tilesToAdjTile.Length; bestLoc = adjTile.WorldLocation; } } if (bestLoc.IsValid()) { player.GoTo = bestLoc; } else { doBreak = true; success = false; } break; } else { player.GoTo = this.CurrentWaypoint.Location; } #endregion break; } if (doBreak) { break; } } if (this.WaypointExecutedEnd != null) { this.WaypointExecutedEnd(this.CurrentWaypoint, success); } this.ResetEvent.Reset(); } catch (Exception ex) { if (this.ErrorOccurred != null) { this.ErrorOccurred(ex); } } } }