mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-13 15:34:42 +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
7 changed files with 62 additions and 38 deletions
|
|
@ -112,6 +112,8 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends VehicleSpawnControlBase
|
||||||
case None => ;
|
case None => ;
|
||||||
}
|
}
|
||||||
trackedOrder = 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
|
concealPlayer ! akka.actor.Kill //should cause the actor to restart, which will abort any trapped messages
|
||||||
|
|
||||||
case _ => ;
|
case _ => ;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class VehicleSpawnControlConcealPlayer(pad : VehicleSpawnPad) extends VehicleSpa
|
||||||
def receive : Receive = {
|
def receive : Receive = {
|
||||||
case order @ VehicleSpawnControl.Order(driver, _) =>
|
case order @ VehicleSpawnControl.Order(driver, _) =>
|
||||||
//TODO how far can the driver stray from the Terminal before his order is cancelled?
|
//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}")
|
trace(s"hiding ${driver.Name}")
|
||||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID)
|
pad.Zone.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID)
|
||||||
context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order)
|
context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ class VehicleSpawnControlDriverControl(pad : VehicleSpawnPad) extends VehicleSpa
|
||||||
else {
|
else {
|
||||||
trace(s"${driver.Name} is not seated in ${vehicle.Definition.Name}; vehicle controls might have been locked")
|
trace(s"${driver.Name} is not seated in ${vehicle.Definition.Name}; vehicle controls might have been locked")
|
||||||
}
|
}
|
||||||
|
vehicle.MountedIn = None
|
||||||
finalClear ! order
|
finalClear ! order
|
||||||
|
|
||||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class VehicleSpawnControlLoadVehicle(pad : VehicleSpawnPad) extends VehicleSpawn
|
||||||
|
|
||||||
def receive : Receive = {
|
def receive : Receive = {
|
||||||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
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}")
|
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.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
|
vehicle.Cloaked = vehicle.Definition.CanCloak && driver.Cloaked
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class VehicleSpawnControlRailJack(pad : VehicleSpawnPad) extends VehicleSpawnCon
|
||||||
|
|
||||||
def receive : Receive = {
|
def receive : Receive = {
|
||||||
case order @ VehicleSpawnControl.Order(_, vehicle) =>
|
case order @ VehicleSpawnControl.Order(_, vehicle) =>
|
||||||
|
vehicle.MountedIn = pad.GUID
|
||||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.AttachToRails(vehicle, pad)
|
pad.Zone.VehicleEvents ! VehicleSpawnPad.AttachToRails(vehicle, pad)
|
||||||
context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, order)
|
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
|
// TODO: Make sure this is the correct response for all cases
|
||||||
ValidObject(object_guid) match {
|
ValidObject(object_guid) match {
|
||||||
case Some(vehicle : Vehicle) =>
|
case Some(vehicle : Vehicle) =>
|
||||||
if((player.VehicleOwned.contains(object_guid) && vehicle.Owner.contains(player.GUID)) ||
|
/* line 1a: player is admin (and overrules other access requirements) */
|
||||||
(player.Faction == vehicle.Faction &&
|
/* line 1b: vehicle and player (as the owner) acknowledge each other */
|
||||||
((vehicle.Owner.isEmpty || continent.GUID(vehicle.Owner.get).isEmpty) || vehicle.Destroyed))) {
|
/* 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()
|
vehicle.Actor ! Vehicle.Deconstruct()
|
||||||
log.info(s"RequestDestroy: vehicle $vehicle")
|
log.info(s"RequestDestroy: vehicle $vehicle")
|
||||||
}
|
}
|
||||||
|
|
@ -5995,45 +6003,56 @@ class WorldSessionActor extends Actor
|
||||||
}
|
}
|
||||||
if(player.GUID == player_guid) {
|
if(player.GUID == player_guid) {
|
||||||
//normally disembarking from a seat
|
//normally disembarking from a seat
|
||||||
player.VehicleSeated match {
|
(interstellarFerry.orElse(continent.GUID(player.VehicleSeated)) match {
|
||||||
case Some(obj_guid) =>
|
case out @ Some(obj : Vehicle) =>
|
||||||
interstellarFerry.orElse(continent.GUID(obj_guid)) match {
|
if(obj.MountedIn.isEmpty) out else None
|
||||||
case Some(obj : Mountable) =>
|
case out @ Some(_ : Mountable) =>
|
||||||
obj.PassengerInSeat(player) match {
|
out
|
||||||
case Some(0) if controlled.nonEmpty =>
|
case _ =>
|
||||||
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 =>
|
|
||||||
dismountWarning(s"DismountVehicleMsg: player $player_guid not considered seated in a mountable entity")
|
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 {
|
else {
|
||||||
//kicking someone else out of a seat; need to own that seat/mountable
|
//kicking someone else out of a seat; need to own that seat/mountable
|
||||||
player.VehicleOwned match {
|
player.VehicleOwned match {
|
||||||
case Some(obj_guid) =>
|
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)) =>
|
case (Some(obj : Mountable), Some(tplayer : Player)) =>
|
||||||
obj.PassengerInSeat(tplayer) match {
|
obj.PassengerInSeat(tplayer) match {
|
||||||
case Some(seat_num : Int) =>
|
case Some(seat_num : Int) =>
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ object VehicleSpawnPadControlTest {
|
||||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||||
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
|
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
|
||||||
val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5))
|
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(vehicle, "test-pool")
|
||||||
guid.register(weapon, "test-pool")
|
guid.register(weapon, "test-pool")
|
||||||
guid.register(weapon.AmmoSlot.Box, "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 = new Building("Building", building_guid = 0, map_id = 0, zone, StructureType.Building, GlobalDefinitions.building)
|
||||||
pad.Owner.Faction = faction
|
pad.Owner.Faction = faction
|
||||||
pad.Zone = zone
|
pad.Zone = zone
|
||||||
|
guid.register(pad, "test-pool")
|
||||||
val player = Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute))
|
val player = Player(Avatar("test", faction, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||||
guid.register(player, "test-pool")
|
guid.register(player, "test-pool")
|
||||||
player.Zone = zone
|
player.Zone = zone
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue