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(); }
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); }
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."); } }