mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-15 16:34:42 +00:00
reusing the existing sector data; better resets, negating an issue during mounting where the player does not switch back to recovery; disabling was bugged due to missed timer upgrade
This commit is contained in:
parent
99aafbe4db
commit
6790ced5a0
9 changed files with 114 additions and 79 deletions
|
|
@ -3,6 +3,7 @@ package net.psforever.actors.session.support
|
||||||
|
|
||||||
import akka.actor.{ActorContext, typed}
|
import akka.actor.{ActorContext, typed}
|
||||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||||
|
import net.psforever.objects.serverobject.environment.interaction.ResetAllEnvironmentInteractions
|
||||||
import net.psforever.objects.vital.InGameHistory
|
import net.psforever.objects.vital.InGameHistory
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -61,6 +62,7 @@ class SessionMountHandlers(
|
||||||
sendResponse(PlanetsideAttributeMessage(obj_guid, attribute_type=45, obj.NtuCapacitorScaled))
|
sendResponse(PlanetsideAttributeMessage(obj_guid, attribute_type=45, obj.NtuCapacitorScaled))
|
||||||
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
||||||
sessionData.accessContainer(obj)
|
sessionData.accessContainer(obj)
|
||||||
|
tplayer.Actor ! ResetAllEnvironmentInteractions
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
||||||
|
|
@ -76,6 +78,7 @@ class SessionMountHandlers(
|
||||||
obj.Cloaked = tplayer.Cloaked
|
obj.Cloaked = tplayer.Cloaked
|
||||||
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
||||||
sessionData.accessContainer(obj)
|
sessionData.accessContainer(obj)
|
||||||
|
tplayer.Actor ! ResetAllEnvironmentInteractions
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
||||||
|
|
@ -90,6 +93,7 @@ class SessionMountHandlers(
|
||||||
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
||||||
sessionData.accessContainer(obj)
|
sessionData.accessContainer(obj)
|
||||||
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
||||||
|
tplayer.Actor ! ResetAllEnvironmentInteractions
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
||||||
|
|
@ -103,6 +107,7 @@ class SessionMountHandlers(
|
||||||
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
sendResponse(GenericObjectActionMessage(obj_guid, code=11))
|
||||||
sessionData.accessContainer(obj)
|
sessionData.accessContainer(obj)
|
||||||
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
||||||
|
tplayer.Actor ! ResetAllEnvironmentInteractions
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
case Mountable.CanMount(obj: Vehicle, seatNumber, _)
|
||||||
|
|
@ -122,6 +127,7 @@ class SessionMountHandlers(
|
||||||
sessionData.accessContainer(obj)
|
sessionData.accessContainer(obj)
|
||||||
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
||||||
sessionData.keepAliveFunc = sessionData.keepAlivePersistence
|
sessionData.keepAliveFunc = sessionData.keepAlivePersistence
|
||||||
|
tplayer.Actor ! ResetAllEnvironmentInteractions
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: Vehicle, seatNumber, _) =>
|
case Mountable.CanMount(obj: Vehicle, seatNumber, _) =>
|
||||||
|
|
@ -139,6 +145,7 @@ class SessionMountHandlers(
|
||||||
sessionData.accessContainer(obj)
|
sessionData.accessContainer(obj)
|
||||||
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
sessionData.updateWeaponAtSeatPosition(obj, seatNumber)
|
||||||
sessionData.keepAliveFunc = sessionData.keepAlivePersistence
|
sessionData.keepAliveFunc = sessionData.keepAlivePersistence
|
||||||
|
tplayer.Actor ! ResetAllEnvironmentInteractions
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: FacilityTurret, seatNumber, _)
|
case Mountable.CanMount(obj: FacilityTurret, seatNumber, _)
|
||||||
|
|
@ -173,7 +180,7 @@ class SessionMountHandlers(
|
||||||
MountingAction(tplayer, obj, seatNumber)
|
MountingAction(tplayer, obj, seatNumber)
|
||||||
|
|
||||||
case Mountable.CanMount(obj: Mountable, _, _) =>
|
case Mountable.CanMount(obj: Mountable, _, _) =>
|
||||||
log.warn(s"MountVehicleMsg: $obj is some mountable object and nothing will happen for ${player.Name}")
|
log.warn(s"MountVehicleMsg: $obj is some kind of mountable object but nothing will happen for ${player.Name}")
|
||||||
|
|
||||||
case Mountable.CanDismount(obj: ImplantTerminalMech, seatNum, _) =>
|
case Mountable.CanDismount(obj: ImplantTerminalMech, seatNum, _) =>
|
||||||
log.info(s"${tplayer.Name} dismounts the implant terminal")
|
log.info(s"${tplayer.Name} dismounts the implant terminal")
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,23 @@ class WithWater(val channel: String)
|
||||||
body: PieceOfEnvironment,
|
body: PieceOfEnvironment,
|
||||||
data: Option[Any]
|
data: Option[Any]
|
||||||
): Unit = {
|
): Unit = {
|
||||||
val (effect, time, percentage) = Watery.drowningInWateryConditions(obj, condition.map(_.state), waterInteractionTime)
|
|
||||||
val cond = OxygenStateTarget(obj.GUID, body, OxygenState.Suffocation, percentage)
|
|
||||||
val extra = data.collect {
|
val extra = data.collect {
|
||||||
case t: OxygenStateTarget => Some(t)
|
case t: OxygenStateTarget => Some(t)
|
||||||
case w: Watery => w.Condition
|
case w: Watery => w.Condition
|
||||||
}.flatten
|
}.flatten
|
||||||
if (effect) {
|
if (extra.isDefined) {
|
||||||
waterInteractionTime = System.currentTimeMillis() + time
|
//inform the player that their mounted vehicle is in trouble (that they are in trouble (but not from drowning (yet)))
|
||||||
condition = Some(cond)
|
stopInteractingWith(obj, body, data)
|
||||||
obj.Actor ! RespondsToZoneEnvironment.Timer(attribute, delay = time milliseconds, obj.Actor, Player.Die())
|
} else {
|
||||||
//inform the player that they are in trouble
|
val (effect, time, percentage) = Watery.drowningInWateryConditions(obj, condition.map(_.state), waterInteractionTime)
|
||||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.OxygenState(cond, extra))
|
if (effect) {
|
||||||
} else if (extra.isDefined) {
|
val cond = OxygenStateTarget(obj.GUID, body, OxygenState.Suffocation, percentage)
|
||||||
//inform the player that their mounted vehicle is in trouble (that they are in trouble)
|
waterInteractionTime = System.currentTimeMillis() + time
|
||||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.OxygenState(cond, None))
|
condition = Some(cond)
|
||||||
|
obj.Actor ! RespondsToZoneEnvironment.Timer(attribute, delay = time milliseconds, obj.Actor, Player.Die())
|
||||||
|
//inform the player that they are in trouble
|
||||||
|
obj.Zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.OxygenState(cond, extra))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,6 +80,9 @@ class WithWater(val channel: String)
|
||||||
|
|
||||||
override def recoverFromInteracting(obj: InteractsWithZone): Unit = {
|
override def recoverFromInteracting(obj: InteractsWithZone): Unit = {
|
||||||
super.recoverFromInteracting(obj)
|
super.recoverFromInteracting(obj)
|
||||||
|
if (condition.exists(_.state == OxygenState.Suffocation)) {
|
||||||
|
stopInteractingWith(obj, condition.map(_.body).get, None)
|
||||||
|
}
|
||||||
waterInteractionTime = 0L
|
waterInteractionTime = 0L
|
||||||
condition = None
|
condition = None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,11 @@ object EnvironmentAttribute extends Enum[EnvironmentTrait] {
|
||||||
/** water can only interact with objects that are negatively affected by being exposed to water;
|
/** water can only interact with objects that are negatively affected by being exposed to water;
|
||||||
* it's better this way */
|
* it's better this way */
|
||||||
def canInteractWith(obj: PlanetSideGameObject): Boolean = {
|
def canInteractWith(obj: PlanetSideGameObject): Boolean = {
|
||||||
obj.Definition.DrownAtMaxDepth || obj.Definition.DisableAtMaxDepth
|
obj.Definition.DrownAtMaxDepth || obj.Definition.DisableAtMaxDepth || (obj match {
|
||||||
|
case p: Player => p.VehicleSeated.isEmpty
|
||||||
|
case v: Vehicle => v.MountedIn.isEmpty
|
||||||
|
case _ => true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import net.psforever.objects.GlobalDefinitions
|
||||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||||
import net.psforever.objects.serverobject.environment.{EnvironmentTrait, PieceOfEnvironment}
|
import net.psforever.objects.serverobject.environment.{EnvironmentTrait, PieceOfEnvironment}
|
||||||
import net.psforever.objects.zones._
|
import net.psforever.objects.zones._
|
||||||
import net.psforever.objects.zones.blockmap.{BlockMapEntity, SectorPopulation}
|
import net.psforever.objects.zones.blockmap.{BlockMapEntity, SectorGroup, SectorPopulation}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@ class InteractWithEnvironment()
|
||||||
def interaction(sector: SectorPopulation, target: InteractsWithZone): Unit = {
|
def interaction(sector: SectorPopulation, target: InteractsWithZone): Unit = {
|
||||||
target match {
|
target match {
|
||||||
case t: InteractsWithZone =>
|
case t: InteractsWithZone =>
|
||||||
interactWith = interactionBehavior.perform(t, interactWith, allow=true)
|
interactWith = interactionBehavior.perform(t, sector, interactWith, allow=true)
|
||||||
interactionBehavior = interactionBehavior.next
|
interactionBehavior = interactionBehavior.next
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
|
|
@ -60,8 +60,8 @@ class InteractWithEnvironment()
|
||||||
*/
|
*/
|
||||||
def resetInteraction(target: InteractsWithZone) : Unit = {
|
def resetInteraction(target: InteractsWithZone) : Unit = {
|
||||||
target match {
|
target match {
|
||||||
case t: InteractsWithZone =>
|
case t: InteractsWithZone with BlockMapEntity =>
|
||||||
AwaitOngoingInteraction(target.Zone).perform(t, interactWith, allow=false)
|
AwaitOngoingInteraction(target.Zone).perform(t, SectorGroup.emptySector, interactWith, allow=false)
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
interactWith = Set()
|
interactWith = Set()
|
||||||
|
|
@ -110,19 +110,17 @@ object InteractWithEnvironment {
|
||||||
/**
|
/**
|
||||||
* Test whether any special terrain component has an affect upon the target entity.
|
* Test whether any special terrain component has an affect upon the target entity.
|
||||||
* @param obj the target entity
|
* @param obj the target entity
|
||||||
|
* @param sector the portion of the block map being tested
|
||||||
* @return any unstable, interactive, or special terrain that is being interacted
|
* @return any unstable, interactive, or special terrain that is being interacted
|
||||||
*/
|
*/
|
||||||
def checkAllEnvironmentInteractions(obj: PlanetSideServerObject): Set[PieceOfEnvironment] = {
|
def checkAllEnvironmentInteractions(
|
||||||
|
obj: PlanetSideServerObject,
|
||||||
|
sector: SectorPopulation
|
||||||
|
): Set[PieceOfEnvironment] = {
|
||||||
val position = obj.Position
|
val position = obj.Position
|
||||||
val depth = GlobalDefinitions.MaxDepth(obj)
|
val depth = GlobalDefinitions.MaxDepth(obj)
|
||||||
(obj match {
|
sector.environmentList
|
||||||
case bme: BlockMapEntity =>
|
.filter(body => body.attribute.canInteractWith(obj) && body.testInteraction(position, depth))
|
||||||
obj.Zone.blockMap.sector(bme).environmentList
|
|
||||||
case _ =>
|
|
||||||
obj.Zone.map.environment
|
|
||||||
}).filter { body =>
|
|
||||||
body.attribute.canInteractWith(obj) && body.testInteraction(position, depth)
|
|
||||||
}
|
|
||||||
.distinctBy(_.attribute)
|
.distinctBy(_.attribute)
|
||||||
.toSet
|
.toSet
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +132,11 @@ object InteractWithEnvironment {
|
||||||
* @param obj the target entity
|
* @param obj the target entity
|
||||||
* @return any unstable, interactive, or special terrain that is being interacted
|
* @return any unstable, interactive, or special terrain that is being interacted
|
||||||
*/
|
*/
|
||||||
def checkSpecificEnvironmentInteraction(zone: Zone, body: PieceOfEnvironment, obj: PlanetSideServerObject): Option[PieceOfEnvironment] = {
|
def checkSpecificEnvironmentInteraction(
|
||||||
|
zone: Zone,
|
||||||
|
body: PieceOfEnvironment,
|
||||||
|
obj: PlanetSideServerObject
|
||||||
|
): Option[PieceOfEnvironment] = {
|
||||||
if ((obj.Zone eq zone) && body.testInteraction(obj.Position, GlobalDefinitions.MaxDepth(obj))) {
|
if ((obj.Zone eq zone) && body.testInteraction(obj.Position, GlobalDefinitions.MaxDepth(obj))) {
|
||||||
Some(body)
|
Some(body)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -146,7 +148,12 @@ object InteractWithEnvironment {
|
||||||
trait InteractionBehavior {
|
trait InteractionBehavior {
|
||||||
protected var nextstep: InteractionBehavior = this
|
protected var nextstep: InteractionBehavior = this
|
||||||
|
|
||||||
def perform(obj: InteractsWithZone, existing: Set[PieceOfEnvironment], allow: Boolean): Set[PieceOfEnvironment]
|
def perform(
|
||||||
|
obj: InteractsWithZone,
|
||||||
|
sector: SectorPopulation,
|
||||||
|
existing: Set[PieceOfEnvironment],
|
||||||
|
allow: Boolean
|
||||||
|
): Set[PieceOfEnvironment]
|
||||||
|
|
||||||
def next: InteractionBehavior = {
|
def next: InteractionBehavior = {
|
||||||
val out = nextstep
|
val out = nextstep
|
||||||
|
|
@ -166,15 +173,20 @@ case class OnStableEnvironment() extends InteractionBehavior {
|
||||||
* @see `AwaitOngoingInteraction`
|
* @see `AwaitOngoingInteraction`
|
||||||
* @see `OnStableEnvironment`
|
* @see `OnStableEnvironment`
|
||||||
* @param obj target entity
|
* @param obj target entity
|
||||||
|
* @param sector the portion of the block map being tested
|
||||||
* @param existing not applicable
|
* @param existing not applicable
|
||||||
* @param allow is this permitted, or will it be blocked?
|
* @param allow is this permitted, or will it be blocked?
|
||||||
* @return the function literal that represents the next iterative call of ongoing interaction testing;
|
* @return applicable interactive environmental fields
|
||||||
* may return itself
|
|
||||||
*/
|
*/
|
||||||
def perform(obj: InteractsWithZone, existing: Set[PieceOfEnvironment], allow: Boolean): Set[PieceOfEnvironment] = {
|
def perform(
|
||||||
|
obj: InteractsWithZone,
|
||||||
|
sector: SectorPopulation,
|
||||||
|
existing: Set[PieceOfEnvironment],
|
||||||
|
allow: Boolean
|
||||||
|
): Set[PieceOfEnvironment] = {
|
||||||
if (allow) {
|
if (allow) {
|
||||||
val interactions = obj.interaction().collectFirst { case inter: InteractWithEnvironment => inter.Interactions }
|
val interactions = obj.interaction().collectFirst { case inter: InteractWithEnvironment => inter.Interactions }
|
||||||
val env = InteractWithEnvironment.checkAllEnvironmentInteractions(obj)
|
val env = InteractWithEnvironment.checkAllEnvironmentInteractions(obj, sector)
|
||||||
env.foreach(body => interactions.flatMap(_.get(body.attribute)).foreach(_.doInteractingWith(obj, body, None)))
|
env.foreach(body => interactions.flatMap(_.get(body.attribute)).foreach(_.doInteractingWith(obj, body, None)))
|
||||||
if (env.nonEmpty) {
|
if (env.nonEmpty) {
|
||||||
nextstep = AwaitOngoingInteraction(obj.Zone)
|
nextstep = AwaitOngoingInteraction(obj.Zone)
|
||||||
|
|
@ -201,21 +213,26 @@ final case class AwaitOngoingInteraction(zone: Zone) extends InteractionBehavior
|
||||||
* @see `InteractWithEnvironment.checkSpecificEnvironmentInteraction`
|
* @see `InteractWithEnvironment.checkSpecificEnvironmentInteraction`
|
||||||
* @see `OnStableEnvironment`
|
* @see `OnStableEnvironment`
|
||||||
* @param obj target entity
|
* @param obj target entity
|
||||||
|
* @param sector the portion of the block map being tested
|
||||||
* @param existing environment fields from the previous step
|
* @param existing environment fields from the previous step
|
||||||
* @param allow is this permitted, or will it be blocked?
|
* @param allow is this permitted, or will it be blocked?
|
||||||
* @return the function literal that represents the next iterative call of ongoing interaction testing;
|
* @return applicable interactive environmental fields
|
||||||
* may return itself
|
|
||||||
*/
|
*/
|
||||||
def perform(obj: InteractsWithZone, existing: Set[PieceOfEnvironment], allow: Boolean): Set[PieceOfEnvironment] = {
|
def perform(
|
||||||
|
obj: InteractsWithZone,
|
||||||
|
sector: SectorPopulation,
|
||||||
|
existing: Set[PieceOfEnvironment],
|
||||||
|
allow: Boolean
|
||||||
|
): Set[PieceOfEnvironment] = {
|
||||||
val interactions = obj.interaction().collectFirst { case inter: InteractWithEnvironment => inter.Interactions }
|
val interactions = obj.interaction().collectFirst { case inter: InteractWithEnvironment => inter.Interactions }
|
||||||
if (allow) {
|
if (allow) {
|
||||||
val env = InteractWithEnvironment.checkAllEnvironmentInteractions(obj)
|
val env = InteractWithEnvironment.checkAllEnvironmentInteractions(obj, sector)
|
||||||
val (in, out) = existing.partition(body => InteractWithEnvironment.checkSpecificEnvironmentInteraction(zone, body, obj).nonEmpty)
|
val (in, out) = existing.partition(body => InteractWithEnvironment.checkSpecificEnvironmentInteraction(zone, body, obj).nonEmpty)
|
||||||
env.diff(in).foreach(body => interactions.flatMap(_.get(body.attribute)).foreach(_.doInteractingWith(obj, body, None)))
|
env.diff(in).foreach(body => interactions.flatMap(_.get(body.attribute)).foreach(_.doInteractingWith(obj, body, None)))
|
||||||
out.foreach(body => interactions.flatMap(_.get(body.attribute)).foreach(_.stopInteractingWith(obj, body, None)))
|
out.foreach(body => interactions.flatMap(_.get(body.attribute)).foreach(_.stopInteractingWith(obj, body, None)))
|
||||||
if (env.isEmpty) {
|
if (env.isEmpty) {
|
||||||
val n = OnStableEnvironment()
|
val n = OnStableEnvironment()
|
||||||
val out = n.perform(obj, Set(), allow)
|
val out = n.perform(obj, sector, Set(), allow)
|
||||||
nextstep = n.next
|
nextstep = n.next
|
||||||
out
|
out
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -236,12 +253,17 @@ case class BlockedFromInteracting() extends InteractionBehavior {
|
||||||
* Considered tail recursive, but not treated that way.
|
* Considered tail recursive, but not treated that way.
|
||||||
* @see `OnStableEnvironment`
|
* @see `OnStableEnvironment`
|
||||||
* @param obj target entity
|
* @param obj target entity
|
||||||
|
* @param sector the portion of the block map being tested
|
||||||
* @param existing not applicable
|
* @param existing not applicable
|
||||||
* @param allow is this permitted, or will it be blocked?
|
* @param allow is this permitted, or will it be blocked?
|
||||||
* @return the function literal that represents the next iterative call of ongoing interaction testing;
|
* @return an empty set
|
||||||
* may return itself
|
|
||||||
*/
|
*/
|
||||||
def perform(obj: InteractsWithZone, existing: Set[PieceOfEnvironment], allow: Boolean): Set[PieceOfEnvironment] = {
|
def perform(
|
||||||
|
obj: InteractsWithZone,
|
||||||
|
sector: SectorPopulation,
|
||||||
|
existing: Set[PieceOfEnvironment],
|
||||||
|
allow: Boolean
|
||||||
|
): Set[PieceOfEnvironment] = {
|
||||||
if (allow) {
|
if (allow) {
|
||||||
nextstep = OnStableEnvironment()
|
nextstep = OnStableEnvironment()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,11 @@ final case class EscapeFromEnvironment(
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Completely reset any internal actions or processes related to environment clipping.
|
* Completely reset internal actions or processes related to environment clipping.
|
||||||
*/
|
*/
|
||||||
final case class RecoveredFromEnvironmentInteraction(attribute: EnvironmentTrait)
|
final case class RecoveredFromEnvironmentInteraction(attribute: EnvironmentTrait)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completely reset internal actions or processes related to environment clipping.
|
||||||
|
*/
|
||||||
|
case object ResetAllEnvironmentInteractions
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@ trait RespondsToZoneEnvironment {
|
||||||
applicableInteractions
|
applicableInteractions
|
||||||
.get(attribute)
|
.get(attribute)
|
||||||
.foreach(_.recoverFromInteracting(InteractiveObject))
|
.foreach(_.recoverFromInteracting(InteractiveObject))
|
||||||
|
|
||||||
|
case ResetAllEnvironmentInteractions =>
|
||||||
|
applicableInteractions.values.foreach(_.recoverFromInteracting(InteractiveObject))
|
||||||
|
interactionTimers.values.foreach(_.cancel())
|
||||||
}
|
}
|
||||||
|
|
||||||
def respondToEnvironmentPostStop(): Unit = {
|
def respondToEnvironmentPostStop(): Unit = {
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,8 @@ class VehicleControl(vehicle: Vehicle)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case VehicleControl.Disable() =>
|
case VehicleControl.Disable(kickPassengers) =>
|
||||||
PrepareForDisabled(kickPassengers = false)
|
PrepareForDisabled(kickPassengers)
|
||||||
context.become(Disabled)
|
context.become(Disabled)
|
||||||
|
|
||||||
case Vehicle.Deconstruct(time) =>
|
case Vehicle.Deconstruct(time) =>
|
||||||
|
|
@ -384,28 +384,20 @@ class VehicleControl(vehicle: Vehicle)
|
||||||
val zone = vehicle.Zone
|
val zone = vehicle.Zone
|
||||||
val zoneId = zone.id
|
val zoneId = zone.id
|
||||||
val events = zone.VehicleEvents
|
val events = zone.VehicleEvents
|
||||||
//miscellaneous changes
|
|
||||||
//recoverFromEnvironmentInteracting()
|
|
||||||
//escape being someone else's cargo
|
//escape being someone else's cargo
|
||||||
vehicle.MountedIn match {
|
vehicle.MountedIn.foreach(_ => startCargoDismounting(bailed = true))
|
||||||
case Some(_) =>
|
|
||||||
startCargoDismounting(bailed = true)
|
|
||||||
case _ => ;
|
|
||||||
}
|
|
||||||
if (!vehicle.isFlying || kickPassengers) {
|
if (!vehicle.isFlying || kickPassengers) {
|
||||||
//kick all passengers (either not flying, or being explicitly instructed)
|
//kick all passengers (either not flying, or being explicitly instructed)
|
||||||
vehicle.Seats.values.foreach { seat =>
|
vehicle.Seats.values.foreach { seat =>
|
||||||
seat.occupant match {
|
seat.occupant.foreach { player =>
|
||||||
case Some(player) =>
|
seat.unmount(player, BailType.Kicked)
|
||||||
seat.unmount(player, BailType.Kicked)
|
player.VehicleSeated = None
|
||||||
player.VehicleSeated = None
|
if (player.isAlive) {
|
||||||
if (player.isAlive) {
|
zone.actor ! ZoneActor.AddToBlockMap(player, vehicle.Position)
|
||||||
zone.actor ! ZoneActor.AddToBlockMap(player, vehicle.Position)
|
}
|
||||||
}
|
if (player.HasGUID) {
|
||||||
if (player.HasGUID) {
|
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2 = true, guid))
|
||||||
events ! VehicleServiceMessage(zoneId, VehicleAction.KickPassenger(player.GUID, 4, unk2 = true, guid))
|
}
|
||||||
}
|
|
||||||
case None => ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -722,7 +714,7 @@ object VehicleControl {
|
||||||
|
|
||||||
private case class PrepareForDeletion()
|
private case class PrepareForDeletion()
|
||||||
|
|
||||||
private[vehicles] case class Disable()
|
final case class Disable(kickPassengers: Boolean = false)
|
||||||
|
|
||||||
private case class Deletion()
|
private case class Deletion()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import net.psforever.objects.serverobject.environment.interaction.{InteractionWi
|
||||||
import net.psforever.objects.serverobject.environment.interaction.common.Watery
|
import net.psforever.objects.serverobject.environment.interaction.common.Watery
|
||||||
import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget
|
import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget
|
||||||
import net.psforever.objects.serverobject.environment.{PieceOfEnvironment, interaction}
|
import net.psforever.objects.serverobject.environment.{PieceOfEnvironment, interaction}
|
||||||
|
import net.psforever.objects.vehicles.control.VehicleControl
|
||||||
import net.psforever.objects.zones.InteractsWithZone
|
import net.psforever.objects.zones.InteractsWithZone
|
||||||
import net.psforever.types.OxygenState
|
import net.psforever.types.OxygenState
|
||||||
|
|
||||||
|
|
@ -38,20 +39,15 @@ class WithWater()
|
||||||
(a, b, c)
|
(a, b, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val cond = OxygenStateTarget(obj.GUID, body, OxygenState.Suffocation, percentage)
|
|
||||||
if (effect) {
|
if (effect) {
|
||||||
condition = Some(cond)
|
condition = Some(OxygenStateTarget(obj.GUID, body, OxygenState.Suffocation, percentage))
|
||||||
waterInteractionTime = System.currentTimeMillis() + time
|
waterInteractionTime = System.currentTimeMillis() + time
|
||||||
|
obj.Actor ! RespondsToZoneEnvironment.Timer(attribute, delay = time milliseconds, obj.Actor, VehicleControl.Disable(true))
|
||||||
doInteractingWithTargets(
|
doInteractingWithTargets(
|
||||||
obj,
|
obj,
|
||||||
percentage,
|
percentage,
|
||||||
body,
|
body,
|
||||||
vehicle.Seats.values
|
vehicle.Seats.values.flatMap(_.occupants).filter(p => p.isAlive && (p.Zone eq obj.Zone))
|
||||||
.flatMap {
|
|
||||||
case seat if seat.isOccupied => seat.occupants
|
|
||||||
case _ => Nil
|
|
||||||
}
|
|
||||||
.filter { p => p.isAlive && (p.Zone eq obj.Zone) }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case _ => ()
|
case _ => ()
|
||||||
|
|
@ -75,21 +71,15 @@ class WithWater()
|
||||||
case vehicle: Vehicle =>
|
case vehicle: Vehicle =>
|
||||||
val (effect: Boolean, time: Long, percentage: Float) =
|
val (effect: Boolean, time: Long, percentage: Float) =
|
||||||
Watery.recoveringFromWateryConditions(obj, condition.map(_.state), waterInteractionTime)
|
Watery.recoveringFromWateryConditions(obj, condition.map(_.state), waterInteractionTime)
|
||||||
val cond = OxygenStateTarget(obj.GUID, body, OxygenState.Recovery, percentage)
|
|
||||||
if (effect) {
|
if (effect) {
|
||||||
condition = Some(cond)
|
condition = Some(OxygenStateTarget(obj.GUID, body, OxygenState.Recovery, percentage))
|
||||||
waterInteractionTime = System.currentTimeMillis() + time
|
waterInteractionTime = System.currentTimeMillis() + time
|
||||||
obj.Actor ! RespondsToZoneEnvironment.Timer(attribute, delay = time milliseconds, obj.Actor, interaction.RecoveredFromEnvironmentInteraction(attribute))
|
obj.Actor ! RespondsToZoneEnvironment.Timer(attribute, delay = time milliseconds, obj.Actor, interaction.RecoveredFromEnvironmentInteraction(attribute))
|
||||||
stopInteractingWithTargets(
|
stopInteractingWithTargets(
|
||||||
obj,
|
obj,
|
||||||
percentage,
|
percentage,
|
||||||
body,
|
body,
|
||||||
vehicle.Seats.values
|
vehicle.Seats.values.flatMap(_.occupants).filter(p => p.isAlive && (p.Zone eq obj.Zone))
|
||||||
.flatMap {
|
|
||||||
case seat if seat.isOccupied => seat.occupants
|
|
||||||
case _ => Nil
|
|
||||||
}
|
|
||||||
.filter { p => p.isAlive && (p.Zone eq obj.Zone) }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case _ => ()
|
case _ => ()
|
||||||
|
|
@ -98,6 +88,9 @@ class WithWater()
|
||||||
|
|
||||||
override def recoverFromInteracting(obj: InteractsWithZone): Unit = {
|
override def recoverFromInteracting(obj: InteractsWithZone): Unit = {
|
||||||
super.recoverFromInteracting(obj)
|
super.recoverFromInteracting(obj)
|
||||||
|
if (condition.exists(_.state == OxygenState.Suffocation)) {
|
||||||
|
stopInteractingWith(obj, condition.map(_.body).get, None)
|
||||||
|
}
|
||||||
waterInteractionTime = 0L
|
waterInteractionTime = 0L
|
||||||
condition = None
|
condition = None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,9 @@ class SectorGroup(
|
||||||
extends SectorPopulation
|
extends SectorPopulation
|
||||||
|
|
||||||
object SectorGroup {
|
object SectorGroup {
|
||||||
|
/** cached sector of no range and no entity coverage */
|
||||||
|
final val emptySector: SectorGroup = SectorGroup(range = 0, sectors = Nil)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded constructor that takes a single sector
|
* Overloaded constructor that takes a single sector
|
||||||
* and transfers the lists of entities into a single conglomeration of the sector populations.
|
* and transfers the lists of entities into a single conglomeration of the sector populations.
|
||||||
|
|
@ -326,7 +329,7 @@ object SectorGroup {
|
||||||
*/
|
*/
|
||||||
def apply(sectors: Iterable[Sector]): SectorGroup = {
|
def apply(sectors: Iterable[Sector]): SectorGroup = {
|
||||||
if (sectors.isEmpty) {
|
if (sectors.isEmpty) {
|
||||||
SectorGroup(range = 0, sectors = Nil)
|
SectorGroup.emptySector
|
||||||
} else if (sectors.size == 1) {
|
} else if (sectors.size == 1) {
|
||||||
SectorGroup(sectors.head.rangeX, sectors.head.rangeY, sectors)
|
SectorGroup(sectors.head.rangeX, sectors.head.rangeY, sectors)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue