//private static long GetNextDefender(Google.Protobuf.Collections.RepeatedField<BattleAction> battleActions) //{ // foreach (var element in battleActions) // if (element.BattleResults != null) // if (element.BattleResults.NextDefenderPokemonId != -1) // return element.BattleResults.NextDefenderPokemonId; // return -1L; //} private static GymStartSessionResponse GymBattleStartSession(Client client, FortData gym, ulong defenderId, IEnumerable <ulong> attackersIDs) { // Sometimes we get a null from startgymBattle so we try to start battle 3 times var numTries = 3; GymStartSessionResponse gymStartSessionResponse = null; do { try { gymStartSessionResponse = client.Fort.GymStartSession(gym.Id, defenderId, attackersIDs).Result; } catch (Exception ex) { Logger.ExceptionInfo("Exception [gymStartSession]:" + ex.Message); return(null); } switch (gymStartSessionResponse.Result) { case GymStartSessionResponse.Types.Result.Unset: Logger.Info("(Gym) Failed with error UNSET"); break; case GymStartSessionResponse.Types.Result.Success: return(gymStartSessionResponse); case GymStartSessionResponse.Types.Result.ErrorGymNotFound: Logger.Info("(Gym) Failed with error ERROR_GYM_NOT_FOUND"); break; case GymStartSessionResponse.Types.Result.ErrorGymNeutral: Logger.Info("(Gym) Failed with error ERROR_GYM_NEUTRAL"); break; case GymStartSessionResponse.Types.Result.ErrorGymWrongTeam: Logger.Info("(Gym) Failed with error ERROR_GYM_WRONG_TEAM"); break; case GymStartSessionResponse.Types.Result.ErrorGymEmpty: Logger.Info("(Gym) Failed with error ERROR_GYM_EMPTY"); // Call to DeployPokemon break; case GymStartSessionResponse.Types.Result.ErrorInvalidDefender: Logger.Info("(Gym) Failed with error ERROR_INVALID_DEFENDER"); break; case GymStartSessionResponse.Types.Result.ErrorTrainingInvalidAttackerCount: Logger.Info("(Gym) Failed with error ERROR_TRAINING_INVALID_ATTACKER_COUNT"); break; case GymStartSessionResponse.Types.Result.ErrorAllPokemonFainted: Logger.Info("(Gym) Failed with error ERROR_ALL_POKEMON_FAINTED"); break; case GymStartSessionResponse.Types.Result.ErrorTooManyBattles: Logger.Info("(Gym) Failed with error ERROR_TOO_MANY_BATTLES"); // Set to try later break; case GymStartSessionResponse.Types.Result.ErrorTooManyPlayers: Logger.Info("(Gym) Failed with error ERROR_TOO_MANY_PLAYERS"); break; case GymStartSessionResponse.Types.Result.ErrorGymBattleLockout: Logger.Info("(Gym) Failed with error ERROR_GYM_BATTLE_LOCKOUT"); break; case GymStartSessionResponse.Types.Result.ErrorPlayerBelowMinimumLevel: Logger.Info("(Gym) Failed with error ERROR_PLAYER_BELOW_MINIMUM_LEVEL"); break; case GymStartSessionResponse.Types.Result.ErrorNotInRange: Logger.Info("(Gym) Failed with error ERROR_NOT_IN_RANGE"); break; case GymStartSessionResponse.Types.Result.ErrorPoiInaccessible: Logger.Info("(Gym) Failed with error ERROR_POI_INACCESSIBLE"); break; case GymStartSessionResponse.Types.Result.ErrorRaidActive: Logger.Info("(Gym) Failed with error ERROR_RAID_ACTIVE"); // Go to Battle Raid break; } Logger.Info("(Gym) Start Gym Failed (" + numTries + "): " + gymStartSessionResponse.Result); numTries--; } while (numTries > 0 && gymStartSessionResponse != null); return(gymStartSessionResponse); }
private static BattleState AttackDefender(GymStartSessionResponse gymBattleStartResponse, Client client, FortData gym) { PokemonData Attacker = gymBattleStartResponse.Battle.Attacker?.ActivePokemon.PokemonData; PokemonData Defender = gymBattleStartResponse.Battle.Defender?.ActivePokemon.PokemonData; if (Attacker == null || Defender == null) { Logger.Info("(Gym) Attacker or defender is NULL!!"); return(BattleState.StateUnset); } Int64 battleStartMs = gymBattleStartResponse.Battle.BattleLog.BattleStartTimestampMs; IEnumerable <BattleAction> lastActions = gymBattleStartResponse.Battle.BattleLog.BattleActions.ToList(); BattleAction lastAction = new BattleAction(); IEnumerable <DownloadItemTemplatesResponse.Types.ItemTemplate> moveSettings = client.Download.GetItemTemplates().ItemTemplates.Where(x => x.MoveSettings != null); Logger.ColoredConsoleWrite(gymColorLog, $"(Gym) Battle against {gymBattleStartResponse.Battle.Defender.ActivePokemon.PokemonData.PokemonId}" + $" | CP: {gymBattleStartResponse.Battle.Defender.ActivePokemon.PokemonData.Cp}"); int AttackerEnergy = 0; int DefenderEnergy = 0; while (true) { lastAction = lastActions.LastOrDefault(); var AttackerMove1Settings = moveSettings.FirstOrDefault(x => x.MoveSettings.MovementId == gymBattleStartResponse.Battle.Attacker.ActivePokemon.PokemonData.Move1).MoveSettings; var AttackerMove2Settings = moveSettings.FirstOrDefault(x => x.MoveSettings.MovementId == gymBattleStartResponse.Battle.Attacker.ActivePokemon.PokemonData.Move2).MoveSettings; List <BattleAction> battleActions = new List <BattleAction>(); BattleAction battleAction = new BattleAction(); battleAction.ActionStartMs = DateTime.UtcNow.ToUnixTime(); //battleStartMs + RandomNumbers.Next(110, 170); battleAction.TargetIndex = -1; // What is that? battleAction.ActivePokemonId = Attacker.Id; battleAction.TargetPokemonId = Defender.Id; // Selection of attacks // two each ten times we try to evade attack if (RandomNumbers.Next(1, 10) <= 2 || DefenderEnergy == 100) { var dodgeAction = new BattleAction(); dodgeAction.Type = BattleActionType.ActionDodge; dodgeAction.ActionStartMs = battleAction.ActionStartMs; dodgeAction.DurationMs = 500; //dodgeAction.EnergyDelta = ?? dodgeAction.TargetIndex = battleAction.TargetIndex; dodgeAction.TargetPokemonId = battleAction.TargetPokemonId; dodgeAction.ActivePokemonId = battleAction.ActivePokemonId; battleActions.Add(dodgeAction); Logger.Debug("Dodge Action Added"); battleAction.ActionStartMs = dodgeAction.ActionStartMs + dodgeAction.DurationMs; } if (AttackerEnergy >= Math.Abs(AttackerMove2Settings.EnergyDelta)) { var specialAttack = new BattleAction(); specialAttack.Type = BattleActionType.ActionSpecialAttack; specialAttack.ActionStartMs = battleAction.ActionStartMs; specialAttack.DurationMs = AttackerMove2Settings.DurationMs; specialAttack.EnergyDelta = AttackerMove2Settings.EnergyDelta; specialAttack.TargetIndex = battleAction.TargetIndex; specialAttack.TargetPokemonId = battleAction.TargetPokemonId; specialAttack.ActivePokemonId = battleAction.ActivePokemonId; specialAttack.DamageWindowsStartTimestampMs = specialAttack.ActionStartMs + AttackerMove2Settings.DamageWindowStartMs; specialAttack.DamageWindowsEndTimestampMs = specialAttack.ActionStartMs + AttackerMove2Settings.DamageWindowEndMs; battleActions.Add(specialAttack); Logger.Debug("Special Attack Added"); battleAction.ActionStartMs = specialAttack.ActionStartMs + specialAttack.DurationMs; } else { // One each nine times we do not attack if (RandomNumbers.Next(1, 9) != 1) { var normalAttack = new BattleAction(); normalAttack.Type = BattleActionType.ActionAttack; normalAttack.ActionStartMs = battleAction.ActionStartMs; normalAttack.TargetIndex = battleAction.TargetIndex; normalAttack.TargetPokemonId = battleAction.TargetPokemonId; normalAttack.ActivePokemonId = battleAction.ActivePokemonId; normalAttack.DurationMs = battleAction.DurationMs; normalAttack.DamageWindowsStartTimestampMs = normalAttack.ActionStartMs + AttackerMove1Settings.DamageWindowStartMs; normalAttack.DamageWindowsEndTimestampMs = normalAttack.ActionStartMs + AttackerMove1Settings.DamageWindowEndMs; normalAttack.EnergyDelta = AttackerMove1Settings.EnergyDelta; battleActions.Add(normalAttack); Logger.Debug("Normal Attack Added"); battleAction.ActionStartMs = normalAttack.ActionStartMs + normalAttack.DurationMs; } } long TimeBeforeAttack = DateTime.UtcNow.ToUnixTime(); GymBattleAttackResponse attackResponse = client.Fort.GymBattleAttack(gym.Id, gymBattleStartResponse.Battle.BattleId, battleActions, lastAction, battleStartMs); long TimeAfterAttack = DateTime.UtcNow.ToUnixTime(); var AttackDuration = battleActions.Sum(x => x.DurationMs); //if (battleActions.Any(a => a.Type != BattleActionType.ActionSpecialAttack)) AttackDuration = AttackDuration - (int)(TimeAfterAttack - TimeBeforeAttack); //if (battleActions.Any(a => a.Type == BattleActionType.ActionSwapPokemon)) AttackDuration = AttackDuration + 2000; if (AttackDuration > 0) { RandomHelper.RandomSleep(AttackDuration); } if (attackResponse.Result == GymBattleAttackResponse.Types.Result.Success) { if (attackResponse.BattleUpdate.BattleLog != null && attackResponse.BattleUpdate.BattleLog.BattleActions.Count > 0) { lastActions = attackResponse.BattleUpdate.BattleLog.BattleActions.OrderBy(o => o.ActionStartMs).Distinct(); } battleStartMs = attackResponse.BattleUpdate.BattleLog.ServerMs; switch (attackResponse.BattleUpdate.BattleLog.State) { case BattleState.Active: if (attackResponse.BattleUpdate.ActiveAttacker != null && attackResponse.BattleUpdate.ActiveDefender != null) { AttackerEnergy = attackResponse.BattleUpdate.ActiveAttacker.CurrentEnergy; var AttackerHealth = attackResponse.BattleUpdate.ActiveAttacker.CurrentHealth; var ActiveAttacker = attackResponse.BattleUpdate.ActiveAttacker.PokemonData.PokemonId; DefenderEnergy = attackResponse.BattleUpdate.ActiveDefender.CurrentEnergy; var DefenderHealth = attackResponse.BattleUpdate.ActiveDefender.CurrentHealth; var ActiveDefender = attackResponse.BattleUpdate.ActiveDefender.PokemonData.PokemonId; Defender = attackResponse.BattleUpdate.ActiveDefender?.PokemonData; Attacker = attackResponse.BattleUpdate.ActiveAttacker?.PokemonData; Logger.Info($"(Gym) - Attacker: {ActiveAttacker.ToString().PadLeft(15)}|E={AttackerEnergy.ToString().PadLeft(5)}|H={AttackerHealth.ToString().PadLeft(5)} " + $"vs. Defender: {ActiveDefender.ToString().PadLeft(15)}|E={DefenderEnergy.ToString().PadLeft(5)}|H={DefenderHealth.ToString().PadLeft(5)}"); if (true) { //Logger.Info($"(Gym) Battle timing. battleStartMs {battleStartMs} | TimeBefore {TimeBeforeAttack} | TimeAfter {TimeAfterAttack} | Duration {AttackDuration}"); foreach (BattleAction ba in battleActions) { Logger.Info($"(Gym) Action -> {ba.ActionStartMs}|{ba.DurationMs.ToString().PadLeft(4)}|{ba.Type}|{ba.DamageWindowsStartTimestampMs}|{ba.DamageWindowsEndTimestampMs}"); } } } break; case BattleState.Defeated: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - We have lost"); return(BattleState.Defeated); case BattleState.Victory: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Defender " + Defender.PokemonId + " defeated."); foreach (var element in attackResponse.BattleUpdate.BattleLog.BattleActions) { if (element.BattleResults != null) { Logger.Info("(Gym) - Gym points: " + element.BattleResults.GymPointsDelta); Logger.Info("(Gym) - Experience Awarded: " + element.BattleResults.PlayerXpAwarded); Logger.Debug("(Gym) - Next Pokemon: " + element.BattleResults.NextDefenderPokemonId); } } return(BattleState.Victory); case BattleState.TimedOut: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Timed Out"); return(BattleState.TimedOut); case BattleState.StateUnset: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Status UNSET"); return(BattleState.StateUnset); } } else { switch (attackResponse.Result) { case GymBattleAttackResponse.Types.Result.ErrorInvalidAttackActions: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Attack - ERROR_INVALID_ATTACK_ACTIONS"); Logger.ColoredConsoleWrite(gymColorLog, "(Gym) BattleActions: " + string.Join(", ", (IEnumerable <BattleAction>)battleActions.ToArray())); break; case GymBattleAttackResponse.Types.Result.ErrorNotInRange: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Attack - ERROR_NOT_IN_RANGE"); return(BattleState.StateUnset); case GymBattleAttackResponse.Types.Result.ErrorRaidActive: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Attack - ERROR_RAID_ACTIVE"); return(BattleState.StateUnset); case GymBattleAttackResponse.Types.Result.ErrorWrongBattleType: Logger.ColoredConsoleWrite(gymColorLog, "(Gym) - Attack - ERROR_WRONG_BATTLE_TYPE"); return(BattleState.StateUnset); } //return BattleState.StateUnset; } } }
public static BattleState AttackGym(FortData gym, Client client) { GymsLogic.StopAttack = false; GymGetInfoResponse gymGetInfoResponse = null; GymStartSessionResponse gymStartSessionResponse = null; gymGetInfoResponse = client.Fort.GymGetInfo(gym.Id, gym.Latitude, gym.Longitude); // Get defenders info int currentDefender = 0; var defenders = gymGetInfoResponse.GymStatusAndDefenders.GymDefender.Select(x => x.MotivatedPokemon.Pokemon).ToList(); var defender = gymGetInfoResponse.GymStatusAndDefenders.GymDefender[currentDefender]; for (int i = 0; i < defenders.Count(); i++) { Logger.Debug($"(Gym) Defender {i + 1}: {gymGetInfoResponse.GymStatusAndDefenders.GymDefender[i].MotivatedPokemon.Pokemon.PokemonId}" + $" | CpNow: {gymGetInfoResponse.GymStatusAndDefenders.GymDefender[i].MotivatedPokemon.CpNow}" + $" | MotivationNow: {gymGetInfoResponse.GymStatusAndDefenders.GymDefender[i].MotivatedPokemon.MotivationNow}" + $" | Id: {gymGetInfoResponse.GymStatusAndDefenders.GymDefender[i].MotivatedPokemon.Pokemon.Id}"); } // Get atackers IEnumerable <PokemonData> selectedAttackers = getPokeAttackers(defender.MotivatedPokemon.Pokemon, GlobalVars.Gyms.Attackers); var pokeAttackers = selectedAttackers as PokemonData[] ?? selectedAttackers.ToArray(); var pokeAttackersIds = selectedAttackers.Select(x => x.Id); if (selectedAttackers.Count() < 6) { Logger.ColoredConsoleWrite(gymColorLog, "(Gym) Not enougth pokemons to fight."); return(BattleState.StateUnset); } Logger.ColoredConsoleWrite(gymColorLog, "(Gym) Defender: " + GymsLogic.strPokemon(defender.MotivatedPokemon.Pokemon) + $" [{defender.TrainerPublicProfile.Name} ({defender.TrainerPublicProfile.Level})]"); GymsLogic.ShowPokemons(selectedAttackers); while (currentDefender < defenders.Count()) { try { // Initialization of attach agains a defender gymStartSessionResponse = GymBattleStartSession(client, gym, defenders[currentDefender].Id, pokeAttackersIds); } catch (Exception ex) { Logger.ExceptionInfo($"Can't start battle against defender {currentDefender}: " + ex.Message); break; } if (gymStartSessionResponse == null || gymStartSessionResponse.Battle == null || gymStartSessionResponse.Result != GymStartSessionResponse.Types.Result.Success) { return(BattleState.StateUnset); } // Battle loop if (gymStartSessionResponse.Battle.BattleLog.State == BattleState.Active) { //Logger.ColoredConsoleWrite(gymColorLog, "(Gym) Battle Started"); RandomHelper.RandomSleep(2000); // Attack each defender BattleState attackDefender = AttackDefender(gymStartSessionResponse, client, gym); if (attackDefender == BattleState.Victory) { currentDefender++; } else { return(attackDefender); } } } return(BattleState.Victory); }