mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-20 02:54:46 +00:00
Spawn Pad Fix (#394)
* reset pad order queueing system if the player forces a system fix; blocking dismounting of vehicle in certain situations, such as the vehicle just being spawned * test fixes
This commit is contained in:
parent
9f12cfa625
commit
4e5bb3a252
|
|
@ -112,6 +112,8 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase
|
|||
case None => ;
|
||||
}
|
||||
trackedOrder = None
|
||||
handleOrderFunc = NewTasking
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad) //cautious animation reset
|
||||
concealPlayer ! akka.actor.Kill //should cause the actor to restart, which will abort any trapped messages
|
||||
|
||||
case _ => ;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class VehicleSpawnControlConcealPlayer(pad : VehicleSpawnPad) extends VehicleSpa
|
|||
def receive : Receive = {
|
||||
case order @ VehicleSpawnControl.Order(driver, _) =>
|
||||
//TODO how far can the driver stray from the Terminal before his order is cancelled?
|
||||
if(driver.Continent == pad.Continent && driver.VehicleSeated.isEmpty) {
|
||||
if(driver.Continent == pad.Continent && driver.VehicleSeated.isEmpty && driver.isAlive) {
|
||||
trace(s"hiding ${driver.Name}")
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID)
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class VehicleSpawnControlDriverControl(pad : VehicleSpawnPad) extends VehicleSpa
|
|||
else {
|
||||
trace(s"${driver.Name} is not seated in ${vehicle.Definition.Name}; vehicle controls might have been locked")
|
||||
}
|
||||
vehicle.MountedIn = None
|
||||
finalClear ! order
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class VehicleSpawnControlLoadVehicle(pad : VehicleSpawnPad) extends VehicleSpawn
|
|||
|
||||
def receive : Receive = {
|
||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
if(driver.Continent == pad.Continent && vehicle.Health > 0) {
|
||||
if(driver.Continent == pad.Continent && vehicle.Health > 0 && driver.isAlive) {
|
||||
trace(s"loading the ${vehicle.Definition.Name}")
|
||||
vehicle.Position = vehicle.Position - Vector3.z(if(GlobalDefinitions.isFlightVehicle(vehicle.Definition)) 9 else 5) //appear below the trench and doors
|
||||
vehicle.Cloaked = vehicle.Definition.CanCloak && driver.Cloaked
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class VehicleSpawnControlRailJack(pad : VehicleSpawnPad) extends VehicleSpawnCon
|
|||
|
||||
def receive : Receive = {
|
||||
case order @ VehicleSpawnControl.Order(_, vehicle) =>
|
||||
vehicle.MountedIn = pad.GUID
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.AttachToRails(vehicle, pad)
|
||||
context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, order)
|
||||
|
||||
|
|
|
|||
|
|
@ -5024,9 +5024,17 @@ class WorldSessionActor extends Actor
|
|||
// TODO: Make sure this is the correct response for all cases
|
||||
ValidObject(object_guid) match {
|
||||
case Some(vehicle : Vehicle) =>
|
||||
if((player.VehicleOwned.contains(object_guid) && vehicle.Owner.contains(player.GUID)) ||
|
||||
(player.Faction == vehicle.Faction &&
|
||||
((vehicle.Owner.isEmpty || continent.GUID(vehicle.Owner.get).isEmpty) || vehicle.Destroyed))) {
|
||||
/* line 1a: player is admin (and overrules other access requirements) */
|
||||
/* line 1b: vehicle and player (as the owner) acknowledge each other */
|
||||
/* line 1c: vehicle is the same faction as player and either the owner is absent or the vehicle is destroyed */
|
||||
/* line 2: vehicle is not mounted in anything or, if it is, its seats are empty */
|
||||
if(
|
||||
(admin ||
|
||||
(player.VehicleOwned.contains(object_guid) && vehicle.Owner.contains(player.GUID)) ||
|
||||
(player.Faction == vehicle.Faction && ((vehicle.Owner.isEmpty || continent.GUID(vehicle.Owner.get).isEmpty) || vehicle.Destroyed))
|
||||
) &&
|
||||
(vehicle.MountedIn.isEmpty || !vehicle.Seats.values.exists(_.isOccupied))
|
||||
) {
|
||||
vehicle.Actor ! Vehicle.Deconstruct()
|
||||
log.info(s"RequestDestroy: vehicle $vehicle")
|
||||
}
|
||||
|
|
@ -5995,45 +6003,56 @@ class WorldSessionActor extends Actor
|
|||
}
|
||||
if(player.GUID == player_guid) {
|
||||
//normally disembarking from a seat
|
||||
player.VehicleSeated match {
|
||||
case Some(obj_guid) =>
|
||||
interstellarFerry.orElse(continent.GUID(obj_guid)) match {
|
||||
case Some(obj : Mountable) =>
|
||||
obj.PassengerInSeat(player) match {
|
||||
case Some(0) if controlled.nonEmpty =>
|
||||
log.warn(s"DismountVehicleMsg: can not dismount from vehicle as driver while server has asserted control; please wait ...")
|
||||
case Some(seat_num : Int) =>
|
||||
obj.Actor ! Mountable.TryDismount(player, seat_num)
|
||||
if(interstellarFerry.isDefined) {
|
||||
//short-circuit the temporary channel for transferring between zones, the player is no longer doing that
|
||||
//see above in VehicleResponse.TransferPassenger case
|
||||
interstellarFerry = None
|
||||
}
|
||||
// Deconstruct the vehicle if the driver has bailed out and the vehicle is capable of flight
|
||||
//todo: implement auto landing procedure if the pilot bails but passengers are still present instead of deconstructing the vehicle
|
||||
//todo: continue flight path until aircraft crashes if no passengers present (or no passenger seats), then deconstruct.
|
||||
//todo: kick cargo passengers out. To be added after PR #216 is merged
|
||||
obj match {
|
||||
case v : Vehicle if bailType == BailType.Bailed && seat_num == 0 && v.Flying =>
|
||||
v.Actor ! Vehicle.Deconstruct() // Immediately deconstruct vehicle
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case None =>
|
||||
dismountWarning(s"DismountVehicleMsg: can not find where player $player_guid is seated in mountable $obj_guid")
|
||||
}
|
||||
case _ =>
|
||||
dismountWarning(s"DismountVehicleMsg: can not find mountable entity $obj_guid")
|
||||
}
|
||||
case None =>
|
||||
(interstellarFerry.orElse(continent.GUID(player.VehicleSeated)) match {
|
||||
case out @ Some(obj : Vehicle) =>
|
||||
if(obj.MountedIn.isEmpty) out else None
|
||||
case out @ Some(_ : Mountable) =>
|
||||
out
|
||||
case _ =>
|
||||
dismountWarning(s"DismountVehicleMsg: player $player_guid not considered seated in a mountable entity")
|
||||
None
|
||||
}) match {
|
||||
case Some(obj : Mountable) =>
|
||||
obj.PassengerInSeat(player) match {
|
||||
case Some(0) if controlled.nonEmpty =>
|
||||
log.warn(s"DismountVehicleMsg: can not dismount from vehicle as driver while server has asserted control; please wait ...")
|
||||
case Some(seat_num : Int) =>
|
||||
obj.Actor ! Mountable.TryDismount(player, seat_num)
|
||||
if(interstellarFerry.isDefined) {
|
||||
//short-circuit the temporary channel for transferring between zones, the player is no longer doing that
|
||||
//see above in VehicleResponse.TransferPassenger case
|
||||
interstellarFerry = None
|
||||
}
|
||||
// Deconstruct the vehicle if the driver has bailed out and the vehicle is capable of flight
|
||||
//todo: implement auto landing procedure if the pilot bails but passengers are still present instead of deconstructing the vehicle
|
||||
//todo: continue flight path until aircraft crashes if no passengers present (or no passenger seats), then deconstruct.
|
||||
//todo: kick cargo passengers out. To be added after PR #216 is merged
|
||||
obj match {
|
||||
case v : Vehicle if bailType == BailType.Bailed && seat_num == 0 && v.Flying =>
|
||||
continent.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(obj), continent))
|
||||
continent.VehicleEvents ! VehicleServiceMessage.Decon(RemoverActor.AddTask(obj, continent, Some(0 seconds))) // Immediately deconstruct vehicle
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case None =>
|
||||
dismountWarning(s"DismountVehicleMsg: can not find where player $player_guid is seated in mountable ${player.VehicleSeated}")
|
||||
}
|
||||
case _ =>
|
||||
dismountWarning(s"DismountVehicleMsg: can not find mountable entity ${player.VehicleSeated}")
|
||||
}
|
||||
}
|
||||
else {
|
||||
//kicking someone else out of a seat; need to own that seat/mountable
|
||||
player.VehicleOwned match {
|
||||
case Some(obj_guid) =>
|
||||
(ValidObject(obj_guid), ValidObject(player_guid)) match {
|
||||
((ValidObject(obj_guid), ValidObject(player_guid)) match {
|
||||
case (vehicle @ Some(obj : Vehicle), tplayer) =>
|
||||
if(obj.MountedIn.isEmpty) (vehicle, tplayer) else (None, None)
|
||||
case (mount @ Some(obj : Mountable), tplayer) =>
|
||||
(mount, tplayer)
|
||||
case _ =>
|
||||
(None, None)
|
||||
}) match {
|
||||
case (Some(obj : Mountable), Some(tplayer : Player)) =>
|
||||
obj.PassengerInSeat(tplayer) match {
|
||||
case Some(seat_num : Int) =>
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ object VehicleSpawnPadControlTest {
|
|||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
|
||||
val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5))
|
||||
guid.AddPool("test-pool", (0 to 3).toList)
|
||||
guid.AddPool("test-pool", (0 to 5).toList)
|
||||
guid.register(vehicle, "test-pool")
|
||||
guid.register(weapon, "test-pool")
|
||||
guid.register(weapon.AmmoSlot.Box, "test-pool")
|
||||
|
|
@ -241,6 +241,7 @@ object VehicleSpawnPadControlTest {
|
|||
pad.Owner = new Building("Building", building_guid = 0, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||
pad.Owner.Faction = faction
|
||||
pad.Zone = zone
|
||||
guid.register(pad, "test-pool")
|
||||
val player = Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
guid.register(player, "test-pool")
|
||||
player.Zone = zone
|
||||
|
|
|
|||
Loading…
Reference in a new issue