NTU Related fixes/changes (#308)

* Send map updates when NTU bar changes

* Make bases turn neutral when NTU hits 0

* Fix sync of low NTU warning light to players joining zone

* Swap IFF Lock logic around to allow for more efficient short circuiting of checks

* Small fix to stop player disconnect when hacking an object that no longer has a GUID
This commit is contained in:
Mazo 2020-01-05 03:58:48 +00:00 committed by Fate-JH
parent 16c20eaeac
commit ebd8170de4
3 changed files with 21 additions and 12 deletions

View file

@ -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

View file

@ -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.

View file

@ -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))