Пример #1
0
        public static long[] SendResCapToStorage(Account acc, Resources resources)
        {
            var mainVill = AccountHelper.GetMainVillage(acc);
            var stored   = mainVill.Res.Stored.Resources.ToArray();

            var resSend = resources.ToArray();

            long[] ret = new long[4];
            for (int i = 0; i < 4; i++)
            {
                ret[i] = stored[i] < resSend[i] ? stored[i] : resSend[i];
            }
            return(ret);
        }
Пример #2
0
        private static TimeSpan CalculateTransitTime(Account acc, Village vill1, Village vill2)
        {
            var mainVill = AccountHelper.GetMainVillage(acc);

            if (mainVill == null)
            {
                acc.Villages.First();
            }

            var distance = MapHelper.CalculateDistance(acc, vill1.Coordinates, vill2.Coordinates);
            //Speed is per hour
            var speed = GetMerchantsSpeed(acc.AccInfo.Tribe ?? Classificator.TribeEnum.Any);

            speed *= acc.AccInfo.ServerSpeed;

            var hours = distance / speed;

            return(TimeSpan.FromHours(hours));
        }
Пример #3
0
        /// <summary>
        /// Will send resources from main village to the target village
        /// </summary>
        /// <param name="vill">(target) Village to get the resources</param>
        /// <returns>Returns DateTime when approximately will resources get transited to target village </returns>
        public static DateTime TransitResourcesFromMain(Account acc, Village vill)
        {
            // Transit resources for this village is disabled.
            if (!vill.Market.Settings.Configuration.Enabled)
            {
                return(DateTime.MaxValue);
            }

            // There already is a sendResources BotTask for this village
            var transitTask = (SendResources)acc.Tasks.FirstOrDefault(x =>
                                                                      x.GetType() == typeof(SendResources) &&
                                                                      ((SendResources)x).Coordinates == vill.Coordinates
                                                                      );

            //vill.Market.Settings.Configuration.
            if (transitTask != null)
            {
                return(transitTask.Configuration.TransitArrival);
            }
            //Less than 5min ago we already sent resources. Just to catch bugs.
            //if(vill.Market.)

            // Merchants are on their way
            if (vill.Market.Settings.Configuration.TransitArrival > DateTime.Now)
            {
                return(vill.Market.Settings.Configuration.TransitArrival);
            }

            //send resources
            var sendRes    = new Resources();
            var conf       = vill.Market.Settings.Configuration;
            var currentRes = vill.Res.Stored.Resources;
            var cap        = vill.Res.Capacity;

            var woodNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Wood / 100.0);

            sendRes.Wood = (woodNeeded > conf.FillLimit.Wood ? conf.FillLimit.Wood : woodNeeded) - currentRes.Wood;
            sendRes.Wood = (sendRes.Wood < 0 ? 0 : sendRes.Wood);

            var clayNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Clay / 100.0);

            sendRes.Clay = (clayNeeded > conf.FillLimit.Clay ? conf.FillLimit.Clay : clayNeeded) - currentRes.Clay;
            sendRes.Clay = (sendRes.Clay < 0 ? 0 : sendRes.Clay);

            var ironNeeded = (long)(cap.WarehouseCapacity * conf.TargetLimit.Iron / 100.0);

            sendRes.Iron = (ironNeeded > conf.FillLimit.Iron ? conf.FillLimit.Iron : ironNeeded) - currentRes.Iron;
            sendRes.Iron = (sendRes.Iron < 0 ? 0 : sendRes.Iron);

            var cropNeeded = (long)(cap.GranaryCapacity * conf.TargetLimit.Crop / 100.0);

            sendRes.Crop = (cropNeeded > conf.FillLimit.Crop ? conf.FillLimit.Crop : cropNeeded) - currentRes.Crop;
            sendRes.Crop = (sendRes.Crop < 0 ? 0 : sendRes.Crop);

            if (ResourcesHelper.IsZeroResources(sendRes)) //we have enough res :)
            {
                return(DateTime.MinValue);
            }

            // Send resources to a village only once per 5 minutes
            TimeSpan transitAfter = vill.Market.LastTransit.AddMinutes(5) - DateTime.Now;

            if (transitAfter < TimeSpan.Zero)
            {
                transitAfter = TimeSpan.Zero;
            }

            var sendResTask = new SendResources
            {
                Configuration = conf,
                Coordinates   = vill.Coordinates,
                ExecuteAt     = DateTime.Now + transitAfter,
                Vill          = AccountHelper.GetMainVillage(acc),
                Resources     = sendRes
            };


            TaskExecutor.AddTask(acc, sendResTask);

            //AddMinutes(1) since bot has to wait for the SendResources task and then
            //go to the marketplace and send resources
            //TransitArrival will get updated to more specific time

            return(DateTime.Now.Add(transitAfter + CalculateTransitTimeMainVillage(acc, vill)).AddMinutes(1));
        }
Пример #4
0
 /// <summary>
 /// Calculates the time it takes for resources to be transited from main village (supplying village) to target village
 /// </summary>
 /// <param name="acc">Account</param>
 /// <param name="targetVillage">Target village to receive the resources</param>
 /// <returns></returns>
 private static TimeSpan CalculateTransitTimeMainVillage(Account acc, Village targetVillage)
 {
     return(CalculateTransitTime(acc, targetVillage, AccountHelper.GetMainVillage(acc)));
 }
Пример #5
0
        /// <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);
        }