restored vehicle decay upon a vehicle becoming unowned; PlayerSource should be much more simple

This commit is contained in:
FateJH 2020-05-13 21:24:46 -04:00
parent 42a2512aa0
commit 2b8e879c2e
5 changed files with 86 additions and 30 deletions

View file

@ -605,6 +605,16 @@ object Vehicle {
*/
final case class UpdateShieldsCharge(vehicle : Vehicle)
/**
* Change a vehicle's internal ownership property to match that of the target player.
* @param player the person who will own the vehicle, or `None` if the vehicle will go unowned
*/
final case class Ownership(player : Option[Player])
object Ownership {
def apply(player : Player) : Ownership = Ownership(Some(player))
}
/**
* Overloaded constructor.
* @param vehicleDef the vehicle's definition entry

View file

@ -41,6 +41,34 @@ object Vehicles {
}
}
/**
* Disassociate a vehicle fromthe player who owns it.
* @param guid the unique identifier for that vehicle
* @param vehicle the vehicle
* @return the vehicle, if it had a previous owner;
* `None`, otherwise
*/
def Disown(guid : PlanetSideGUID, vehicle : Vehicle) : Option[Vehicle] = vehicle.Zone.GUID(vehicle.Owner) match {
case Some(player : Player) =>
if(player.VehicleOwned.contains(guid)) {
player.VehicleOwned = None
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, VehicleAction.Ownership(player.GUID, PlanetSideGUID(0)))
}
vehicle.AssignOwnership(None)
val empire = VehicleLockState.Empire.id
val factionChannel = s"${vehicle.Faction}"
(0 to 2).foreach(group => {
vehicle.PermissionGroup(group, empire)
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(factionChannel,
VehicleAction.SeatPermissions(Service.defaultPlayerGUID, guid, group, empire)
)
})
ReloadAccessPermissions(vehicle, player.Name)
Some(vehicle)
case _ =>
None
}
/**
* Disassociate a player from a vehicle that he owns.
* The vehicle must exist in the game world on the specified continent.
@ -82,13 +110,12 @@ object Vehicles {
val pguid = player.GUID
if(vehicle.Owner.contains(pguid)) {
vehicle.AssignOwnership(None)
val factionChannel = s"${vehicle.Faction}"
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(factionChannel, VehicleAction.Ownership(pguid, PlanetSideGUID(0)))
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, VehicleAction.Ownership(pguid, PlanetSideGUID(0)))
val vguid = vehicle.GUID
val empire = VehicleLockState.Empire.id
(0 to 2).foreach(group => {
vehicle.PermissionGroup(group, empire)
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(factionChannel, VehicleAction.SeatPermissions(pguid, vguid, group, empire))
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(s"${vehicle.Faction}", VehicleAction.SeatPermissions(pguid, vguid, group, empire))
})
ReloadAccessPermissions(vehicle, player.Name)
Some(vehicle)

View file

@ -2,7 +2,7 @@
package net.psforever.objects.ballistics
import net.psforever.objects.Player
import net.psforever.objects.definition.ObjectDefinition
import net.psforever.objects.definition.{ExoSuitDefinition, ObjectDefinition}
import net.psforever.objects.vital.resistance.ResistanceProfile
import net.psforever.types.{ExoSuitType, PlanetSideEmpire, Vector3}
@ -35,6 +35,7 @@ final case class PlayerSource(name : String,
object PlayerSource {
def apply(tplayer : Player) : PlayerSource = {
PlayerSource(tplayer.Name, tplayer.CharId, tplayer.Definition, tplayer.Faction, tplayer.ExoSuit, tplayer.VehicleSeated.nonEmpty,
tplayer.Health, tplayer.Armor, tplayer.Position, tplayer.Orientation, tplayer.Velocity, tplayer.asInstanceOf[ResistanceProfile])
tplayer.Health, tplayer.Armor, tplayer.Position, tplayer.Orientation, tplayer.Velocity,
ExoSuitDefinition.Select(tplayer.ExoSuit, tplayer.Faction))
}
}

View file

@ -2,7 +2,7 @@
package net.psforever.objects.vehicles
import akka.actor.{Actor, ActorRef, Cancellable}
import net.psforever.objects.{DefaultCancellable, GlobalDefinitions, SimpleItem, Vehicle, Vehicles}
import net.psforever.objects._
import net.psforever.objects.ballistics.{ResolvedProjectile, VehicleSource}
import net.psforever.objects.equipment.JammableMountedWeapons
import net.psforever.objects.serverobject.CommonMessages
@ -73,11 +73,31 @@ class VehicleControl(vehicle : Vehicle) extends Actor
.orElse(takesDamage)
.orElse(canBeRepairedByNanoDispenser)
.orElse {
case msg : Mountable.TryMount =>
case Vehicle.Ownership(None) =>
LoseOwnership()
case Vehicle.Ownership(Some(player)) =>
GainOwnership(player)
case msg @ Mountable.TryMount(player, seat_num) =>
tryMountBehavior.apply(msg)
if(MountableObject.Seats.values.exists(_.isOccupied)) {
decaying = false
decayTimer.cancel
val obj = MountableObject
if(obj.Seats.values.exists(_.isOccupied)) {
if(seat_num == 0 && !obj.OwnerName.contains(player.Name)) {
//whatever vehicle was previously owned
vehicle.Zone.GUID(player.VehicleOwned) match {
case Some(v : Vehicle) =>
v.Actor ! Vehicle.Ownership(None)
case _ =>
player.VehicleOwned = None
}
LoseOwnership() //lose our current ownership
GainOwnership(player) //gain new ownership
}
else {
decaying = false
decayTimer.cancel
}
}
case msg : Mountable.TryDismount =>
@ -88,7 +108,6 @@ class VehicleControl(vehicle : Vehicle) extends Actor
if(!obj.Seats(0).isOccupied) {
obj.Velocity = Some(Vector3.Zero)
}
if(!decaying && obj.Owner.isEmpty && obj.Seats.values.forall(!_.isOccupied)) {
decaying = true
decayTimer = context.system.scheduler.scheduleOnce(MountableObject.Definition.DeconstructionTime.getOrElse(5 minutes), self, VehicleControl.PrepareForDeletion())
@ -221,6 +240,24 @@ class VehicleControl(vehicle : Vehicle) extends Actor
super.TryJammerEffectActivate(target, cause)
}
}
def LoseOwnership() : Unit = {
val obj = MountableObject
Vehicles.Disown(obj.GUID, obj)
if(!decaying && obj.Seats.values.forall(!_.isOccupied)) {
decaying = true
decayTimer = context.system.scheduler.scheduleOnce(obj.Definition.DeconstructionTime.getOrElse(5 minutes), self, VehicleControl.PrepareForDeletion())
}
}
def GainOwnership(player : Player) : Unit = {
Vehicles.Own(MountableObject, player) match {
case Some(_) =>
decaying = false
decayTimer.cancel
case None => ;
}
}
}
object VehicleControl {

View file

@ -792,9 +792,6 @@ class WorldSessionActor extends Actor
failWithError(s"ListAccountCharacters: no connection - ${e.getMessage}")
}
case VehicleLoaded(_ /*vehicle*/) => ;
//currently being handled by VehicleSpawnPad.LoadVehicle during testing phase
case Zone.ClientInitialization(zone) =>
Thread.sleep(connectionState)
val continentNumber = zone.Number
@ -2291,19 +2288,6 @@ class WorldSessionActor extends Actor
sendResponse(PlanetsideAttributeMessage(obj_guid, 113, capacitor))
}
if(seat_num == 0) {
//simplistic vehicle ownership management
obj.Owner match {
case Some(owner_guid) =>
continent.GUID(owner_guid) match {
case Some(previous_owner : Player) =>
if(previous_owner.VehicleOwned.contains(obj_guid)) {
previous_owner.VehicleOwned = None //simplistic ownership management, player loses vehicle ownership
}
case _ => ;
}
case None => ;
}
Vehicles.Own(obj, tplayer)
if(obj.Definition == GlobalDefinitions.quadstealth) {
//wraith cloak state matches the cloak state of the driver
//phantasm doesn't uncloak if the driver is uncloaked and no other vehicle cloaks
@ -6488,7 +6472,6 @@ class WorldSessionActor extends Actor
TaskResolver.GiveTask(
new Task() {
private val localVehicle = vehicle
private val localAnnounce = self
override def isComplete : Task.Resolution.Value = {
if(localVehicle.HasGUID) {
@ -6502,7 +6485,6 @@ class WorldSessionActor extends Actor
def Execute(resolver : ActorRef) : Unit = {
log.info(s"Vehicle $localVehicle is registered")
resolver ! scala.util.Success(this)
localAnnounce ! VehicleLoaded(localVehicle) //alerts WSA
}
}, List(GUIDTask.RegisterVehicle(vehicle)(continent.GUID))
)
@ -11226,7 +11208,6 @@ object WorldSessionActor {
private final case class CreateCharacter(name : String, head : Int, voice : CharacterVoice.Value, gender : CharacterGender.Value, empire : PlanetSideEmpire.Value)
private final case class ListAccountCharacters()
private final case class SetCurrentAvatar(tplayer : Player)
private final case class VehicleLoaded(vehicle : Vehicle)
private final case class ZoningReset()
final val ftes = (