/// <summary>
        /// Processes a building placement request and adds a new pending building to be placed.
        /// </summary>
        /// <param name="buildingPrefab">The Building prefab to be cloned and placed.</param>
        /// <param name="buildAround">Defines where the building will be placed around.</param>
        /// <param name="buildAroundRadius">How far should the building from its 'buildAround' position?</param>
        /// <param name="buildingCenter">The Building center instance that the new building will be placed under.</param>
        /// <param name="buildAroundDistance">Initial ditsance between the building and its 'buildAround' position.</param>
        /// <param name="rotate">Can the building be rotated while getting placed?</param>
        public void OnBuildingPlacementRequest(Building buildingPrefab, GameObject buildAround, float buildAroundRadius, Building buildingCenter, float buildAroundDistance, bool rotate)
        {
            //if the building center or the build around object hasn't been specified:
            if (buildAround == null || buildingCenter == null)
            {
                Debug.LogError("Build Around object or Building Center for " + buildingPrefab.GetName() + " hasn't been specified in the Building Placement Request!");
                return;
            }

            //take resources to place building.
            gameMgr.ResourceMgr.UpdateRequiredResources(buildingPrefab.GetResources(), false, factionMgr.FactionID);

            //pick the building's spawn pos:
            Vector3 buildAroundPos = buildAround.transform.position;

            //for the sample height method, the last parameter presents the navigation layer mask and 0 stands for the built-in walkable layer where buildings can be placed
            buildAroundPos.y = gameMgr.TerrainMgr.SampleHeight(buildAround.transform.position, buildAroundRadius, 0) + gameMgr.PlacementMgr.GetBuildingYOffset();
            Vector3 buildingSpawnPos = buildAroundPos;

            buildingSpawnPos.x += buildAroundDistance;

            //create new instance of building and add it to the pending buildings list:
            NPCPendingBuilding newPendingBuilding = new NPCPendingBuilding
            {
                prefab              = buildingPrefab,
                instance            = Instantiate(buildingPrefab.gameObject, buildingSpawnPos, buildingPrefab.transform.rotation).GetComponent <Building>(),
                buildAroundPos      = buildAroundPos,
                buildAroundDistance = buildAroundDistance,
                center              = buildingCenter,
                rotate              = rotate
            };

            //pick a random starting position for building by randomly rotating it around its build around positio
            newPendingBuilding.instance.transform.RotateAround(newPendingBuilding.buildAroundPos, Vector3.up, Random.Range(0.0f, 360.0f));
            //keep initial rotation (because the RotateAround method will change the building's rotation as well which we do not want)
            newPendingBuilding.instance.transform.rotation = newPendingBuilding.prefab.transform.rotation;

            //initialize the building instance for placement:
            newPendingBuilding.instance.InitPlacementInstance(gameMgr, factionMgr.FactionID, buildingCenter.BorderComp);

            //we need to hide the building initially, when its turn comes to be placed, appropriate settings will be applied.
            newPendingBuilding.instance.gameObject.SetActive(false);
            newPendingBuilding.instance.ToggleModel(false); //Hide the building's model:

            //Call the start building placement custom event:
            CustomEvents.OnBuildingStartPlacement(newPendingBuilding.instance);

            //add the new pending building to the list:
            pendingBuildings.Push(newPendingBuilding);

            if (!IsActive)                                             //if building placer was not active (had no building to place)
            {
                StartPlacingNextBuilding();                            //immediately start placing it.

                heightCheckCoroutine = HeightCheck(heightCheckReload); //Start the height check coroutine to keep the building always on top of the terrain
                StartCoroutine(heightCheckCoroutine);
            }
        }
        public void StartPlacingBuilding(int id)
        {
            //make sure the building hasn't reached its limits:
            if (gameMgr.GetFaction(GameManager.PlayerFactionID).FactionMgr.HasReachedLimit(buildings[id].GetCode(), buildings[id].GetCategory()))
            {
                gameMgr.UIMgr.ShowPlayerMessage("Building " + buildings[id].GetName() + " has reached its placement limit", UIManager.MessageTypes.error);
                return;
            }
            //make sure that all required buildings to place this one are here:
            if (!gameMgr.GetFaction(GameManager.PlayerFactionID).FactionMgr.CheckRequiredBuildings(buildings[id]))
            {
                gameMgr.UIMgr.ShowPlayerMessage("Building requirements for " + buildings[id].GetName() + " are missing.", UIManager.MessageTypes.error);
                return;
            }
            //make sure we have enough resources
            if (!gameMgr.ResourceMgr.HasRequiredResources(buildings[id].GetResources(), GameManager.PlayerFactionID))
            {
                gameMgr.UIMgr.ShowPlayerMessage("Not enough resources to launch task!", UIManager.MessageTypes.error);
                return;
            }

            //Spawn the building for the player to place on the map:
            currentBuilding = Instantiate(buildings[id].gameObject, new Vector3(0, 0, 0), buildings[id].transform.rotation).GetComponent <Building>();
            lastBuildingID  = id;                                                        //set the last building ID

            currentBuilding.InitPlacementInstance(gameMgr, GameManager.PlayerFactionID); //initiliaze the placement instance.

            //Set the position of the new building (and make sure it's on the terrain)
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit))
            {
                Vector3 nextBuildingPos = hit.point;
                nextBuildingPos.y += buildingYOffset;
                currentBuilding.transform.position = nextBuildingPos;
            }

            gameMgr.SelectionMgr.Box.Disable(); //disable the selection box

            //Call the start building placement custom event:
            CustomEvents.OnBuildingStartPlacement(currentBuilding);
        }