private async Task <bool> KillDiablo(Client client, CSManager csManager, Action <uint> setTeleportId) { var pathToDiabloStar = await _pathingService.GetPathToObject(client.Game.MapId, Difficulty.Normal, Area.ChaosSanctuary, client.Game.Me.Location, EntityCode.DiabloStar, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToDiabloStar, MovementMode.Teleport)) { Log.Warning($"Client {client.Game.Me.Name} Teleporting to {EntityCode.DiabloStar} failed at location {client.Game.Me.Location}"); return(false); } if (!_townManagementService.CreateTownPortal(client)) { return(false); } var myPortal = client.Game.GetEntityByCode(EntityCode.TownPortal).First(t => t.TownPortalOwnerId == client.Game.Me.Id); setTeleportId.Invoke(myPortal.Id); var action = GetSorceressKillAction(client); if (!await KillBosses(client, csManager, null, client.Game.Me.Location, action, 0, () => 0)) { return(false); } return(true); }
private async Task <bool> KillLeftSeal(Client client, CSManager csManager, Action <uint> setTeleportId) { Log.Information($"Teleporting to {EntityCode.LeftSeal1}"); var pathToLeftSeal = await _pathingService.GetPathToObject(client.Game.MapId, Difficulty.Normal, Area.ChaosSanctuary, client.Game.Me.Location, EntityCode.LeftSeal1, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToLeftSeal, MovementMode.Teleport)) { Log.Warning($"Teleporting to {EntityCode.LeftSeal1} failed at location {client.Game.Me.Location}"); return(false); } var leftSeal1 = client.Game.GetEntityByCode(EntityCode.LeftSeal1).First(); var leftSeal2 = client.Game.GetEntityByCode(EntityCode.LeftSeal2).First(); var leftSealKillLocation = leftSeal1.Location.Y > leftSeal2.Location.Y ? leftSeal1.Location.Add(26, -21) : leftSeal1.Location.Add(20, 40); if (!await GeneralHelpers.TryWithTimeout(async(_) => { return(await client.Game.TeleportToLocationAsync(leftSealKillLocation)); }, TimeSpan.FromSeconds(5))) { return(false); } if (!_townManagementService.CreateTownPortal(client)) { return(false); } var myPortal = client.Game.GetEntityByCode(EntityCode.TownPortal).First(t => t.TownPortalOwnerId == client.Game.Me.Id); setTeleportId.Invoke(myPortal.Id); if (!await GeneralHelpers.TryWithTimeout(async(_) => { return(await client.Game.TeleportToLocationAsync(leftSeal1.Location)); }, TimeSpan.FromSeconds(5))) { return(false); } if (!GeneralHelpers.TryWithTimeout((_) => { client.Game.InteractWithEntity(leftSeal1); return(leftSeal1.State == EntityState.Enabled); }, TimeSpan.FromSeconds(5))) { return(false); } if (!await GeneralHelpers.TryWithTimeout(async(_) => { return(await client.Game.TeleportToLocationAsync(leftSeal2.Location)); }, TimeSpan.FromSeconds(5))) { return(false); } if (!GeneralHelpers.TryWithTimeout((_) => { client.Game.InteractWithEntity(leftSeal2); return(leftSeal2.State == EntityState.Enabled); }, TimeSpan.FromSeconds(5))) { return(false); } if (!await GeneralHelpers.TryWithTimeout(async(_) => { return(await client.Game.TeleportToLocationAsync(leftSealKillLocation)); }, TimeSpan.FromSeconds(5))) { return(false); } var action = GetSorceressKillAction(client); if (!await KillBosses(client, csManager, null, leftSealKillLocation, action, 0, () => 0)) { return(false); } return(true); }
private async Task <bool> KillTopSeal(Client client, CSManager csManager, Action <uint> setTeleportId) { Log.Information($"Teleporting to {EntityCode.TopSeal}"); var pathToTopSeal = await _pathingService.GetPathToObject(client.Game.MapId, Difficulty.Normal, Area.ChaosSanctuary, client.Game.Me.Location, EntityCode.TopSeal, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToTopSeal, MovementMode.Teleport)) { Log.Warning($"Teleporting to {EntityCode.TopSeal} failed at location {client.Game.Me.Location}"); return(false); } var topSeal = client.Game.GetEntityByCode(EntityCode.TopSeal).First(); var toLeftOfSealIsValid = await _pathingService.IsNavigatablePointInArea(client.Game.MapId, Difficulty.Normal, Area.ChaosSanctuary, topSeal.Location.Add(-20, 0)); var killLocation = toLeftOfSealIsValid ? topSeal.Location.Add(-37, 31) : topSeal.Location.Add(0, 70); var pathToKillingLocation = await _pathingService.GetPathToLocation(client.Game, killLocation, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToKillingLocation, MovementMode.Teleport)) { Log.Warning($"Teleporting to {pathToKillingLocation} failed at location {client.Game.Me.Location}"); return(false); } if (!_townManagementService.CreateTownPortal(client)) { return(false); } var myPortal = client.Game.GetEntityByCode(EntityCode.TownPortal).First(t => t.TownPortalOwnerId == client.Game.Me.Id); setTeleportId.Invoke(myPortal.Id); var pathToTopSeal2 = await _pathingService.GetPathToObject(client.Game.MapId, Difficulty.Normal, Area.ChaosSanctuary, client.Game.Me.Location, EntityCode.TopSeal, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToTopSeal2, MovementMode.Teleport)) { Log.Warning($"Teleporting to {pathToKillingLocation} failed at location {client.Game.Me.Location}"); return(false); } if (!await GeneralHelpers.TryWithTimeout(async(_) => { client.Game.InteractWithEntity(topSeal); await Task.Delay(100); return(client.Game.GetEntityByCode(EntityCode.TopSeal).First().State == EntityState.Enabled); }, TimeSpan.FromSeconds(5))) { Log.Warning($"Opening {EntityCode.TopSeal} failed at location {client.Game.Me.Location}"); return(false); } if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToKillingLocation, MovementMode.Teleport)) { Log.Warning($"Teleporting to {pathToKillingLocation} failed at location {client.Game.Me.Location}"); return(false); } var action = GetSorceressKillAction(client); if (!await KillBosses(client, csManager, null, killLocation, action, 0, () => 0)) { return(false); } return(true); }
private async Task <bool> TaxiCs(Client client, CSManager csManager, Action <uint> setTeleportId) { Log.Information($"Client {client.Game.Me.Name} Taking waypoint to {Waypoint.RiverOfFlame}"); if (!await _townManagementService.TakeWaypoint(client, Waypoint.RiverOfFlame)) { Log.Warning($"Client {client.Game.Me.Name} Teleporting failed at location {client.Game.Me.Location}"); return(false); } Log.Information($"Client {client.Game.Me.Name} Teleporting to {Area.ChaosSanctuary}"); var pathToChaos = await _pathingService.GetPathToObjectWithOffset(client.Game.MapId, Difficulty.Normal, Area.RiverOfFlame, client.Game.Me.Location, EntityCode.WaypointAct4Levels, -6, -319, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToChaos, MovementMode.Teleport)) { Log.Warning($"Client {client.Game.Me.Name} Teleporting to {Area.ChaosSanctuary} warp failed at location {client.Game.Me.Location}"); return(false); } var goalLocation = client.Game.Me.Location.Add(0, -30); if (!await GeneralHelpers.TryWithTimeout(async(_) => { return(await client.Game.TeleportToLocationAsync(goalLocation)); }, TimeSpan.FromSeconds(5))) { return(false); } var pathToDiabloStar = await _pathingService.GetPathToObject(client.Game.MapId, Difficulty.Normal, Area.ChaosSanctuary, client.Game.Me.Location, EntityCode.DiabloStar, MovementMode.Teleport); if (!await MovementHelpers.TakePathOfLocations(client.Game, pathToDiabloStar, MovementMode.Teleport)) { Log.Warning($"Client {client.Game.Me.Name} Teleporting to {EntityCode.DiabloStar} failed at location {client.Game.Me.Location}"); return(false); } if (!_townManagementService.CreateTownPortal(client)) { return(false); } var myPortal = client.Game.GetEntityByCode(EntityCode.TownPortal).First(t => t.TownPortalOwnerId == client.Game.Me.Id); setTeleportId.Invoke(myPortal.Id); csManager.ResetAliveMonsters(); if (!await WaitForBo(client)) { return(false); } csManager.ResetAliveMonsters(); setTeleportId.Invoke(0); if (!await KillLeftSeal(client, csManager, setTeleportId)) { return(false); } csManager.ResetAliveMonsters(); setTeleportId.Invoke(0); if (!await KillTopSeal(client, csManager, setTeleportId)) { return(false); } csManager.ResetAliveMonsters(); setTeleportId.Invoke(0); if (!await KillRightSeal(client, csManager, setTeleportId)) { return(false); } csManager.ResetAliveMonsters(); setTeleportId.Invoke(0); return(await KillDiablo(client, csManager, setTeleportId)); }
private async Task <bool> BaseCsBot(CSManager csManager, Func <uint> getTeleportId, CancellationTokenSource nextGameCancellation, Client client, Func <CSManager, List <AliveMonster>, List <AliveMonster>, Task> action) { var localTeleportId = 0U; while (!nextGameCancellation.IsCancellationRequested && client.Game.IsInGame()) { await Task.Delay(100); if (localTeleportId != getTeleportId() && !client.Game.IsInTown()) { Log.Information($"Client {client.Game.Me.Name} Taking town portal to town"); if (!await _townManagementService.TakeTownPortalToTown(client)) { continue; } } if (client.Game.IsInTown() && getTeleportId() != 0 && getTeleportId() != localTeleportId) { Log.Information($"Client {client.Game.Me.Name} taking town portal to chaos"); var teleportPlayer = client.Game.Players.First(p => p.Name.Equals(_csconfig.TeleportCharacterName, StringComparison.CurrentCultureIgnoreCase)); if (!await _townManagementService.TakeTownPortalToArea(client, teleportPlayer, Area.ChaosSanctuary)) { continue; } localTeleportId = getTeleportId(); } if (!client.Game.IsInTown()) { var anyPlayersWithoutShouts = ClassHelpers.AnyPlayerIsMissingShouts(client); if (anyPlayersWithoutShouts && client.Game.Me.Class == CharacterClass.Barbarian) { await ClassHelpers.CastAllShouts(client); } else if (ClassHelpers.IsMissingShouts(client.Game.Me)) { Log.Information($"Client {client.Game.Me.Name} waiting for bo"); await WaitForBo(client); } else { await Task.Delay(100); if (!await KillBosses(client, csManager, nextGameCancellation, client.Game.Me.Location, action, localTeleportId, getTeleportId)) { return(false); } } } } if (!nextGameCancellation.IsCancellationRequested && !client.Game.IsInGame()) { return(false); } 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; } }