/// <summary>
        /// Calculates how many resources should be sent to the main village based on configurable limit
        /// </summary>
        /// <param name="vill">Village</param>
        /// <returns>Resources to be sent</returns>
        public static long[] GetResToMainVillage(Village vill)
        {
            var ret   = new long[4];
            var res   = ResourcesHelper.ResourcesToArray(vill.Res.Stored.Resources);
            var limit = ResourcesHelper.ResourcesToArray(vill.Market.Settings.Configuration.SendResLimit);

            for (int i = 0; i < 4; i++)
            {
                // % into resource mode
                if (limit[i] < 100)
                {
                    var capacity = i == 3 ? vill.Res.Capacity.GranaryCapacity : vill.Res.Capacity.WarehouseCapacity;
                    limit[i] = (long)(limit[i] / 100.0 * capacity);
                }

                ret[i] = res[i] - limit[i];
                if (ret[i] < 0)
                {
                    ret[i] = 0;
                }
            }
            return(ret);
        }
        /// <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));
        }
Exemple #3
0
 public static void NotEnoughRes(Account acc, Village vill, long[] requiredRes, BotTask task, BuildingTask buildingTask = null) =>
 NotEnoughRes(acc, vill, ResourcesHelper.ArrayToResources(requiredRes), task, buildingTask);
        /// <summary>
        /// Used by BotTasks to insert resources/coordinates into the page.
        /// </summary>
        /// <param name="acc">Account</param>
        /// <param name="resources">Target resources</param>
        /// <param name="coordinates">Target coordinates</param>
        /// <returns>Time it will take for transit to complete</returns>
        public static async Task <TimeSpan?> MarketSendResource(Account acc, Resources resources, Village targetVillage, BotTask botTask)
        {
            var res = ResourcesHelper.ResourcesToArray(resources);

            return(await MarketSendResource(acc, res, targetVillage, botTask));
        }