Beispiel #1
0
        private void DoPlaceStructure()
        {
            var    data = BaseService.GetPlayerTempData(GetPC());
            string canPlaceStructure = BaseService.CanPlaceStructure(GetPC(), data.StructureItem, data.TargetLocation, data.BaseStructureID);
            var    baseStructure     = DataService.BaseStructure.GetByID(data.BaseStructureID);

            if (!string.IsNullOrWhiteSpace(canPlaceStructure))
            {
                GetPC().SendMessage(canPlaceStructure);
                return;
            }

            var position        = _.GetPositionFromLocation(data.TargetLocation);
            int?interiorStyleID = data.StructureItem.GetLocalInt("STRUCTURE_BUILDING_INTERIOR_ID");
            int?exteriorStyleID = data.StructureItem.GetLocalInt("STRUCTURE_BUILDING_EXTERIOR_ID");

            interiorStyleID = interiorStyleID <= 0 ? null : interiorStyleID;
            exteriorStyleID = exteriorStyleID <= 0 ? null : exteriorStyleID;

            var structure = new PCBaseStructure
            {
                BaseStructureID         = data.BaseStructureID,
                Durability              = DurabilityService.GetDurability(data.StructureItem),
                LocationOrientation     = _.GetFacingFromLocation(data.TargetLocation),
                LocationX               = position.m_X,
                LocationY               = position.m_Y,
                LocationZ               = position.m_Z,
                PCBaseID                = data.PCBaseID,
                InteriorStyleID         = interiorStyleID,
                ExteriorStyleID         = exteriorStyleID,
                CustomName              = string.Empty,
                ParentPCBaseStructureID = data.ParentStructureID,
                StructureBonus          = data.StructureItem.StructureBonus,
                StructureModeID         = baseStructure.DefaultStructureModeID
            };

            DataService.SubmitDataChange(structure, DatabaseActionType.Insert);

            // Placing a control tower. Set base shields to 100%
            if (baseStructure.BaseStructureTypeID == (int)BaseStructureType.ControlTower)
            {
                var pcBase = DataService.PCBase.GetByID(data.PCBaseID);
                pcBase.ShieldHP = BaseService.CalculateMaxShieldHP(structure);
                DataService.SubmitDataChange(pcBase, DatabaseActionType.Update);
            }

            BaseService.SpawnStructure(data.TargetArea, structure.ID);
            data.StructureItem.Destroy();
            EndConversation();
        }
Beispiel #2
0
        public void Main()
        {
            NWCreature      attacker    = (_.GetLastDamager(_.OBJECT_SELF));
            NWPlaceable     tower       = (_.OBJECT_SELF);
            NWItem          weapon      = (_.GetLastWeaponUsed(attacker.Object));
            int             damage      = _.GetTotalDamageDealt();
            var             structureID = tower.GetLocalString("PC_BASE_STRUCTURE_ID");
            PCBaseStructure structure   = DataService.PCBaseStructure.GetByID(new Guid(structureID));
            int             maxShieldHP = BaseService.CalculateMaxShieldHP(structure);
            PCBase          pcBase      = DataService.PCBase.GetByID(structure.PCBaseID);
            var             playerIDs   = DataService.PCBasePermission.GetAllByHasPrivatePermissionToBase(structure.PCBaseID)
                                          .Select(s => s.PlayerID);
            var      toNotify = NWModule.Get().Players.Where(x => playerIDs.Contains(x.GlobalID));
            DateTime timer    = DateTime.UtcNow.AddSeconds(30);
            string   clock    = timer.ToString(CultureInfo.InvariantCulture);
            string   sector   = BaseService.GetSectorOfLocation(attacker.Location);

            if (DateTime.UtcNow <= DateTime.Parse(clock))
            {
                foreach (NWPlayer player in toNotify)
                {
                    player.SendMessage("Your base in " + attacker.Area.Name + " " + sector + " is under attack!");
                }
            }

            // Apply damage to the shields. Never fall below 0.
            pcBase.ShieldHP -= damage;
            if (pcBase.ShieldHP <= 0)
            {
                pcBase.ShieldHP = 0;
            }

            // Calculate the amount of shield percentage remaining. If the tower is in reinforced mode, HP
            // will always be set back to 25% of shields.
            float hpPercentage = (float)pcBase.ShieldHP / (float)maxShieldHP * 100.0f;

            if (hpPercentage <= 25.0f && pcBase.ReinforcedFuel > 0)
            {
                pcBase.IsInReinforcedMode = true;
                pcBase.ShieldHP           = (int)(maxShieldHP * 0.25f);
                hpPercentage = (float)pcBase.ShieldHP / (float)maxShieldHP * 100.0f;
            }

            // Notify the attacker.
            attacker.SendMessage("Tower Shields: " + hpPercentage.ToString("0.00") + "%");
            if (pcBase.IsInReinforcedMode)
            {
                attacker.SendMessage("Control tower is in reinforced mode and cannot be damaged. Reinforced mode will be disabled when the tower runs out of fuel.");
            }

            // HP is tracked in the database. Heal the placeable so it doesn't get destroyed.
            _.ApplyEffectToObject(DurationType.Instant, _.EffectHeal(9999), tower.Object);

            if (attacker.IsPlayer)
            {
                DurabilityService.RunItemDecay(attacker.Object, weapon, RandomService.RandomFloat(0.01f, 0.03f));
            }

            // If the shields have fallen to zero, the tower will begin to take structure damage.
            if (pcBase.ShieldHP <= 0)
            {
                pcBase.ShieldHP = 0;

                structure.Durability -= RandomService.RandomFloat(0.5f, 2.0f);
                if (structure.Durability < 0.0f)
                {
                    structure.Durability = 0.0f;
                }
                attacker.SendMessage("Structure Durability: " + structure.Durability.ToString("0.00"));

                // If the structure durability drops to zero, destroy everything in the base.
                if (structure.Durability <= 0.0f)
                {
                    structure.Durability = 0.0f;
                    BaseService.ClearPCBaseByID(pcBase.ID, true, false);
                    MessageHub.Instance.Publish(new OnBaseDestroyed(pcBase, attacker));
                    return;
                }
            }

            DataService.SubmitDataChange(pcBase, DatabaseActionType.Update);
            DataService.SubmitDataChange(structure, DatabaseActionType.Update);
        }
Beispiel #3
0
        public void Main()
        {
            NWPlaceable     tower       = _.OBJECT_SELF;
            Guid            structureID = new Guid(tower.GetLocalString("PC_BASE_STRUCTURE_ID"));
            PCBaseStructure structure   = DataService.PCBaseStructure.GetByID(structureID);
            int             maxShieldHP = BaseService.CalculateMaxShieldHP(structure);
            var             pcBase      = DataService.PCBase.GetByID(structure.PCBaseID);

            // Regular fuel usage
            if (DateTime.UtcNow >= pcBase.DateFuelEnds && pcBase.Fuel > 0)
            {
                pcBase.Fuel--;
                BaseStructure towerStructure = DataService.BaseStructure.GetByID(structure.BaseStructureID);
                int           fuelRating     = towerStructure.FuelRating;
                int           minutes;

                switch (fuelRating)
                {
                case 1:     // Small
                    minutes = 45;
                    break;

                case 2:     // Medium
                    minutes = 15;
                    break;

                case 3:     // Large
                    minutes = 5;
                    break;

                default:
                    throw new Exception("Invalid fuel rating value: " + fuelRating);
                }

                pcBase.DateFuelEnds = DateTime.UtcNow.AddMinutes(minutes);

                // If a player is manipulating fuel, look for a fuel item and reduce its stack size or destroy it
                NWPlaceable bay = tower.GetLocalObject("CONTROL_TOWER_FUEL_BAY");
                if (bay.IsValid)
                {
                    bool isStronidium = bay.GetLocalBool("CONTROL_TOWER_FUEL_TYPE") == true;
                    if (!isStronidium)
                    {
                        NWItem fuel = _.GetFirstItemInInventory(bay.Object);

                        if (fuel.IsValid)
                        {
                            fuel.ReduceItemStack();
                        }
                    }
                }
            }

            // If completely out of power, show tower in red.
            if (pcBase.Fuel <= 0 && DateTime.UtcNow > pcBase.DateFuelEnds)
            {
                bool outOfPowerHasBeenApplied = false;
                foreach (var effect in tower.Effects)
                {
                    if (_.GetEffectTag(effect) == "CONTROL_TOWER_OUT_OF_POWER")
                    {
                        outOfPowerHasBeenApplied = true;
                        break;
                    }
                }

                if (!outOfPowerHasBeenApplied)
                {
                    Effect outOfPowerEffect = _.EffectVisualEffect(VisualEffect.Vfx_Dur_Aura_Red);
                    outOfPowerEffect = _.TagEffect(outOfPowerEffect, "CONTROL_TOWER_OUT_OF_POWER");
                    _.ApplyEffectToObject(DurationType.Permanent, outOfPowerEffect, tower.Object);

                    var instances = NWModule.Get().Areas.Where(x => x.GetLocalString("PC_BASE_STRUCTURE_ID") == structureID.ToString());

                    foreach (var instance in instances)
                    {
                        BaseService.ToggleInstanceObjectPower(instance, false);
                    }
                }
            }
            else
            {
                bool outOfPowerWasRemoved = false;
                foreach (var effect in tower.Effects)
                {
                    if (_.GetEffectTag(effect) == "CONTROL_TOWER_OUT_OF_POWER")
                    {
                        _.RemoveEffect(tower.Object, effect);
                        outOfPowerWasRemoved = true;
                        break;
                    }
                }

                if (outOfPowerWasRemoved)
                {
                    var instances = NWModule.Get().Areas.Where(x => x.GetLocalString("PC_BASE_STRUCTURE_ID") == structureID.ToString());
                    foreach (var instance in instances)
                    {
                        BaseService.ToggleInstanceObjectPower(instance, true);
                    }
                }
            }


            // Reinforced mode fuel usage
            if (pcBase.IsInReinforcedMode)
            {
                pcBase.ReinforcedFuel--;

                if (pcBase.ReinforcedFuel <= 0)
                {
                    pcBase.ReinforcedFuel     = 0;
                    pcBase.IsInReinforcedMode = false;
                }
            }
            // Tower regeneration only happens if fueled.
            else if (pcBase.DateFuelEnds > DateTime.UtcNow)
            {
                pcBase.ShieldHP += 12 + 4 * structure.StructureBonus;
            }

            if (pcBase.ShieldHP > maxShieldHP)
            {
                pcBase.ShieldHP = maxShieldHP;
            }

            DataService.SubmitDataChange(pcBase, DatabaseActionType.Update);
        }
        private void DoRetrieveStructure()
        {
            var               data           = BaseService.GetPlayerTempData(GetPC());
            PCBaseStructure   structure      = DataService.PCBaseStructure.GetByID(data.ManipulatingStructure.PCBaseStructureID);
            BaseStructure     baseStructure  = DataService.BaseStructure.GetByID(structure.BaseStructureID);
            PCBase            pcBase         = DataService.PCBase.GetByID(structure.PCBaseID);
            BaseStructureType structureType  = (BaseStructureType)baseStructure.BaseStructureTypeID;
            var               tempStorage    = _.GetObjectByTag("TEMP_ITEM_STORAGE");
            var               pcStructureID  = structure.ID;
            int               impoundedCount = 0;

            var controlTower = BaseService.GetBaseControlTower(pcBase.ID);
            int maxShields   = BaseService.CalculateMaxShieldHP(controlTower);

            if (structureType == BaseStructureType.Starship)
            {
                GetPC().SendMessage("You cannot pick up starships once they are built.  You can only fly them away.");
                return;
            }

            if (pcBase.PCBaseTypeID != (int)Enumeration.PCBaseType.Starship && pcBase.ShieldHP < maxShields && structureType != BaseStructureType.ControlTower)
            {
                GetPC().FloatingText("You cannot retrieve any structures because the control tower has less than 100% shields.");
                return;
            }

            bool canRetrieveStructures;

            if (data.BuildingType == Enumeration.BuildingType.Exterior ||
                data.BuildingType == Enumeration.BuildingType.Apartment)
            {
                canRetrieveStructures = BasePermissionService.HasBasePermission(GetPC(), data.ManipulatingStructure.PCBaseID, BasePermission.CanRetrieveStructures);
            }
            else if (data.BuildingType == Enumeration.BuildingType.Interior || data.BuildingType == Enumeration.BuildingType.Starship)
            {
                var structureID = new Guid(data.ManipulatingStructure.Structure.Area.GetLocalString("PC_BASE_STRUCTURE_ID"));
                canRetrieveStructures = BasePermissionService.HasStructurePermission(GetPC(), structureID, StructurePermission.CanRetrieveStructures);
            }
            else
            {
                throw new Exception("BaseManagementTool -> DoRetrieveStructure: Cannot handle building type " + data.BuildingType);
            }

            if (!canRetrieveStructures)
            {
                GetPC().FloatingText("You don't have permission to retrieve structures.");
                return;
            }

            if (structureType == BaseStructureType.ControlTower)
            {
                var structureCount = DataService.PCBaseStructure.GetAllByPCBaseID(structure.PCBaseID).Count();

                if (structureCount > 1)
                {
                    GetPC().FloatingText("You must remove all structures in this sector before picking up the control tower.");
                    return;
                }

                // Impound resources retrieved by drills.
                var items = DataService.PCBaseStructureItem.GetAllByPCBaseStructureID(structure.ID);
                foreach (var item in items)
                {
                    ImpoundService.Impound(item);
                    DataService.SubmitDataChange(item, DatabaseActionType.Delete);
                    impoundedCount++;
                }
            }
            else if (structureType == BaseStructureType.Building)
            {
                var childStructures = DataService.PCBaseStructure.GetAllByParentPCBaseStructureID(structure.ID).ToList();
                for (int x = childStructures.Count - 1; x >= 0; x--)
                {
                    var    furniture     = childStructures.ElementAt(x);
                    NWItem furnitureItem = BaseService.ConvertStructureToItem(furniture, tempStorage);
                    ImpoundService.Impound(GetPC().GlobalID, furnitureItem);
                    furnitureItem.Destroy();

                    DataService.SubmitDataChange(furniture, DatabaseActionType.Delete);
                    impoundedCount++;
                }

                // Remove any primary owner permissions.
                var primaryOwner = DataService.Player.GetByPrimaryResidencePCBaseStructureIDOrDefault(structure.ID);
                if (primaryOwner != null)
                {
                    primaryOwner.PrimaryResidencePCBaseStructureID = null;
                    DataService.SubmitDataChange(primaryOwner, DatabaseActionType.Update);
                }

                // Remove any access permissions.
                foreach (var buildingPermission in DataService.PCBaseStructurePermission.GetAllByPCBaseStructureID(structure.ID))
                {
                    DataService.SubmitDataChange(buildingPermission, DatabaseActionType.Delete);
                }
            }
            else if (structureType == BaseStructureType.StarshipProduction && data.ManipulatingStructure.Structure.GetLocalInt("DOCKED_STARSHIP") == 1)
            {
                GetPC().SendMessage("You cannot move a dock that has a starship docked in it.  Fly the ship away first.");
                return;
            }

            BaseService.ConvertStructureToItem(structure, GetPC());
            DataService.SubmitDataChange(structure, DatabaseActionType.Delete);
            data.ManipulatingStructure.Structure.Destroy();

            // Impound any fuel that's over the limit.
            if (structureType == BaseStructureType.StronidiumSilo || structureType == BaseStructureType.FuelSilo)
            {
                int maxFuel           = BaseService.CalculateMaxFuel(pcBase.ID);
                int maxReinforcedFuel = BaseService.CalculateMaxReinforcedFuel(pcBase.ID);

                if (pcBase.Fuel > maxFuel)
                {
                    int    returnAmount = pcBase.Fuel - maxFuel;
                    NWItem refund       = _.CreateItemOnObject("fuel_cell", tempStorage, returnAmount);
                    pcBase.Fuel = maxFuel;
                    ImpoundService.Impound(pcBase.PlayerID, refund);
                    GetPC().SendMessage("Excess fuel cells have been impounded by the planetary government. The owner of the base will need to retrieve it.");
                    refund.Destroy();
                }

                if (pcBase.ReinforcedFuel > maxReinforcedFuel)
                {
                    int    returnAmount = pcBase.ReinforcedFuel - maxReinforcedFuel;
                    NWItem refund       = _.CreateItemOnObject("stronidium", tempStorage, returnAmount);
                    pcBase.ReinforcedFuel = maxReinforcedFuel;
                    ImpoundService.Impound(pcBase.PlayerID, refund);
                    GetPC().SendMessage("Excess stronidium units have been impounded by the planetary government. The owner of the base will need to retrieve it.");
                    refund.Destroy();
                }
            }
            else if (structureType == BaseStructureType.ResourceSilo)
            {
                int maxResources = BaseService.CalculateResourceCapacity(pcBase.ID);
                var items        = DataService.PCBaseStructureItem.GetAllByPCBaseStructureID(controlTower.ID).ToList();

                while (items.Count > maxResources)
                {
                    var item = items.ElementAt(0);

                    var impoundItem = new PCImpoundedItem
                    {
                        PlayerID      = pcBase.PlayerID,
                        ItemResref    = item.ItemResref,
                        ItemObject    = item.ItemObject,
                        DateImpounded = DateTime.UtcNow,
                        ItemName      = item.ItemName,
                        ItemTag       = item.ItemTag
                    };

                    DataService.SubmitDataChange(impoundItem, DatabaseActionType.Insert);
                    GetPC().SendMessage(item.ItemName + " has been impounded by the planetary government because your base ran out of space to store resources. The owner of the base will need to retrieve it.");
                    DataService.SubmitDataChange(item, DatabaseActionType.Delete);
                }
            }

            // Update the cache
            List <AreaStructure> areaStructures = data.TargetArea.Data["BASE_SERVICE_STRUCTURES"];
            var records = areaStructures.Where(x => x.PCBaseStructureID == pcStructureID).ToList();

            for (int x = records.Count() - 1; x >= 0; x--)
            {
                var record = records[x];
                record.ChildStructure?.Destroy();
                areaStructures.Remove(record);
            }

            EndConversation();

            if (impoundedCount > 0)
            {
                GetPC().FloatingText(impoundedCount + " item(s) were sent to the planetary impound.");
            }
        }