mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
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:
parent
a246fd1244
commit
9d2be17c1c
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue