public async Task <bool> TakeTownPortalToArea(Client client, Player player, Area area) { var portal = client.Game.GetEntityByCode(EntityCode.TownPortal).FirstOrDefault(t => t.TownPortalArea == area && t.TownPortalOwnerId == player.Id); if (portal == null) { return(false); } var movementMode = GetMovementMode(client.Game); var pathToPortal = await _pathingService.GetPathToLocation(client.Game, portal.Location, movementMode); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToPortal, movementMode)) { Log.Information($"Moving to {portal.Location} failed"); return(false); } if (!await GeneralHelpers.TryWithTimeout(async(retryCount) => { if (retryCount > 0 && retryCount % 5 == 0) { client.Game.RequestUpdate(client.Game.Me.Id); } client.Game.InteractWithEntity(portal); return(await GeneralHelpers.TryWithTimeout(async(retryCount) => { await Task.Delay(50); return client.Game.Area == area; }, TimeSpan.FromSeconds(0.5))); }, TimeSpan.FromSeconds(10))) { return(false); } if (!await GeneralHelpers.TryWithTimeout(async(retryCount) => { if (retryCount > 0 && retryCount % 5 == 0) { client.Game.RequestUpdate(client.Game.Me.Id); } await Task.Delay(100); return(await _pathingService.IsNavigatablePointInArea(client.Game.MapId, Difficulty.Normal, area, client.Game.Me.Location)); }, TimeSpan.FromSeconds(10))) { return(false); } return(true); }
public static async Task <bool> PickupCorpseIfExists(Client client, IPathingService pathingService) { var corpseId = client.Game.Me.CorpseId; if (corpseId != null) { var pickupSucceeded = false; var corpse = client.Game.Players.FirstOrDefault(p => p.Id == corpseId); Log.Information($"Found corpse {corpse.Id} for {client.LoggedInUserName()}, trying to pickup"); pickupSucceeded = await GeneralHelpers.TryWithTimeout(async (retryCount) => { if (client.Game.Me.Location.Distance(corpse.Location) > 5) { Log.Information($"Getting walking path from {client.Game.Me.Location} to {corpse.Location} with distance {client.Game.Me.Location.Distance(corpse.Location)}"); var walkingPath = await pathingService.GetPathToLocation(client.Game, corpse.Location, MovementMode.Walking); await MovementHelpers.TakePathOfLocations(client.Game, walkingPath, MovementMode.Walking); return(false); } return(client.Game.PickupBody(corpse)); }, TimeSpan.FromSeconds(5)); var message = pickupSucceeded ? "succeeded" : "failed"; Log.Information($"Pickup of corpse {message}"); return(pickupSucceeded); } return(true); }
private async Task <bool> PickupNearbyItems(Game game, double distance) { var pickupItems = game.Items.Where(i => { return(i.Ground && game.Me.Location.Distance(i.Location) < distance && Pickit.Pickit.ShouldPickupItem(game, i)); }).OrderBy(n => game.Me.Location.Distance(n.Location)); foreach (var item in pickupItems) { if (!game.IsInGame()) { return(false); } InventoryHelpers.MoveInventoryItemsToCube(game); if (game.Inventory.FindFreeSpace(item) == null) { continue; } await GeneralHelpers.TryWithTimeout(async (retryCount) => { if (game.Me.Location.Distance(item.Location) >= 5) { var pathNearest = await _pathingService.GetPathToLocation(game.MapId, Difficulty.Normal, Area.Travincal, game.Me.Location, item.Location, MovementMode.Walking); await MovementHelpers.TakePathOfLocations(game, pathNearest, MovementMode.Walking); return(false); } return(true); }, TimeSpan.FromSeconds(3)); if (game.Me.Location.Distance(item.Location) < 5) { game.PickupItem(item); } } InventoryHelpers.MoveInventoryItemsToCube(game); return(true); }
public async Task GameLoop(List <Tuple <AccountCharacter, Client> > clients, int gameCount) { var leadClient = clients.Single(c => GetIsLeadClient(c)); var csManager = new CSManager(new List <Client> { leadClient.Item2 }); uint currentTeleportId = 0; var nextGameCancellation = new CancellationTokenSource(); var gameTasks = clients.Select(async(c, i) => { bool isLeadClient = leadClient == c; if (!isLeadClient) { await Task.Delay(TimeSpan.FromSeconds(2 * i)); if (!await RealmConnectHelpers.JoinGameWithRetry(gameCount, c.Item2, _config, c.Item1)) { return(false); } } Log.Information("In game"); var client = c.Item2; client.Game.RequestUpdate(client.Game.Me.Id); if (!GeneralHelpers.TryWithTimeout( (_) => client.Game.Me.Location.X != 0 && client.Game.Me.Location.Y != 0, TimeSpan.FromSeconds(10))) { return(false); } var townManagementOptions = new TownManagementOptions() { Act = Act.Act4 }; if (!await _townManagementService.PerformTownTasks(c.Item2, townManagementOptions)) { return(false); } Func <uint> getTeleportId = () => currentTeleportId; if (c.Item1.Character.Equals(_csconfig.TeleportCharacterName, StringComparison.CurrentCultureIgnoreCase)) { var result = await TaxiCs(c.Item2, csManager, t => currentTeleportId = t); nextGameCancellation.Cancel(); return(result); } else { var movementMode = client.Game.Me.HasSkill(Skill.Teleport) ? MovementMode.Teleport : MovementMode.Walking; var pathToTpLocation = await _pathingService.GetPathToLocation(client.Game, new Point(5042, 5036), movementMode); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToTpLocation, movementMode)) { Log.Warning($"Client {client.Game.Me.Name} {movementMode} to portal area failed at {client.Game.Me.Location}"); return(false); } await BaseCsBot(csManager, getTeleportId, nextGameCancellation, client, GetKillActionForClass(client)); } return(true); } ).ToList(); var firstCompletedResult = await Task.WhenAny(gameTasks); if (!await firstCompletedResult) { Log.Warning($"One or more characters failed there town task"); nextGameCancellation.Cancel(); await Task.WhenAll(gameTasks); return; } var townResults = await Task.WhenAll(gameTasks); if (townResults.Any(r => !r)) { Log.Warning($"One or more characters failed there town task"); nextGameCancellation.Cancel(); return; } }
public static async Task <List <Point> > GetPathToLocation(this IPathingService pathingService, Game game, Point toLocation, MovementMode movementMode) { return(await pathingService.GetPathToLocation(game.MapId, Difficulty.Normal, game.Area, game.Me.Location, toLocation, movementMode)); }
protected override async Task <bool> RunSingleGame(Client client) { Log.Information("In game"); client.Game.RequestUpdate(client.Game.Me.Id); if (!GeneralHelpers.TryWithTimeout( (_) => client.Game.Me.Location.X != 0 && client.Game.Me.Location.Y != 0, TimeSpan.FromSeconds(10))) { return(false); } if (client.Game.Me.Class != CharacterClass.Sorceress) { throw new NotSupportedException("Only sorceress is supported on Mephisto"); } /* * while (client.Game.Players.Count < 2) * { * Thread.Sleep(TimeSpan.FromMilliseconds(100)); * } */ var townManagementOptions = new TownManagementOptions() { Act = Act.Act3 }; await _townManagementService.PerformTownTasks(client, townManagementOptions); NeedsMule = client.Game.Inventory.Items.Any(i => i.IsIdentified && Pickit.Pickit.ShouldKeepItem(client.Game, i) && Pickit.Pickit.CanTouchInventoryItem(client.Game, i)) || client.Game.Cube.Items.Any(i => i.IsIdentified && Pickit.Pickit.ShouldKeepItem(client.Game, i)); if (NeedsMule) { return(true); } Log.Information("Taking DuranceOfHateLevel2 Waypoint"); if (!await _townManagementService.TakeWaypoint(client, Waypoint.DuranceOfHateLevel2)) { Log.Information("Taking DuranceOfHateLevel2 waypoint failed"); return(false); } var path2 = await _pathingService.GetPathFromWaypointToArea(client.Game.MapId, Difficulty.Normal, Area.DuranceOfHateLevel2, Waypoint.DuranceOfHateLevel2, Area.DuranceOfHateLevel3, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, path2, MovementMode.Teleport)) { Log.Warning($"Teleporting to DuranceOfHateLevel3 warp failed at location {client.Game.Me.Location}"); return(false); } var warp = client.Game.GetNearestWarp(); if (warp == null || warp.Location.Distance(client.Game.Me.Location) > 20) { Log.Warning($"Warp not close enough at location {warp?.Location} while at location {client.Game.Me.Location}"); return(false); } Log.Information($"Taking warp to Durance 3"); if (!GeneralHelpers.TryWithTimeout((_) => client.Game.TakeWarp(warp) && client.Game.Area == Area.DuranceOfHateLevel3, TimeSpan.FromSeconds(2))) { Log.Warning($"Taking warp failed at location {client.Game.Me.Location} to warp at location {warp.Location}"); return(false); } if (!await GeneralHelpers.TryWithTimeout(async(retryCount) => { client.Game.RequestUpdate(client.Game.Me.Id); var isValidPoint = await _pathingService.IsNavigatablePointInArea(client.Game.MapId, Difficulty.Normal, Area.DuranceOfHateLevel3, client.Game.Me.Location); return(isValidPoint); }, TimeSpan.FromSeconds(3.5))) { Log.Error("Checking whether moved to area failed"); return(false); } Log.Information($"Teleporting to Mephisto"); var path3 = await _pathingService.GetPathToLocation(client.Game, new Point(17566, 8070), MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, path3, MovementMode.Teleport)) { Log.Warning($"Teleporting to Mephisto failed at location {client.Game.Me.Location}"); return(false); } if (!GeneralHelpers.TryWithTimeout((_) => client.Game.GetNPCsByCode(NPCCode.Mephisto).Count > 0, TimeSpan.FromSeconds(2))) { Log.Warning($"Finding Mephisto failed while at location {client.Game.Me.Location}"); return(false); } var mephisto = client.Game.GetNPCsByCode(NPCCode.Mephisto).Single(); Log.Information($"Killing Mephisto"); if (!GeneralHelpers.TryWithTimeout((retryCount) => { if (!client.Game.IsInGame()) { return(true); } if (mephisto.Location.Distance(client.Game.Me.Location) < 30) { client.Game.RepeatRightHandSkillOnLocation(Skill.StaticField, client.Game.Me.Location); } Thread.Sleep(200); if (retryCount % 5 == 0) { client.Game.UseRightHandSkillOnEntity(Skill.FrozenOrb, mephisto); } return(mephisto.LifePercentage < 30); }, TimeSpan.FromSeconds(30))) { Log.Warning($"Killing Mephisto failed at location {client.Game.Me.Location}"); return(false); } if (!GeneralHelpers.TryWithTimeout((_) => { client.Game.UseRightHandSkillOnEntity(Skill.FrozenOrb, mephisto); if (!client.Game.IsInGame()) { return(true); } return(GeneralHelpers.TryWithTimeout((_) => mephisto.State == EntityState.Dead, TimeSpan.FromSeconds(0.7))); }, TimeSpan.FromSeconds(30))) { Log.Warning($"Killing Mephisto failed at location {client.Game.Me.Location}"); return(false); } if (!PickupNearbyItems(client)) { Log.Warning($"Failed to pickup items at location {client.Game.Me.Location}"); return(false); } return(true); }