diff --git a/common/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/common/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index 5fb57fe5d..c5a0a437d 100644 --- a/common/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/common/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -45,7 +45,8 @@ class PlayerControl(player : Player) extends Actor // todo: disable implants with stamina cost when changing armour type val implantSlot = player.ImplantSlot(slot) - if(status == 0 && implantSlot.Active) { + // Allow uninitialized implants to be deactivated in case they're stuck in a state where they are no longer active or initialized but still draining stamina (e.g. by EMP) + if(status == 0 && (implantSlot.Active || !implantSlot.Initialized)) { // Cancel stamina drain timer implantSlotStaminaDrainTimers(slot).cancel() implantSlotStaminaDrainTimers(slot) = DefaultCancellable.obj @@ -261,7 +262,7 @@ class PlayerControl(player : Player) extends Actor for(slot <- 0 to player.Implants.length - 1) { // Deactivate & uninitialize all implants player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.Id, AvatarAction.PlanetsideAttribute(player.GUID, 28, player.Implant(slot).id * 2)) // Deactivation sound / effect - events ! AvatarServiceMessage(player.Name, AvatarAction.DeactivateImplantSlot(guid, slot)) + self ! Player.ImplantActivation(slot, 0) PlayerControl.UninitializeImplant(player, slot) } diff --git a/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSilo.scala b/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSilo.scala index 315902bf9..b9ac5669c 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSilo.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSilo.scala @@ -39,11 +39,7 @@ class ResourceSilo extends Amenity { LowNtuWarningOn } - def CapacitorDisplay : Long = capacitorDisplay - def CapacitorDisplay_=(value: Long) : Long = { - capacitorDisplay = value - CapacitorDisplay - } + def CapacitorDisplay : Long = scala.math.ceil((ChargeLevel.toFloat / MaximumCharge.toFloat) * 10).toInt def Definition : ResourceSiloDefinition = GlobalDefinitions.resource_silo diff --git a/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala b/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala index 57f1c4e0e..e6198f403 100644 --- a/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala +++ b/common/src/main/scala/net/psforever/objects/serverobject/resourcesilo/ResourceSiloControl.scala @@ -50,6 +50,7 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio case ResourceSilo.UpdateChargeLevel(amount: Int) => val siloChargeBeforeChange = resourceSilo.ChargeLevel + val siloDisplayBeforeChange = resourceSilo.CapacitorDisplay val building = resourceSilo.Owner.asInstanceOf[Building] val zone = building.Zone @@ -59,11 +60,9 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio log.trace(s"UpdateChargeLevel: Silo ${resourceSilo.GUID} set to ${resourceSilo.ChargeLevel}") } - val ntuBarLevel = scala.math.ceil((resourceSilo.ChargeLevel.toFloat / resourceSilo.MaximumCharge.toFloat) * 10).toInt // Only send updated capacitor display value to all clients if it has actually changed - if(resourceSilo.CapacitorDisplay != ntuBarLevel) { - log.trace(s"Silo ${resourceSilo.GUID} NTU bar level has changed from ${resourceSilo.CapacitorDisplay} to $ntuBarLevel") - resourceSilo.CapacitorDisplay = ntuBarLevel + if(resourceSilo.CapacitorDisplay != siloDisplayBeforeChange) { + log.trace(s"Silo ${resourceSilo.GUID} NTU bar level has changed from $siloDisplayBeforeChange to ${resourceSilo.CapacitorDisplay}") resourceSilo.Owner.Actor ! Building.SendMapUpdate(all_clients = true) zone.AvatarEvents ! AvatarServiceMessage( zone.Id, diff --git a/common/src/main/scala/net/psforever/packet/game/ZoneForcedCavernConnectionsMessage.scala b/common/src/main/scala/net/psforever/packet/game/ZoneForcedCavernConnectionsMessage.scala index 0a10fe33a..447413542 100644 --- a/common/src/main/scala/net/psforever/packet/game/ZoneForcedCavernConnectionsMessage.scala +++ b/common/src/main/scala/net/psforever/packet/game/ZoneForcedCavernConnectionsMessage.scala @@ -8,7 +8,13 @@ import scodec.codecs._ /** * Dispatched to the client in regards to cavern connections via geowarp gates. * @param zone the zone - * @param unk na + * @param unk determines the number and composition of cavern links + * assuming two geowarps per continent the logic seems to be roughly: + * 0 - gate A disabled, B active + * 1 - gate A active, B disabled + * 2 - gate A and B active + * 3 - same as 2 (no change in destination) + * Destinations also change (north/south/east/west), but seemingly only to two of the currently active caverns can be linked to? */ final case class ZoneForcedCavernConnectionsMessage(zone : Int, unk : Int) diff --git a/common/src/main/scala/services/vehicle/support/VehicleRemover.scala b/common/src/main/scala/services/vehicle/support/VehicleRemover.scala index 131eaabbb..3637393a5 100644 --- a/common/src/main/scala/services/vehicle/support/VehicleRemover.scala +++ b/common/src/main/scala/services/vehicle/support/VehicleRemover.scala @@ -1,6 +1,7 @@ // Copyright (c) 2017 PSForever package services.vehicle.support +import akka.actor.ActorRef import net.psforever.objects.Vehicle import net.psforever.objects.guid.{GUIDTask, TaskResolver} import net.psforever.objects.zones.Zone @@ -26,7 +27,9 @@ class VehicleRemover extends RemoverActor { entry.zone.GUID(vehicleGUID) match { case Some(vehicle : Vehicle) if vehicle.HasGUID => val zoneId = entry.zone.Id - vehicle.Actor ! Vehicle.PrepareForDeletion() + if(vehicle.Actor != ActorRef.noSender) { + vehicle.Actor ! Vehicle.PrepareForDeletion() + } //escape being someone else's cargo (vehicle.MountedIn match { case Some(carrierGUID) => diff --git a/common/src/test/scala/objects/ResourceSiloTest.scala b/common/src/test/scala/objects/ResourceSiloTest.scala index 27d08ca49..4f6445e8a 100644 --- a/common/src/test/scala/objects/ResourceSiloTest.scala +++ b/common/src/test/scala/objects/ResourceSiloTest.scala @@ -36,10 +36,9 @@ class ResourceSiloTest extends Specification { // obj.ChargeLevel = 50 obj.LowNtuWarningOn = false - obj.CapacitorDisplay = 75 obj.ChargeLevel mustEqual 50 obj.LowNtuWarningOn mustEqual false - obj.CapacitorDisplay mustEqual 75 + obj.CapacitorDisplay mustEqual 1 } "charge level can not exceed limits(0 to maximum)" in { @@ -237,7 +236,6 @@ class ResourceSiloControlUpdate2Test extends ActorTest { bldg.Actor = buildingEvents.ref obj.ChargeLevel = 100 - obj.CapacitorDisplay = 1 obj.LowNtuWarningOn = true assert(obj.ChargeLevel == 100) assert(obj.CapacitorDisplay == 1) @@ -295,7 +293,6 @@ class ResourceSiloControlNoUpdateTest extends ActorTest { bldg.Actor = buildingEvents.ref obj.ChargeLevel = 250 - obj.CapacitorDisplay = 3 obj.LowNtuWarningOn = false assert(obj.ChargeLevel == 250) assert(obj.CapacitorDisplay == 3) diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 6552b5b78..c132f904c 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -1157,7 +1157,8 @@ class WorldSessionActor extends Actor //in between subsequent reply messages, it does not matter if the destination changes //so long as there is at least one destination at all (including the fallback) if(ContemplateZoningResponse(Zoning.InstantAction.Request(player.Faction))) { - SpawnThroughZoningProcess(zone, spawn_point.Position, spawn_point) + val (pos, ori) = spawn_point.SpecificPoint(player) + SpawnThroughZoningProcess(zone, pos, ori) } else if(zoningStatus != Zoning.Status.None) { instantActionFallbackDestination = Some(msg) @@ -1167,7 +1168,8 @@ class WorldSessionActor extends Actor instantActionFallbackDestination match { case Some(Zoning.InstantAction.Located(zone, _, spawn_point)) if spawn_point.Owner.Faction == player.Faction && !spawn_point.Offline => if(ContemplateZoningResponse(Zoning.InstantAction.Request(player.Faction))) { - SpawnThroughZoningProcess(zone, spawn_point.Position, spawn_point) + val (pos, ori) = spawn_point.SpecificPoint(player) + SpawnThroughZoningProcess(zone, pos, ori) } else if(zoningCounter == 0) { CancelZoningProcessWithReason("@InstantActionNoHotspotsAvailable") @@ -1179,7 +1181,8 @@ class WorldSessionActor extends Actor case Zoning.Recall.Located(zone, spawn_point) => if(ContemplateZoningResponse(Zoning.Recall.Request(player.Faction, zone.Id))) { - SpawnThroughZoningProcess(zone, spawn_point.Position, spawn_point) + val (pos, ori) = spawn_point.SpecificPoint(player) + SpawnThroughZoningProcess(zone, pos, ori) } case Zoning.Recall.Denied(reason) => @@ -1591,10 +1594,10 @@ class WorldSessionActor extends Actor /** * Use the zoning process using some spawnable entity in the destination zone. * @param zone the destination zone - * @param spawnPosition the destination spawn position (may not be related to `spawnPoint`) - * @param spawnPoint a `SpawntPoint` entity that is the target of our spawning in the destination zone + * @param spawnPosition the destination spawn position + * @param spawnOrientation the destination spawn orientation */ - def SpawnThroughZoningProcess(zone : Zone, spawnPosition : Vector3, spawnPoint : SpawnPoint) : Unit = { + def SpawnThroughZoningProcess(zone : Zone, spawnPosition : Vector3, spawnOrientation : Vector3) : Unit = { CancelZoningProcess() PlayerActionsToCancel() CancelAllProximityUnits() @@ -1608,7 +1611,7 @@ class WorldSessionActor extends Actor //zone loading will take long enough 0L } - LoadZonePhysicalSpawnPoint(zone.Id, spawnPosition, spawnPoint.Orientation, respawnTime) + LoadZonePhysicalSpawnPoint(zone.Id, spawnPosition, spawnOrientation, respawnTime) } /** @@ -4329,55 +4332,59 @@ class WorldSessionActor extends Actor } } CSRZone.read(traveler, msg) match { - case (true, zone, pos) if player.isAlive => - deadState = DeadState.Release //cancel movement updates - PlayerActionsToCancel() - continent.GUID(player.VehicleSeated) match { - case Some(vehicle : Vehicle) if vehicle.MountedIn.isEmpty => - vehicle.PassengerInSeat(player) match { - case Some(0) => - vehicle.Position = pos - CancelAllProximityUnits() - LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0) - case _ => //not seated as the driver, in which case we can't move - deadState = DeadState.Alive - } - case None => - player.Position = pos - CancelAllProximityUnits() - //continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player.GUID, player.GUID)) - CancelZoningProcess() - LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0) - case _ => //seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move - deadState = DeadState.Alive + case (true, zone, pos) => + if (player.isAlive && zone != player.Continent && (admin || zone == "z8" || zone == "c1" || zone == "c2" || zone == "c3" || zone == "c4" || zone == "c5" || zone == "c6" || + zone == "tzshtr" || zone == "tzcotr" || zone == "tzdrtr" || + zone == "tzshnc" || zone == "tzconc" || zone == "tzdrnc" || + zone == "tzshvs" || zone == "tzcovs" || zone == "tzdrvs")) { + deadState = DeadState.Release //cancel movement updates + PlayerActionsToCancel() + continent.GUID(player.VehicleSeated) match { + case Some(vehicle : Vehicle) if vehicle.MountedIn.isEmpty => + vehicle.PassengerInSeat(player) match { + case Some(0) => + vehicle.Position = pos + LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0) + case _ => //not seated as the driver, in which case we can't move + deadState = DeadState.Alive + } + case None => + player.Position = pos + //continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player.GUID, player.GUID)) + LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0) + case _ => //seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move + deadState = DeadState.Alive + } } - case (_, _, _) => ; } - CSRWarp.read(traveler, msg) match { - case (true, pos) if player.isAlive => - deadState = DeadState.Release //cancel movement updates - PlayerActionsToCancel() - continent.GUID(player.VehicleSeated) match { - case Some(vehicle : Vehicle) if vehicle.MountedIn.isEmpty => - vehicle.PassengerInSeat(player) match { - case Some(0) => - vehicle.Position = pos - CancelAllProximityUnits() - LoadZonePhysicalSpawnPoint(continent.Id, pos, Vector3.z(vehicle.Orientation.z), 0) - case _ => //not seated as the driver, in which case we can't move - deadState = DeadState.Alive - } - case None => - player.Position = pos - CancelAllProximityUnits() - CancelZoningProcessWithDescriptiveReason("cancel_motion") - sendResponse(PlayerStateShiftMessage(ShiftState(0, pos, player.Orientation.z, None))) - deadState = DeadState.Alive //must be set here - case _ => //seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move - deadState = DeadState.Alive - } + CSRWarp.read(traveler, msg) match { + case (true, pos) => + // continent.Id == "c1" || continent.Id == "c2" || continent.Id == "c3" || continent.Id == "c4" || continent.Id == "c5" || continent.Id == "c6" || + if (player.isAlive && (admin || continent.Id == "z8" || + continent.Id == "tzshtr" || continent.Id == "tzcotr" || continent.Id == "tzdrtr" || + continent.Id == "tzshnc" || continent.Id == "tzconc" || continent.Id == "tzdrnc" || + continent.Id == "tzshvs" || continent.Id == "tzcovs" || continent.Id == "tzdrvs")) { + deadState = DeadState.Release //cancel movement updates + PlayerActionsToCancel() + continent.GUID(player.VehicleSeated) match { + case Some(vehicle : Vehicle) if vehicle.MountedIn.isEmpty => + vehicle.PassengerInSeat(player) match { + case Some(0) => + vehicle.Position = pos + LoadZonePhysicalSpawnPoint(continent.Id, pos, Vector3.z(vehicle.Orientation.z), 0) + case _ => //not seated as the driver, in which case we can't move + deadState = DeadState.Alive + } + case None => + player.Position = pos + sendResponse(PlayerStateShiftMessage(ShiftState(0, pos, player.Orientation.z, None))) + deadState = DeadState.Alive //must be set here + case _ => //seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move + deadState = DeadState.Alive + } + } case (_, _) => ; } diff --git a/pslogin/src/main/scala/Zones.scala b/pslogin/src/main/scala/Zones.scala index eeb7da93c..eb3d91b0e 100644 --- a/pslogin/src/main/scala/Zones.scala +++ b/pslogin/src/main/scala/Zones.scala @@ -14,10 +14,7 @@ object Zones { HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules - BuildingByMapId(1).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR - BuildingByMapId(2).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR - BuildingByMapId(3).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR - BuildingByMapId(4).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR + InitZoneAmenities(zone = this) } } @@ -26,6 +23,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -34,6 +33,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -43,13 +44,8 @@ object Zones { HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules - Buildings.values.flatMap { - _.Amenities.collect { - case amenity if amenity.Definition == GlobalDefinitions.resource_silo => - val silo = amenity.asInstanceOf[ResourceSilo] - silo.ChargeLevel = silo.MaximumCharge - } - } + InitZoneAmenities(zone = this) + BuildingByMapId(5).get.Faction = PlanetSideEmpire.TR //Akkan BuildingByMapId(6).get.Faction = PlanetSideEmpire.TR //Baal BuildingByMapId(7).get.Faction = PlanetSideEmpire.TR //Dagon @@ -119,6 +115,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -128,21 +126,12 @@ object Zones { HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules - GUID(2094) match { - case Some(silo : ResourceSilo) => - silo.ChargeLevel = silo.MaximumCharge - case _ => ; - } import net.psforever.types.PlanetSideEmpire BuildingByMapId(2).get.Faction = PlanetSideEmpire.VS - BuildingByMapId(10).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS - BuildingByMapId(11).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS - BuildingByMapId(12).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS - BuildingByMapId(13).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS BuildingByMapId(48).get.Faction = PlanetSideEmpire.VS BuildingByMapId(49).get.Faction = PlanetSideEmpire.VS - BuildingByMapId(18657).get.asInstanceOf[WarpGate].Active = false - BuildingByMapId(18658).get.asInstanceOf[WarpGate].Active = false + + InitZoneAmenities(zone = this) } } @@ -151,6 +140,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -159,6 +150,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -167,6 +160,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -175,6 +170,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -184,6 +181,8 @@ object Zones { import net.psforever.types.PlanetSideEmpire Buildings.values.foreach { _.Faction = PlanetSideEmpire.NC } + + InitZoneAmenities(zone = this) } } @@ -193,9 +192,8 @@ object Zones { import net.psforever.types.PlanetSideEmpire Buildings.values.foreach { _.Faction = PlanetSideEmpire.TR } - BuildingByMapId(1).get.asInstanceOf[WarpGate].Broadcast = true - BuildingByMapId(2).get.asInstanceOf[WarpGate].Broadcast = true - BuildingByMapId(3).get.asInstanceOf[WarpGate].Broadcast = true + + InitZoneAmenities(zone = this) } } @@ -205,9 +203,8 @@ object Zones { import net.psforever.types.PlanetSideEmpire Buildings.values.foreach { _.Faction = PlanetSideEmpire.VS } - BuildingByMapId(60).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower - BuildingByMapId(1).get.asInstanceOf[WarpGate].Broadcast = true - BuildingByMapId(3).get.asInstanceOf[WarpGate].Broadcast = true + + InitZoneAmenities(zone = this) } } @@ -234,6 +231,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -242,6 +241,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -250,6 +251,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -258,6 +261,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -266,6 +271,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -274,6 +281,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -282,6 +291,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -290,6 +301,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -298,6 +311,8 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) } } @@ -306,6 +321,37 @@ object Zones { super.Init(context) HotSpotCoordinateFunction = Zones.HotSpots.StandardRemapping(Map.Scale, 80, 80) HotSpotTimeFunction = Zones.HotSpots.StandardTimeRules + + InitZoneAmenities(zone = this) + } + } + + def InitZoneAmenities(zone: Zone): Unit = { + InitResourceSilos(zone) + InitWarpGates(zone) + + def InitWarpGates(zone: Zone): Unit = { + // todo: work out which faction owns links to this warpgate and if they should be marked as broadcast or not + // todo: enable geowarps to go to the correct cave + zone.Buildings.values.collect { + case wg : WarpGate if wg.Definition == GlobalDefinitions.warpgate || wg.Definition == GlobalDefinitions.warpgate_small => + wg.Active = true + wg.Faction = PlanetSideEmpire.NEUTRAL + wg.Broadcast = true + case geowarp : WarpGate if geowarp.Definition == GlobalDefinitions.warpgate_cavern || geowarp.Definition == GlobalDefinitions.hst => + geowarp.Faction = PlanetSideEmpire.NEUTRAL + geowarp.Active = false + } + } + + def InitResourceSilos(zone: Zone): Unit = { + // todo: load silo charge from database + zone.Buildings.values.flatMap { + _.Amenities.collect { + case silo : ResourceSilo => + silo.Actor ! ResourceSilo.UpdateChargeLevel(silo.MaximumCharge) + } + } } }