Пример #1
0
        private static (string, bool) GetUrlGeneralTask(Village vill, BuildingTask task)
        {
            // Check if there is already a different building in this spot (not Site)
            if (task.BuildingId == null ||
                (vill.Build.Buildings.First(x => x.Id == task.BuildingId).Type != task.Building &&
                 vill.Build.Buildings.First(x => x.Id == task.BuildingId).Type != BuildingEnum.Site))
            {
                var targetBuilding = vill.Build.Buildings.FirstOrDefault(x => x.Type == task.Building);
                // Re-select the buildingId
                if (targetBuilding != null && !task.ConstructNew)
                {
                    task.BuildingId = targetBuilding.Id;
                }
                else // there's already a building in this spot, construct a building elsewhere
                {
                    if (!BuildingHelper.FindBuildingId(vill, task))
                    {
                        return(null, false);
                    }
                }
            }

            var url = task.BuildingId.ToString();

            bool constructNew = false;

            // If there is no building in that space currently, construct a new building
            if (vill.Build.Buildings.Any(x => x.Type == BuildingEnum.Site && x.Id == task.BuildingId))
            {
                url         += "&category=" + (int)BuildingsData.GetBuildingsCategory(task.Building);
                constructNew = true;
            }
            return(url, constructNew);
        }
Пример #2
0
    public void Start()
    {
        Building      building = GetComponent <Building>();
        BuildingsData data     = DataManager.BuildingData.dataArray[dataIndex];

        buildMode.BuildAtStart(building, data, coordinates);
    }
    public override bool Load()
    {
        Buildings targetData = target as Buildings;

        var    client = new DatabaseClient("", "");
        string error  = string.Empty;
        var    db     = client.GetDatabase(targetData.SheetName, ref error);
        var    table  = db.GetTable <BuildingsData>(targetData.WorksheetName) ?? db.CreateTable <BuildingsData>(targetData.WorksheetName);

        List <BuildingsData> myDataList = new List <BuildingsData>();

        var all = table.FindAll();

        foreach (var elem in all)
        {
            BuildingsData data = new BuildingsData();

            data = Cloner.DeepCopy <BuildingsData>(elem.Element);
            myDataList.Add(data);
        }

        targetData.dataArray = myDataList.ToArray();

        EditorUtility.SetDirty(targetData);
        AssetDatabase.SaveAssets();

        return(true);
    }
Пример #4
0
        private void InstantiateNewBuildingCostsPopup(BuildingBase building, BuildingsData data)
        {
            ProductionEffectPopup popup = Instantiate(effect, building.tilesStandingOn[0, 0].transform.position, effect.transform.rotation, transform);

            popup.transform.localRotation = effect.transform.rotation;
            popup.Init(building, data);
        }
Пример #5
0
        private BuildingsData GetDataWithoutEnergyResource(BuildingsData data)
        {
            BuildingsData dataWithoutEnergy = data.Clone() as BuildingsData;
            List <int>    input             = new List <int>();
            List <int>    inputAmount       = new List <int>();

            for (int i = 0; i < data.Resourceinput.Length; i++)
            {
                if (data.Resourceinput[i] != 0)
                {
                    input.Add(data.Resourceinput[i]);
                    inputAmount.Add(data.Resourceinputamount[i]);
                }
            }
            dataWithoutEnergy.Resourceinput       = input.ToArray();
            dataWithoutEnergy.Resourceinputamount = inputAmount.ToArray();

            List <int> output       = new List <int>();
            List <int> outputAmount = new List <int>();

            for (int i = 0; i < data.Resourceoutput.Length; i++)
            {
                if (data.Resourceoutput[i] != 0)
                {
                    output.Add(data.Resourceoutput[i]);
                    outputAmount.Add(data.Resourceoutputamount[i]);
                }
            }
            dataWithoutEnergy.Resourceoutput       = output.ToArray();
            dataWithoutEnergy.Resourceoutputamount = outputAmount.ToArray();
            return(dataWithoutEnergy);
        }
Пример #6
0
        public async Task <bool> TTWarsTryFastUpgrade(Account acc, string url)
        {
            var building = Vill.Build.Buildings.FirstOrDefault(x => x.Id == this.Task.BuildingId);
            var lvl      = building.Level;

            if (building.UnderConstruction)
            {
                lvl++;
            }

            var neededRes = BuildingsData.GetBuildingCost(building.Type, lvl + 1);

            if (ResourcesHelper.IsEnoughRes(Vill, neededRes) &&
                lvl != 0 &&
                lvl < Task.Level)
            {
                await acc.Wb.Navigate(url + "&fastUP=1");

                CheckIfTaskFinished(++lvl);

                acc.Wb.Log($"Started (fast) upgrading {building.Type} to level {lvl} in {this.Vill?.Name}");

                await PostTaskCheckDorf(acc);

                ConfigNextExecute(acc);
                return(true);
            }

            return(false);
        }
Пример #7
0
        /// <summary>
        /// Upgrades specified building for exactly one level. Will upgrade the lowest level building.
        /// </summary>
        /// <param name="acc">Account</param>
        /// <param name="vill">Village</param>
        /// <param name="building">Building to be upgraded by one</param>
        /// <param name="bottom">Whether to insert the building task on the bottom of the build list</param>
        /// <returns>Whether the method executed successfully</returns>
        internal static bool UpgradeBuildingForOneLvl(Account acc, Village vill, BuildingEnum building, bool bottom = true)
        {
            // We already have a build task
            if (!bottom && vill.Build.Tasks.FirstOrDefault()?.Building == building)
            {
                return(true);
            }
            if (bottom && vill.Build.Tasks.LastOrDefault()?.Building == building)
            {
                return(true);
            }

            var upgrade = vill.Build
                          .Buildings
                          .OrderBy(x => x.Level)
                          .FirstOrDefault(x => x.Type == building);

            // We don't have this building in the village yet
            if (upgrade == null)
            {
                return(AddBuildingTask(acc, vill, new BuildingTask()
                {
                    TaskType = BuildingType.General,
                    Building = building,
                    Level = 1,
                }, bottom));
            }

            var currentLvl = (int)upgrade.Level;

            RemoveFinishedCB(vill);
            currentLvl += vill.Build.CurrentlyBuilding.Count(x => x.Building == building);

            if (BuildingsData.MaxBuildingLevel(acc, building) == currentLvl)
            {
                // Building is on max level, construct new building if possible
                if (!BuildingsData.CanHaveMultipleBuildings(building))
                {
                    return(false);
                }

                return(AddBuildingTask(acc, vill, new BuildingTask()
                {
                    TaskType = BuildingType.General,
                    Building = building,
                    Level = 1,
                }, bottom));
            }
            else // Upgrade the defined building
            {
                return(AddBuildingTask(acc, vill, new BuildingTask()
                {
                    TaskType = BuildingType.General,
                    Building = building,
                    Level = currentLvl + 1,
                    BuildingId = upgrade.Id
                }, bottom));
            }
        }
Пример #8
0
 private void AddBuilding(BuildingBase building, BuildingsData data)
 {
     buildings.Add(building);
     if (OnBuildingListChanged != null)
     {
         OnBuildingListChanged();
     }
 }
 public void Init(BuildingBase building, BuildingsData data)
 {
     transform.position = new Vector3(building.transform.position.x, building.tilesStandingOn[0, 0].transform.position.y + spawnHeight, building.transform.position.z);
     transform.SetAsFirstSibling();
     CreatePopupItems(data);
     StartCoroutine(Move());
     StartCoroutine(WaitForFade());
 }
Пример #10
0
 private void InstantiateNewInputPopup(Building building, BuildingsData data)
 {
     if (data.Moneyinput > 0 || data.Resourceinput.Length > 0)
     {
         ProductionEffectPopup popup = Instantiate(effect, building.transform.position, effect.transform.rotation, transform);
         popup.transform.localRotation = effect.transform.rotation;
         popup.InitInputCost(building, data);
     }
 }
        public void InitInputCost(Building building, BuildingsData data)
        {
            float horizontalOffset = 1;

            transform.position = new Vector3(building.transform.position.x + horizontalOffset, building.tilesStandingOn[0, 0].transform.position.y + spawnHeight, building.transform.position.z);
            transform.SetAsFirstSibling();
            CreateInputPopupItems(data);
            StartCoroutine(Move());
            StartCoroutine(WaitForFade());
        }
Пример #12
0
    public void Initialize(GameSystem gameSystem, BuildingsData data)
    {
        _gameSystem = gameSystem;
        _data       = data;

        Type = data.Type;

        Setup(_data.Data[Level]);

        StartCoroutine(nameof(ShootEnemy));
    }
        private void CreateInputPopupItems(BuildingsData data)
        {
            if (data.Moneyinput != 0)
            {
                InstantiateNewPopupItem(DataManager.ResourcePrefabs.MoneySprite, -data.Moneyinput);
            }

            for (int i = 0; i < data.Resourceinput.Length; i++)
            {
                GameResourcesData resource = DataManager.ResourcesData.dataArray[data.Resourceinput[i]];
                InstantiateNewPopupItem(DataManager.ResourcePrefabs.GetResourceSprite(resource.ID), -data.Resourceinputamount[i]);
            }
        }
Пример #14
0
        public override void Init(System.Object data, Tile[,] tilesStandingOn)
        {
            this.data            = data as BuildingsData;
            this.tilesStandingOn = tilesStandingOn;
            StartCoroutine(WaitForNewProductionStart());

            foreach (Tile t in tilesStandingOn)
            {
                t.OnWaterStateChanged += CheckWaterState;
            }

            initialized = true;
        }
Пример #15
0
 private Building[] InitializeArray(int length, Account acc)
 {
     Building[] array = new Building[length];
     for (int i = 0; i < length; ++i)
     {
         var building = new Building();
         building.Init(i + 1, 0, 0, false);
         array[i] = building;
     }
     array[39].Type = BuildingsData.GetTribesWall(acc.AccInfo.Tribe);
     array[38].Type = Classificator.BuildingEnum.RallyPoint;
     return(array);
 }
        public static List <Building> GetBuildings(Account acc, HtmlAgilityPack.HtmlDocument htmlDoc)
        {
            List <Building> buildings = new List <Building>();
            var             villMap   = htmlDoc.GetElementbyId("village_map");

            if (villMap == null)
            {
                return(buildings);
            }

            var fields = villMap.ChildNodes.Where(x => x.Name == "div").ToList();

            for (byte i = 0; i < fields.Count; i++)
            {
                var vals = fields[i].GetAttributeValue("class", "").Split(' ');

                var location = (int)Parser.RemoveNonNumeric(vals.FirstOrDefault(x => x.StartsWith("a")));
                if (location <= 18 || location > 40)
                {
                    continue;
                }

                var gid = Convert.ToByte(vals.FirstOrDefault(x => x.StartsWith("g")).Replace("g", ""));

                byte lvl;
                // TODO: aid
                var lvlNode = fields[i].Descendants().FirstOrDefault(x => x.HasClass("aid" + location));
                if (lvlNode == null)
                {
                    lvl = 0;
                }
                else
                {
                    lvl = Convert.ToByte(lvlNode.InnerText);
                }

                var uc = fields[i].Descendants().FirstOrDefault(x => x.HasClass("underConstruction")) != null;
                //var b = fields[i].Child
                var building = new Building();
                buildings.Add(building.Init(
                                  location,
                                  lvl,//Convert.ToByte(vals[4].Replace("level", "")),
                                  gid,
                                  uc
                                  ));
            }
            buildings.FirstOrDefault(x => x.Id == 39).Type = Classificator.BuildingEnum.RallyPoint;
            buildings.FirstOrDefault(x => x.Id == 40).Type = BuildingsData.GetTribesWall(acc.AccInfo.Tribe);
            return(buildings);
        }
    private BuildingsData LoadBuildingsData()
    {
        BuildingsData buildingData = serializer.Deserialize <BuildingsData>($"{Application.dataPath}/Files/buildings.json");

        Assert.IsNotNull(buildingData);

        foreach (var building in buildingData)
        {
            Assert.IsFalse(string.IsNullOrEmpty(building.Id));
            Assert.IsNotNull(building.Cost);
        }

        return(buildingData);
    }
Пример #18
0
 private void FillGridBuildingData()
 {
     contentGrid.RemoveChildren();
     contentWidget.gameObject.SetActive(true);
     for (int i = 0; i < DataManager.BuildingData.dataArray.Length; i++)
     {
         BuildingsData data = DataManager.BuildingData.dataArray[i];
         if (data.BuildingType == buildingType)
         {
             bool correctClimate = (data.Climate == Climate.None || data.Climate == Player.LocalPlayer.ClimateType);
             Instantiate(itemPrefab, contentGrid).Init(i, buildings, data, correctClimate, buildMode);
         }
     }
 }
Пример #19
0
        /// <summary>
        /// Finds appropriate building space/site for the building
        /// </summary>
        /// <param name="vill">Village</param>
        /// <param name="task">Building task</param>
        /// <returns>True if successful</returns>
        public static bool FindBuildingId(Village vill, BuildingTask task)
        {
            //auto field upgrade/demolish task, no need for Id
            if (task.TaskType == BuildingType.AutoUpgradeResFields)
            {
                return(true);
            }

            var existingBuilding = vill.Build.Buildings
                                   .FirstOrDefault(x => x.Type == task.Building);

            // Only special buildings (warehouse, cranny, granary etc.) can have multiple
            // buildings of it's type and use ConstructNew option
            if (!BuildingsData.CanHaveMultipleBuildings(task.Building))
            {
                task.ConstructNew = false;
            }

            if (existingBuilding != null && !task.ConstructNew)
            {
                task.BuildingId = existingBuilding.Id;
                return(true);
            }

            var ExistingBuildingTask = vill.Build.Tasks
                                       .FirstOrDefault(x => x.Building == task.Building && x.BuildingId != null);

            if (ExistingBuildingTask != null && !task.ConstructNew)
            {
                task.BuildingId = ExistingBuildingTask.BuildingId;
                return(true);
            }

            var FreeSites = vill.Build.Buildings
                            .Where(x => x.Type == BuildingEnum.Site && 19 <= x.Id && x.Id <= 39)
                            .OrderBy(a => Guid.NewGuid()) // Shuffle the free sites
                            .ToList();

            foreach (var FreeSite in FreeSites)
            {
                if (!vill.Build.Tasks.Any(x => x.BuildingId == FreeSite.Id))
                {
                    // Site is free and there's no building task that reserves it.
                    task.BuildingId = FreeSite.Id;
                    return(true);
                }
            }
            return(false);
        }
Пример #20
0
        /// <summary>
        /// Adds all building prerequisites for this building if they do not exist yet.
        /// After this you should call RemoveDuplicates().
        /// </summary>
        /// <param name="acc"></param>
        /// <param name="vill"></param>
        /// <param name="building"></param>
        /// <returns>Whether we have all prerequisite buildings</returns>
        public static bool AddBuildingPrerequisites(Account acc, Village vill, BuildingEnum building, bool bottom = true)
        {
            RemoveFinishedCB(vill);

            (var tribe, var prereqs) = BuildingsData.GetBuildingPrerequisites(building);
            if (acc.AccInfo.Tribe != tribe && tribe != TribeEnum.Any)
            {
                return(false);
            }
            if (prereqs.Count == 0)
            {
                return(true);
            }
            var ret = true;

            foreach (var prereq in prereqs)
            {
                var prereqBuilding = vill.Build.Buildings.Where(x => x.Type == prereq.Building);

                // Prerequired building already exists and is on on/above/being upgraded on desired level
                if (prereqBuilding.Any(x =>
                                       prereq.Level <= x.Level + (x.UnderConstruction ? 1 : 0))
                    )
                {
                    continue;
                }

                if (bottom && vill.Build.Tasks.Any(x => prereq.Building == x.Building &&
                                                   prereq.Level <= x.Level))
                {
                    continue;
                }

                // If there is no required building, build it's prerequisites first
                if (!prereqBuilding.Any())
                {
                    AddBuildingPrerequisites(acc, vill, prereq.Building);
                }

                AddBuildingTask(acc, vill, new BuildingTask()
                {
                    Building = prereq.Building,
                    Level    = prereq.Level,
                    TaskType = BuildingType.General
                }, bottom);
                ret = false;
            }
            return(ret);
        }
    public ProductionCycle(BuildingsData data, Action <ProductionCycleResult> OnComplete)
    {
        ProductionTime  = data.Productiontime;
        Money           = data.Moneyoutput;
        ResourcesAmount = data.Resourceoutputamount;
        Pollution       = data.Pollution;
        ResourcesIDs    = data.Resourceoutput;
        //ResourcesAmount = data.Resourceinputamount;

        PlayerResources.Instance.RemoveResources(data.Resourceinput, data.Resourceinputamount);
        PlayerResources.Instance.RemoveMoney(data.Moneyinput);

        this.OnComplete = OnComplete;
        timer           = ProductionTime;
    }
Пример #22
0
        public void BuildAtStart(Building building, BuildingsData data, IntVector2 coordinates)
        {
            Tile[,] tiles = GetNeededTiles(coordinates, building.Size);
            AverageOutTerrain(tiles);

            foreach (Tile tile in tiles)
            {
                tile.SetOccupant(building);
            }

            building.transform.position = Tile.GetCentrePoint(tiles);
            building.enabled            = true;
            building.Init(data, tiles);
            building.AddOutline(outlinePrefab);

            OnBuildingPlaced(building, data);
        }
Пример #23
0
        public void Init(int id, BuildingPrefabs prefab, BuildingsData data, bool isCorrectClimate, BuildModeBase buildMode)
        {
            this.id               = id;
            this.data             = data;
            this.isCorrectClimate = isCorrectClimate;
            img.sprite            = prefab.GetBuildingSprite(id);
            button.onClick.AddListener(() => buildMode.SelectBuilding(id));
            button.interactable = Building.IsBuildingBuildable(id);
            PlayerResources.OnResourceChanged       += UpdateInteractableStateBuilding;
            PlayerResources.OnMoneyChanged          += UpdateInteractableStateBuilding;
            Construction.BuildMode.OnBuildingPlaced += UpdateInteractableStateBuilding;

            if (!isCorrectClimate)
            {
                button.interactable = false;
                img.color           = incorrectClimateColor;
            }
        }
Пример #24
0
        public static bool IsBuildingBuildable(int dataID)
        {
            BuildingsData data = DataManager.BuildingData.dataArray[dataID];

            if (!PlayerResources.Instance.HasMoneyAmount(data.Moneycost))
            {
                return(false);
            }
            if (!PlayerResources.Instance.HasResourcesAmount(data.Resourcecost, data.Resourcecostamount))
            {
                return(false);
            }
            //int energyIndex = 0;
            //if (data.Resourceinput.Contains(energyIndex)) {
            //    if (!PlayerResources.Instance.HasEnergyAmount(data.Resourceinputamount[energyIndex]))
            //        return false;
            //}
            return(true);
        }
Пример #25
0
        public static bool BuildingRequirementsAreMet(BuildingEnum building, Village vill, TribeEnum tribe) //check if user can construct this building
        {
            bool exists = (vill.Build.Buildings.FirstOrDefault(x => x.Type == building) != null);           //there is already a building of this type in the vill

            if (exists)
            {
                //check cranny/warehouse/grannary/trapper/GG/GW
                switch (building)
                {
                case BuildingEnum.Warehouse: return(BuildingIsOnLevel(BuildingEnum.Warehouse, 20, vill));

                case BuildingEnum.Granary: return(BuildingIsOnLevel(BuildingEnum.Granary, 20, vill));

                case BuildingEnum.GreatWarehouse: return(BuildingIsOnLevel(BuildingEnum.GreatWarehouse, 20, vill));

                case BuildingEnum.GreatGranary: return(BuildingIsOnLevel(BuildingEnum.GreatGranary, 20, vill));

                case BuildingEnum.Trapper: return(BuildingIsOnLevel(BuildingEnum.Trapper, 20, vill));

                case BuildingEnum.Cranny: return(BuildingIsOnLevel(BuildingEnum.Cranny, 10, vill));

                default: return(false);
                }
            }

            //check for prerequisites for this building
            (var ReqTribe, var Prerequisites) = BuildingsData.GetBuildingPrerequisites(building);
            if (ReqTribe != TribeEnum.Any && ReqTribe != tribe)
            {
                return(false);
            }
            //if we either already have this building OR is on our build task list, requirements are met.
            foreach (var prerequisite in Prerequisites)
            {
                if (!vill.Build.Buildings.Any(x => x.Level >= prerequisite.Level && x.Type == prerequisite.Building) &&
                    !vill.Build.Tasks.Any(x => x.Level >= prerequisite.Level && x.Building == prerequisite.Building))
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #26
0
        public static List <string> SetPrereqCombo(Account acc, Village vill)
        {
            var ret = new List <string>();

            for (int i = 5; i <= 45; i++) // Go through each building
            {
                var building = (BuildingEnum)i;

                // Don't show these buildings:
                if (building == BuildingEnum.GreatWarehouse ||
                    building == BuildingEnum.GreatGranary
                    )
                {
                    continue;
                }

                if (vill.Build.Buildings.Any(x => x.Type == building))
                {
                    continue;
                }
                if (vill.Build.Tasks.Any(x => x.Building == building))
                {
                    continue;
                }

                (var reqTribe, var prerequisites) = BuildingsData.GetBuildingPrerequisites((BuildingEnum)i);

                if (reqTribe != TribeEnum.Any && reqTribe != acc.AccInfo.Tribe)
                {
                    continue;
                }

                ret.Add(building.ToString());
            }

            return(ret);
        }
Пример #27
0
    /// <summary>
    /// Load building list from .json file. Calls onComplete after loading is done.
    /// </summary>
    /// <param name="onComplete"></param>
    /// <returns></returns>
    public IEnumerator LoadBuildingListJson(Action onComplete)
    {
        var filePath = Path.Combine(Application.streamingAssetsPath, buildingsJson);

        var jsonData = "";

        if (filePath.Contains("://"))
        {
            UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequest.Get(filePath);
            yield return(www.SendWebRequest());

            jsonData = www.downloadHandler.text;
            print(jsonData);
            buildingsData = JsonUtility.FromJson <BuildingsData>(jsonData);
            onComplete();
        }
        else
        {
            jsonData = System.IO.File.ReadAllText(filePath);
            print(jsonData);
            buildingsData = JsonUtility.FromJson <BuildingsData>(jsonData);
            onComplete();
        }
    }
Пример #28
0
        private void StartNewProduction()
        {
            BuildingsData dataWithoutEnergy = GetDataWithoutEnergyResource(data);

            productionCycle = new ProductionCycle(dataWithoutEnergy, OnProductionCycleCompletedHandler);
            PlayerResources.OnResourceChanged -= CheckIfNecessaryInputResourcesAreAvailable;
            //PlayerResources.OnMoneyChanged -= (x) => CheckIfNecessaryInputResourcesAreAvailable();
            OnProductionInputProcessed(this, dataWithoutEnergy);

            if (!enabled)
            {
                enabled = true;
            }
            ToggleBuildingEffects(true);

            if (!sentEnergyCapacity)
            {
                if (OnBuildingEnabled != null)
                {
                    OnBuildingEnabled(this);
                }
                sentEnergyCapacity = true;
            }
        }
 private void Construct(BuildingsData buildingsData)
 {
     this.buildingsData = buildingsData;
 }
Пример #30
0
        /// <summary>
        /// Adds the building task to the village list of building tasks. Restarts BotTask UpgradeBuilding if needed.
        /// </summary>
        /// <param name="acc">Account</param>
        /// <param name="vill">Village</param>
        /// <param name="task">BuildingTask to add</param>
        /// <param name="bottom">Whether to insert the BuildingTask on the bottom of the list</param>
        /// <returns>Whether the method completed successfully</returns>
        public static bool AddBuildingTask(Account acc, Village vill, BuildingTask task, bool bottom = true, bool restart = true)
        {
            if (vill == null)
            {
                return(false);
            }

            //check wall
            if (IsWall(task.Building))
            {
                var wall = BuildingsData.GetTribesWall(acc.AccInfo.Tribe);
                // check type
                if (task.Building != wall)
                {
                    task.Building = wall;
                }
                // check position
                if (task.BuildingId != 40)
                {
                    task.BuildingId = 40;
                }
            }
            // check rally point
            else if (task.Building == BuildingEnum.Site)
            {
                // check position
                if (task.BuildingId != 39)
                {
                    task.BuildingId = 39;
                }
            }
            // other building
            else if (task.BuildingId == null ||
                     vill.Build.Buildings.Any(x => x.Id == task.BuildingId &&
                                              x.Type != task.Building &&
                                              x.Type != BuildingEnum.Site))
            {
                //Check if bot has any space to build new buildings, otherwise return
                if (!FindBuildingId(vill, task))
                {
                    return(false);
                }
            }

            // checking multiple building
            // you need at least one at level 20 before building other
            if (BuildingsData.CanHaveMultipleBuildings(task.Building))
            {
                if (task.ConstructNew)
                {
                    // Highest level building
                    var highestLvl = vill.Build
                                     .Buildings
                                     .Where(x => x.Type == task.Building)
                                     .OrderByDescending(x => x.Level)
                                     .FirstOrDefault();

                    if (highestLvl != null &&
                        highestLvl.Level != BuildingsData.MaxBuildingLevel(acc, task.Building))
                    {
                        task.BuildingId = highestLvl.Id;
                    }
                }
            }
            else if (!IsResourceField(task.Building))
            {
                var buildings = vill.Build.Buildings.Where(x => x.Type == task.Building);
                if (buildings.Count() > 0)
                {
                    var id = buildings.First().Id;
                    if (id != task.BuildingId)
                    {
                        task.BuildingId = id;
                    }
                }
            }

            if (bottom)
            {
                vill.Build.Tasks.Add(task);
            }
            else
            {
                vill.Build.Tasks.Insert(0, task);
            }

            if (acc.Wb != null && restart)
            {
                ReStartBuilding(acc, vill);
            }
            return(true);
        }