diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index 7e8b366e..0f83c48b 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -94,7 +94,7 @@ class SessionAvatarHandlers( lazy val targetDelay = { val populationOver = math.max( 0, - continent.blockMap.sector(ourPosition, range=drawConfig.rangeMax.toFloat).livePlayerList.size - drawConfig.populationThreshold + sessionData.localSector.livePlayerList.size - drawConfig.populationThreshold ) val distanceAdjustment = math.pow(populationOver / drawConfig.populationStep * drawConfig.rangeStep, 2) //sq.m val adjustedDistance = currentDistance + distanceAdjustment //sq.m diff --git a/src/main/scala/net/psforever/actors/session/support/SessionData.scala b/src/main/scala/net/psforever/actors/session/support/SessionData.scala index 196bb8a1..2aa1feb4 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionData.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionData.scala @@ -4,6 +4,7 @@ package net.psforever.actors.session.support import akka.actor.typed.scaladsl.adapter._ import akka.actor.{ActorContext, ActorRef, Cancellable, typed} import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} +import net.psforever.objects.zones.blockmap.{SectorGroup, SectorPopulation} import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global @@ -137,6 +138,12 @@ class SessionData( def squad: SessionSquadHandlers = squadResponseOpt.orNull def zoning: ZoningOperations = zoningOpt.orNull + /** + * updated when an upstream packet arrives; + * allow to be a little stale for a short while + */ + private[support] var localSector: SectorPopulation = SectorGroup(Nil) + def session: Session = theSession def session_=(session: Session): Unit = { @@ -206,7 +213,7 @@ class SessionData( )= pkt persist() turnCounterFunc(avatarGuid) - updateBlockMap(player, continent, pos) + updateBlockMap(player, pos) val isMoving = WorldEntity.isMoving(vel) val isMovingPlus = isMoving || isJumping || jumpThrust if (isMovingPlus) { @@ -2665,16 +2672,22 @@ class SessionData( middlewareActor ! MiddlewareActor.Teardown() } - def updateBlockMap(target: BlockMapEntity, zone: Zone, newCoords: Vector3): Unit = { + def updateBlockMap(target: BlockMapEntity, newCoords: Vector3): Unit = { target.blockMapEntry.foreach { entry => - if (BlockMap.findSectorIndices(continent.blockMap, newCoords, entry.rangeX, entry.rangeY).toSet.equals(entry.sectors)) { + val sectorIndices = BlockMap.findSectorIndices(continent.blockMap, newCoords, entry.rangeX, entry.rangeY).toSet + if (sectorIndices.equals(entry.sectors)) { target.updateBlockMapEntry(newCoords) //soft update + localSector = continent.blockMap.sector(sectorIndices, Config.app.game.playerDraw.rangeMax.toFloat) } else { - zone.actor ! ZoneActor.UpdateBlockMap(target, newCoords) //hard update + continent.actor ! ZoneActor.UpdateBlockMap(target, newCoords) //hard update } } } + def updateLocalBlockMap(pos: Vector3): Unit = { + localSector = continent.blockMap.sector(pos, Config.app.game.playerDraw.rangeMax.toFloat) + } + private[support] var oldRefsMap: mutable.HashMap[PlanetSideGUID, String] = new mutable.HashMap[PlanetSideGUID, String]() def updateOldRefsMap(): Unit = { if(player.HasGUID) { diff --git a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala index 55d2d428..915390ee 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala @@ -55,6 +55,7 @@ class SessionVehicleHandlers( player.Position = pos player.Orientation = orient player.Velocity = vel + sessionData.updateLocalBlockMap(pos) case VehicleResponse.VehicleState( vehicleGuid, diff --git a/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala b/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala index 47ef7469..a3a91f61 100644 --- a/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala @@ -44,7 +44,7 @@ class VehicleOperations( sessionData.turnCounterFunc(player.GUID) sessionData.fallHeightTracker(pos.z) if (obj.MountedIn.isEmpty) { - sessionData.updateBlockMap(obj, continent, pos) + sessionData.updateBlockMap(obj, pos) } player.Position = pos //convenient if (obj.WeaponControlledFromSeat(0).isEmpty) { @@ -127,7 +127,7 @@ class VehicleOperations( sessionData.turnCounterFunc(player.GUID) val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match { case Some(v: Vehicle) => - sessionData.updateBlockMap(obj, continent, pos) + sessionData.updateBlockMap(obj, pos) (pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false) case _ => (pos, ang, vel, true) @@ -243,7 +243,7 @@ class VehicleOperations( obj.Position = pos obj.Orientation = ang obj.Velocity = vel - sessionData.updateBlockMap(obj, continent, pos) + sessionData.updateBlockMap(obj, pos) obj.zoneInteractions() continent.VehicleEvents ! VehicleServiceMessage( continent.id, diff --git a/src/main/scala/net/psforever/objects/zones/blockmap/BlockMap.scala b/src/main/scala/net/psforever/objects/zones/blockmap/BlockMap.scala index b6c91ec9..a35d3f1c 100644 --- a/src/main/scala/net/psforever/objects/zones/blockmap/BlockMap.scala +++ b/src/main/scala/net/psforever/objects/zones/blockmap/BlockMap.scala @@ -74,13 +74,25 @@ class BlockMap(fullMapWidth: Int, fullMapHeight: Int, desiredSpanSize: Int) { * find the sector conglomerate to which this range allocates. * @see `BlockMap.findSectorIndices` * @see `BlockMap.quickToSectorGroup` + * @see `BlockMap::sector(Iterable[Int], Float)` * @param p the game world coordinates * @param range the axis distance from the provided coordinates * @return a conglomerate sector which lists all of the entities in the discovered sector(s) */ def sector(p: Vector3, range: Float): SectorPopulation = { - val indices = BlockMap.findSectorIndices(blockMap = this, p, range) + sector(BlockMap.findSectorIndices(blockMap = this, p, range), range) + } + /** + * Given a coordinate position within representable space and a range from that representable space, + * find the sector conglomerate to which this range allocates. + * @see `BlockMap.findSectorIndices` + * @see `BlockMap.quickToSectorGroup` + * @param indices an enumeration that directly associates with the structure of the block map + * @param range the axis distance from the provided coordinates + * @return a conglomerate sector which lists all of the entities in the discovered sector(s) + */ + def sector(indices: Iterable[Int], range: Float): SectorPopulation = { if (indices.max < blocks.size) { BlockMap.quickToSectorGroup(range, BlockMap.sectorsOnlyWithinBlockStructure(indices, blocks) ) } else {