mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-04-29 16:25:30 +00:00
demoted soi from being a top-level assignment of players into zone facilities, giving each player the ability to self-inform the facilities they occupy
This commit is contained in:
parent
b8ea569b1c
commit
6b0c29f502
6 changed files with 99 additions and 10 deletions
|
|
@ -2974,6 +2974,7 @@ class ZoningOperations(
|
||||||
physSpawnPoint: Option[SpawnPoint]
|
physSpawnPoint: Option[SpawnPoint]
|
||||||
): Unit = {
|
): Unit = {
|
||||||
log.info(s"${player.Name} will load in zone $zoneId at position $pos in $respawnTime")
|
log.info(s"${player.Name} will load in zone $zoneId at position $pos in $respawnTime")
|
||||||
|
player.resetInteractions()
|
||||||
respawnTimer.cancel()
|
respawnTimer.cancel()
|
||||||
reviveTimer.cancel()
|
reviveTimer.cancel()
|
||||||
deadState = DeadState.RespawnTime
|
deadState = DeadState.RespawnTime
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.objects
|
package net.psforever.objects
|
||||||
|
|
||||||
import net.psforever.objects.avatar.interaction.{TriggerOnPlayerRule, WithEntrance, WithGantry, WithLava, WithWater}
|
import net.psforever.objects.avatar.interaction.{InteractWithSOI, TriggerOnPlayerRule, WithEntrance, WithGantry, WithLava, WithWater}
|
||||||
import net.psforever.objects.avatar.{Avatar, LoadoutManager, SpecialCarry}
|
import net.psforever.objects.avatar.{Avatar, LoadoutManager, SpecialCarry}
|
||||||
import net.psforever.objects.ballistics.InteractWithRadiationClouds
|
import net.psforever.objects.ballistics.InteractWithRadiationClouds
|
||||||
import net.psforever.objects.ce.{Deployable, InteractWithMines, InteractWithTurrets}
|
import net.psforever.objects.ce.{Deployable, InteractWithMines, InteractWithTurrets}
|
||||||
|
|
@ -39,6 +39,7 @@ class Player(var avatar: Avatar)
|
||||||
with InteriorAwareFromInteraction
|
with InteriorAwareFromInteraction
|
||||||
with AuraContainer
|
with AuraContainer
|
||||||
with MountableEntity {
|
with MountableEntity {
|
||||||
|
interaction(new InteractWithSOI())
|
||||||
interaction(environment.interaction.InteractWithEnvironment(Seq(
|
interaction(environment.interaction.InteractWithEnvironment(Seq(
|
||||||
new WithEntrance(),
|
new WithEntrance(),
|
||||||
new WithWater(avatar.name),
|
new WithWater(avatar.name),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) 2025 PSForever
|
||||||
|
package net.psforever.objects.avatar.interaction
|
||||||
|
|
||||||
|
import net.psforever.objects.Player
|
||||||
|
import net.psforever.objects.serverobject.structures.Building
|
||||||
|
import net.psforever.objects.zones.{InteractsWithZone, ZoneInteraction, ZoneInteractionType}
|
||||||
|
import net.psforever.objects.zones.blockmap.SectorPopulation
|
||||||
|
import net.psforever.types.Vector3
|
||||||
|
|
||||||
|
case object SOIInteraction extends ZoneInteractionType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
*/
|
||||||
|
class InteractWithSOI()
|
||||||
|
extends ZoneInteraction {
|
||||||
|
|
||||||
|
private var skipTargetCounter: Int = 0
|
||||||
|
private var occupiedSOIs: List[(String, Building)] = List()
|
||||||
|
|
||||||
|
def Type: ZoneInteractionType = SOIInteraction
|
||||||
|
|
||||||
|
def range: Float = 0f
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
* @param sector the portion of the block map being tested
|
||||||
|
* @param target the fixed element in this test
|
||||||
|
*/
|
||||||
|
def interaction(sector: SectorPopulation, target: InteractsWithZone): Unit = {
|
||||||
|
if (skipTargetCounter < 4) {
|
||||||
|
skipTargetCounter += 1
|
||||||
|
} else {
|
||||||
|
skipTargetCounter = 0
|
||||||
|
val buildings = sector.buildingList
|
||||||
|
if (occupiedSOIs.nonEmpty || buildings.nonEmpty) {
|
||||||
|
val targetZone = target.Zone
|
||||||
|
val targetPosition = target.Position
|
||||||
|
val targetAsPlayer = target.asInstanceOf[Player]
|
||||||
|
val key = targetAsPlayer.CharId
|
||||||
|
val (ongoingOccupancy, nowUnoccupied) = occupiedSOIs.partition { case (_, b) =>
|
||||||
|
targetZone == b.Zone && Vector3.DistanceSquared(targetPosition, b.Position) < math.pow(b.Definition.SOIRadius, 2).toFloat
|
||||||
|
}
|
||||||
|
val (_, targetBuildingsOnly) = ongoingOccupancy.unzip
|
||||||
|
val (_, newOccupancy) = buildings
|
||||||
|
.filter { b =>
|
||||||
|
Vector3.DistanceSquared(b.Position, targetPosition) < math.pow(b.Definition.SOIRadius, 2)
|
||||||
|
}
|
||||||
|
.partition { b => targetBuildingsOnly.exists(_.Name.equals(b.Name)) }
|
||||||
|
occupiedSOIs = ongoingOccupancy ++ newOccupancy.map { building => (building.Name, building) }
|
||||||
|
nowUnoccupied.map(_._2).foreach { _.RemovePlayersFromSOI(key) }
|
||||||
|
newOccupancy.foreach { _.AddPlayersInSOI(key, targetAsPlayer) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def resetInteraction(target: InteractsWithZone): Unit = {
|
||||||
|
skipTargetCounter = 0
|
||||||
|
val charId = target.asInstanceOf[Player].CharId
|
||||||
|
occupiedSOIs.map(_._2).foreach { _.RemovePlayersFromSOI(charId) }
|
||||||
|
occupiedSOIs = List()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,8 @@ import net.psforever.objects.serverobject.structures.participation.{MajorFacilit
|
||||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
|
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
|
||||||
import net.psforever.util.Config
|
import net.psforever.util.Config
|
||||||
|
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
class Building(
|
class Building(
|
||||||
private val name: String,
|
private val name: String,
|
||||||
private val building_guid: Int,
|
private val building_guid: Int,
|
||||||
|
|
@ -31,7 +33,7 @@ class Building(
|
||||||
with BlockMapEntity {
|
with BlockMapEntity {
|
||||||
|
|
||||||
private var faction: PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
private var faction: PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||||
private var playersInSOI: List[Player] = List.empty
|
private var playersInSOI: mutable.HashMap[Long, Player] = mutable.HashMap[Long, Player]()
|
||||||
private var forceDomeActive: Boolean = false
|
private var forceDomeActive: Boolean = false
|
||||||
private var participationFunc: ParticipationLogic = NoParticipation
|
private var participationFunc: ParticipationLogic = NoParticipation
|
||||||
super.Zone_=(zone)
|
super.Zone_=(zone)
|
||||||
|
|
@ -69,9 +71,10 @@ class Building(
|
||||||
Faction
|
Faction
|
||||||
}
|
}
|
||||||
|
|
||||||
def PlayersInSOI: List[Player] = playersInSOI
|
def PlayersInSOI: List[Player] = playersInSOI.values.toList
|
||||||
|
|
||||||
def PlayersInSOI_=(list: List[Player]): List[Player] = {
|
def PlayersInSOI_=(list: List[Player]): List[Player] = {
|
||||||
|
//todo
|
||||||
if (playersInSOI.isEmpty && list.nonEmpty) {
|
if (playersInSOI.isEmpty && list.nonEmpty) {
|
||||||
Amenities.collect {
|
Amenities.collect {
|
||||||
case box: Painbox =>
|
case box: Painbox =>
|
||||||
|
|
@ -83,9 +86,29 @@ class Building(
|
||||||
box.Actor ! Painbox.Stop()
|
box.Actor ! Painbox.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playersInSOI = list
|
list.foreach { player =>
|
||||||
|
playersInSOI.put(player.CharId, player)
|
||||||
|
}
|
||||||
participationFunc.TryUpdate()
|
participationFunc.TryUpdate()
|
||||||
playersInSOI
|
PlayersInSOI
|
||||||
|
}
|
||||||
|
|
||||||
|
def AddPlayersInSOI(player: Player): List[Player] = {
|
||||||
|
AddPlayersInSOI(player.CharId, player)
|
||||||
|
}
|
||||||
|
def AddPlayersInSOI(key: Long, player: Player): List[Player] = {
|
||||||
|
playersInSOI.put(key, player)
|
||||||
|
participationFunc.TryUpdate()
|
||||||
|
PlayersInSOI
|
||||||
|
}
|
||||||
|
|
||||||
|
def RemovePlayersFromSOI(player: Player): List[Player] = {
|
||||||
|
RemovePlayersFromSOI(player.CharId)
|
||||||
|
}
|
||||||
|
def RemovePlayersFromSOI(key: Long): List[Player] = {
|
||||||
|
playersInSOI.remove(key)
|
||||||
|
participationFunc.TryUpdate()
|
||||||
|
PlayersInSOI
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all lattice neighbours
|
// Get all lattice neighbours
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
|
||||||
var actor: typed.ActorRef[ZoneActor.Command] = Default.typed.Actor
|
var actor: typed.ActorRef[ZoneActor.Command] = Default.typed.Actor
|
||||||
|
|
||||||
/** Actor that handles SOI related functionality, for example if a player is in an SOI */
|
/** Actor that handles SOI related functionality, for example if a player is in an SOI */
|
||||||
private var soi = Default.Actor
|
//private var soi = Default.Actor
|
||||||
|
|
||||||
/** The basic support structure for the globally unique number system used by this `Zone`. */
|
/** The basic support structure for the globally unique number system used by this `Zone`. */
|
||||||
private var guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(max = 65536))
|
private var guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(max = 65536))
|
||||||
|
|
@ -520,11 +520,11 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
def StartPlayerManagementSystems(): Unit = {
|
def StartPlayerManagementSystems(): Unit = {
|
||||||
soi ! SOI.Start()
|
//soi ! SOI.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
def StopPlayerManagementSystems(): Unit = {
|
def StopPlayerManagementSystems(): Unit = {
|
||||||
soi ! SOI.Stop()
|
//soi ! SOI.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
def Activity: ActorRef = projector
|
def Activity: ActorRef = projector
|
||||||
|
|
@ -1536,7 +1536,7 @@ object Zone {
|
||||||
Props(classOf[ZoneHotSpotDisplay], zone, zone.hotspots, 15 seconds, zone.hotspotHistory, 60 seconds),
|
Props(classOf[ZoneHotSpotDisplay], zone, zone.hotspots, 15 seconds, zone.hotspotHistory, 60 seconds),
|
||||||
s"$id-hotspots"
|
s"$id-hotspots"
|
||||||
)
|
)
|
||||||
zone.soi = context.actorOf(Props(classOf[SphereOfInfluenceActor], zone), s"$id-soi")
|
//zone.soi = context.actorOf(Props(classOf[SphereOfInfluenceActor], zone), s"$id-soi")
|
||||||
|
|
||||||
zone.avatarEvents = context.actorOf(Props(classOf[AvatarService], zone), s"$id-avatar-events")
|
zone.avatarEvents = context.actorOf(Props(classOf[AvatarService], zone), s"$id-avatar-events")
|
||||||
zone.localEvents = context.actorOf(Props(classOf[LocalService], zone), s"$id-local-events")
|
zone.localEvents = context.actorOf(Props(classOf[LocalService], zone), s"$id-local-events")
|
||||||
|
|
@ -1647,7 +1647,7 @@ object Zone {
|
||||||
obj.Actor ! Service.Startup()
|
obj.Actor ! Service.Startup()
|
||||||
}
|
}
|
||||||
//allocate soi information
|
//allocate soi information
|
||||||
zone.soi ! SOI.Build()
|
//zone.soi ! SOI.Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private def MakeLattice(zone: Zone): Unit = {
|
private def MakeLattice(zone: Zone): Unit = {
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ class ZonePopulationActor(zone: Zone, playerMap: TrieMap[Int, Option[Player]], c
|
||||||
case Zone.Corpse.Remove(player) =>
|
case Zone.Corpse.Remove(player) =>
|
||||||
if (CorpseRemove(player, corpseList)) {
|
if (CorpseRemove(player, corpseList)) {
|
||||||
PlayerLeave(player)
|
PlayerLeave(player)
|
||||||
|
player.allowInteraction = false
|
||||||
zone.actor ! ZoneActor.RemoveFromBlockMap(player)
|
zone.actor ! ZoneActor.RemoveFromBlockMap(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue