Vehicle jacking (#264)

* Jacking changes

* GOAM documentation

* Don't disable a deployed router's internal telepad when cleaning up remote telepads (i.e. when router is hacked)

* Reduce some log spam
This commit is contained in:
Mazo 2019-08-21 15:39:44 +01:00 committed by Fate-JH
parent 0730c0deb6
commit 2048fa19cb
8 changed files with 223 additions and 59 deletions

View file

@ -4867,8 +4867,9 @@ object GlobalDefinitions {
fury.TrunkOffset = 30
fury.AutoPilotSpeeds = (24, 10)
fury.DestroyedModel = Some(DestroyedVehicle.QuadAssault)
fury.JackingDuration = Array(0, 10, 3, 2)
quadassault.Name = "quadassault"
quadassault.Name = "quadassault" // Basilisk
quadassault.MaxHealth = 650
quadassault.MaxShields = 130 + 1
quadassault.Seats += 0 -> new SeatDefinition()
@ -4881,8 +4882,9 @@ object GlobalDefinitions {
quadassault.TrunkOffset = 30
quadassault.AutoPilotSpeeds = (24, 10)
quadassault.DestroyedModel = Some(DestroyedVehicle.QuadAssault)
quadassault.JackingDuration = Array(0, 10, 3, 2)
quadstealth.Name = "quadstealth"
quadstealth.Name = "quadstealth" // Wraith
quadstealth.MaxHealth = 650
quadstealth.MaxShields = 130 + 1
quadstealth.CanCloak = true
@ -4895,8 +4897,9 @@ object GlobalDefinitions {
quadstealth.TrunkOffset = 30
quadstealth.AutoPilotSpeeds = (24, 10)
quadstealth.DestroyedModel = Some(DestroyedVehicle.QuadStealth)
quadstealth.JackingDuration = Array(0, 10, 3, 2)
two_man_assault_buggy.Name = "two_man_assault_buggy"
two_man_assault_buggy.Name = "two_man_assault_buggy" // Harasser
two_man_assault_buggy.MaxHealth = 1250
two_man_assault_buggy.MaxShields = 250 + 1
two_man_assault_buggy.Seats += 0 -> new SeatDefinition()
@ -4911,6 +4914,7 @@ object GlobalDefinitions {
two_man_assault_buggy.TrunkOffset = 30
two_man_assault_buggy.AutoPilotSpeeds = (22, 8)
two_man_assault_buggy.DestroyedModel = Some(DestroyedVehicle.TwoManAssaultBuggy)
two_man_assault_buggy.JackingDuration = Array(0, 15, 5, 3)
skyguard.Name = "skyguard"
skyguard.MaxHealth = 1000
@ -4928,8 +4932,9 @@ object GlobalDefinitions {
skyguard.TrunkOffset = 30
skyguard.AutoPilotSpeeds = (22, 8)
skyguard.DestroyedModel = Some(DestroyedVehicle.Skyguard)
skyguard.JackingDuration = Array(0, 15, 5, 3)
threemanheavybuggy.Name = "threemanheavybuggy"
threemanheavybuggy.Name = "threemanheavybuggy" // Marauder
threemanheavybuggy.MaxHealth = 1700
threemanheavybuggy.MaxShields = 340 + 1
threemanheavybuggy.Seats += 0 -> new SeatDefinition()
@ -4950,8 +4955,9 @@ object GlobalDefinitions {
threemanheavybuggy.AutoPilotSpeeds = (22, 8)
threemanheavybuggy.DestroyedModel = Some(DestroyedVehicle.ThreeManHeavyBuggy)
threemanheavybuggy.Subtract.Damage1 = 5
threemanheavybuggy.JackingDuration = Array(0, 20, 7, 5)
twomanheavybuggy.Name = "twomanheavybuggy"
twomanheavybuggy.Name = "twomanheavybuggy" // Enforcer
twomanheavybuggy.MaxHealth = 1800
twomanheavybuggy.MaxShields = 360 + 1
twomanheavybuggy.Seats += 0 -> new SeatDefinition()
@ -4967,8 +4973,9 @@ object GlobalDefinitions {
twomanheavybuggy.AutoPilotSpeeds = (22, 8)
twomanheavybuggy.DestroyedModel = Some(DestroyedVehicle.TwoManHeavyBuggy)
twomanheavybuggy.Subtract.Damage1 = 5
twomanheavybuggy.JackingDuration = Array(0, 20, 7, 5)
twomanhoverbuggy.Name = "twomanhoverbuggy"
twomanhoverbuggy.Name = "twomanhoverbuggy" // Thresher
twomanhoverbuggy.MaxHealth = 1600
twomanhoverbuggy.MaxShields = 320 + 1
twomanhoverbuggy.Seats += 0 -> new SeatDefinition()
@ -4984,8 +4991,9 @@ object GlobalDefinitions {
twomanhoverbuggy.AutoPilotSpeeds = (22, 10)
twomanhoverbuggy.DestroyedModel = Some(DestroyedVehicle.TwoManHoverBuggy)
twomanhoverbuggy.Subtract.Damage1 = 5
twomanhoverbuggy.JackingDuration = Array(0, 20, 7, 5)
mediumtransport.Name = "mediumtransport"
mediumtransport.Name = "mediumtransport" // Deliverer
mediumtransport.MaxHealth = 2500
mediumtransport.MaxShields = 500 + 1
mediumtransport.Seats += 0 -> new SeatDefinition()
@ -5008,8 +5016,9 @@ object GlobalDefinitions {
mediumtransport.AutoPilotSpeeds = (18, 6)
mediumtransport.DestroyedModel = Some(DestroyedVehicle.MediumTransport)
mediumtransport.Subtract.Damage1 = 7
mediumtransport.JackingDuration = Array(0, 25, 8, 5)
battlewagon.Name = "battlewagon"
battlewagon.Name = "battlewagon" // Raider
battlewagon.MaxHealth = 2500
battlewagon.MaxShields = 500 + 1
battlewagon.Seats += 0 -> new SeatDefinition()
@ -5035,6 +5044,7 @@ object GlobalDefinitions {
battlewagon.TrunkOffset = 30
battlewagon.AutoPilotSpeeds = (18, 6)
battlewagon.DestroyedModel = Some(DestroyedVehicle.MediumTransport)
battlewagon.JackingDuration = Array(0, 25, 8, 5)
thunderer.Name = "thunderer"
thunderer.MaxHealth = 2500
@ -5059,6 +5069,7 @@ object GlobalDefinitions {
thunderer.AutoPilotSpeeds = (18, 6)
thunderer.DestroyedModel = Some(DestroyedVehicle.MediumTransport)
thunderer.Subtract.Damage1 = 7
thunderer.JackingDuration = Array(0, 25, 8, 5)
aurora.Name = "aurora"
aurora.MaxHealth = 2500
@ -5083,8 +5094,9 @@ object GlobalDefinitions {
aurora.AutoPilotSpeeds = (18, 6)
aurora.DestroyedModel = Some(DestroyedVehicle.MediumTransport)
aurora.Subtract.Damage1 = 7
aurora.JackingDuration = Array(0, 25, 8 ,5)
apc_tr.Name = "apc_tr"
apc_tr.Name = "apc_tr" // Juggernaut
apc_tr.MaxHealth = 6000
apc_tr.MaxShields = 1200 + 1
apc_tr.Seats += 0 -> new SeatDefinition()
@ -5129,8 +5141,9 @@ object GlobalDefinitions {
apc_tr.TrunkOffset = 30
apc_tr.AutoPilotSpeeds = (16, 6)
apc_tr.DestroyedModel = Some(DestroyedVehicle.Apc)
apc_tr.JackingDuration = Array(0, 45, 15, 10)
apc_nc.Name = "apc_nc"
apc_nc.Name = "apc_nc" // Vindicator
apc_nc.MaxHealth = 6000
apc_nc.MaxShields = 1200 + 1
apc_nc.Seats += 0 -> new SeatDefinition()
@ -5175,8 +5188,9 @@ object GlobalDefinitions {
apc_nc.TrunkOffset = 30
apc_nc.AutoPilotSpeeds = (16, 6)
apc_nc.DestroyedModel = Some(DestroyedVehicle.Apc)
apc_nc.JackingDuration = Array(0, 45, 15, 10)
apc_vs.Name = "apc_vs"
apc_vs.Name = "apc_vs" // Leviathan
apc_vs.MaxHealth = 6000
apc_vs.MaxShields = 1200 + 1
apc_vs.Seats += 0 -> new SeatDefinition()
@ -5221,6 +5235,7 @@ object GlobalDefinitions {
apc_vs.TrunkOffset = 30
apc_vs.AutoPilotSpeeds = (16, 6)
apc_vs.DestroyedModel = Some(DestroyedVehicle.Apc)
apc_vs.JackingDuration = Array(0, 45, 15, 10)
lightning.Name = "lightning"
lightning.MaxHealth = 2000
@ -5236,6 +5251,7 @@ object GlobalDefinitions {
lightning.AutoPilotSpeeds = (20, 8)
lightning.DestroyedModel = Some(DestroyedVehicle.Lightning)
lightning.Subtract.Damage1 = 7
lightning.JackingDuration = Array(0, 20, 7 ,5)
prowler.Name = "prowler"
prowler.MaxHealth = 4800
@ -5256,6 +5272,7 @@ object GlobalDefinitions {
prowler.AutoPilotSpeeds = (14, 6)
prowler.DestroyedModel = Some(DestroyedVehicle.Prowler)
prowler.Subtract.Damage1 = 9
prowler.JackingDuration = Array(0, 30, 10, 5)
vanguard.Name = "vanguard"
vanguard.MaxHealth = 5400
@ -5272,6 +5289,7 @@ object GlobalDefinitions {
vanguard.AutoPilotSpeeds = (16, 6)
vanguard.DestroyedModel = Some(DestroyedVehicle.Vanguard)
vanguard.Subtract.Damage1 = 9
vanguard.JackingDuration = Array(0, 30, 10, 5)
magrider.Name = "magrider"
magrider.MaxHealth = 4200
@ -5290,6 +5308,7 @@ object GlobalDefinitions {
magrider.AutoPilotSpeeds = (18, 6)
magrider.DestroyedModel = Some(DestroyedVehicle.Magrider)
magrider.Subtract.Damage1 = 9
magrider.JackingDuration = Array(0, 30, 10, 5)
val utilityConverter = new UtilityVehicleConverter
ant.Name = "ant"
@ -5307,6 +5326,7 @@ object GlobalDefinitions {
ant.Packet = utilityConverter
ant.DestroyedModel = Some(DestroyedVehicle.Ant)
ant.Subtract.Damage1 = 5
ant.JackingDuration = Array (0, 60, 20, 15)
ams.Name = "ams"
ams.MaxHealth = 3000
@ -5327,6 +5347,7 @@ object GlobalDefinitions {
ams.Packet = utilityConverter
ams.DestroyedModel = Some(DestroyedVehicle.Ams)
ams.Subtract.Damage1 = 10
ams.JackingDuration = Array(0, 60, 20, 15)
val variantConverter = new VariantVehicleConverter
router.Name = "router"
@ -5346,6 +5367,7 @@ object GlobalDefinitions {
router.Packet = variantConverter
router.DestroyedModel = Some(DestroyedVehicle.Router)
router.Subtract.Damage1 = 5
router.JackingDuration = Array(0, 20, 7, 5)
switchblade.Name = "switchblade"
switchblade.MaxHealth = 1750
@ -5365,6 +5387,7 @@ object GlobalDefinitions {
switchblade.DestroyedModel = Some(DestroyedVehicle.Switchblade)
switchblade.Subtract.Damage0 = 5
switchblade.Subtract.Damage1 = 5
switchblade.JackingDuration = Array(0, 20, 7, 5)
flail.Name = "flail"
flail.MaxHealth = 2400
@ -5382,6 +5405,7 @@ object GlobalDefinitions {
flail.Packet = variantConverter
flail.DestroyedModel = Some(DestroyedVehicle.Flail)
flail.Subtract.Damage1 = 7
flail.JackingDuration = Array(0, 20, 7, 5)
mosquito.Name = "mosquito"
mosquito.MaxHealth = 665
@ -5398,8 +5422,9 @@ object GlobalDefinitions {
mosquito.AutoPilotSpeeds = (0, 6)
mosquito.Packet = variantConverter
mosquito.DestroyedModel = Some(DestroyedVehicle.Mosquito)
mosquito.JackingDuration = Array(0, 20, 7, 5)
lightgunship.Name = "lightgunship"
lightgunship.Name = "lightgunship" // Reaver
lightgunship.MaxHealth = 1000
lightgunship.MaxShields = 200 + 1
lightgunship.CanFly = true
@ -5415,6 +5440,7 @@ object GlobalDefinitions {
lightgunship.Packet = variantConverter
lightgunship.DestroyedModel = Some(DestroyedVehicle.LightGunship)
lightgunship.Subtract.Damage1 = 3
lightgunship.JackingDuration = Array(0, 30, 10, 5)
wasp.Name = "wasp"
wasp.MaxHealth = 515
@ -5431,6 +5457,7 @@ object GlobalDefinitions {
wasp.AutoPilotSpeeds = (0, 6)
wasp.Packet = variantConverter
wasp.DestroyedModel = Some(DestroyedVehicle.Mosquito) //set_resource_parent wasp game_objects mosquito
wasp.JackingDuration = Array(0, 20, 7, 5)
liberator.Name = "liberator"
liberator.MaxHealth = 2500
@ -5455,6 +5482,7 @@ object GlobalDefinitions {
liberator.Packet = variantConverter
liberator.DestroyedModel = Some(DestroyedVehicle.Liberator)
liberator.Subtract.Damage1 = 5
liberator.JackingDuration = Array(0, 30, 10, 5)
vulture.Name = "vulture"
vulture.MaxHealth = 2500
@ -5479,8 +5507,9 @@ object GlobalDefinitions {
vulture.Packet = variantConverter
vulture.DestroyedModel = Some(DestroyedVehicle.Liberator) //add_property vulture destroyedphysics liberator_destroyed
vulture.Subtract.Damage1 = 5
vulture.JackingDuration = Array(0, 30, 10, 5)
dropship.Name = "dropship"
dropship.Name = "dropship" // Galaxy
dropship.MaxHealth = 5000
dropship.MaxShields = 1000 + 1
dropship.CanFly = true
@ -5535,6 +5564,7 @@ object GlobalDefinitions {
dropship.Packet = variantConverter
dropship.DestroyedModel = Some(DestroyedVehicle.Dropship)
dropship.Subtract.Damage1 = 7
dropship.JackingDuration = Array(0, 60, 20, 10)
galaxy_gunship.Name = "galaxy_gunship"
galaxy_gunship.MaxHealth = 6000
@ -5568,6 +5598,7 @@ object GlobalDefinitions {
galaxy_gunship.Packet = variantConverter
galaxy_gunship.DestroyedModel = Some(DestroyedVehicle.Dropship) //the adb calls out a galaxy_gunship_destroyed but no such asset exists
galaxy_gunship.Subtract.Damage1 = 7
galaxy_gunship.JackingDuration = Array(0, 60, 20, 10)
lodestar.Name = "lodestar"
lodestar.MaxHealth = 5000
@ -5591,6 +5622,7 @@ object GlobalDefinitions {
lodestar.Packet = variantConverter
lodestar.DestroyedModel = Some(DestroyedVehicle.Lodestar)
lodestar.Subtract.Damage1 = 7
lodestar.JackingDuration = Array(0, 60, 20, 10)
phantasm.Name = "phantasm"
phantasm.MaxHealth = 2500
@ -5616,6 +5648,7 @@ object GlobalDefinitions {
phantasm.AutoPilotSpeeds = (0, 6)
phantasm.Packet = variantConverter
phantasm.DestroyedModel = None //the adb calls out a phantasm_destroyed but no such asset exists
phantasm.JackingDuration = Array(0, 60, 20, 10)
}
/**

View file

@ -123,6 +123,9 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
faction
}
/** How long it takes to jack the vehicle in seconds, based on the hacker's certification level */
def JackingDuration: Array[Int] = Definition.JackingDuration
def MountedIn : Option[PlanetSideGUID] = {
this.mountedIn
}

View file

@ -160,6 +160,13 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId)
MaximumCapacitor
}
private var jackDuration = Array(0, 0, 0, 0)
def JackingDuration: Array[Int] = jackDuration
def JackingDuration_=(arr: Array[Int]) : Array[Int] = {
jackDuration = arr
arr
}
def DestroyedModel : Option[DestroyedVehicle.Value] = destroyedModel
def DestroyedModel_=(model : Option[DestroyedVehicle.Value]) : Option[DestroyedVehicle.Value] = {

View file

@ -28,7 +28,7 @@ class ResourceSiloControl(resourceSilo : ResourceSilo) extends Actor with Factio
case ServiceManager.LookupResult("avatar", endpoint) =>
avatarService = endpoint
log.info("ResourceSiloControl: Silo " + resourceSilo.GUID + " Got avatar service " + endpoint)
log.trace("ResourceSiloControl: Silo " + resourceSilo.GUID + " Got avatar service " + endpoint)
// todo: This is just a temporary solution to drain NTU over time. When base object destruction is properly implemented NTU should be deducted when base objects repair themselves
context.system.scheduler.schedule(5 second, 5 second, self, ResourceSilo.UpdateChargeLevel(-1))

View file

@ -15,7 +15,7 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
private[this] val log = org.log4s.getLogger
override def preStart = {
log.info(s"Starting BuildingControl for ${building.GUID} / ${building.MapId}")
log.trace(s"Starting BuildingControl for ${building.GUID} / ${building.MapId}")
ServiceManager.serviceManager ! Lookup("galaxy")
ServiceManager.serviceManager ! Lookup("local")
}
@ -23,10 +23,10 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
def receive : Receive = checkBehavior.orElse {
case ServiceManager.LookupResult("galaxy", endpoint) =>
galaxyService = endpoint
log.info("BuildingControl: Building " + building.GUID + " Got galaxy service " + endpoint)
log.trace("BuildingControl: Building " + building.GUID + " Got galaxy service " + endpoint)
case ServiceManager.LookupResult("local", endpoint) =>
localService = endpoint
log.info("BuildingControl: Building " + building.GUID + " Got local service " + endpoint)
log.trace("BuildingControl: Building " + building.GUID + " Got local service " + endpoint)
case FactionAffinity.ConvertFactionAffinity(faction) =>
val originalAffinity = building.Faction
if(originalAffinity != (building.Faction = faction)) {
@ -37,7 +37,7 @@ class BuildingControl(building : Building) extends Actor with FactionAffinityBeh
case Building.SendMapUpdate(all_clients: Boolean) =>
val zoneNumber = building.Zone.Number
val buildingNumber = building.MapId
log.info(s"sending BuildingInfoUpdateMessage update - zone=$zoneNumber, building=$buildingNumber")
log.trace(s"sending BuildingInfoUpdateMessage update - zone=$zoneNumber, building=$buildingNumber")
val (
ntuLevel,
isHacked, empireHack, hackTimeRemaining, controllingEmpire,

View file

@ -12,6 +12,13 @@ import shapeless.{::, HNil}
* (Write more some other time.)
* @param object_guid the target object
* @param code the action code
* 24 - deconstructs player
* 28 - start imprinting process (progress bar + character animation)
* 32 - finish imprinting?
* 36 - cloak
* 40 - uncloak
* 82 - hit flinch?
* 138 - time till item can be used ?????
* 44, 45, 46, 47 - Deploy capital base shield pole with animation and broadcasts "The capitol force dome at X has been activated"
* 48, 49, 50, 51 - Stow capital base shield pole with animation and broadcasts "The capitol force dome at X has been deactivated"
* 52, 53, 54, 55 - Deploy capital base shield pole (instantly, unless still in the middle of the stow animation)

View file

@ -112,7 +112,7 @@ class SessionRouter(role : String, pipeline : List[SessionPipeline]) extends Act
}
case SessionReaper() =>
sessionById.foreach { case (id, session) =>
log.debug(session.toString)
log.trace(session.toString)
if(session.getState == Closed()) {
// clear mappings
session.getPipeline.foreach(sessionByActor remove)

View file

@ -2048,10 +2048,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
case VehicleResponse.Ownership(vehicle_guid) =>
sendResponse(PlanetsideAttributeMessage(tplayer_guid, 21, vehicle_guid))
if(tplayer_guid == guid) { // Only the player that owns this vehicle needs the ownership packet
sendResponse(PlanetsideAttributeMessage(tplayer_guid, 21, vehicle_guid))
}
case VehicleResponse.PlanetsideAttribute(vehicle_guid, attribute_type, attribute_value) =>
if(tplayer_guid != guid) {
player.VehicleOwned = Some(vehicle_guid)
sendResponse(PlanetsideAttributeMessage(vehicle_guid, attribute_type, attribute_value))
}
@ -2123,8 +2126,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
}
case VehicleResponse.ForceDismountVehicleCargo(vehicle_guid, bailed, requestedByPassenger, kicked) =>
DismountVehicleCargo(tplayer_guid, vehicle_guid, bailed, requestedByPassenger, kicked)
case VehicleResponse.ForceDismountVehicleCargo(cargo_guid, bailed, requestedByPassenger, kicked) =>
DismountVehicleCargo(tplayer_guid, cargo_guid, bailed, requestedByPassenger, kicked)
case VehicleResponse.KickCargo(vehicle, speed, delay) =>
if(player.VehicleSeated.nonEmpty && deadState == DeadState.Alive) {
if(speed > 0) {
@ -2781,7 +2784,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
def handleControlPkt(pkt : PlanetSideControlPacket) = {
pkt match {
case sync @ ControlSync(diff, _, _, _, _, _, fa, fb) =>
log.debug(s"SYNC: $sync")
log.trace(s"SYNC: $sync")
val serverTick = Math.abs(System.nanoTime().toInt) // limit the size to prevent encoding error
sendResponse(ControlSyncResp(diff, serverTick, fa, fb, fb, fa))
@ -2889,10 +2892,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
case _ => ;
}
case msg @ DismountVehicleCargoMsg(player_guid, vehicle_guid, bailed, requestedByPassenger, kicked) =>
case msg @ DismountVehicleCargoMsg(player_guid, cargo_guid, bailed, requestedByPassenger, kicked) =>
log.info(msg.toString)
if(!requestedByPassenger) {
DismountVehicleCargo(player_guid, vehicle_guid, bailed, requestedByPassenger, kicked)
DismountVehicleCargo(player_guid, cargo_guid, bailed, requestedByPassenger, kicked)
}
case msg @ CharacterCreateRequestMessage(name, head, voice, gender, empire) =>
@ -4138,8 +4141,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
else if(equipment.isDefined) {
equipment.get.Definition match {
case GlobalDefinitions.remote_electronics_kit =>
//TODO hacking behavior
val hackSpeed = GetPlayerHackSpeed(obj)
if(hackSpeed > 0) {
progressBarValue = Some(-hackSpeed)
self ! WorldSessionActor.HackingProgress(progressType = 1, player, obj, equipment.get.GUID, hackSpeed, FinishHackingVehicle(obj, 3212836864L))
log.info("Hacking a vehicle")
}
case _ => ;
}
}
@ -5289,14 +5297,108 @@ class WorldSessionActor extends Actor with MDCContextAware {
ask(target.Actor, CommonMessages.Hack(player))(1 second).mapTo[Boolean].onComplete {
case Success(_) =>
localService ! LocalServiceMessage(continent.Id, LocalAction.TriggerSound(player.GUID, target.HackSound, player.Position, 30, 0.49803925f))
target match {
case term : CaptureTerminal =>
target match {
case term: CaptureTerminal =>
val isResecured = player.Faction == target.Faction
localService ! LocalServiceMessage(continent.Id, LocalAction.HackCaptureTerminal(player.GUID, continent, term, unk, 8L, isResecured))
case _ => localService ! LocalServiceMessage(continent.Id, LocalAction.HackTemporarily(player.GUID, continent, target, unk, target.HackEffectDuration(GetPlayerHackLevel())))
}
case scala.util.Failure(_) => log.warn(s"Hack message failed on target guid: ${target.GUID}")
}
}
/**
* The process of hacking/jacking a vehicle is complete.
* Change the faction of the vehicle to the hacker's faction and remove all occupants.
*
* @param target The `Vehicle` object that has been hacked/jacked
* @param unk na; used by HackMessage` as `unk5`
*/
private def FinishHackingVehicle(target : Vehicle, unk : Long)(): Unit = {
log.info(s"Vehicle guid: ${target.GUID} has been jacked")
// Forcefully dismount any cargo
target.CargoHolds.values.foreach(cargoHold => {
cargoHold.Occupant match {
case Some(cargo : Vehicle) => {
cargo.Seats(0).Occupant match {
case Some(cargoDriver: Player) =>
DismountVehicleCargo(cargoDriver.GUID, cargo.GUID, bailed = target.Flying, requestedByPassenger = false, kicked = true )
case None =>
log.error("FinishHackingVehicle: vehicle in cargo hold missing driver")
HandleDismountVehicleCargo(player.GUID, cargo.GUID, cargo, target.GUID, target, false, false, true)
}
}
case None => ;
}
})
// Forcefully dismount all seated occupants from the vehicle
target.Seats.values.foreach(seat => {
seat.Occupant match {
case Some(tplayer) =>
seat.Occupant = None
tplayer.VehicleSeated = None
if(tplayer.HasGUID) {
vehicleService ! VehicleServiceMessage(tplayer.Continent, VehicleAction.KickPassenger(tplayer.GUID, 4, unk2 = false, target.GUID))
}
case None => ;
}
})
// If the vehicle can fly and is flying deconstruct it, and well played to whomever managed to hack a plane in mid air. I'm impressed.
if(target.Definition.CanFly && target.Flying) {
// todo: Should this force the vehicle to land in the same way as when a pilot bails with passengers on board?
vehicleService ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(target), continent))
vehicleService ! VehicleServiceMessage.Decon(RemoverActor.AddTask(target, continent, Some(0 seconds)))
} else { // Otherwise handle ownership transfer as normal
// Remove ownership of our current vehicle, if we have one
player.VehicleOwned match {
case Some(guid : PlanetSideGUID) =>
continent.GUID(guid) match {
case Some(vehicle: Vehicle) =>
DisownVehicle(player, vehicle)
case _ => ;
}
case _ => ;
}
target.Owner match {
case Some(previousOwnerGuid: PlanetSideGUID) =>
// Remove ownership of the vehicle from the previous player
continent.GUID(previousOwnerGuid) match {
case Some(player: Player) =>
DisownVehicle(player, target)
case _ => ; // Vehicle already has no owner
}
case _ => ;
}
// Now take ownership of the jacked vehicle
target.Faction = player.Faction
OwnVehicle(target, player)
//todo: Send HackMessage -> HackCleared to vehicle? can be found in packet captures. Not sure if necessary.
// And broadcast the faction change to other clients
sendResponse(SetEmpireMessage(target.GUID, player.Faction))
avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.SetEmpire(player.GUID, target.GUID, player.Faction))
}
localService ! LocalServiceMessage(continent.Id, LocalAction.TriggerSound(player.GUID, TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f))
// Clean up after specific vehicles, e.g. remove router telepads
// If AMS is deployed, swap it to the new faction
target.Definition match {
case GlobalDefinitions.router =>
log.info("FinishHackingVehicle: cleaning up after a router ...")
RemoveTelepads(target)
case GlobalDefinitions.ams
if(target.DeploymentState == DriveState.Deployed) =>
vehicleService ! VehicleServiceMessage.AMSDeploymentChange(continent)
case _ => ;
}
}
/**
@ -5374,6 +5476,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(tplayer) =>
tplayer.VehicleOwned = vehicle.GUID
vehicle.AssignOwnership(playerOpt)
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.Ownership(player.GUID, vehicle.GUID))
ReloadVehicleAccessPermissions(vehicle)
Some(vehicle)
case None =>
None
@ -8459,22 +8564,25 @@ class WorldSessionActor extends Actor with MDCContextAware {
case GlobalDefinitions.router =>
//this may repeat for multiple players on the same continent but that's okay(?)
log.info("BeforeUnload: cleaning up after a router ...")
(vehicle.Utility(UtilityType.internal_router_telepad_deployable) match {
case Some(util : Utility.InternalTelepad) =>
val telepad = util.Telepad
util.Active = false
util.Telepad = None
continent.GUID(telepad)
case _ =>
None
}) match {
case Some(telepad : TelepadDeployable) =>
log.info(s"BeforeUnload: deconstructing telepad $telepad that was linked to router $vehicle ...")
telepad.Active = false
localService ! LocalServiceMessage.Deployables(RemoverActor.ClearSpecific(List(telepad), continent))
localService ! LocalServiceMessage.Deployables(RemoverActor.AddTask(telepad, continent, Some(0 seconds)))
case _ => ;
}
RemoveTelepads(vehicle)
case _ => ;
}
}
def RemoveTelepads(vehicle: Vehicle) : Unit = {
(vehicle.Utility(UtilityType.internal_router_telepad_deployable) match {
case Some(util : Utility.InternalTelepad) =>
val telepad = util.Telepad
util.Telepad = None
continent.GUID(telepad)
case _ =>
None
}) match {
case Some(telepad : TelepadDeployable) =>
log.info(s"BeforeUnload: deconstructing telepad $telepad that was linked to router $vehicle ...")
telepad.Active = false
localService ! LocalServiceMessage.Deployables(RemoverActor.ClearSpecific(List(telepad), continent))
localService ! LocalServiceMessage.Deployables(RemoverActor.AddTask(telepad, continent, Some(0 seconds)))
case _ => ;
}
}
@ -8569,9 +8677,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.SendResponse(player_guid, cargoDetachMessage))
driverOpt match {
case Some(driver) =>
if(kicked) {
vehicleService ! VehicleServiceMessage(s"${driver.Name}", VehicleAction.KickCargo(player_guid, cargo, cargo.Definition.AutoPilotSpeed2, 4500))
}
vehicleService ! VehicleServiceMessage(s"${driver.Name}", VehicleAction.KickCargo(player_guid, cargo, cargo.Definition.AutoPilotSpeed2, 2500))
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
//check every quarter second if the vehicle has moved far enough away to be considered dismounted
@ -8595,37 +8702,44 @@ class WorldSessionActor extends Actor with MDCContextAware {
/**
* na
* @param player_guid na
* @param vehicle_guid na
* @param cargo_guid na
* @param bailed na
* @param requestedByPassenger na
* @param kicked na
*/
def DismountVehicleCargo(player_guid : PlanetSideGUID, vehicle_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) : Unit = {
continent.GUID(vehicle_guid) match {
def DismountVehicleCargo(player_guid : PlanetSideGUID, cargo_guid : PlanetSideGUID, bailed : Boolean, requestedByPassenger : Boolean, kicked : Boolean) : Unit = {
continent.GUID(cargo_guid) match {
case Some(cargo : Vehicle) =>
continent.GUID(cargo.MountedIn) match {
case Some(ferry : Vehicle) =>
HandleDismountVehicleCargo(player_guid, vehicle_guid, cargo, ferry.GUID, ferry, bailed, requestedByPassenger, kicked)
HandleDismountVehicleCargo(player_guid, cargo_guid, cargo, ferry.GUID, ferry, bailed, requestedByPassenger, kicked)
case _ =>
log.warn(s"DismountVehicleCargo: target ${cargo.Definition.Name}@$vehicle_guid does not know what treats it as cargo")
log.warn(s"DismountVehicleCargo: target ${cargo.Definition.Name}@$cargo_guid does not know what treats it as cargo")
}
case _ =>
log.warn(s"DismountVehicleCargo: target $vehicle_guid either is not a vehicle in ${continent.Id} or does not exist")
log.warn(s"DismountVehicleCargo: target $cargo_guid either is not a vehicle in ${continent.Id} or does not exist")
}
}
def GetPlayerHackSpeed(obj: PlanetSideServerObject with Hackable): Float = {
def GetPlayerHackSpeed(obj: PlanetSideServerObject): Float = {
val playerHackLevel = GetPlayerHackLevel()
val timeToHack = obj.HackDuration(playerHackLevel)
val timeToHack = obj match {
case (hackable: Hackable) => hackable.HackDuration(playerHackLevel)
case (vehicle: Vehicle) => vehicle.JackingDuration(playerHackLevel)
case _ =>
log.warn(s"Player tried to hack an object that has no hack time defined ${obj.GUID} - ${obj.Definition.Name}")
0
}
if(timeToHack == 0) {
log.warn(s"Player ${player.GUID} tried to hack an object ${obj.GUID} - ${obj.Definition.Name} that they don't have the correct hacking level for")
0f
} else {
// 250 ms per tick on the hacking progress bar
val ticks = (timeToHack * 1000) / 250
100f / ticks
}
// 250 ms per tick on the hacking progress bar
val ticks = (timeToHack * 1000) / 250
100f / ticks
}
def GetPlayerHackLevel(): Int = {