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); } } } }
private void Run() { Map.TileCollection tiles = null; Objects.Map.Tile corpseTile = null; Objects.Container lootContainer = null; Loot[] loots = null; Random rand = new Random(); this.OpenCorpseCalled += new OpenCorpseCalledHandler(delegate(Map.TileCollection tileCollection, Objects.Map.Tile tile) { tiles = tileCollection; corpseTile = tile; this.ResetEvent.Set(); }); this.LootItemsCalled += new LootItemsCalledHandler(delegate(Objects.Container container, IEnumerable <Loot> loot) { lootContainer = container; loots = loot.ToArray(); this.ResetEvent.Set(); }); // signal parent thread that this thread is ready this.ResetEventMultiUse.Set(); while (true) { try { this.Cancel = false; this.ResetEvent.Wait(); #region open corpse if (corpseTile != null) { while (!this.Cancel) { this.ResetEventMultiUse.WaitOne(); if (this.Cancel || corpseTile == null) { break; } if (!this.Parent.Client.Player.Location.IsOnScreen(corpseTile.WorldLocation)) { break; } if (this.Parent.Client.Player.IsWalking) { continue; } Map.TileObject topItem = corpseTile.GetTopUseItem(false); if (topItem == null || !topItem.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) { break; } Objects.Map.Tile playerTile = this.CachedTiles.GetTile(count: this.Parent.Client.Player.ID); if (playerTile == null) { break; } if (playerTile.WorldLocation.DistanceTo(corpseTile.WorldLocation) >= 2) { int distance = int.MaxValue; Objects.Map.Tile bestTile = corpseTile; foreach (Objects.Map.Tile tile in this.CachedTiles.GetAdjacentTileCollection(corpseTile).GetTiles()) { if (!tile.IsWalkable()) { continue; } var pathToTile = playerTile.WorldLocation.GetTilesToLocation(this.Parent.Client, tile.WorldLocation, this.CachedTiles, this.Parent.PathFinder, true).ToArray(); if (pathToTile.Length == 0) { continue; } if (distance > pathToTile.Length) { distance = pathToTile.Length; bestTile = tile; } } if (bestTile == corpseTile && !playerTile.WorldLocation.CanReachLocation(this.Parent.Client, bestTile.WorldLocation)) { break; } this.Parent.Client.Player.GoTo = bestTile.WorldLocation; continue; } for (int i = 0; i < 2; i++) { if (this.Cancel) { break; } Objects.Container container = this.Parent.Client.Inventory.GetContainer(this.Parent.Client.Inventory.GetClosedContainerNumber()); topItem.Use(); for (int j = 0; j < 5; j++) { Thread.Sleep(100); if (container.IsOpen) { break; } } if (!container.IsOpen) { continue; } if (this.CorpseOpened != null) { this.CorpseOpened(container); } break; } break; } corpseTile = null; } #endregion #region loot item(s) if (lootContainer != null) { if (!lootContainer.IsOpen || lootContainer.ItemsAmount == 0) { if (!this.Cancel && this.LootingFinished != null) { this.LootingFinished(lootContainer); } lootContainer = null; continue; } this.LootItems(lootContainer, loots, tiles); if (!this.Cancel && this.LootingFinished != null) { this.LootingFinished(lootContainer); } lootContainer = null; loots = null; } #endregion this.ResetEvent.Reset(); } catch (Exception ex) { if (this.ErrorOccurred != null) { this.ErrorOccurred(ex); } } } }
public static void Main(Client client) { Location offset = new Location(1, 0, 0), // fixed offset of loot pile finishedContainerOffset = new Location(0, 0, 0); // fixed offset of finished container bool useOffset = false, // whether to only check on a location specified by offset useNestedContainers = true, // whether to dump into nested containers openContainersOnGround = true; // whether to use containers on the ground as loot containers Container lootContainer = null, finishedContainer = null; Location lootContainerLocation = null; int fullIndex = int.MaxValue; string statusBarFull = "You cannot put more objects"; while (true) { Thread.Sleep(50); if (!client.Player.Connected) { continue; } if (openContainersOnGround) { if (lootContainerLocation != null && lootContainer != null && lootContainer.IsOpen && finishedContainer != null && finishedContainer.IsOpen) { if (fullIndex <= 0) { lootContainer.Close(); fullIndex = int.MaxValue; var top = client.Map.GetTopMoveItem(lootContainerLocation); if (top != null && top.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) { var best = finishedContainer.GetBestSlot(top.ToItemLocation()); if (best != null) { top.Move(best); Thread.Sleep(500); } } lootContainer = null; lootContainerLocation = null; } } // find loot container if (lootContainer == null || !lootContainer.IsOpen) { lootContainer = null; foreach (var tile in client.Map.GetAdjacentTiles(client.Player.Location).GetTiles()) { if (tile.WorldLocation == client.Player.Location.Offset(finishedContainerOffset)) { continue; } var top = tile.GetTopUseItem(false); if (top == null || !top.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) { continue; } for (int i = 0; i < 3; i++) { lootContainer = top.TryOpen(); if (lootContainer != null) { break; } } if (lootContainer == null) { continue; } lootContainerLocation = tile.WorldLocation; break; } // check if container wasn't found // exit script if so if (lootContainer == null) { return; } } // find finished container if (finishedContainer == null || !finishedContainer.IsOpen) { finishedContainer = null; var top = client.Map.GetTopUseItem(client.Player.Location.Offset(finishedContainerOffset), false); if (top == null || !top.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) { return; } for (int i = 0; i < 3; i++) { finishedContainer = top.TryOpen(); if (finishedContainer != null) { break; } } if (finishedContainer == null) { return; } } } else { // assign loot container to any open container that has free slots foreach (var container in client.Inventory.GetContainers()) { if (container.IsFull) { continue; } lootContainer = container; break; } // check if container wasn't found // wait and try again if so if (lootContainer == null) { continue; } } Map.TileObject topitem = null; if (!useOffset) { // find loot pile foreach (var tile in client.Map.GetAdjacentTiles(client.Player.Location).GetTiles()) { if (openContainersOnGround) { var loc = tile.WorldLocation; if (loc == client.Player.Location.Offset(finishedContainerOffset) || loc == lootContainerLocation) { continue; } } var top = tile.GetTopMoveItem(); if (top == null || !top.HasFlag(Enums.ObjectPropertiesFlags.IsPickupable) || top.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) { continue; } topitem = top; break; } } else { var tile = client.Map.GetTile(client.Player.Location.Offset(offset)); if (tile == null) { continue; } if (tile.GetObjects().ToArray().Length <= 1) { break; // tile is empty } var top = tile.GetTopMoveItem(); if (topitem == null || topitem.ID < 100) { return; } if (!topitem.HasFlag(Enums.ObjectPropertiesFlags.IsPickupable)) { return; } topitem = top; } if (topitem == null) { return; } if (!useNestedContainers) { ItemLocation itemLoc = lootContainer.GetBestSlot(topitem.ToItemLocation()); if (itemLoc == null) { continue; } topitem.Move(itemLoc); } else { var items = lootContainer.GetItems().ToArray(); int i = Math.Min(fullIndex, items.Length - 1); while (i >= 0) { if (!lootContainer.IsOpen) { break; } var item = items[i]; if (fullIndex <= i || !item.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) { i--; continue; } topitem.Move(item.ToItemLocation()); //Thread.Sleep(200); if (client.Window.StatusBar.GetText().StartsWith(statusBarFull)) { fullIndex = i; client.Window.StatusBar.SetText(string.Empty); Thread.Sleep(1000); client.Window.StatusBar.SetText(string.Empty); } break; } } } }