mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-11 06:24:38 +00:00
Cargo Bail (#258)
* deconstructing a vehicle that has cargo will eject the cargo before despawning the vehicle * cargo that dismounts without a driver is scheduled for deconstruction; any player that disconnects while in a vehicle that is flying has the vehicle scheduled for immediate deconstruction instead of the standard deconstruction time * modified routine for disowning vehicles outside of the conventional 'driver is owner' system * standardized player-driven ownership fields; adjusted how vehicles transfer and announce ownership on zone join events (SetCurrentAvatar) * stop /zone and /warp if in a cargo vehicle (even if driver) * fix for landed-dismount cargo logic not starting distance checking loop * concatenated Owner and OwnerName assignment to a singular object method, and the vehicle use of assignment to a singular WSA function
This commit is contained in:
parent
fca14e6b1b
commit
a467a79c71
9 changed files with 284 additions and 179 deletions
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2019 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
|
||||
trait OwnableByPlayer {
|
||||
private var owner : Option[PlanetSideGUID] = None
|
||||
private var ownerName : Option[String] = None
|
||||
|
||||
def Owner : Option[PlanetSideGUID] = owner
|
||||
|
||||
def Owner_=(owner : PlanetSideGUID) : Option[PlanetSideGUID] = Owner_=(Some(owner))
|
||||
|
||||
def Owner_=(owner : Player) : Option[PlanetSideGUID] = Owner_=(Some(owner.GUID))
|
||||
|
||||
def Owner_=(owner : Option[PlanetSideGUID]) : Option[PlanetSideGUID] = {
|
||||
owner match {
|
||||
case Some(_) =>
|
||||
this.owner = owner
|
||||
case None =>
|
||||
this.owner = None
|
||||
}
|
||||
Owner
|
||||
}
|
||||
|
||||
def OwnerName : Option[String] = ownerName
|
||||
|
||||
def OwnerName_=(owner : String) : Option[String] = OwnerName_=(Some(owner))
|
||||
|
||||
def OwnerName_=(owner : Player) : Option[String] = OwnerName_=(Some(owner.Name))
|
||||
|
||||
def OwnerName_=(owner : Option[String]) : Option[String] = {
|
||||
owner match {
|
||||
case Some(_) =>
|
||||
ownerName = owner
|
||||
case None =>
|
||||
ownerName = None
|
||||
}
|
||||
OwnerName
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param player na
|
||||
* @return na
|
||||
*/
|
||||
def AssignOwnership(player : Player) : OwnableByPlayer = AssignOwnership(Some(player))
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param playerOpt na
|
||||
* @return na
|
||||
*/
|
||||
def AssignOwnership(playerOpt : Option[Player]) : OwnableByPlayer = {
|
||||
playerOpt match {
|
||||
case Some(player) =>
|
||||
Owner = player
|
||||
OwnerName = player
|
||||
case None =>
|
||||
Owner = None
|
||||
OwnerName = None
|
||||
}
|
||||
this
|
||||
}
|
||||
}
|
||||
|
|
@ -72,10 +72,10 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
with MountedWeapons
|
||||
with Deployment
|
||||
with Vitality
|
||||
with OwnableByPlayer
|
||||
with StandardResistanceProfile
|
||||
with Container {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.TR
|
||||
private var owner : Option[PlanetSideGUID] = None
|
||||
private var health : Int = 1
|
||||
private var shields : Int = 0
|
||||
private var decal : Int = 0
|
||||
|
|
@ -139,26 +139,6 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
MountedIn
|
||||
}
|
||||
|
||||
def Owner : Option[PlanetSideGUID] = {
|
||||
this.owner
|
||||
}
|
||||
|
||||
def Owner_=(owner : PlanetSideGUID) : Option[PlanetSideGUID] = Owner_=(Some(owner))
|
||||
|
||||
def Owner_=(owner : Player) : Option[PlanetSideGUID] = Owner_=(Some(owner.GUID))
|
||||
|
||||
def Owner_=(owner : Option[PlanetSideGUID]) : Option[PlanetSideGUID] = {
|
||||
owner match {
|
||||
case Some(_) =>
|
||||
if(Definition.CanBeOwned) {
|
||||
this.owner = owner
|
||||
}
|
||||
case None =>
|
||||
this.owner = None
|
||||
}
|
||||
Owner
|
||||
}
|
||||
|
||||
def Health : Int = {
|
||||
health
|
||||
}
|
||||
|
|
@ -499,7 +479,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
if(trunkAccess.isEmpty || trunkAccess.contains(player.GUID)) {
|
||||
groupPermissions(3) match {
|
||||
case VehicleLockState.Locked => //only the owner
|
||||
owner.isEmpty || (owner.isDefined && player.GUID == owner.get)
|
||||
Owner.isEmpty || (Owner.isDefined && player.GUID == Owner.get)
|
||||
case VehicleLockState.Group => //anyone in the owner's squad or platoon
|
||||
faction == player.Faction //TODO this is not correct
|
||||
case VehicleLockState.Empire => //anyone of the owner's faction
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@ import net.psforever.packet.game.{DeployableIcon, PlanetSideGUID}
|
|||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
trait Deployable extends FactionAffinity
|
||||
with Vitality {
|
||||
with Vitality
|
||||
with OwnableByPlayer {
|
||||
this : PlanetSideGameObject =>
|
||||
private var health : Int = 1
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
private var owner : Option[PlanetSideGUID] = None
|
||||
private var ownerName : Option[String] = None
|
||||
|
||||
def Health : Int = health
|
||||
|
||||
|
|
@ -32,38 +31,6 @@ trait Deployable extends FactionAffinity
|
|||
Faction
|
||||
}
|
||||
|
||||
def Owner : Option[PlanetSideGUID] = owner
|
||||
|
||||
def Owner_=(owner : PlanetSideGUID) : Option[PlanetSideGUID] = Owner_=(Some(owner))
|
||||
|
||||
def Owner_=(owner : Player) : Option[PlanetSideGUID] = Owner_=(Some(owner.GUID))
|
||||
|
||||
def Owner_=(owner : Option[PlanetSideGUID]) : Option[PlanetSideGUID] = {
|
||||
owner match {
|
||||
case Some(_) =>
|
||||
this.owner = owner
|
||||
case None =>
|
||||
this.owner = None
|
||||
}
|
||||
Owner
|
||||
}
|
||||
|
||||
def OwnerName : Option[String] = ownerName
|
||||
|
||||
def OwnerName_=(owner : String) : Option[String] = OwnerName_=(Some(owner))
|
||||
|
||||
def OwnerName_=(owner : Player) : Option[String] = OwnerName_=(Some(owner.Name))
|
||||
|
||||
def OwnerName_=(owner : Option[String]) : Option[String] = {
|
||||
owner match {
|
||||
case Some(_) =>
|
||||
ownerName = owner
|
||||
case None =>
|
||||
ownerName = None
|
||||
}
|
||||
OwnerName
|
||||
}
|
||||
|
||||
def DamageModel : DamageResistanceModel = Definition.asInstanceOf[DamageResistanceModel]
|
||||
|
||||
def Definition : ObjectDefinition with BaseDeployableDefinition
|
||||
|
|
|
|||
|
|
@ -155,11 +155,11 @@ import scodec.codecs._
|
|||
* `81 - ???`<br>
|
||||
* `113 - Vehicle capacitor - e.g. Leviathan EMP charge`
|
||||
*
|
||||
* @param player_guid the player
|
||||
* @param attribute_type na
|
||||
* @param attribute_value na
|
||||
* @param guid the object
|
||||
* @param attribute_type the field
|
||||
* @param attribute_value the value
|
||||
*/
|
||||
final case class PlanetsideAttributeMessage(player_guid : PlanetSideGUID,
|
||||
final case class PlanetsideAttributeMessage(guid : PlanetSideGUID,
|
||||
attribute_type : Int,
|
||||
attribute_value : Long)
|
||||
extends PlanetSideGamePacket {
|
||||
|
|
@ -169,12 +169,16 @@ final case class PlanetsideAttributeMessage(player_guid : PlanetSideGUID,
|
|||
}
|
||||
|
||||
object PlanetsideAttributeMessage extends Marshallable[PlanetsideAttributeMessage] {
|
||||
def apply(player_guid : PlanetSideGUID, attribute_type : Int, attribute_value : Int) : PlanetsideAttributeMessage = {
|
||||
PlanetsideAttributeMessage(player_guid, attribute_type, attribute_value.toLong)
|
||||
def apply(guid : PlanetSideGUID, attribute_type : Int, attribute_value : Int) : PlanetsideAttributeMessage = {
|
||||
PlanetsideAttributeMessage(guid, attribute_type, attribute_value.toLong)
|
||||
}
|
||||
|
||||
def apply(guid : PlanetSideGUID, attribute_type : Int, attribute_value : PlanetSideGUID) : PlanetsideAttributeMessage = {
|
||||
PlanetsideAttributeMessage(guid, attribute_type, attribute_value.guid)
|
||||
}
|
||||
|
||||
implicit val codec : Codec[PlanetsideAttributeMessage] = (
|
||||
("player_guid" | PlanetSideGUID.codec) ::
|
||||
("guid" | PlanetSideGUID.codec) ::
|
||||
("attribute_type" | uint8L) ::
|
||||
("attribute_value" | uint32L)
|
||||
).as[PlanetsideAttributeMessage]
|
||||
|
|
|
|||
|
|
@ -36,5 +36,6 @@ object VehicleAction {
|
|||
final case class TransferPassengerChannel(player_guid : PlanetSideGUID, temp_channel : String, new_channel : String, vehicle : Vehicle) extends Action
|
||||
final case class TransferPassenger(player_guid : PlanetSideGUID, temp_channel : String, vehicle : Vehicle, vehicle_to_delete : PlanetSideGUID) extends Action
|
||||
|
||||
final case class KickCargo(player_guid : PlanetSideGUID, cargo : Vehicle, speed : Int) extends Action
|
||||
final case class ForceDismountVehicleCargo(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) extends Action
|
||||
final case class KickCargo(player_guid : PlanetSideGUID, cargo : Vehicle, speed : Int, delay : Long) extends Action
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,5 +40,6 @@ object VehicleResponse {
|
|||
final case class TransferPassengerChannel(old_channel : String, temp_channel : String, vehicle : Vehicle) extends Response
|
||||
final case class TransferPassenger(temp_channel : String, vehicle : Vehicle, vehicle_to_delete : PlanetSideGUID) extends Response
|
||||
|
||||
final case class KickCargo(cargo : Vehicle, speed : Int) extends Response
|
||||
final case class ForceDismountVehicleCargo(vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) extends Response
|
||||
final case class KickCargo(cargo : Vehicle, speed : Int, delay : Long) extends Response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,9 +140,13 @@ class VehicleService extends Actor {
|
|||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.TransferPassenger(temp_channel, vehicle, vehicle_to_delete))
|
||||
)
|
||||
|
||||
case VehicleAction.KickCargo(player_guid, cargo, speed) =>
|
||||
case VehicleAction.ForceDismountVehicleCargo(player_guid, vehicle_guid, bailed, requestedByPassenger, kicked) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.KickCargo(cargo, speed))
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.ForceDismountVehicleCargo(vehicle_guid, bailed, requestedByPassenger, kicked))
|
||||
)
|
||||
case VehicleAction.KickCargo(player_guid, cargo, speed, delay) =>
|
||||
VehicleEvents.publish(
|
||||
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.KickCargo(cargo, speed, delay))
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package services.vehicle.support
|
|||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.DriveState
|
||||
import services.{RemoverActor, Service}
|
||||
import services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
|
@ -26,6 +27,21 @@ class VehicleRemover extends RemoverActor {
|
|||
val vehicleGUID = vehicle.GUID
|
||||
val zoneId = entry.zone.Id
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
//escape being someone else's cargo
|
||||
(vehicle.MountedIn match {
|
||||
case Some(carrierGUID) =>
|
||||
entry.zone.Vehicles.find(v => v.GUID == carrierGUID)
|
||||
case None =>
|
||||
None
|
||||
}) match {
|
||||
case Some(carrier : Vehicle) =>
|
||||
val driverName = carrier.Seats(0).Occupant match {
|
||||
case Some(driver) => driver.Name
|
||||
case _ => zoneId
|
||||
}
|
||||
context.parent ! VehicleServiceMessage(s"$driverName", VehicleAction.ForceDismountVehicleCargo(PlanetSideGUID(0), vehicleGUID, true, false, false))
|
||||
case _ => ;
|
||||
}
|
||||
//kick out all passengers
|
||||
vehicle.Seats.values.foreach(seat => {
|
||||
seat.Occupant match {
|
||||
|
|
@ -37,6 +53,12 @@ class VehicleRemover extends RemoverActor {
|
|||
}
|
||||
case None => ;
|
||||
}
|
||||
//abandon all cargo
|
||||
vehicle.CargoHolds.values
|
||||
.collect { case hold if hold.isOccupied =>
|
||||
val cargo = hold.Occupant.get
|
||||
context.parent ! VehicleServiceMessage(zoneId, VehicleAction.ForceDismountVehicleCargo(PlanetSideGUID(0), cargo.GUID, true, false, false))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue