This commit is contained in:
Fate-JH 2026-01-12 22:12:10 +09:00 committed by GitHub
commit ad77c11085
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 99 additions and 10 deletions

View file

@ -3025,6 +3025,7 @@ class ZoningOperations(
physSpawnPoint: Option[SpawnPoint]
): Unit = {
log.info(s"${player.Name} will load in zone $zoneId at position $pos in $respawnTime")
player.resetInteractions()
respawnTimer.cancel()
reviveTimer.cancel()
deadState = DeadState.RespawnTime

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever
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.ballistics.InteractWithRadiationClouds
import net.psforever.objects.ce.{Deployable, InteractWithMines, InteractWithTurrets}
@ -40,6 +40,7 @@ class Player(var avatar: Avatar)
with InteriorAwareFromInteraction
with AuraContainer
with MountableEntity {
interaction(new InteractWithSOI())
interaction(environment.interaction.InteractWithEnvironment(Seq(
new WithEntrance(),
new WithWater(avatar.name),

View file

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

View file

@ -20,6 +20,8 @@ import net.psforever.objects.serverobject.structures.participation.{MajorFacilit
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
import net.psforever.util.Config
import scala.collection.mutable
class Building(
private val name: String,
private val building_guid: Int,
@ -31,7 +33,7 @@ class Building(
with BlockMapEntity {
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 participationFunc: ParticipationLogic = NoParticipation
var virusId: Long = 8 // 8 default = no virus
@ -72,9 +74,10 @@ class Building(
Faction
}
def PlayersInSOI: List[Player] = playersInSOI
def PlayersInSOI: List[Player] = playersInSOI.values.toList
def PlayersInSOI_=(list: List[Player]): List[Player] = {
//todo
if (playersInSOI.isEmpty && list.nonEmpty) {
Amenities.collect {
case box: Painbox =>
@ -86,9 +89,29 @@ class Building(
box.Actor ! Painbox.Stop()
}
}
playersInSOI = list
list.foreach { player =>
playersInSOI.put(player.CharId, player)
}
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

View file

@ -91,7 +91,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
var actor: typed.ActorRef[ZoneActor.Command] = Default.typed.Actor
/** 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`. */
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 = {
soi ! SOI.Start()
//soi ! SOI.Start()
}
def StopPlayerManagementSystems(): Unit = {
soi ! SOI.Stop()
//soi ! SOI.Stop()
}
def Activity: ActorRef = projector
@ -1536,7 +1536,7 @@ object Zone {
Props(classOf[ZoneHotSpotDisplay], zone, zone.hotspots, 15 seconds, zone.hotspotHistory, 60 seconds),
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.localEvents = context.actorOf(Props(classOf[LocalService], zone), s"$id-local-events")
@ -1647,7 +1647,7 @@ object Zone {
obj.Actor ! Service.Startup()
}
//allocate soi information
zone.soi ! SOI.Build()
//zone.soi ! SOI.Build()
}
private def MakeLattice(zone: Zone): Unit = {

View file

@ -110,6 +110,7 @@ class ZonePopulationActor(zone: Zone, playerMap: TrieMap[Int, Option[Player]], c
case Zone.Corpse.Remove(player) =>
if (CorpseRemove(player, corpseList)) {
PlayerLeave(player)
player.allowInteraction = false
zone.actor ! ZoneActor.RemoveFromBlockMap(player)
}