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 3572d978..ac73f519 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 @@ -9,6 +9,7 @@ import net.psforever.packet.game.UseItemMessage class ResourceSilo extends Amenity { private var chargeLevel : Int = 0 private val maximumCharge : Int = 1000 + // For the flashing red light on top of the NTU silo on. // Default to true until charge level can be persisted across restarts as default charge level is 0 private var lowNtuWarningOn : Boolean = true 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 100e4b54..68287d67 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 @@ -4,7 +4,9 @@ package net.psforever.objects.serverobject.resourcesilo import akka.actor.Actor import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} import net.psforever.objects.serverobject.structures.Building +import net.psforever.types.PlanetSideEmpire import services.avatar.{AvatarAction, AvatarServiceMessage} +import services.local.{LocalAction, LocalServiceMessage} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.duration._ @@ -41,6 +43,8 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio case ResourceSilo.UpdateChargeLevel(amount: Int) => val siloChargeBeforeChange = resourceSilo.ChargeLevel + val building = resourceSilo.Owner.asInstanceOf[Building] + val zone = building.Zone // Increase if positive passed in or decrease charge level if negative number is passed in resourceSilo.ChargeLevel += amount @@ -54,12 +58,11 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio log.trace(s"Silo ${resourceSilo.GUID} NTU bar level has changed from ${resourceSilo.CapacitorDisplay} to $ntuBarLevel") resourceSilo.CapacitorDisplay = ntuBarLevel resourceSilo.Owner.Actor ! Building.SendMapUpdate(all_clients = true) - val building = resourceSilo.Owner - val zone = building.Zone zone.AvatarEvents ! AvatarServiceMessage( zone.Id, AvatarAction.PlanetsideAttribute(resourceSilo.GUID, 45, resourceSilo.CapacitorDisplay) ) + building.Actor ! Building.SendMapUpdate(all_clients = true) } val ntuIsLow = resourceSilo.ChargeLevel.toFloat / resourceSilo.MaximumCharge.toFloat < 0.2f @@ -69,12 +72,11 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio self ! ResourceSilo.LowNtuWarning(enabled = true) } - val building = resourceSilo.Owner.asInstanceOf[Building] - val zone = building.Zone if(resourceSilo.ChargeLevel == 0 && siloChargeBeforeChange > 0) { // Oops, someone let the base run out of power. Shut it all down. - //todo: Make base neutral if silo hits zero NTU zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.PlanetsideAttribute(building.GUID, 48, 1)) + building.Faction = PlanetSideEmpire.NEUTRAL + zone.LocalEvents ! LocalServiceMessage(zone.Id, LocalAction.SetEmpire(building.GUID, PlanetSideEmpire.NEUTRAL)) building.TriggerZoneMapUpdate() } else if (siloChargeBeforeChange == 0 && resourceSilo.ChargeLevel > 0) { // Power restored. Reactor Online. Sensors Online. Weapons Online. All systems nominal. diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 5c283eeb..bc83a622 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -2971,7 +2971,6 @@ class WorldSessionActor extends Actor //todo: grant BEP to user //todo: grant BEP to squad in range - //todo: notify map service to update ntu % on map for all users //todo: handle silo orb / panel glow properly if more than one person is refilling silo and one player stops. effects should stay on until all players stop @@ -3036,7 +3035,12 @@ class WorldSessionActor extends Actor HackState.Ongoing } - if(vis == HackState.Cancelled) { + if(!target.HasGUID) { + // Target is gone, cancel the hack. + // Note: I couldn't find any examples of an object that no longer has a GUID in packet captures, but sending the hacking player's GUID as the target to cancel the hack seems to work + sendResponse(HackMessage(progressType, player.GUID, player.GUID, 0, 0L, HackState.Cancelled, 8L)) + } + else if(vis == HackState.Cancelled) { // Object moved. Cancel the hack (e.g. vehicle drove away) sendResponse(HackMessage(progressType, target.GUID, player.GUID, 0, 0L, vis, 8L)) } @@ -4570,16 +4574,18 @@ class WorldSessionActor extends Actor if(player.Faction == door.Faction || (continent.Map.DoorToLock.get(object_guid.guid) match { case Some(lock_guid) => val lock = continent.GUID(lock_guid).get.asInstanceOf[IFFLock] + val owner = lock.Owner.asInstanceOf[Building] val playerIsOnInside = Vector3.ScalarProjection(lock.Outwards, player.Position - door.Position) < 0f // If an IFF lock exists and the IFF lock faction doesn't match the current player and one of the following conditions are met open the door: - // A base is neutral - // A base is hacked - // The lock is hacked // The player is on the inside of the door, determined by the lock orientation + // The lock is hacked + // A base is hacked + // A base is neutral + // todo: A base is out of power (generator down) - lock.HackedBy.isDefined || lock.Owner.asInstanceOf[Building].CaptureConsoleIsHacked || lock.Faction == PlanetSideEmpire.NEUTRAL || playerIsOnInside + playerIsOnInside || lock.HackedBy.isDefined || owner.CaptureConsoleIsHacked || lock.Faction == PlanetSideEmpire.NEUTRAL case None => !door.isOpen // If there's no linked IFF lock just open the door if it's closed. })) { door.Actor ! Door.Use(player, msg) @@ -7591,7 +7597,7 @@ class WorldSessionActor extends Actor // Synchronise warning light & silo capacity val silo = amenity.asInstanceOf[ResourceSilo] sendResponse(PlanetsideAttributeMessage(amenityId, 45, silo.CapacitorDisplay)) - sendResponse(PlanetsideAttributeMessage(amenityId, 47, if(silo.LowNtuWarningOn) 1 else 0)) + sendResponse(PlanetsideAttributeMessage(silo.Owner.GUID, 47, if(silo.LowNtuWarningOn) 1 else 0)) if(silo.ChargeLevel == 0) { sendResponse(PlanetsideAttributeMessage(silo.Owner.GUID, 48, 1))