mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Spawn Update (#1002)
* changes to spawn point selection for warp gates; updating coordinates for a few /warp destinations; just block map things * additional securities against wrong blockmap domain
This commit is contained in:
parent
ced228509c
commit
229777559f
|
|
@ -1334,8 +1334,8 @@ object GlobalDefinitions {
|
|||
|
||||
val hst = new WarpGateDefinition(402)
|
||||
hst.Name = "hst"
|
||||
hst.UseRadius = 20.4810f
|
||||
hst.SOIRadius = 21
|
||||
hst.UseRadius = 64.96882005f
|
||||
hst.SOIRadius = 82
|
||||
hst.VehicleAllowance = true
|
||||
hst.NoWarp += dropship
|
||||
hst.NoWarp += galaxy_gunship
|
||||
|
|
@ -1346,28 +1346,28 @@ object GlobalDefinitions {
|
|||
hst.NoWarp += colossus_flight
|
||||
hst.NoWarp += peregrine_gunner
|
||||
hst.NoWarp += peregrine_flight
|
||||
hst.SpecificPointFunc = SpawnPoint.Gate
|
||||
hst.SpecificPointFunc = SpawnPoint.SmallGate(innerRadius = 5f)
|
||||
|
||||
val warpgate = new WarpGateDefinition(993)
|
||||
warpgate.Name = "warpgate"
|
||||
warpgate.UseRadius = 301.8713f
|
||||
warpgate.UseRadius = 67.81070029f //301.8713f
|
||||
warpgate.SOIRadius = 302
|
||||
warpgate.VehicleAllowance = true
|
||||
warpgate.SpecificPointFunc = SpawnPoint.Gate
|
||||
|
||||
val warpgate_cavern = new WarpGateDefinition(994)
|
||||
warpgate_cavern.Name = "warpgate_cavern"
|
||||
warpgate_cavern.UseRadius = 51.0522f
|
||||
warpgate_cavern.UseRadius = 20.72639434f
|
||||
warpgate_cavern.SOIRadius = 52
|
||||
warpgate_cavern.VehicleAllowance = true
|
||||
warpgate_cavern.SpecificPointFunc = SpawnPoint.HalfHighGate
|
||||
warpgate_cavern.SpecificPointFunc = SpawnPoint.CavernGate
|
||||
|
||||
val warpgate_small = new WarpGateDefinition(995)
|
||||
warpgate_small.Name = "warpgate_small"
|
||||
warpgate_small.UseRadius = 103f
|
||||
warpgate_small.UseRadius = 69.03687655f
|
||||
warpgate_small.SOIRadius = 103
|
||||
warpgate_small.VehicleAllowance = true
|
||||
warpgate_small.SpecificPointFunc = SpawnPoint.Gate
|
||||
warpgate_small.SpecificPointFunc = SpawnPoint.SmallGate(innerRadius = 27.60654127f)
|
||||
|
||||
val bunker_gauntlet = new BuildingDefinition(150) { Name = "bunker_gauntlet" }
|
||||
val bunker_lg = new BuildingDefinition(151) { Name = "bunker_lg" }
|
||||
|
|
|
|||
|
|
@ -105,17 +105,17 @@ object SpawnPoint {
|
|||
)
|
||||
}
|
||||
|
||||
def Gate(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
|
||||
private def metaGate(obj: SpawnPoint, target: PlanetSideGameObject, innerRadius: Float): (Vector3, Vector3) = {
|
||||
obj.Definition match {
|
||||
case d: SpawnPointDefinition =>
|
||||
val ori = target.Orientation
|
||||
val zrad = math.toRadians(ori.z)
|
||||
val radius =
|
||||
scala.math.random().toFloat * d.UseRadius / 2 + 20f //20 is definitely outside of the gating energy field
|
||||
val shift = Vector3(math.sin(zrad).toFloat, math.cos(zrad).toFloat, 0) * radius
|
||||
scala.math.random().toFloat * (d.UseRadius - innerRadius) + innerRadius
|
||||
val shift = Vector3(math.sin(zrad).toFloat, math.cos(zrad).toFloat, 0) * radius
|
||||
val altitudeShift = target.Definition match {
|
||||
case vdef: VehicleDefinition if GlobalDefinitions.isFlightVehicle(vdef) =>
|
||||
Vector3.z(scala.math.random().toFloat * d.UseRadius / 4 + 20f)
|
||||
Vector3.z(scala.math.random().toFloat * d.UseRadius)
|
||||
case _ =>
|
||||
Vector3.Zero
|
||||
}
|
||||
|
|
@ -125,13 +125,34 @@ object SpawnPoint {
|
|||
}
|
||||
}
|
||||
|
||||
def HalfHighGate(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
|
||||
val (a, b) = Gate(obj, target)
|
||||
def Gate(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
|
||||
val (pos, ori) = metaGate(obj, target, innerRadius = 10f)
|
||||
(
|
||||
target.Definition match {
|
||||
case vdef: VehicleDefinition if GlobalDefinitions.isFlightVehicle(vdef) => pos
|
||||
case _ => pos + Vector3.z(value = 9.328125f)
|
||||
},
|
||||
ori
|
||||
)
|
||||
}
|
||||
|
||||
def CavernGate(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
|
||||
val (a, b) = metaGate(obj, target, innerRadius = 5f)
|
||||
target match {
|
||||
case v: Vehicle if GlobalDefinitions.isFlightVehicle(v.Definition) =>
|
||||
(a.xy + Vector3.z((target.Position.z + a.z) * 0.5f), b)
|
||||
case _ =>
|
||||
(a, b)
|
||||
(a + Vector3.z(value = 3f), b)
|
||||
}
|
||||
}
|
||||
|
||||
def SmallGate(innerRadius: Float)(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
|
||||
val (a, b) = metaGate(obj, target, innerRadius)
|
||||
target match {
|
||||
case v: Vehicle if GlobalDefinitions.isFlightVehicle(v.Definition) =>
|
||||
(a.xy + Vector3.z((target.Position.z + a.z) * 0.5f), b)
|
||||
case _ =>
|
||||
(a + Vector3.z(value = 0.5f), b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ case object MapInfo extends StringEnum[MapInfo] {
|
|||
value = "ugd03",
|
||||
checksum = 1673539651L,
|
||||
scale = MapScale.Dim2048,
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Death, 30)) //not actually lava, but a kill plane if you fall beneath the map
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Death, 10)) //not actually lava, but a kill plane if you fall beneath the map
|
||||
)
|
||||
|
||||
case object Ugd04
|
||||
|
|
@ -361,7 +361,7 @@ case object MapInfo extends StringEnum[MapInfo] {
|
|||
value = "ugd04",
|
||||
checksum = 3797992164L,
|
||||
scale = MapScale.Dim2048,
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Death, 51.215f)) //ADB: 51.414f
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Death, 51f)) //ADB: 51.414f
|
||||
)
|
||||
|
||||
case object Ugd05
|
||||
|
|
@ -377,7 +377,7 @@ case object MapInfo extends StringEnum[MapInfo] {
|
|||
value = "ugd06",
|
||||
checksum = 4274683970L,
|
||||
scale = MapScale.Dim2560,
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Death, 55)) //not actually lava, but a kill plane if you fall beneath the map
|
||||
environment = List(SeaLevel(EnvironmentAttribute.Death, 30)) //not actually lava, but a kill plane if you fall beneath the map
|
||||
)
|
||||
|
||||
case object Map96
|
||||
|
|
|
|||
|
|
@ -62,8 +62,10 @@ class BlockMap(fullMapWidth: Int, fullMapHeight: Int, desiredSpanSize: Int) {
|
|||
*/
|
||||
def sector(entity: BlockMapEntity): SectorPopulation = {
|
||||
entity.blockMapEntry match {
|
||||
case Some(entry) => BlockMap.quickToSectorGroup(entry.sectors.map { blocks })
|
||||
case None => SectorGroup(Nil)
|
||||
case Some(entry) =>
|
||||
BlockMap.quickToSectorGroup(BlockMap.sectorsOnlyWithinBlockStructure(entry.sectors, entry.map.blocks))
|
||||
case None =>
|
||||
SectorGroup(Nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,8 +80,9 @@ class BlockMap(fullMapWidth: Int, fullMapHeight: Int, desiredSpanSize: Int) {
|
|||
*/
|
||||
def sector(p: Vector3, range: Float): SectorPopulation = {
|
||||
val indices = BlockMap.findSectorIndices(blockMap = this, p, range)
|
||||
|
||||
if (indices.max < blocks.size) {
|
||||
BlockMap.quickToSectorGroup(range, indices.map { blocks } )
|
||||
BlockMap.quickToSectorGroup(range, BlockMap.sectorsOnlyWithinBlockStructure(indices, blocks) )
|
||||
} else {
|
||||
SectorGroup(Nil)
|
||||
}
|
||||
|
|
@ -146,9 +149,9 @@ class BlockMap(fullMapWidth: Int, fullMapHeight: Int, desiredSpanSize: Int) {
|
|||
*/
|
||||
def addTo(target: BlockMapEntity, toPosition: Vector3, rangeX: Float, rangeY: Float): SectorPopulation = {
|
||||
val to = BlockMap.findSectorIndices(blockMap = this, toPosition, rangeX, rangeY)
|
||||
val toSectors = to.toSet.map { blocks }
|
||||
val toSectors = BlockMap.sectorsOnlyWithinBlockStructure(to, blocks)
|
||||
toSectors.foreach { block => block.addTo(target) }
|
||||
target.blockMapEntry = Some(BlockMapEntry(toPosition, rangeX, rangeY, to.toSet))
|
||||
target.blockMapEntry = Some(BlockMapEntry(this, toPosition, rangeX, rangeY, to.toSet))
|
||||
BlockMap.quickToSectorGroup(rangeX, rangeY, toSectors)
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +223,7 @@ class BlockMap(fullMapWidth: Int, fullMapHeight: Int, desiredSpanSize: Int) {
|
|||
target.blockMapEntry match {
|
||||
case Some(entry) =>
|
||||
target.blockMapEntry = None
|
||||
val from = entry.sectors.map { blocks }
|
||||
val from = BlockMap.sectorsOnlyWithinBlockStructure(entry.sectors, entry.map.blocks)
|
||||
from.foreach { block => block.removeFrom(target) }
|
||||
BlockMap.quickToSectorGroup(rangeX, rangeY, from)
|
||||
case None =>
|
||||
|
|
@ -293,10 +296,10 @@ class BlockMap(fullMapWidth: Int, fullMapHeight: Int, desiredSpanSize: Int) {
|
|||
case Some(entry) =>
|
||||
val from = entry.sectors
|
||||
val to = BlockMap.findSectorIndices(blockMap = this, toPosition, rangeX, rangeY).toSet
|
||||
to.diff(from).foreach { index => blocks(index).addTo(target) }
|
||||
from.diff(to).foreach { index => blocks(index).removeFrom(target) }
|
||||
target.blockMapEntry = Some(BlockMapEntry(toPosition, rangeX, rangeY, to))
|
||||
BlockMap.quickToSectorGroup(rangeX, rangeY, to.map { blocks })
|
||||
to.diff(from).foreach { index => BlockMap.sectorOnlyWithinBlockStructure(index, blocks).addTo(target) }
|
||||
from.diff(to).foreach { index => BlockMap.sectorOnlyWithinBlockStructure(index, entry.map.blocks).removeFrom(target) }
|
||||
target.blockMapEntry = Some(BlockMapEntry(this, toPosition, rangeX, rangeY, to))
|
||||
BlockMap.quickToSectorGroup(rangeX, rangeY, BlockMap.sectorsOnlyWithinBlockStructure(to, blocks))
|
||||
case None =>
|
||||
SectorGroup(Nil)
|
||||
}
|
||||
|
|
@ -482,4 +485,40 @@ object BlockMap {
|
|||
SectorGroup(rangeX, rangeY, to)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a blockmap sector that most closely corresponds to the index.
|
||||
* @see `sectorsOnlyWithinBlockStructure`
|
||||
* @param index the index of the sector
|
||||
* @param structure the collection of sectors
|
||||
* @return the sector at the index position, or a blank sector
|
||||
*/
|
||||
private def sectorOnlyWithinBlockStructure(
|
||||
index: Int,
|
||||
structure: Iterable[Sector]
|
||||
): Sector = {
|
||||
if (index < structure.size) {
|
||||
structure.toSeq(index)
|
||||
} else {
|
||||
Sector.Empty
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a collection of blockmap sectors that most closely corresponds to the indices.
|
||||
* @see `sectorOnlyWithinBlockStructure`
|
||||
* @param list the indices of sectors
|
||||
* @param structure the collection of sectors
|
||||
* @return the collection of sectors at the index positions, or a blank collection
|
||||
*/
|
||||
private def sectorsOnlyWithinBlockStructure(
|
||||
list: Iterable[Int],
|
||||
structure: Iterable[Sector]
|
||||
): Iterable[Sector] = {
|
||||
if (list.max < structure.size) {
|
||||
list.toSet.map { structure.toSeq }
|
||||
} else {
|
||||
List[Sector]()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import net.psforever.objects.entity.WorldEntity
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
sealed case class BlockMapEntry(coords: Vector3, rangeX: Float, rangeY: Float, sectors: Set[Int])
|
||||
sealed case class BlockMapEntry(map: BlockMap, coords: Vector3, rangeX: Float, rangeY: Float, sectors: Set[Int])
|
||||
|
||||
/**
|
||||
* An game object that can be represented on a blockmap.
|
||||
|
|
@ -71,8 +71,8 @@ object BlockMapEntity {
|
|||
* @param sectors the indices of sectors on the blockmap
|
||||
* @return a `BlockMapEntry` entity
|
||||
*/
|
||||
def apply(coords: Vector3, range: Float, sectors: Set[Int]): BlockMapEntry =
|
||||
BlockMapEntry(coords, range, range, sectors)
|
||||
def apply(blocks: BlockMap, coords: Vector3, range: Float, sectors: Set[Int]): BlockMapEntry =
|
||||
BlockMapEntry(blocks, coords, range, range, sectors)
|
||||
|
||||
/**
|
||||
* The entity is currently excluded from being represented on a blockmap structure.
|
||||
|
|
@ -97,7 +97,9 @@ object BlockMapEntity {
|
|||
private def updateBlockMap(target: BlockMapEntity, newCoords: Vector3): Boolean = {
|
||||
target.blockMapEntry match {
|
||||
case Some(oldEntry) =>
|
||||
target.blockMapEntry = Some(BlockMapEntry(newCoords, oldEntry.rangeX, oldEntry.rangeY, oldEntry.sectors))
|
||||
target.blockMapEntry = Some(
|
||||
BlockMapEntry(oldEntry.map, newCoords, oldEntry.rangeX, oldEntry.rangeY, oldEntry.sectors)
|
||||
)
|
||||
true
|
||||
case None =>
|
||||
false
|
||||
|
|
|
|||
|
|
@ -239,6 +239,15 @@ class Sector(val longitude: Int, val latitude: Int, val span: Int)
|
|||
}
|
||||
}
|
||||
|
||||
object Sector {
|
||||
/**
|
||||
* An sector that is empty forever.
|
||||
*/
|
||||
final val Empty = new Sector(longitude = 0, latitude = 0, span = 0) {
|
||||
override def addTo(o : BlockMapEntity): Boolean = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The specific datastructure that is mentioned when using the term "sector conglomerate".
|
||||
* Typically used to compose the lists of entities from various individual sectors.
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ object PointOfInterest {
|
|||
"geowarp1" -> Vector3(902, 1811, 93),
|
||||
"geowarp2" -> Vector3(185, 922, 113),
|
||||
"geowarp3" -> Vector3(1696, 1188, 92),
|
||||
"geowarp4" -> Vector3(887, 227, 115)
|
||||
"geowarp4" -> Vector3(887, 218, 117)
|
||||
)
|
||||
zones("c5").gates ++= Map(
|
||||
"geowarp1" -> Vector3(1195, 1752, 244),
|
||||
|
|
@ -541,10 +541,10 @@ object PointOfInterest {
|
|||
"geowarp4" -> Vector3(1042, 225, 246)
|
||||
)
|
||||
zones("c6").gates ++= Map(
|
||||
"geowarp1" -> Vector3(1067, 2044, 95),
|
||||
"geowarp1" -> Vector3(1066, 2053, 97),
|
||||
"geowarp2" -> Vector3(290, 693, 73),
|
||||
"geowarp3" -> Vector3(1922, 928, 33),
|
||||
"geowarp4" -> Vector3(1174, 249, 114)
|
||||
"geowarp4" -> Vector3(1172, 249, 114)
|
||||
)
|
||||
zones("i3").gates ++= Map(
|
||||
"gate1" -> Vector3(1219, 2580, 30),
|
||||
|
|
|
|||
Loading…
Reference in a new issue