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.packet.game._
import net.psforever.types.{PlanetSideEmpire, Vector3} import net.psforever.types.{PlanetSideEmpire, Vector3}
import scalax.collection.{Graph, GraphEdge} import scalax.collection.{Graph, GraphEdge}
import services.Service
import services.local.{LocalAction, LocalServiceMessage}
class Building(private val name: String, class Building(private val name: String,
private val building_guid : Int, private val building_guid : Int,
@ -28,6 +30,8 @@ class Building(private val name: String,
*/ */
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
private var playersInSOI : List[Player] = List.empty 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) super.Zone_=(zone)
GUID = PlanetSideGUID(building_guid) GUID = PlanetSideGUID(building_guid)
@ -38,10 +42,31 @@ class Building(private val name: String,
def MapId : Int = map_id 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 def Faction : PlanetSideEmpire.Value = faction
override def Faction_=(fac : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = { override def Faction_=(fac : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
faction = fac 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() TriggerZoneMapUpdate()
Faction Faction
} }
@ -95,6 +120,34 @@ class Building(private val name: String,
if(Actor != ActorRef.noSender) Actor ! Building.TriggerZoneMapUpdate(Zone.Number) 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 // Get all lattice neighbours matching the specified faction
def Neighbours(faction: PlanetSideEmpire.Value): Option[Set[Building]] = { def Neighbours(faction: PlanetSideEmpire.Value): Option[Set[Building]] = {
this.Neighbours match { this.Neighbours match {
@ -192,7 +245,7 @@ class Building(private val name: String,
None, None,
generatorState, generatorState,
spawnTubesNormal, spawnTubesNormal,
false, //force_dome_active ForceDomeActive,
latticeBenefit, latticeBenefit,
0, //cavern_benefit; !! Field > 0 will cause malformed packet. See class def. 0, //cavern_benefit; !! Field > 0 will cause malformed packet. See class def.
Nil, Nil,

View file

@ -146,6 +146,11 @@ class LocalService(zone : Zone) extends Actor {
LocalEvents.publish( LocalEvents.publish(
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.TriggerSound(sound, pos, unk, volume)) 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 _ => ; 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 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 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 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 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 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 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) => case LocalResponse.TriggerSound(sound, pos, unk, volume) =>
sendResponse(TriggerSoundMessage(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 _ => ; case _ => ;
} }
} }
@ -7594,6 +7601,12 @@ class WorldSessionActor extends Actor
def configZone(zone : Zone) : Unit = { def configZone(zone : Zone) : Unit = {
zone.Buildings.values.foreach(building => { zone.Buildings.values.foreach(building => {
sendResponse(SetEmpireMessage(building.GUID, building.Faction)) 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 => { building.Amenities.foreach(amenity => {
val amenityId = amenity.GUID val amenityId = amenity.GUID
sendResponse(PlanetsideAttributeMessage(amenityId, 50, 0)) sendResponse(PlanetsideAttributeMessage(amenityId, 50, 0))