Worked ams spawning rules into normal SpawnRequestMessage workflow using the (reliable) spawn group number of 2

This commit is contained in:
FateJH 2018-05-03 20:06:05 -04:00
parent cc3e1dde86
commit cd91080c9a
6 changed files with 181 additions and 64 deletions

View file

@ -373,10 +373,9 @@ object Zone {
/**
* Message that returns a discovered spawn point to a request source.
* @param zone_id the zone's text identifier
* @param building the `Building` in which the spawnpoint is located
* @param spawn_tube the spawn point holding object
*/
final case class SpawnPoint(zone_id : String, building : Building, spawn_tube : SpawnTube)
final case class SpawnPoint(zone_id : String, spawn_tube : SpawnTube)
/**
* Message that informs a request source that a spawn point could not be discovered with the previous criteria.
* @param zone_number this zone's numeric identifier

View file

@ -4,9 +4,11 @@ package net.psforever.objects.zones
import java.util.concurrent.atomic.AtomicInteger
import akka.actor.Actor
import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.{GlobalDefinitions, PlanetSideGameObject}
import net.psforever.objects.serverobject.structures.StructureType
import net.psforever.types.Vector3
import net.psforever.objects.serverobject.tube.SpawnTube
import net.psforever.objects.vehicles.UtilityType
import net.psforever.types.{DriveState, Vector3}
import org.log4s.Logger
/**
@ -64,30 +66,61 @@ class ZoneActor(zone : Zone) extends Actor {
//own
case Zone.Lattice.RequestSpawnPoint(zone_number, player, spawn_group) =>
if(zone_number == zone.Number) {
val buildingTypeSet = if(spawn_group == 6) {
Set(StructureType.Tower)
}
else if(spawn_group == 7) {
Set(StructureType.Facility, StructureType.Building)
}
else {
Set.empty[StructureType.Value]
}
val playerPosition = player.Position.xy
zone.SpawnGroups()
.filter({ case((building, _)) =>
building.Faction == player.Faction && buildingTypeSet.contains(building.BuildingType)
})
.toSeq
.sortBy({ case ((building, _)) =>
Vector3.DistanceSquared(playerPosition, building.Position.xy)
})
.headOption match {
case Some((building, List(tube))) =>
sender ! Zone.Lattice.SpawnPoint(zone.Id, building, tube)
(
if(spawn_group == 2) {
//ams
zone.Vehicles
.filter(veh =>
veh.DeploymentState == DriveState.Deployed &&
veh.Definition == GlobalDefinitions.ams &&
veh.Faction == player.Faction
)
.sortBy(veh => Vector3.DistanceSquared(playerPosition, veh.Position.xy))
.flatMap(veh => veh.Utilities.values.filter(util => util.UtilType == UtilityType.ams_respawn_tube))
.headOption match {
case None =>
None
case Some(util) =>
Some(List(util().asInstanceOf[SpawnTube]))
}
}
else {
//facilities, towers, and buildings
val buildingTypeSet = if(spawn_group == 0) {
Set(StructureType.Facility, StructureType.Tower, StructureType.Building)
}
else if(spawn_group == 6) {
Set(StructureType.Tower)
}
else if(spawn_group == 7) {
Set(StructureType.Facility, StructureType.Building)
}
else {
Set.empty[StructureType.Value]
}
zone.SpawnGroups()
.filter({ case ((building, _)) =>
building.Faction == player.Faction &&
buildingTypeSet.contains(building.BuildingType)
})
.toSeq
.sortBy({ case ((building, _)) =>
Vector3.DistanceSquared(playerPosition, building.Position.xy)
})
.headOption match {
case None | Some((_, Nil)) =>
None
case Some((_, tubes)) =>
Some(tubes)
}
}
) match {
case Some(List(tube)) =>
sender ! Zone.Lattice.SpawnPoint(zone.Id, tube)
case Some((building, tubes)) =>
sender ! Zone.Lattice.SpawnPoint(zone.Id, building, scala.util.Random.shuffle(tubes).head)
case Some(tubes) =>
sender ! Zone.Lattice.SpawnPoint(zone.Id, scala.util.Random.shuffle(tubes).head)
case None =>
sender ! Zone.Lattice.NoValidSpawnPoint(zone_number, Some(spawn_group))
@ -143,6 +176,68 @@ class ZoneActor(zone : Zone) extends Actor {
}
object ZoneActor {
// import net.psforever.types.PlanetSideEmpire
// import net.psforever.objects.Vehicle
// import net.psforever.objects.serverobject.structures.Building
// def AllSpawnGroup(zone : Zone, targetPosition : Vector3, targetFaction : PlanetSideEmpire.Value) : Option[List[SpawnTube]] = {
// ClosestOwnedSpawnTube(AmsSpawnGroup(zone) ++ BuildingSpawnGroup(zone, 0), targetPosition, targetFaction)
// }
//
// def AmsSpawnGroup(vehicles : List[Vehicle]) : Iterable[(Vector3, PlanetSideEmpire.Value, Iterable[SpawnTube])] = {
// vehicles
// .filter(veh => veh.DeploymentState == DriveState.Deployed && veh.Definition == GlobalDefinitions.ams)
// .map(veh =>
// (veh.Position, veh.Faction,
// veh.Utilities
// .values
// .filter(util => util.UtilType == UtilityType.ams_respawn_tube)
// .map { _().asInstanceOf[SpawnTube] }
// )
// )
// }
//
// def AmsSpawnGroup(zone : Zone, spawn_group : Int = 2) : Iterable[(Vector3, PlanetSideEmpire.Value, Iterable[SpawnTube])] = {
// if(spawn_group == 2) {
// AmsSpawnGroup(zone.Vehicles)
// }
// else {
// Nil
// }
// }
//
// def BuildingSpawnGroup(spawnGroups : Map[Building, List[SpawnTube]]) : Iterable[(Vector3, PlanetSideEmpire.Value, Iterable[SpawnTube])] = {
// spawnGroups
// .map({ case ((building, tubes)) => (building.Position.xy, building.Faction, tubes) })
// }
//
// def BuildingSpawnGroup(zone : Zone, spawn_group : Int) : Iterable[(Vector3, PlanetSideEmpire.Value, Iterable[SpawnTube])] = {
// val buildingTypeSet = if(spawn_group == 0) {
// Set(StructureType.Facility, StructureType.Tower, StructureType.Building)
// }
// else if(spawn_group == 6) {
// Set(StructureType.Tower)
// }
// else if(spawn_group == 7) {
// Set(StructureType.Facility, StructureType.Building)
// }
// else {
// Set.empty[StructureType.Value]
// }
// BuildingSpawnGroup(
// zone.SpawnGroups().filter({ case((building, _)) => buildingTypeSet.contains(building.BuildingType) })
// )
// }
//
// def ClosestOwnedSpawnTube(tubes : Iterable[(Vector3, PlanetSideEmpire.Value, Iterable[SpawnTube])], targetPosition : Vector3, targetFaction : PlanetSideEmpire.Value) : Option[List[SpawnTube]] = {
// tubes
// .toSeq
// .filter({ case (_, faction, _) => faction == targetFaction })
// .sortBy({ case (pos, _, _) => Vector3.DistanceSquared(pos, targetPosition) })
// .take(1)
// .map({ case (_, _, tubes : List[SpawnTube]) => tubes })
// .headOption
// }
/**
* Recover an object from a collection and perform any number of validating tests upon it.
* If the object fails any tests, log an error.

View file

@ -10,7 +10,8 @@ import scodec.codecs._
* @param unk1 when defined, na;
* non-zero when selecting the sanctuary option from a non-sanctuary continent deployment map
* @param unk2 when defined, indicates type of spawn point by destination;
* 0 is unknown (may refer to all available spawns regardless of last position);
* 0 is nothing;
* 2 is ams;
* 6 is towers;
* 7 is facilities
* @param unk3 na

View file

@ -194,7 +194,6 @@ class ZoneActorTest extends ActorTest {
val reply1 = receiveOne(Duration.create(200, "ms"))
assert(reply1.isInstanceOf[Zone.Lattice.SpawnPoint])
assert(reply1.asInstanceOf[Zone.Lattice.SpawnPoint].zone_id == "test")
assert(reply1.asInstanceOf[Zone.Lattice.SpawnPoint].building == bldg1)
assert(reply1.asInstanceOf[Zone.Lattice.SpawnPoint].spawn_tube.Owner == bldg1)
player.Position = Vector3(3,3,3) //closer to bldg3
@ -202,7 +201,6 @@ class ZoneActorTest extends ActorTest {
val reply3 = receiveOne(Duration.create(200, "ms"))
assert(reply3.isInstanceOf[Zone.Lattice.SpawnPoint])
assert(reply3.asInstanceOf[Zone.Lattice.SpawnPoint].zone_id == "test")
assert(reply3.asInstanceOf[Zone.Lattice.SpawnPoint].building == bldg3)
assert(reply3.asInstanceOf[Zone.Lattice.SpawnPoint].spawn_tube.Owner == bldg3)
}