Basic functionality for capitol force domes (#315)

This commit is contained in:
Mazo 2020-01-08 13:31:02 +00:00 committed by Fate-JH
parent ddf702eea9
commit 50df2bace0
5 changed files with 74 additions and 1 deletions

View file

@ -15,6 +15,8 @@ import net.psforever.objects.zones.Zone
import net.psforever.packet.game._
import net.psforever.types.{PlanetSideEmpire, Vector3}
import scalax.collection.{Graph, GraphEdge}
import services.Service
import services.local.{LocalAction, LocalServiceMessage}
class Building(private val name: String,
private val building_guid : Int,
@ -28,6 +30,8 @@ class Building(private val name: String,
*/
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
private var playersInSOI : List[Player] = List.empty
private val capitols = List("Thoth", "Voltan", "Neit", "Anguta", "Eisa", "Verica")
private var forceDomeActive : Boolean = false
super.Zone_=(zone)
GUID = PlanetSideGUID(building_guid)
@ -38,10 +42,31 @@ class Building(private val name: String,
def MapId : Int = map_id
def IsCapitol : Boolean = capitols.contains(name)
def IsSubCapitol : Boolean = {
Neighbours match {
case Some(buildings: Set[Building]) => !buildings.filter(x => capitols.contains(x.name)).isEmpty
case None => false
}
}
def ForceDomeActive : Boolean = forceDomeActive
def ForceDomeActive_=(activated : Boolean) : Boolean = {
forceDomeActive = activated
forceDomeActive
}
def Faction : PlanetSideEmpire.Value = faction
override def Faction_=(fac : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
faction = fac
if(IsSubCapitol) {
Neighbours match {
case Some(buildings: Set[Building]) => buildings.filter(x => x.IsCapitol).head.UpdateForceDomeStatus()
case None => ;
}
} else if (IsCapitol) {
UpdateForceDomeStatus()
}
TriggerZoneMapUpdate()
Faction
}
@ -95,6 +120,34 @@ class Building(private val name: String,
if(Actor != ActorRef.noSender) Actor ! Building.TriggerZoneMapUpdate(Zone.Number)
}
def UpdateForceDomeStatus() : Unit = {
if(IsCapitol) {
val originalStatus = ForceDomeActive
if(Faction == PlanetSideEmpire.NEUTRAL) {
ForceDomeActive = false
} else {
val ownedSubCapitols = Neighbours(Faction) match {
case Some(buildings: Set[Building]) => buildings.size
case None => 0
}
if(ForceDomeActive && ownedSubCapitols <= 1) {
ForceDomeActive = false
} else if(!ForceDomeActive && ownedSubCapitols > 1) {
ForceDomeActive = true
}
}
if(originalStatus != ForceDomeActive) {
if(Actor != ActorRef.noSender) {
Zone.LocalEvents ! LocalServiceMessage(Zone.Id, LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, GUID, ForceDomeActive))
Actor ! Building.SendMapUpdate(all_clients = true)
}
}
}
}
// Get all lattice neighbours matching the specified faction
def Neighbours(faction: PlanetSideEmpire.Value): Option[Set[Building]] = {
this.Neighbours match {
@ -192,7 +245,7 @@ class Building(private val name: String,
None,
generatorState,
spawnTubesNormal,
false, //force_dome_active
ForceDomeActive,
latticeBenefit,
0, //cavern_benefit; !! Field > 0 will cause malformed packet. See class def.
Nil,

View file

@ -146,6 +146,11 @@ class LocalService(zone : Zone) extends Actor {
LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.TriggerSound(sound, pos, unk, volume))
)
case LocalAction.UpdateForceDomeStatus(player_guid, building_guid, activated) => {
LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.UpdateForceDomeStatus(building_guid, activated))
)
}
case _ => ;
}

View file

@ -39,4 +39,5 @@ object LocalAction {
final case class TriggerEffectInfo(player_guid : PlanetSideGUID, effect : String, target : PlanetSideGUID, unk1 : Boolean, unk2 : Long) extends Action
final case class TriggerEffectLocation(player_guid : PlanetSideGUID, effect : String, pos : Vector3, orient : Vector3) extends Action
final case class TriggerSound(player_guid : PlanetSideGUID, sound : TriggeredSound.Value, pos : Vector3, unk : Int, volume : Float) extends Action
final case class UpdateForceDomeStatus(player_guid : PlanetSideGUID, building_guid : PlanetSideGUID, activated : Boolean) extends Action
}

View file

@ -35,4 +35,5 @@ object LocalResponse {
final case class ToggleTeleportSystem(router : Vehicle, systemPlan : Option[(Utility.InternalTelepad, TelepadDeployable)]) extends Response
final case class TriggerEffect(target: PlanetSideGUID, effect: String, effectInfo: Option[TriggeredEffect] = None, triggeredLocation: Option[TriggeredEffectLocation] = None) extends Response
final case class TriggerSound(sound : TriggeredSound.Value, pos : Vector3, unk : Int, volume : Float) extends Response
final case class UpdateForceDomeStatus(building_guid : PlanetSideGUID, activated : Boolean) extends Response
}

View file

@ -1688,6 +1688,13 @@ class WorldSessionActor extends Actor
case LocalResponse.TriggerSound(sound, pos, unk, volume) =>
sendResponse(TriggerSoundMessage(sound, pos, unk, volume))
case LocalResponse.UpdateForceDomeStatus(building_guid, activated) => {
if(activated) {
sendResponse(GenericObjectActionMessage(building_guid, 11))
} else {
sendResponse(GenericObjectActionMessage(building_guid, 12))
}
}
case _ => ;
}
}
@ -7594,6 +7601,12 @@ class WorldSessionActor extends Actor
def configZone(zone : Zone) : Unit = {
zone.Buildings.values.foreach(building => {
sendResponse(SetEmpireMessage(building.GUID, building.Faction))
// Synchronise capitol force dome state
if(building.IsCapitol && building.ForceDomeActive) {
sendResponse(GenericObjectActionMessage(building.GUID, 13))
}
building.Amenities.foreach(amenity => {
val amenityId = amenity.GUID
sendResponse(PlanetsideAttributeMessage(amenityId, 50, 0))