private static Building GetLowestRes(Account acc, Village vill, List <Building> buildings) { //get distinct field types var distinct = buildings.Select(x => x.Type).Distinct().ToList(); long lowestRes = long.MaxValue; BuildingEnum toUpgrade = BuildingEnum.Cropland; var heroRes = vill.Settings.UseHeroRes ? HeroHelper.GetHeroResources(acc) : new long[] { 0, 0, 0, 0 }; var resSum = ResourcesHelper.SumArr(vill.Res.Stored.Resources.ToArray(), heroRes); foreach (var distinctType in distinct) { if (distinctType == BuildingEnum.Woodcutter && resSum[0] < lowestRes) { lowestRes = resSum[0]; toUpgrade = BuildingEnum.Woodcutter; } else if (distinctType == BuildingEnum.ClayPit && resSum[1] < lowestRes) { lowestRes = resSum[1]; toUpgrade = BuildingEnum.ClayPit; } else if (distinctType == BuildingEnum.IronMine && resSum[2] < lowestRes) { lowestRes = resSum[2]; toUpgrade = BuildingEnum.IronMine; } else if (distinctType == BuildingEnum.Cropland && resSum[3] < lowestRes) { lowestRes = resSum[3]; toUpgrade = BuildingEnum.Cropland; } } return(FindLowestLevelBuilding(buildings.Where(x => x.Type == toUpgrade).ToList())); }
/// <summary> /// If there are enough resources, return TimeSpan(0) /// Otherwise calculate how long it will take to get enough resources and transit res from /// main village, if we have that enabled. Return the one that takes less time. /// DateTime for usage in nextExecution time /// </summary> /// <param name="acc">Account</param> /// <param name="vill">(target) Village</param> /// <param name="requiredRes">Resources required</param> /// <param name="task">Bot task that doesn't have enough resources</param> /// <param name="buildingTask">Potential building task</param> /// <returns>When next village update should occur</returns> private static DateTime?NewUnfinishedTask(Account acc, Village vill, Resources requiredRes, BotTask task, BuildingTask buildingTask = null) { var stillNeededRes = SubtractResources(requiredRes.ToArray(), vill.Res.Stored.Resources.ToArray(), true); // Whether we have enough resources. This should already be checked before calling this method! if (IsZeroResources(stillNeededRes)) { ResSpendingHelper.AddUnfinishedTask(vill, task, requiredRes); return(DateTime.Now); } acc.Wb.Log($"Not enough resources for the task {task.GetName()}! Needed {requiredRes}. Bot will try finish the task later"); if (IsStorageTooLow(acc, vill, requiredRes)) { acc.Wb.Log($"Storage is too low."); ResSpendingHelper.AddUnfinishedTask(vill, task, requiredRes); return(null); } // Try to use hero resources first if (vill.Settings.UseHeroRes && acc.AccInfo.ServerVersion == ServerVersionEnum.T4_5) // Only T4.5 has resources in hero inv { var heroRes = HeroHelper.GetHeroResources(acc); // If we have some hero resources, we should use those first if (!IsZeroResources(heroRes)) { var heroEquipTask = UseHeroResources(acc, vill, ref stillNeededRes, heroRes, buildingTask); // If we have enough hero res for our task, execute the task // right after hero equip finishes if (IsZeroResources(SubtractResources(stillNeededRes, heroRes, true))) { heroEquipTask.NextTask = task; return(null); } } } ResSpendingHelper.AddUnfinishedTask(vill, task, requiredRes); // When will we have enough resources from production DateTime enoughRes = TimeHelper.EnoughResToUpgrade(vill, stillNeededRes); var mainVill = AccountHelper.GetMainVillage(acc); if (mainVill == vill) { return(enoughRes); } DateTime resTransit = MarketHelper.TransitResourcesFromMain(acc, vill); if (resTransit < enoughRes) { enoughRes = resTransit; } if (enoughRes < DateTime.Now) { return(DateTime.Now); } return(enoughRes); }