Ejemplo n.º 1
0
        private void LoadBaseDetailsPage()
        {
            var    data           = _base.GetPlayerTempData(GetPC());
            PCBase pcBase         = _data.Single <PCBase>(x => x.ID == data.PCBaseID);
            Area   dbArea         = _data.Single <Area>(x => x.Resref == pcBase.AreaResref);
            var    owner          = _data.Get <Player>(pcBase.PlayerID);
            bool   canExtendLease = _perm.HasBasePermission(GetPC(), pcBase.ID, BasePermission.CanExtendLease);
            bool   canCancelLease = _perm.HasBasePermission(GetPC(), pcBase.ID, BasePermission.CanCancelLease);

            string header = _color.Green("Location: ") + dbArea.Name + " (" + pcBase.Sector + ")\n\n";

            header += _color.Green("Owned By: ") + owner.CharacterName + "\n";
            header += _color.Green("Purchased: ") + pcBase.DateInitialPurchase + "\n";
            header += _color.Green("Rent Due: ") + pcBase.DateRentDue + "\n";
            header += _color.Green("Daily Upkeep: ") + dbArea.DailyUpkeep + " credits\n\n";
            header += "Daily upkeep may be paid up to 30 days in advance.\n";


            SetPageHeader("BaseDetailsPage", header);

            const int MaxAdvancePay = 30;
            DateTime  newRentDate   = pcBase.DateRentDue.AddDays(1);
            TimeSpan  ts            = newRentDate - DateTime.UtcNow;
            bool      canPayRent    = ts.TotalDays < MaxAdvancePay;

            SetResponseVisible("BaseDetailsPage", 1, canPayRent && canExtendLease);

            newRentDate = pcBase.DateRentDue.AddDays(7);
            ts          = newRentDate - DateTime.UtcNow;
            canPayRent  = ts.TotalDays < MaxAdvancePay;

            SetResponseVisible("BaseDetailsPage", 2, canPayRent && canExtendLease);
            SetResponseVisible("BaseDetailsPage", 3, canCancelLease);
        }
Ejemplo n.º 2
0
        public override void Initialize()
        {
            Guid            structureID = new Guid(GetDialogTarget().GetLocalString("PC_BASE_STRUCTURE_ID"));
            PCBaseStructure structure   = _data.Single <PCBaseStructure>(x => x.ID == structureID);
            Guid            pcBaseID    = structure.PCBaseID;
            PCBase          pcBase      = _data.Get <PCBase>(pcBaseID);

            double currentCPU   = _base.GetCPUInUse(pcBaseID);
            double currentPower = _base.GetPowerInUse(pcBaseID);
            double maxCPU       = _base.GetMaxBaseCPU(pcBaseID);
            double maxPower     = _base.GetMaxBasePower(pcBaseID);

            int currentReinforcedFuel = pcBase.ReinforcedFuel;
            int currentFuel           = pcBase.Fuel;
            int currentResources      = _data.Where <PCBaseStructureItem>(x => x.PCBaseStructureID == structure.ID).Count();
            int maxReinforcedFuel     = _base.CalculateMaxReinforcedFuel(pcBaseID);
            int maxFuel      = _base.CalculateMaxFuel(pcBaseID);
            int maxResources = _base.CalculateResourceCapacity(pcBaseID);

            string time;

            if (pcBase.DateFuelEnds > DateTime.UtcNow)
            {
                TimeSpan deltaTime = pcBase.DateFuelEnds - DateTime.UtcNow;
                TimeSpan timeSpan  = TimeSpan.FromMinutes(30.0f * currentFuel) + deltaTime;
                time = _time.GetTimeLongIntervals(timeSpan.Days, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, false);

                time = "Fuel will expire in " + time;
            }
            else
            {
                time = _color.Red("Fuel has expired.");
            }



            string header = _color.Green("Power: ") + currentPower + " / " + maxPower + "\n";

            header += _color.Green("CPU: ") + currentCPU + " / " + maxCPU + "\n";
            header += _color.Green("Fuel: ") + currentFuel + " / " + maxFuel + "\n";
            header += _color.Green("Reinforced Fuel: ") + currentReinforcedFuel + " / " + maxReinforcedFuel + "\n";
            header += _color.Green("Resource Bay: ") + currentResources + " / " + maxResources + "\n";
            header += time + "\n";
            header += "What would you like to do with this control tower?";

            SetPageHeader("MainPage", header);

            if (!_perm.HasBasePermission(GetPC(), structure.PCBaseID, BasePermission.CanManageBaseFuel))
            {
                SetResponseVisible("MainPage", 1, false);
                SetResponseVisible("MainPage", 2, false);
            }

            if (!_perm.HasBasePermission(GetPC(), structure.PCBaseID, BasePermission.CanAccessStructureInventory))
            {
                SetResponseVisible("MainPage", 3, false);
            }
        }
Ejemplo n.º 3
0
        public bool Run(params object[] args)
        {
            NWPlayer    clicker = (_.GetPlaceableLastClickedBy());
            NWPlaceable tower   = (Object.OBJECT_SELF);

            clicker.ClearAllActions();
            if (!clicker.IsPlayer)
            {
                return(false);
            }
            if (_.GetDistanceBetween(clicker.Object, tower.Object) > 5.0f)
            {
                clicker.SendMessage("You are too far away to interact with that control tower.");
                return(false);
            }
            Guid            structureID = new Guid(tower.GetLocalString("PC_BASE_STRUCTURE_ID"));
            PCBaseStructure structure   = _data.Single <PCBaseStructure>(x => x.ID == structureID);

            if (_perm.HasBasePermission(clicker, structure.PCBaseID, BasePermission.CanManageBaseFuel))
            {
                _dialog.StartConversation(clicker, tower, "ControlTower");
            }
            else
            {
                clicker.SendMessage("You don't have permission to interact with this control tower.");
            }

            return(true);
        }
Ejemplo n.º 4
0
        public override void Initialize()
        {
            Guid            structureID = new Guid(GetDialogTarget().GetLocalString("PC_BASE_STRUCTURE_ID"));
            PCBaseStructure structure   = _data.Single <PCBaseStructure>(x => x.ID == structureID);

            if (!_perm.HasBasePermission(GetPC(), structure.PCBaseID, BasePermission.CanManageBaseFuel))
            {
                SetResponseVisible("MainPage", 1, false);
                SetResponseVisible("MainPage", 2, false);
            }

            if (!_perm.HasBasePermission(GetPC(), structure.PCBaseID, BasePermission.CanAccessStructureInventory))
            {
                SetResponseVisible("MainPage", 3, false);
            }
        }
Ejemplo n.º 5
0
        private void BuildMainPageResponses()
        {
            var player = GetPC();
            var data   = _base.GetPlayerTempData(player);

            Player dbPlayer = _data.Single <Player>(x => x.ID == player.GlobalID);
            Player primaryResident;

            bool isPrimaryResident;
            bool canEditPrimaryResidence;
            bool canRemovePrimaryResidence;

            if (data.BuildingType == BuildingType.Interior)
            {
                Guid structureID = data.StructureID;
                primaryResident = _data.SingleOrDefault <Player>(x => x.PrimaryResidencePCBaseStructureID == structureID);

                isPrimaryResident         = dbPlayer.PrimaryResidencePCBaseStructureID != null && dbPlayer.PrimaryResidencePCBaseStructureID == structureID;
                canEditPrimaryResidence   = _perm.HasStructurePermission(player, structureID, StructurePermission.CanEditPrimaryResidence);
                canRemovePrimaryResidence = _perm.HasStructurePermission(player, structureID, StructurePermission.CanRemovePrimaryResidence);
            }
            else if (data.BuildingType == BuildingType.Apartment)
            {
                Guid pcBaseID = data.PCBaseID;
                primaryResident = _data.SingleOrDefault <Player>(x => x.PrimaryResidencePCBaseID == pcBaseID);

                isPrimaryResident         = dbPlayer.PrimaryResidencePCBaseID != null && dbPlayer.PrimaryResidencePCBaseID == pcBaseID;
                canEditPrimaryResidence   = _perm.HasBasePermission(player, pcBaseID, BasePermission.CanEditPrimaryResidence);
                canRemovePrimaryResidence = _perm.HasBasePermission(player, pcBaseID, BasePermission.CanRemovePrimaryResidence);
            }
            else
            {
                throw new Exception("Invalid building type on EditPrimaryResidence conversation. Type = " + data.BuildingType);
            }

            // If another person is a resident and this player does not have the "remove" permission, don't allow them to make primary residence.
            if (!isPrimaryResident && primaryResident != null && !canRemovePrimaryResidence)
            {
                canEditPrimaryResidence = false;
            }

            SetResponseVisible("MainPage", 1, canEditPrimaryResidence);
            SetResponseVisible("MainPage", 2, canRemovePrimaryResidence || isPrimaryResident);
        }
        private void MainResponses(int responseID)
        {
            var data = _base.GetPlayerTempData(GetPC());

            switch (responseID)
            {
            case 1:     // Change Permissions
                if (!_perm.HasBasePermission(GetPC(), data.PCBaseID, BasePermission.CanAdjustPermissions))
                {
                    GetPC().FloatingText("You do not have permission to change other players' permissions.");
                    return;
                }

                BuildPlayerListPage();
                ChangePage("PlayerListPage");
                break;

            case 2:     // Change Public Permissions
                var pcBase = _data.Get <PCBase>(data.PCBaseID);

                if (pcBase.Sector == "AP")
                {
                    GetPC().FloatingText("Public permissions cannot be adjusted inside apartments.");
                    return;
                }

                if (!_perm.HasBasePermission(GetPC(), data.PCBaseID, BasePermission.CanAdjustPublicPermissions))
                {
                    GetPC().FloatingText("You do not have permission to change this base's public permissions.");
                    return;
                }

                BuildPublicPermissionsPage();
                ChangePage("PublicPermissionsPage");
                break;
            }
        }
Ejemplo n.º 7
0
        private void MainResponses(int responseID)
        {
            switch (responseID)
            {
            case 1:     // Change Permissions
                var data = _base.GetPlayerTempData(GetPC());
                if (!_perm.HasBasePermission(GetPC(), data.PCBaseID, BasePermission.CanAdjustPermissions))
                {
                    GetPC().FloatingText("You do not have permission to change other players' permissions.");
                    return;
                }

                BuildPlayerListPage();
                ChangePage("PlayerListPage");
                break;
            }
        }
Ejemplo n.º 8
0
        private void LoadMainPage()
        {
            ClearPageResponses("MainPage");
            var    data   = _base.GetPlayerTempData(GetPC());
            int    cellX  = (int)(_.GetPositionFromLocation(data.TargetLocation).m_X / 10.0f);
            int    cellY  = (int)(_.GetPositionFromLocation(data.TargetLocation).m_Y / 10.0f);
            string sector = _base.GetSectorOfLocation(data.TargetLocation);

            Area dbArea         = _data.Single <Area>(x => x.Resref == data.TargetArea.Resref);
            bool hasUnclaimed   = false;
            Guid playerID       = GetPC().GlobalID;
            int  buildingTypeID = data.TargetArea.GetLocalInt("BUILDING_TYPE");

            Enumeration.BuildingType buildingType = buildingTypeID <= 0 ? Enumeration.BuildingType.Exterior : (Enumeration.BuildingType)buildingTypeID;
            data.BuildingType = buildingType;

            bool canEditBasePermissions     = false;
            bool canEditBuildingPermissions = false;
            bool canEditStructures;
            bool canEditPrimaryResidence   = false;
            bool canRemovePrimaryResidence = false;

            if (buildingType == Enumeration.BuildingType.Interior)
            {
                Guid pcBaseStructureID = new Guid(data.TargetArea.GetLocalString("PC_BASE_STRUCTURE_ID"));
                canEditStructures          = _perm.HasStructurePermission(GetPC(), pcBaseStructureID, StructurePermission.CanPlaceEditStructures);
                canEditBuildingPermissions = _perm.HasStructurePermission(GetPC(), pcBaseStructureID, StructurePermission.CanAdjustPermissions);
                canEditPrimaryResidence    = _perm.HasStructurePermission(GetPC(), pcBaseStructureID, StructurePermission.CanEditPrimaryResidence);
                canRemovePrimaryResidence  = _perm.HasStructurePermission(GetPC(), pcBaseStructureID, StructurePermission.CanRemovePrimaryResidence);
                data.StructureID           = pcBaseStructureID;
            }
            else if (buildingType == Enumeration.BuildingType.Apartment)
            {
                Guid pcBaseID = new Guid(data.TargetArea.GetLocalString("PC_BASE_ID"));
                canEditStructures         = _perm.HasBasePermission(GetPC(), pcBaseID, BasePermission.CanPlaceEditStructures);
                canEditBasePermissions    = _perm.HasBasePermission(GetPC(), pcBaseID, BasePermission.CanAdjustPermissions);
                canEditPrimaryResidence   = _perm.HasBasePermission(GetPC(), pcBaseID, BasePermission.CanEditPrimaryResidence);
                canRemovePrimaryResidence = _perm.HasBasePermission(GetPC(), pcBaseID, BasePermission.CanRemovePrimaryResidence);
                data.PCBaseID             = pcBaseID;
            }
            else if (buildingType == Enumeration.BuildingType.Exterior)
            {
                var pcBase = _data.SingleOrDefault <PCBase>(x => x.AreaResref == data.TargetArea.Resref && x.Sector == sector);
                canEditStructures      = pcBase != null && _perm.HasBasePermission(GetPC(), pcBase.ID, BasePermission.CanPlaceEditStructures);
                canEditBasePermissions = pcBase != null && _perm.HasBasePermission(GetPC(), pcBase.ID, BasePermission.CanAdjustPermissions);
                if (pcBase != null)
                {
                    data.PCBaseID = pcBase.ID;
                }
            }
            else
            {
                throw new Exception("BaseManagementTool -> Cannot locate building type with ID " + buildingTypeID);
            }

            string header = _color.Green("Base Management Menu\n\n");

            header += _color.Green("Area: ") + data.TargetArea.Name + " (" + cellX + ", " + cellY + ")\n\n";

            if (!dbArea.IsBuildable)
            {
                header += "Land in this area cannot be claimed. However, you can still manage any leases you own from the list below.";
            }
            else if (buildingType == Enumeration.BuildingType.Interior)
            {
                Guid pcBaseStructureID = new Guid(data.TargetArea.GetLocalString("PC_BASE_STRUCTURE_ID"));
                var  structure         = _data.Single <PCBaseStructure>(x => x.ID == pcBaseStructureID);
                var  baseStructure     = _data.Get <BaseStructure>(structure.BaseStructureID);
                int  itemLimit         = baseStructure.Storage + structure.StructureBonus;
                var  childStructures   = _data.Where <PCBaseStructure>(x => x.ParentPCBaseStructureID == structure.ID);
                header += _color.Green("Item Limit: ") + childStructures.Count() + " / " + itemLimit + "\n";
            }
            else if (buildingType == Enumeration.BuildingType.Apartment)
            {
                Guid pcBaseID      = new Guid(data.TargetArea.GetLocalString("PC_BASE_ID"));
                var  pcBase        = _data.Get <PCBase>(pcBaseID);
                var  buildingStyle = _data.Get <BuildingStyle>(pcBase.BuildingStyleID);
                int  itemLimit     = buildingStyle.FurnitureLimit;
                var  structures    = _data.Where <PCBaseStructure>(x => x.PCBaseID == pcBase.ID);
                header += _color.Green("Item Limit: ") + structures.Count() + " / " + itemLimit + "\n";
            }
            else if (buildingType == Enumeration.BuildingType.Exterior)
            {
                var northeastOwner = dbArea.NortheastOwner == null ? null : _data.Get <Player>(dbArea.NortheastOwner);
                var northwestOwner = dbArea.NorthwestOwner == null ? null : _data.Get <Player>(dbArea.NorthwestOwner);
                var southeastOwner = dbArea.SoutheastOwner == null ? null : _data.Get <Player>(dbArea.SoutheastOwner);
                var southwestOwner = dbArea.SouthwestOwner == null ? null : _data.Get <Player>(dbArea.SouthwestOwner);

                if (northeastOwner != null)
                {
                    header += _color.Green("Northeast Owner: ") + "Claimed";
                    if (dbArea.NortheastOwner == playerID)
                    {
                        header += " (" + northeastOwner.CharacterName + ")";
                    }
                    header += "\n";
                }
                else
                {
                    header      += _color.Green("Northeast Owner: ") + "Unclaimed\n";
                    hasUnclaimed = true;
                }

                if (northwestOwner != null)
                {
                    header += _color.Green("Northwest Owner: ") + "Claimed";
                    if (dbArea.NorthwestOwner == playerID)
                    {
                        header += " (" + northwestOwner.CharacterName + ")";
                    }
                    header += "\n";
                }
                else
                {
                    header      += _color.Green("Northwest Owner: ") + "Unclaimed\n";
                    hasUnclaimed = true;
                }

                if (southeastOwner != null)
                {
                    header += _color.Green("Southeast Owner: ") + "Claimed";
                    if (dbArea.SoutheastOwner == playerID)
                    {
                        header += " (" + southeastOwner.CharacterName + ")";
                    }
                    header += "\n";
                }
                else
                {
                    header      += _color.Green("Southeast Owner: ") + "Unclaimed\n";
                    hasUnclaimed = true;
                }

                if (southwestOwner != null)
                {
                    header += _color.Green("Southwest Owner: ") + "Claimed";
                    if (dbArea.SouthwestOwner == playerID)
                    {
                        header += " (" + southwestOwner.CharacterName + ")";
                    }
                    header += "\n";
                }
                else
                {
                    header      += _color.Green("Southwest Owner: ") + "Unclaimed\n";
                    hasUnclaimed = true;
                }
            }

            SetPageHeader("MainPage", header);

            bool showManage = _data.GetAll <PCBase>().Count(x => x.PlayerID == playerID) > 0;


            AddResponseToPage("MainPage", "Manage My Leases", showManage);
            AddResponseToPage("MainPage", "Purchase Territory", hasUnclaimed && dbArea.IsBuildable);
            AddResponseToPage("MainPage", "Edit Nearby Structures", canEditStructures);
            AddResponseToPage("MainPage", "Edit Base Permissions", canEditBasePermissions);
            AddResponseToPage("MainPage", "Edit Building Permissions", canEditBuildingPermissions);
            AddResponseToPage("MainPage", "Edit Primary Residence", canEditPrimaryResidence || canRemovePrimaryResidence);
        }
Ejemplo n.º 9
0
        public string CanPlaceStructure(NWCreature user, NWItem structureItem, NWLocation targetLocation, int baseStructureID)
        {
            NWPlayer player = user.Object;
            string   sector = GetSectorOfLocation(targetLocation);

            // Picked an invalid sector
            if (sector == "INVALID")
            {
                return("Invalid location selected.");
            }

            // Can't find the structure item for some reason.
            if (structureItem == null || !structureItem.IsValid || !Equals(structureItem.Possessor, user))
            {
                return("Unable to locate structure item.");
            }

            NWArea area = _.GetAreaFromLocation(targetLocation);
            string buildingStructureID   = area.GetLocalString("PC_BASE_STRUCTURE_ID");
            Guid   buildingStructureGuid = string.IsNullOrWhiteSpace(buildingStructureID) ? Guid.Empty : new Guid(buildingStructureID);
            string pcBaseID   = area.GetLocalString("PC_BASE_ID");
            Guid   pcBaseGUID = string.IsNullOrWhiteSpace(pcBaseID) ? Guid.Empty : new Guid(pcBaseID);

            // Identify the building type.
            BuildingType buildingType;

            if (!string.IsNullOrWhiteSpace(pcBaseID))
            {
                buildingType = BuildingType.Apartment;
            }
            else if (string.IsNullOrWhiteSpace(buildingStructureID))
            {
                buildingType = BuildingType.Exterior;
            }
            else
            {
                buildingType = BuildingType.Interior;
            }

            Area dbArea = _data.SingleOrDefault <Area>(x => x.Resref == area.Resref);

            // Can't build in this area.
            if (dbArea == null || !dbArea.IsBuildable)
            {
                return("Structures cannot be placed in this area.");
            }
            PCBase pcBase = !string.IsNullOrWhiteSpace(pcBaseID) ?
                            _data.Get <PCBase>(pcBaseGUID) :
                            _data.SingleOrDefault <PCBase>(x => x.AreaResref == area.Resref && x.Sector == sector);

            // Check and see if the player has hit the structure limit.
            if (pcBase == null && buildingType == BuildingType.Interior)
            {
                var parentStructure     = _data.Get <PCBaseStructure>(buildingStructureGuid);
                var parentBaseStructure = _data.Get <BaseStructure>(parentStructure.BaseStructureID);
                pcBase = _data.Get <PCBase>(parentStructure.PCBaseID);

                int buildingStructureCount = _data.GetAll <PCBaseStructure>().Count(x => x.ParentPCBaseStructureID == parentStructure.ID) + 1;
                if (buildingStructureCount > parentBaseStructure.Storage + parentStructure.StructureBonus)
                {
                    return("No more structures can be placed inside this building.");
                }
            }

            // Area is unclaimed but PC doesn't own it.
            if (pcBase == null)
            {
                return("This area is unclaimed but not owned by you. You may purchase a lease on it from the planetary government by using your Base Management Tool (found under feats).");
            }

            // Check whether player has permission to place or edit structures.
            var canPlaceOrEditStructures = buildingType == BuildingType.Apartment || buildingType == BuildingType.Exterior ?
                                           _perm.HasBasePermission(player, pcBase.ID, BasePermission.CanPlaceEditStructures) :                      // Bases
                                           _perm.HasStructurePermission(player, buildingStructureGuid, StructurePermission.CanPlaceEditStructures); // Buildings

            // Don't have permission.
            if (!canPlaceOrEditStructures)
            {
                return("You do not have permission to place or edit structures in this territory.");
            }

            var baseStructure     = _data.Get <BaseStructure>(baseStructureID);
            var baseStructureType = _data.Get <Data.Entity.BaseStructureType>(baseStructure.BaseStructureTypeID);

            // Can only place this structure inside buildings and the player is currently outside.
            if (!baseStructureType.CanPlaceOutside && buildingType == BuildingType.Exterior)
            {
                return("That structure can only be placed inside buildings.");
            }

            // Can only place this structure outside
            if (!baseStructureType.CanPlaceInside && (buildingType == BuildingType.Interior || buildingType == BuildingType.Apartment))
            {
                return("That structure can only be placed outside of buildings.");
            }

            // Check for control tower requirements.
            if (buildingType == BuildingType.Exterior)
            {
                var structures = _data.Where <PCBaseStructure>(x => x.PCBaseID == pcBase.ID).ToList();

                bool hasControlTower = structures
                                       .SingleOrDefault(x =>
                {
                    var bs = _data.Get <BaseStructure>(x.BaseStructureID);
                    return(bs.BaseStructureTypeID == (int)BaseStructureType.ControlTower);
                }) != null;

                if (!hasControlTower && baseStructureType.ID != (int)BaseStructureType.ControlTower)
                {
                    return("A control tower must be placed down in the sector first.");
                }

                if (hasControlTower && baseStructureType.ID == (int)BaseStructureType.ControlTower)
                {
                    return("Only one control tower can be placed down per sector.");
                }
            }

            // Crafting devices may only be placed inside buildings set to the 'Workshop' mode.
            if (baseStructureType.ID == (int)BaseStructureType.CraftingDevice)
            {
                if (buildingType == BuildingType.Interior)
                {
                    var parentBuilding = _data.Get <PCBaseStructure>(buildingStructureGuid);
                    var mode           = (StructureModeType)parentBuilding.StructureModeID;

                    if (mode != StructureModeType.Workshop)
                    {
                        return("Crafting devices may only be placed inside buildings set to the 'Workshop' mode.");
                    }
                }
            }

            return(null);
        }
Ejemplo n.º 10
0
        public string CanPlaceStructure(NWCreature user, NWItem structureItem, NWLocation targetLocation, int baseStructureID)
        {
            NWPlayer player = user.Object;
            string   sector = GetSectorOfLocation(targetLocation);

            if (sector == "INVALID")
            {
                return("Invalid location selected.");
            }

            if (structureItem == null || !structureItem.IsValid || !Equals(structureItem.Possessor, user))
            {
                return("Unable to locate structure item.");
            }

            NWArea       area = _.GetAreaFromLocation(targetLocation);
            string       buildingStructureID   = area.GetLocalString("PC_BASE_STRUCTURE_ID");
            Guid         buildingStructureGuid = new Guid(buildingStructureID);
            string       pcBaseID   = area.GetLocalString("PC_BASE_ID");
            Guid         pcBaseGUID = new Guid(pcBaseID);
            BuildingType buildingType;

            if (!string.IsNullOrWhiteSpace(pcBaseID))
            {
                buildingType = BuildingType.Apartment;
            }
            else if (string.IsNullOrWhiteSpace(buildingStructureID))
            {
                buildingType = BuildingType.Exterior;
            }
            else
            {
                buildingType = BuildingType.Interior;
            }

            Area dbArea = _data.SingleOrDefault <Area>(x => x.Resref == area.Resref);

            if (dbArea == null || !dbArea.IsBuildable)
            {
                return("Structures cannot be placed in this area.");
            }
            PCBase pcBase = !string.IsNullOrWhiteSpace(pcBaseID) ?
                            _data.Get <PCBase>(pcBaseID) :
                            _data.SingleOrDefault <PCBase>(x => x.AreaResref == area.Resref && x.Sector == sector);

            if (pcBase == null && buildingType == BuildingType.Interior)
            {
                var parentStructure     = _data.Single <PCBaseStructure>(x => x.ID == buildingStructureGuid);
                var parentBaseStructure = _data.Get <BaseStructure>(parentStructure.BaseStructureID);
                pcBase = _data.Get <PCBase>(parentStructure.PCBaseID);

                int buildingStructureCount = _data.GetAll <PCBaseStructure>().Count(x => x.ParentPCBaseStructureID == parentStructure.ID) + 1;
                if (buildingStructureCount > parentBaseStructure.Storage)
                {
                    return("No more structures can be placed inside this building.");
                }
            }

            if (pcBase == null)
            {
                return("This area is unclaimed but not owned by you. You may purchase a lease on it from the planetary government by using your Base Management Tool (found under feats).");
            }

            var canPlaceOrEditStructures = buildingType == BuildingType.Apartment || buildingType == BuildingType.Exterior ?
                                           _perm.HasBasePermission(player, pcBase.ID, BasePermission.CanPlaceEditStructures) :                      // Bases
                                           _perm.HasStructurePermission(player, buildingStructureGuid, StructurePermission.CanPlaceEditStructures); // Buildings

            if (!canPlaceOrEditStructures)
            {
                return("You do not have permission to place or edit structures in this territory.");
            }

            var structure     = _data.Get <BaseStructure>(baseStructureID);
            var structureType = _data.Get <Data.Entity.BaseStructureType>(structure.BaseStructureTypeID);

            if (!structureType.CanPlaceOutside && buildingType == BuildingType.Exterior)
            {
                return("That structure can only be placed inside buildings.");
            }

            if (!structureType.CanPlaceInside && (buildingType == BuildingType.Interior || buildingType == BuildingType.Apartment))
            {
                return("That structure can only be placed outside of buildings.");
            }

            if (buildingType == BuildingType.Exterior)
            {
                var  structures      = _data.Where <PCBaseStructure>(x => x.PCBaseID == pcBaseGUID);
                bool hasControlTower = structures
                                       .SingleOrDefault(x =>
                {
                    var baseStructure = _data.Get <BaseStructure>(x.BaseStructureID);
                    return(baseStructure.BaseStructureTypeID == (int)BaseStructureType.ControlTower);
                }) != null;

                if (!hasControlTower && structureType.ID != (int)BaseStructureType.ControlTower)
                {
                    return("A control tower must be placed down in the sector first.");
                }

                if (hasControlTower && structureType.ID == (int)BaseStructureType.ControlTower)
                {
                    return("Only one control tower can be placed down per sector.");
                }
            }

            return(null);
        }