mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-23 14:20:45 +00:00
streamline pass on the vehicle operation and aaccountability
This commit is contained in:
parent
26b70dbcd9
commit
398b98514a
6 changed files with 133 additions and 137 deletions
|
|
@ -8,7 +8,6 @@ import net.psforever.objects.serverobject.ServerObject
|
|||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||
import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage, PlanetsideAttributeMessage}
|
||||
import net.psforever.packet.game.objectcreate.RibbonBars
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
|
@ -110,20 +109,22 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
|
|||
|
||||
private def keepAlivePersistanceCSR(): Unit = {
|
||||
val player = data.player
|
||||
data.keepAlivePersistence()
|
||||
topOffHealthOfPlayer(player)
|
||||
player.allowInteraction = false
|
||||
topOffHealthOfPlayer(player)
|
||||
data.continent.GUID(data.player.VehicleSeated)
|
||||
.collect {
|
||||
case obj: PlanetSideGameObject with Vitality with BlockMapEntity =>
|
||||
data.zoning.spawn.interimUngunnedVehicle = None
|
||||
data.keepAlivePersistence()
|
||||
if (player.HasGUID) {
|
||||
data.zoning.spawn.tryQueuedActivity()
|
||||
data.turnCounterFunc(player.GUID)
|
||||
data.continent
|
||||
.GUID(player.VehicleSeated)
|
||||
.collect { case obj: PlanetSideGameObject with Vitality =>
|
||||
topOffHealth(obj)
|
||||
data.updateBlockMap(obj, obj.Position)
|
||||
obj
|
||||
}
|
||||
.getOrElse {
|
||||
data.updateBlockMap(player, player.Position)
|
||||
}
|
||||
}
|
||||
data.squad.updateSquad()
|
||||
} else {
|
||||
data.turnCounterFunc(PlanetSideGUID(0))
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealth(obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import net.psforever.objects.serverobject.mount.Mountable
|
|||
import net.psforever.objects.vehicles.control.BfrFlight
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
|
@ -30,6 +31,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
/* packets */
|
||||
|
||||
def handleVehicleState(pkt: VehicleStateMessage): Unit = {
|
||||
player.allowInteraction = false
|
||||
val VehicleStateMessage(
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
|
|
@ -46,23 +48,21 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
ops.GetVehicleAndSeat() match {
|
||||
case (Some(obj), Some(0)) =>
|
||||
//we're driving the vehicle
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(vel)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
sessionLogic.general.fallHeightTracker(pos.z)
|
||||
if (obj.MountedIn.isEmpty) {
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
}
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealth(obj)
|
||||
player.Position = pos //convenient
|
||||
if (obj.WeaponControlledFromSeat(0).isEmpty) {
|
||||
player.Orientation = Vector3.z(ang.z) //convenient
|
||||
val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match {
|
||||
case Some(v: Vehicle) =>
|
||||
(pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false)
|
||||
case _ =>
|
||||
(pos, ang, vel, true)
|
||||
}
|
||||
obj.Position = pos
|
||||
obj.Orientation = ang
|
||||
if (obj.MountedIn.isEmpty) {
|
||||
if (notMountedState) {
|
||||
sessionLogic.updateBlockMap(obj, position)
|
||||
if (obj.DeploymentState != DriveState.Deployed) {
|
||||
obj.Velocity = vel
|
||||
obj.Velocity = velocity
|
||||
} else {
|
||||
obj.Velocity = Some(Vector3.Zero)
|
||||
}
|
||||
|
|
@ -74,20 +74,20 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Velocity = None
|
||||
obj.Flying = None
|
||||
}
|
||||
player.Position = position //convenient
|
||||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
//
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.VehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
obj.Position,
|
||||
ang,
|
||||
obj.Velocity,
|
||||
if (obj.isFlying) {
|
||||
is_flying
|
||||
} else {
|
||||
None
|
||||
},
|
||||
position,
|
||||
angle,
|
||||
velocity,
|
||||
obj.Flying,
|
||||
unk6,
|
||||
unk7,
|
||||
wheels,
|
||||
|
|
@ -96,8 +96,6 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
)
|
||||
)
|
||||
sessionLogic.squad.updateSquad()
|
||||
player.allowInteraction = false
|
||||
obj.zoneInteractions()
|
||||
case (None, _) =>
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
//TODO placing a "not driving" warning here may trigger as we are disembarking the vehicle
|
||||
|
|
@ -113,6 +111,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
}
|
||||
|
||||
def handleFrameVehicleState(pkt: FrameVehicleStateMessage): Unit = {
|
||||
player.allowInteraction = false
|
||||
val FrameVehicleStateMessage(
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
|
|
@ -132,34 +131,21 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
ops.GetVehicleAndSeat() match {
|
||||
case (Some(obj), Some(0)) =>
|
||||
//we're driving the vehicle
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(vel)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealth(obj)
|
||||
val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match {
|
||||
case Some(v: Vehicle) =>
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
(pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false)
|
||||
case _ =>
|
||||
(pos, ang, vel, true)
|
||||
}
|
||||
player.Position = position //convenient
|
||||
if (obj.WeaponControlledFromSeat(seatNumber = 0).isEmpty) {
|
||||
player.Orientation = Vector3.z(ang.z) //convenient
|
||||
}
|
||||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
obj.Velocity = velocity
|
||||
// if (is_crouched && obj.DeploymentState != DriveState.Kneeling) {
|
||||
// //dev stuff goes here
|
||||
// }
|
||||
// else
|
||||
// if (!is_crouched && obj.DeploymentState == DriveState.Kneeling) {
|
||||
// //dev stuff goes here
|
||||
// }
|
||||
obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile
|
||||
if (notMountedState) {
|
||||
sessionLogic.updateBlockMap(obj, position)
|
||||
if (obj.DeploymentState != DriveState.Kneeling) {
|
||||
obj.Velocity = velocity
|
||||
if (is_airborne) {
|
||||
val flight = if (ascending_flight) flight_time else -flight_time
|
||||
obj.Flying = Some(flight)
|
||||
|
|
@ -172,12 +158,14 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Velocity = None
|
||||
obj.Flying = None
|
||||
}
|
||||
player.allowInteraction = false
|
||||
obj.zoneInteractions()
|
||||
} else {
|
||||
obj.Velocity = None
|
||||
obj.Flying = None
|
||||
}
|
||||
player.Position = position //convenient
|
||||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.FrameVehicleState(
|
||||
|
|
@ -214,34 +202,40 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
}
|
||||
|
||||
def handleChildObjectState(pkt: ChildObjectStateMessage): Unit = {
|
||||
player.allowInteraction = false
|
||||
val ChildObjectStateMessage(object_guid, pitch, yaw) = pkt
|
||||
val (o, tools) = sessionLogic.shooting.FindContainedWeapon
|
||||
//is COSM our primary upstream packet?
|
||||
(o match {
|
||||
case Some(mount: Mountable) => (o, mount.PassengerInSeat(player))
|
||||
case Some(mount: Mountable) => (mount, mount.PassengerInSeat(player))
|
||||
case _ => (None, None)
|
||||
}) match {
|
||||
case (None, None) | (_, None) | (Some(_: Vehicle), Some(0)) =>
|
||||
case (None, _) | (_, None) => //error - we do not recognize being mounted or controlling anything, but what can we do about it?
|
||||
()
|
||||
case (Some(obj: PlanetSideGameObject with Vitality), _) =>
|
||||
case (Some(_: Vehicle), Some(0)) => //see VSM or FVSM for valid cases
|
||||
()
|
||||
case (Some(entity: PlanetSideGameObject with Mountable with InteractsWithZone), Some(_)) => //COSM is our primary upstream packet
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealth(obj)
|
||||
case _ =>
|
||||
topOffHealth(entity)
|
||||
sessionLogic.squad.updateSquad()
|
||||
case _ => //we can't disprove that COSM is our primary upstream packet, it's just that we may be missing some details
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
}
|
||||
//the majority of the following check retrieves information to determine if we are in control of the child
|
||||
tools.find { _.GUID == object_guid } match {
|
||||
//in the following condition we are in control of the child
|
||||
tools.find(_.GUID == object_guid) match {
|
||||
case None =>
|
||||
//todo: old warning; this state is problematic, but can trigger in otherwise valid instances
|
||||
//old warning; this state is problematic, but can trigger in otherwise valid instances
|
||||
//log.warn(
|
||||
// s"ChildObjectState: ${player.Name} is using a different controllable agent than entity ${object_guid.guid}"
|
||||
//)
|
||||
case Some(_) =>
|
||||
//TODO set tool orientation?
|
||||
player.Orientation = Vector3(0f, pitch, yaw)
|
||||
case Some(tool) =>
|
||||
val angle = Vector3(0f, pitch, yaw)
|
||||
tool.Orientation = angle
|
||||
player.Orientation = angle
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw)
|
||||
|
|
|
|||
|
|
@ -49,18 +49,16 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
sessionLogic.general.fallHeightTracker(pos.z)
|
||||
if (obj.MountedIn.isEmpty) {
|
||||
val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match {
|
||||
case Some(v: Vehicle) =>
|
||||
(pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false)
|
||||
case _ =>
|
||||
(pos, ang, vel, true)
|
||||
}
|
||||
if (notMountedState) {
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
}
|
||||
player.Position = pos //convenient
|
||||
if (obj.WeaponControlledFromSeat(0).isEmpty) {
|
||||
player.Orientation = Vector3.z(ang.z) //convenient
|
||||
}
|
||||
obj.Position = pos
|
||||
obj.Orientation = ang
|
||||
if (obj.MountedIn.isEmpty) {
|
||||
if (obj.DeploymentState != DriveState.Deployed) {
|
||||
obj.Velocity = vel
|
||||
obj.Velocity = velocity
|
||||
} else {
|
||||
obj.Velocity = Some(Vector3.Zero)
|
||||
}
|
||||
|
|
@ -68,10 +66,14 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Flying = is_flying //usually Some(7)
|
||||
}
|
||||
obj.Cloaked = obj.Definition.CanCloak && is_cloaked
|
||||
obj.zoneInteractions()
|
||||
} else {
|
||||
obj.Velocity = None
|
||||
obj.Flying = None
|
||||
}
|
||||
player.Position = position //convenient
|
||||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
//
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
|
|
@ -79,14 +81,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
obj.Position,
|
||||
ang,
|
||||
obj.Velocity,
|
||||
if (obj.isFlying) {
|
||||
is_flying
|
||||
} else {
|
||||
None
|
||||
},
|
||||
position,
|
||||
angle,
|
||||
velocity,
|
||||
obj.Flying,
|
||||
unk6,
|
||||
unk7,
|
||||
wheels,
|
||||
|
|
@ -95,10 +93,9 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
)
|
||||
)
|
||||
sessionLogic.squad.updateSquad()
|
||||
VehicleOperations.updateMountableZoneInteractionFromEarliestSeat(obj, player)
|
||||
case (None, _) =>
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
//TODO placing a "not driving" warning here may trigger as we are disembarking the vehicle
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
//placing a "not driving" warning here may trigger as we are disembarking the vehicle
|
||||
case (_, Some(index)) =>
|
||||
log.error(
|
||||
s"VehicleState: ${player.Name} should not be dispatching this kind of packet from vehicle ${vehicle_guid.guid} when not the driver (actually, seat $index)"
|
||||
|
|
@ -133,30 +130,17 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
sessionLogic.zoning.spawn.tryQueuedActivity(vel)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
sessionLogic.general.fallHeightTracker(pos.z)
|
||||
val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match {
|
||||
case Some(v: Vehicle) =>
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
(pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false)
|
||||
case _ =>
|
||||
(pos, ang, vel, true)
|
||||
}
|
||||
player.Position = position //convenient
|
||||
if (obj.WeaponControlledFromSeat(seatNumber = 0).isEmpty) {
|
||||
player.Orientation = Vector3.z(ang.z) //convenient
|
||||
}
|
||||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
obj.Velocity = velocity
|
||||
// if (is_crouched && obj.DeploymentState != DriveState.Kneeling) {
|
||||
// //dev stuff goes here
|
||||
// }
|
||||
// else
|
||||
// if (!is_crouched && obj.DeploymentState == DriveState.Kneeling) {
|
||||
// //dev stuff goes here
|
||||
// }
|
||||
obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile
|
||||
if (notMountedState) {
|
||||
sessionLogic.updateBlockMap(obj, position)
|
||||
if (obj.DeploymentState != DriveState.Kneeling) {
|
||||
obj.Velocity = velocity
|
||||
if (is_airborne) {
|
||||
val flight = if (ascending_flight) flight_time else -flight_time
|
||||
obj.Flying = Some(flight)
|
||||
|
|
@ -169,11 +153,15 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Velocity = None
|
||||
obj.Flying = None
|
||||
}
|
||||
VehicleOperations.updateMountableZoneInteractionFromEarliestSeat(obj, player)
|
||||
obj.zoneInteractions()
|
||||
} else {
|
||||
obj.Velocity = None
|
||||
obj.Flying = None
|
||||
}
|
||||
player.Position = position //convenient
|
||||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.FrameVehicleState(
|
||||
|
|
@ -196,8 +184,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
)
|
||||
sessionLogic.squad.updateSquad()
|
||||
case (None, _) =>
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
//TODO placing a "not driving" warning here may trigger as we are disembarking the vehicle
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
//placing a "not driving" warning here may trigger as we are disembarking the vehicle
|
||||
case (_, Some(index)) =>
|
||||
log.error(
|
||||
s"VehicleState: ${player.Name} should not be dispatching this kind of packet from vehicle ${vehicle_guid.guid} when not the driver (actually, seat $index)"
|
||||
|
|
@ -212,35 +200,36 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
def handleChildObjectState(pkt: ChildObjectStateMessage): Unit = {
|
||||
val ChildObjectStateMessage(object_guid, pitch, yaw) = pkt
|
||||
val (o, tools) = sessionLogic.shooting.FindContainedWeapon
|
||||
//is COSM our primary upstream packet?
|
||||
(o match {
|
||||
case Some(mount: Mountable) => (o, mount.PassengerInSeat(player))
|
||||
case Some(mount: Mountable) => (mount, mount.PassengerInSeat(player))
|
||||
case _ => (None, None)
|
||||
}) match {
|
||||
case (None, _) | (_, None) => //error - we do not recognize being mounted or controlling anything, but what can we do about it?
|
||||
()
|
||||
case (Some(_: Vehicle), Some(0)) => //no (see: VSM or FVSM for valid cases)
|
||||
case (Some(_: Vehicle), Some(0)) => //see VSM or FVSM for valid cases
|
||||
()
|
||||
case (Some(entity: PlanetSideGameObject with InteractsWithZone), Some(_)) => //yes
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity() //todo conditionals?
|
||||
case (Some(entity: PlanetSideGameObject with Mountable with InteractsWithZone), Some(seatNumber)) => //COSM is our primary upstream packet
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
VehicleOperations.updateMountableZoneInteractionFromEarliestSeat(entity, player)
|
||||
case _ => //yes
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity() //todo conditionals?
|
||||
VehicleOperations.updateMountableZoneInteractionFromEarliestSeat(entity, seatNumber)
|
||||
sessionLogic.squad.updateSquad()
|
||||
case _ => //we can't disprove that COSM is our primary upstream packet, it's just that we may be missing some details
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
}
|
||||
//the majority of the following check retrieves information to determine if we are in control of the child
|
||||
tools.find { _.GUID == object_guid } match {
|
||||
//in the following condition we are in control of the child
|
||||
tools.find(_.GUID == object_guid) match {
|
||||
case None =>
|
||||
//todo: old warning; this state is problematic, but can trigger in otherwise valid instances
|
||||
//old warning; this state is problematic, but can trigger in otherwise valid instances
|
||||
//log.warn(
|
||||
// s"ChildObjectState: ${player.Name} is using a different controllable agent than entity ${object_guid.guid}"
|
||||
//)
|
||||
case Some(_) =>
|
||||
//TODO set tool orientation?
|
||||
player.Orientation = Vector3(0f, pitch, yaw)
|
||||
case Some(tool) =>
|
||||
val angle = Vector3(0f, pitch, yaw)
|
||||
tool.Orientation = angle
|
||||
player.Orientation = angle
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw)
|
||||
|
|
|
|||
|
|
@ -466,12 +466,14 @@ class SessionData(
|
|||
zoning.spawn.interimUngunnedVehicle = None
|
||||
persist()
|
||||
if (player.HasGUID) {
|
||||
zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
turnCounterFunc(player.GUID)
|
||||
continent
|
||||
.GUID(player.VehicleSeated)
|
||||
.foreach {
|
||||
VehicleOperations.updateMountableZoneInteractionFromEarliestSeat(_, player)
|
||||
.collect { case v: PlanetSideGameObject with Mountable =>
|
||||
VehicleOperations.updateMountableZoneInteractionFromEarliestSeat(v, player)
|
||||
}
|
||||
squad.updateSquad()
|
||||
} else {
|
||||
turnCounterFunc(PlanetSideGUID(0))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,17 +198,23 @@ class VehicleOperations(
|
|||
}
|
||||
|
||||
object VehicleOperations {
|
||||
def updateMountableZoneInteractionFromEarliestSeat(obj: PlanetSideGameObject, passenger: Player): Unit = {
|
||||
def updateMountableZoneInteractionFromEarliestSeat(obj: PlanetSideGameObject with Mountable, passenger: Player): Unit = {
|
||||
obj.PassengerInSeat(passenger).foreach { seatNumber =>
|
||||
updateMountableZoneInteractionFromEarliestSeat(obj, seatNumber)
|
||||
}
|
||||
}
|
||||
|
||||
def updateMountableZoneInteractionFromEarliestSeat(obj: PlanetSideGameObject with Mountable, seatNumber: Int): Unit = {
|
||||
obj match {
|
||||
case obj: Vehicle =>
|
||||
updateVehicleZoneInteractionFromEarliestSeat(obj, passenger)
|
||||
updateVehicleZoneInteractionFromEarliestSeat(obj, seatNumber)
|
||||
case obj: Mountable with InteractsWithZone =>
|
||||
updateEntityZoneInteractionFromEarliestSeat(obj, passenger, obj)
|
||||
updateEntityZoneInteractionFromEarliestSeat(obj, seatNumber, obj)
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
private def updateVehicleZoneInteractionFromEarliestSeat(obj: Vehicle, passenger: Player): Unit = {
|
||||
private def updateVehicleZoneInteractionFromEarliestSeat(obj: Vehicle, seatNumber: Int): Unit = {
|
||||
//vehicle being ferried; check if the ferry has occupants that might have speaking rights before us
|
||||
var targetVehicle = obj
|
||||
val carrierSeatVacancy: Boolean = obj match {
|
||||
|
|
@ -223,29 +229,22 @@ object VehicleOperations {
|
|||
case _ => true
|
||||
}
|
||||
if (carrierSeatVacancy) {
|
||||
updateEntityZoneInteractionFromEarliestSeat(obj, passenger, targetVehicle)
|
||||
updateEntityZoneInteractionFromEarliestSeat(obj, seatNumber, targetVehicle)
|
||||
}
|
||||
}
|
||||
|
||||
private def updateEntityZoneInteractionFromEarliestSeat(
|
||||
obj: Mountable with InteractsWithZone,
|
||||
passenger: Player,
|
||||
seatNumber: Int,
|
||||
updateTarget: InteractsWithZone
|
||||
): Unit = {
|
||||
val inSeatNumberOpt = obj.PassengerInSeat(passenger)
|
||||
if (inSeatNumberOpt.contains(0)) {
|
||||
if (seatNumber == 0) {
|
||||
//we're responsible as the primary operator
|
||||
updateTarget.zoneInteractions()
|
||||
} else if (!obj.Seat(seatNumber = 0).exists(_.isOccupied)) {
|
||||
//there is no primary operator; are we responsible?
|
||||
//determine if we are the player in the seat closest to the "front"
|
||||
val noPlayersInEarlierSeats = inSeatNumberOpt
|
||||
.exists { seatIndex =>
|
||||
!(1 until seatIndex).exists { i => obj.Seat(i).exists(_.isOccupied) }
|
||||
}
|
||||
if (noPlayersInEarlierSeats) {
|
||||
updateTarget.zoneInteractions()
|
||||
}
|
||||
} else if(!obj.Seat(seatNumber = 0).exists(_.isOccupied) && obj.OccupiedSeats().headOption.contains(seatNumber)) {
|
||||
//there is no primary operator
|
||||
//we are responsible as the player in the seat closest to the "front"
|
||||
updateTarget.zoneInteractions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,17 @@ trait Mountable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All the seats that have occupants by their seat number.
|
||||
* @return list of the numbers of all occupied seats
|
||||
*/
|
||||
def OccupiedSeats(): List[Int] = {
|
||||
seats
|
||||
.collect { case (index, seat) if seat.isOccupied => index }
|
||||
.toList
|
||||
.sorted
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a mapping of each mount from its mount point index.
|
||||
* @return the mapping of mount point to mount
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue