Gate Spawn Positions (#1004)

* changes to warp gate spawn positioning

* added !suicide command; tried to add recovery from NoGUIDException

* unnecessary imports

* stop some times

* integrated supervisory directives
This commit is contained in:
Fate-JH 2022-07-17 01:04:29 -04:00 committed by GitHub
parent a246fd1244
commit 9d2be17c1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 160 additions and 45 deletions

View file

@ -508,6 +508,12 @@ class ChatActor(
CavernRotationService.HurryNextRotation
})
case (_, _, content) if content.startsWith("!suicide") =>
//this is like CMT_SUICIDE but it ignores checks and forces a suicide state
val tplayer = session.player
tplayer.Revive
tplayer.Actor ! Player.Die()
case _ =>
// unknown ! commands are ignored
}

View file

@ -14,7 +14,7 @@ import net.psforever.objects.ballistics._
import net.psforever.objects.ce._
import net.psforever.objects.definition._
import net.psforever.objects.definition.converter.{CorpseConverter, DestroyedVehicleConverter}
import net.psforever.objects.entity.{SimpleWorldEntity, WorldEntity}
import net.psforever.objects.entity.{NoGUIDException, SimpleWorldEntity, WorldEntity}
import net.psforever.objects.equipment._
import net.psforever.objects.guid._
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
@ -293,31 +293,122 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
override def supervisorStrategy: SupervisorStrategy = {
import net.psforever.objects.inventory.InventoryDisarrayException
import java.io.{StringWriter, PrintWriter}
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
OneForOneStrategy(maxNrOfRetries = -1, withinTimeRange = 1 minute) {
case nge: NoGUIDException =>
nge.getEntity match {
case p: Player =>
continent.GUID(p.VehicleSeated) match {
case Some(v: Vehicle) =>
attemptRecoveryFromNoGuidExceptionAsVehicle(v, nge)
case _ =>
attemptRecoveryFromNoGuidExceptionAsPlayer(p, nge)
}
case v: Vehicle =>
attemptRecoveryFromNoGuidExceptionAsVehicle(v, nge)
case e: Equipment =>
(
player.Holsters().zipWithIndex.flatMap { case (o, i) =>
o.Equipment match {
case Some(e) => Some((player, InventoryItem(e, i)))
case None => None
}
}.toList ++
player.Inventory.Items.map { o => (player, o) } ++
{
player.FreeHand.Equipment match {
case Some(o) => List((player, InventoryItem(e, Player.FreeHandSlot)))
case _ => Nil
}
} ++
(ValidObject(player.VehicleSeated) match {
case Some(v: Vehicle) => v.Trunk.Items.map{ o => (v, o) }
case _ => Nil
})
)
.find { case (_, InventoryItem(o, _)) => o eq e } match {
case Some((c: Container, InventoryItem(obj, index))) =>
if (!obj.HasGUID) {
c.Slot(index).Equipment = None
}
c match {
case _: Player =>
attemptRecoveryFromNoGuidExceptionAsPlayer(player, nge)
case v: Vehicle =>
if (v.PassengerInSeat(player).contains(0)) {
attemptRecoveryFromNoGuidExceptionAsPlayer(player, nge)
}
SupervisorStrategy.resume
case _ =>
writeLogExceptionAndStop(nge)
}
case _ =>
//did not discover or resolve the situation
writeLogExceptionAndStop(nge)
}
case _ =>
SupervisorStrategy.resume
}
case ide: InventoryDisarrayException =>
attemptRecoverFromInventoryDisarrayException(ide.inventory)
attemptRecoveryFromInventoryDisarrayException(ide.inventory)
//re-evaluate results
if (ide.inventory.ElementsOnGridMatchList() > 0) {
val sw = new StringWriter
ide.printStackTrace(new PrintWriter(sw))
log.error(sw.toString)
ImmediateDisconnect()
SupervisorStrategy.stop
writeLogExceptionAndStop(ide)
} else {
SupervisorStrategy.resume
}
case e =>
val sw = new StringWriter
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString)
ImmediateDisconnect()
SupervisorStrategy.stop
writeLogExceptionAndStop(e)
}
}
def attemptRecoverFromInventoryDisarrayException(inv: GridInventory): Unit = {
def attemptRecoveryFromNoGuidExceptionAsVehicle(v: Vehicle, e: Throwable): SupervisorStrategy.Directive = {
val entry = v.Seats.find { case (_, s) => s.occupants.contains(player) }
entry match {
case Some((index, _)) =>
player.VehicleSeated = None
v.Seats(0).unmount(player)
player.Position = v.Position
player.Orientation = v.Orientation
interstellarFerry = None
interstellarFerryTopLevelGUID = None
attemptRecoveryFromNoGuidExceptionAsPlayer(player, e)
case None =>
writeLogException(e)
}
}
def attemptRecoveryFromNoGuidExceptionAsPlayer(p: Player, e: Throwable): SupervisorStrategy.Directive = {
if (p eq player) {
val hasGUID = p.HasGUID
zoneLoaded match {
case Some(true) if hasGUID =>
AvatarCreate() //this will probably work?
SupervisorStrategy.resume
case Some(false) =>
RequestSanctuaryZoneSpawn(p, continent.Number)
SupervisorStrategy.resume
case None =>
if (player.Zone eq Zone.Nowhere) {
RequestSanctuaryZoneSpawn(p, continent.Number)
} else {
zoneReload = true
LoadZoneAsPlayer(player, player.Zone.id)
}
SupervisorStrategy.resume
case _ =>
writeLogExceptionAndStop(e)
}
} else {
SupervisorStrategy.resume
}
}
def attemptRecoveryFromInventoryDisarrayException(inv: GridInventory): Unit = {
inv.ElementsInListCollideInGrid() match {
case Nil => ;
case overlaps =>
@ -403,6 +494,20 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
}
}
def writeLogException(e: Throwable): SupervisorStrategy.Directive = {
import java.io.{PrintWriter, StringWriter}
val sw = new StringWriter
e.printStackTrace(new PrintWriter(sw))
log.error(sw.toString)
SupervisorStrategy.Resume
}
def writeLogExceptionAndStop(e: Throwable): SupervisorStrategy.Directive = {
writeLogException(e)
ImmediateDisconnect()
SupervisorStrategy.stop
}
def session: Session = _session
def session_=(session: Session): Unit = {

View file

@ -1334,7 +1334,7 @@ object GlobalDefinitions {
val hst = new WarpGateDefinition(402)
hst.Name = "hst"
hst.UseRadius = 64.96882005f
hst.UseRadius = 44.96882005f
hst.SOIRadius = 82
hst.VehicleAllowance = true
hst.NoWarp += dropship
@ -1346,28 +1346,28 @@ object GlobalDefinitions {
hst.NoWarp += colossus_flight
hst.NoWarp += peregrine_gunner
hst.NoWarp += peregrine_flight
hst.SpecificPointFunc = SpawnPoint.SmallGate(innerRadius = 5f)
hst.SpecificPointFunc = SpawnPoint.CavernGate(innerRadius = 6f)
val warpgate = new WarpGateDefinition(993)
warpgate.Name = "warpgate"
warpgate.UseRadius = 67.81070029f //301.8713f
warpgate.SOIRadius = 302
warpgate.UseRadius = 67.81070029f
warpgate.SOIRadius = 302 //301.8713f
warpgate.VehicleAllowance = true
warpgate.SpecificPointFunc = SpawnPoint.Gate
val warpgate_cavern = new WarpGateDefinition(994)
warpgate_cavern.Name = "warpgate_cavern"
warpgate_cavern.UseRadius = 20.72639434f
warpgate_cavern.SOIRadius = 52
warpgate_cavern.UseRadius = 19.72639434f
warpgate_cavern.SOIRadius = 41
warpgate_cavern.VehicleAllowance = true
warpgate_cavern.SpecificPointFunc = SpawnPoint.CavernGate
warpgate_cavern.SpecificPointFunc = SpawnPoint.CavernGate(innerRadius = 4.5f)
val warpgate_small = new WarpGateDefinition(995)
warpgate_small.Name = "warpgate_small"
warpgate_small.UseRadius = 69.03687655f
warpgate_small.SOIRadius = 103
warpgate_small.VehicleAllowance = true
warpgate_small.SpecificPointFunc = SpawnPoint.SmallGate(innerRadius = 27.60654127f)
warpgate_small.SpecificPointFunc = SpawnPoint.SmallGate(innerRadius = 27.60654127f, flightlessZOffset = 0.5f)
val bunker_gauntlet = new BuildingDefinition(150) { Name = "bunker_gauntlet" }
val bunker_lg = new BuildingDefinition(151) { Name = "bunker_lg" }

View file

@ -3,6 +3,7 @@ package net.psforever.objects
import net.psforever.objects.definition.{ObjectDefinition, VehicleDefinition}
import net.psforever.objects.serverobject.PlanetSideServerObject
import net.psforever.objects.serverobject.mount.MountableEntity
import net.psforever.types.{PlanetSideGUID, Vector3}
import scala.collection.mutable
@ -111,7 +112,7 @@ object SpawnPoint {
val ori = target.Orientation
val zrad = math.toRadians(ori.z)
val radius =
scala.math.random().toFloat * (d.UseRadius - innerRadius) + innerRadius
scala.math.random().toFloat * 0.5f * (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) =>
@ -136,23 +137,26 @@ object SpawnPoint {
)
}
def CavernGate(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
val (a, b) = metaGate(obj, target, innerRadius = 5f)
def CavernGate(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 m: MountableEntity =>
m.BailProtection = true
(a + Vector3.z(obj.Definition.UseRadius * 0.5f), b)
case _ =>
(a + Vector3.z(value = 3f), b)
(a, b)
}
}
def SmallGate(innerRadius: Float)(obj: SpawnPoint, target: PlanetSideGameObject): (Vector3, Vector3) = {
def SmallGate(innerRadius: Float, flightlessZOffset: 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)
(a + Vector3.z(flightlessZOffset), b)
}
}
}