mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-26 15:29:09 +00:00
Facility Turrets (#223)
* object class, actor class, and definitions for base turrets; untested * wired base turrets into existence, with hoop jumping; created interface for objects with mounted weapons (vehicles and turrets); working example phalanx_sgl_hevgatcan in Anguta, Ceryshen * re-wiring manned turrets so that the turreted weapon itself never changes externally but merely identifies different and changes internally; workflow for upgrading wall turrets in place (30s); clarifications and documentation for HackMessage and UseItemMessage; getting rid of orphaned packages from previous location of services * added a simple task that reverts upgraded manned turrets to their None state after a certain amount of time has passed; it works but need improvement * turret weapon upgrades now last for a duration of 30 minutes before reverting; created a service support actor base actor that underlies all current support actors; nano-dispenser now properly loads 1 unit of upgrade canister, rather than 100 units; all canister types have appropriate 2x3 inventory size * forgot to hurry; moved over the Services tests from main/test folder into the common/test folder and needed to change the location of ActorTest to accommodate it; test and documentation for MannedTurret; codecov ignore update * wired facility turrets in Anguta, Ceryshen; Akna tower, Ceryshen; and S.Villa tower, home3 (Anguta tower is a watchtower); attempted workaround for Travis CI issues with receiveN; re-introduced RemoveActorTest, at least the first test; expanded how ZoneActor performs tests on MannedTurret setup * getting rid of useless commented-out code; making common operations for mounting and dismounting * removed outdated comment; added ResourceSilo tests; added extra test for Zone
This commit is contained in:
parent
61a51c1dd1
commit
b81ff2bbf4
75 changed files with 2246 additions and 680 deletions
|
|
@ -11,6 +11,8 @@ import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
|||
import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.terminals.{ProximityTerminal, Terminal}
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.turret.MannedTurret
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
object Maps {
|
||||
|
|
@ -1215,6 +1217,14 @@ object Maps {
|
|||
LocalObject(1186, Locker.Constructor)
|
||||
LocalObject(1187, Locker.Constructor)
|
||||
LocalObject(1188, Locker.Constructor)
|
||||
LocalObject(1418, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1419, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1421, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1426, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1427, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1428, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1431, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1432, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1492, ProximityTerminal.Constructor(medical_terminal)) //lobby
|
||||
LocalObject(1494, ProximityTerminal.Constructor(medical_terminal)) //kitchen
|
||||
LocalObject(1564, Terminal.Constructor(order_terminal))
|
||||
|
|
@ -1330,6 +1340,14 @@ object Maps {
|
|||
ObjectToBuilding(1186, 2)
|
||||
ObjectToBuilding(1187, 2)
|
||||
ObjectToBuilding(1188, 2)
|
||||
ObjectToBuilding(1418, 2)
|
||||
ObjectToBuilding(1419, 2)
|
||||
ObjectToBuilding(1421, 2)
|
||||
ObjectToBuilding(1426, 2)
|
||||
ObjectToBuilding(1427, 2)
|
||||
ObjectToBuilding(1428, 2)
|
||||
ObjectToBuilding(1431, 2)
|
||||
ObjectToBuilding(1432, 2)
|
||||
ObjectToBuilding(1492, 2)
|
||||
ObjectToBuilding(1494, 2)
|
||||
ObjectToBuilding(1479, 2)
|
||||
|
|
@ -1385,6 +1403,14 @@ object Maps {
|
|||
DoorToLock(715, 751)
|
||||
TerminalToSpawnPad(224, 223)
|
||||
TerminalToSpawnPad(2419, 1479)
|
||||
TurretToWeapon(1418, 5000)
|
||||
TurretToWeapon(1419, 5001)
|
||||
TurretToWeapon(1421, 5002)
|
||||
TurretToWeapon(1426, 5003)
|
||||
TurretToWeapon(1427, 5004)
|
||||
TurretToWeapon(1428, 5005)
|
||||
TurretToWeapon(1431, 5006)
|
||||
TurretToWeapon(1432, 5007)
|
||||
}
|
||||
|
||||
def Building38() : Unit = {
|
||||
|
|
@ -1487,6 +1513,8 @@ object Maps {
|
|||
LocalObject(1226, Locker.Constructor)
|
||||
LocalObject(1227, Locker.Constructor)
|
||||
LocalObject(1228, Locker.Constructor)
|
||||
LocalObject(1440, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1442, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(1591, Terminal.Constructor(order_terminal))
|
||||
LocalObject(1592, Terminal.Constructor(order_terminal))
|
||||
LocalObject(1593, Terminal.Constructor(order_terminal))
|
||||
|
|
@ -1514,6 +1542,8 @@ object Maps {
|
|||
ObjectToBuilding(1226, 49)
|
||||
ObjectToBuilding(1227, 49)
|
||||
ObjectToBuilding(1228, 49)
|
||||
ObjectToBuilding(1440, 49)
|
||||
ObjectToBuilding(1442, 49)
|
||||
ObjectToBuilding(1591, 49)
|
||||
ObjectToBuilding(1592, 49)
|
||||
ObjectToBuilding(1593, 49)
|
||||
|
|
@ -1529,6 +1559,8 @@ object Maps {
|
|||
DoorToLock(431, 907)
|
||||
DoorToLock(432, 902)
|
||||
DoorToLock(433, 903)
|
||||
TurretToWeapon(1440, 5008)
|
||||
TurretToWeapon(1442, 5009)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1615,10 +1647,6 @@ object Maps {
|
|||
Projectiles(this)
|
||||
}
|
||||
|
||||
val map12 = new ZoneMap("map12") {
|
||||
Projectiles(this)
|
||||
}
|
||||
|
||||
val map13 = new ZoneMap("map13") {
|
||||
Building1()
|
||||
Building2()
|
||||
|
|
@ -1766,6 +1794,8 @@ object Maps {
|
|||
LocalObject(557, IFFLock.Constructor)
|
||||
LocalObject(558, IFFLock.Constructor)
|
||||
LocalObject(559, IFFLock.Constructor)
|
||||
LocalObject(670, MannedTurret.Constructor(manned_turret))
|
||||
LocalObject(671, MannedTurret.Constructor(manned_turret))
|
||||
ObjectToBuilding(330, 29)
|
||||
ObjectToBuilding(331, 29)
|
||||
ObjectToBuilding(332, 29)
|
||||
|
|
@ -1774,10 +1804,14 @@ object Maps {
|
|||
ObjectToBuilding(557, 29)
|
||||
ObjectToBuilding(558, 29)
|
||||
ObjectToBuilding(559, 29)
|
||||
ObjectToBuilding(670, 29)
|
||||
ObjectToBuilding(671, 29)
|
||||
DoorToLock(330, 558)
|
||||
DoorToLock(331, 559)
|
||||
DoorToLock(332, 556)
|
||||
DoorToLock(333, 557)
|
||||
TurretToWeapon(670, 5000)
|
||||
TurretToWeapon(671, 5001)
|
||||
}
|
||||
|
||||
def Building42() : Unit = {
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ object PsLogin {
|
|||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import scala.util.{Failure, Success}
|
||||
implicit val timeout = Timeout(500 milliseconds)
|
||||
implicit val timeout = Timeout(5 seconds)
|
||||
val requestVehicleEventBus : Future[ServiceManager.LookupResult] =
|
||||
(ServiceManager.serviceManager ask ServiceManager.Lookup("vehicle")).mapTo[ServiceManager.LookupResult]
|
||||
requestVehicleEventBus.onComplete {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import net.psforever.objects.serverobject.structures.{Building, StructureType, W
|
|||
import net.psforever.objects.serverobject.terminals._
|
||||
import net.psforever.objects.serverobject.terminals.Terminal.TerminalMessage
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.vehicles.{AccessPermissionGroup, Cargo, Utility, VehicleLockState}
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.zones.{InterstellarCluster, Zone}
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.types._
|
||||
|
|
@ -43,7 +43,7 @@ import services.{RemoverActor, _}
|
|||
import services.avatar.{AvatarAction, AvatarResponse, AvatarServiceMessage, AvatarServiceResponse}
|
||||
import services.galaxy.{GalaxyResponse, GalaxyServiceResponse}
|
||||
import services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse}
|
||||
import services.vehicle.VehicleAction.UnstowEquipment
|
||||
import services.vehicle.support.TurretUpgrader
|
||||
import services.vehicle.{VehicleAction, VehicleResponse, VehicleServiceMessage, VehicleServiceResponse}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -54,6 +54,7 @@ import scala.concurrent.duration._
|
|||
import scala.util.Success
|
||||
import akka.pattern.ask
|
||||
import net.psforever.objects.ballistics.{Projectile, ProjectileResolution}
|
||||
import net.psforever.objects.serverobject.turret.{MannedTurret, TurretUpgrade}
|
||||
|
||||
class WorldSessionActor extends Actor with MDCContextAware {
|
||||
import WorldSessionActor._
|
||||
|
|
@ -179,7 +180,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
* Vehicle cleanup that is specific to log out behavior.
|
||||
*/
|
||||
def DismountVehicleOnLogOut() : Unit = {
|
||||
//TODO Will base guns implement Vehicle type? Don't want those to deconstruct
|
||||
(player.VehicleSeated match {
|
||||
case Some(vehicle_guid) =>
|
||||
continent.GUID(vehicle_guid)
|
||||
|
|
@ -572,6 +572,11 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case VehicleResponse.DetachFromRails(vehicle_guid, pad_guid, pad_position, pad_orientation_z) =>
|
||||
sendResponse(ObjectDetachMessage(pad_guid, vehicle_guid, pad_position + Vector3(0,0,0.5f), pad_orientation_z))
|
||||
|
||||
case VehicleResponse.EquipmentInSlot(pkt) =>
|
||||
if(tplayer_guid != guid) {
|
||||
sendResponse(pkt)
|
||||
}
|
||||
|
||||
case VehicleResponse.InventoryState(obj, parent_guid, start, con_data) =>
|
||||
if(tplayer_guid != guid) {
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
|
|
@ -764,20 +769,24 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case Mountable.MountMessages(tplayer, reply) =>
|
||||
reply match {
|
||||
case Mountable.CanMount(obj : ImplantTerminalMech, seat_num) =>
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
val obj_guid : PlanetSideGUID = obj.GUID
|
||||
log.info(s"MountVehicleMsg: $player_guid mounts $obj @ $seat_num")
|
||||
PlayerActionsToCancel()
|
||||
sendResponse(PlanetsideAttributeMessage(obj_guid, 0, 1000L)) //health of mech
|
||||
sendResponse(ObjectAttachMessage(obj_guid, player_guid, seat_num))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seat_num))
|
||||
MountingAction(tplayer, obj, seat_num)
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, 1000L)) //health of mech
|
||||
|
||||
case Mountable.CanMount(obj : MannedTurret, seat_num) =>
|
||||
obj.WeaponControlledFromSeat(seat_num) match {
|
||||
case Some(weapon : Tool) =>
|
||||
//update mounted weapon belonging to seat
|
||||
weapon.AmmoSlots.foreach(slot => { //update the magazine(s) in the weapon, specifically
|
||||
val magazine = slot.Box
|
||||
sendResponse(InventoryStateMessage(magazine.GUID, weapon.GUID, magazine.Capacity.toLong))
|
||||
})
|
||||
case _ => ; //no weapons to update
|
||||
}
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health))
|
||||
MountingAction(tplayer, obj, seat_num)
|
||||
|
||||
case Mountable.CanMount(obj : Vehicle, seat_num) =>
|
||||
val obj_guid : PlanetSideGUID = obj.GUID
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
log.info(s"MountVehicleMsg: $player_guid mounts $obj_guid @ $seat_num")
|
||||
vehicleService ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(obj), continent)) //clear timer
|
||||
PlayerActionsToCancel()
|
||||
if(seat_num == 0) { //simplistic vehicle ownership management
|
||||
obj.Owner match {
|
||||
case Some(owner_guid) =>
|
||||
|
|
@ -791,7 +800,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case None => ;
|
||||
}
|
||||
tplayer.VehicleOwned = Some(obj_guid)
|
||||
obj.Owner = Some(player_guid)
|
||||
obj.Owner = Some(tplayer.GUID)
|
||||
}
|
||||
obj.WeaponControlledFromSeat(seat_num) match {
|
||||
case Some(weapon : Tool) =>
|
||||
|
|
@ -802,29 +811,27 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
})
|
||||
case _ => ; //no weapons to update
|
||||
}
|
||||
sendResponse(ObjectAttachMessage(obj_guid, player_guid, seat_num))
|
||||
//sendResponse(PlanetsideAttributeMessage(obj.GUID, 0, obj.Health)) //TODO vehicle max health in definition
|
||||
vehicleService ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(obj), continent)) //clear timer
|
||||
AccessContents(obj)
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seat_num))
|
||||
MountingAction(tplayer, obj, seat_num)
|
||||
|
||||
case Mountable.CanMount(obj : Mountable, _) =>
|
||||
log.warn(s"MountVehicleMsg: $obj is some generic mountable object and nothing will happen")
|
||||
|
||||
case Mountable.CanDismount(obj : ImplantTerminalMech, seat_num) =>
|
||||
val obj_guid : PlanetSideGUID = obj.GUID
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
log.info(s"DismountVehicleMsg: $player_guid dismounts $obj @ $seat_num")
|
||||
sendResponse(DismountVehicleMsg(player_guid, BailType.Normal, false))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, BailType.Normal, false))
|
||||
DismountAction(tplayer, obj, seat_num)
|
||||
|
||||
case Mountable.CanDismount(obj : MannedTurret, seat_num) =>
|
||||
DismountAction(tplayer, obj, seat_num)
|
||||
|
||||
case Mountable.CanDismount(obj : Vehicle, seat_num) =>
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
if(player_guid == player.GUID) {
|
||||
//disembarking self
|
||||
log.info(s"DismountVehicleMsg: $player_guid dismounts $obj @ $seat_num")
|
||||
TotalDriverVehicleControl(obj)
|
||||
sendResponse(DismountVehicleMsg(player_guid, BailType.Normal, false))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, BailType.Normal, false))
|
||||
UnAccessContents(obj)
|
||||
DismountAction(tplayer, obj, seat_num)
|
||||
}
|
||||
else {
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, seat_num, true, obj.GUID))
|
||||
|
|
@ -1713,7 +1720,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
antDischargingTick.cancel()
|
||||
}
|
||||
|
||||
case ItemHacking(tplayer, target, tool_guid, delta, completeAction, tickAction) =>
|
||||
case HackingProgress(progressType, tplayer, target, tool_guid, delta, completeAction, tickAction) =>
|
||||
progressBarUpdate.cancel
|
||||
if(progressBarValue.isDefined) {
|
||||
val progressBarVal : Float = progressBarValue.get + delta
|
||||
|
|
@ -1726,10 +1733,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
else {
|
||||
HackState.Ongoing
|
||||
}
|
||||
sendResponse(HackMessage(1, target.GUID, player.GUID, progressBarVal.toInt, 0L, vis, 8L))
|
||||
sendResponse(HackMessage(progressType, target.GUID, player.GUID, progressBarVal.toInt, 0L, vis, 8L))
|
||||
if(progressBarVal > 100) { //done
|
||||
progressBarValue = None
|
||||
log.info(s"Hacked a $target")
|
||||
// sendResponse(HackMessage(0, target.GUID, player.GUID, 100, 1114636288L, HackState.Hacked, 8L))
|
||||
completeAction()
|
||||
}
|
||||
|
|
@ -1737,7 +1743,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
tickAction.getOrElse(() => Unit)()
|
||||
progressBarValue = Some(progressBarVal)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
progressBarUpdate = context.system.scheduler.scheduleOnce(250 milliseconds, self, ItemHacking(tplayer, target, tool_guid, delta, completeAction))
|
||||
progressBarUpdate = context.system.scheduler.scheduleOnce(250 milliseconds, self, HackingProgress(progressType, tplayer, target, tool_guid, delta, completeAction))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1803,6 +1809,11 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
avatar.Certifications += GalaxyGunship
|
||||
avatar.Certifications += Phantasm
|
||||
avatar.Certifications += UniMAX
|
||||
avatar.Certifications += Engineering
|
||||
avatar.Certifications += CombatEngineering
|
||||
avatar.Certifications += AdvancedEngineering
|
||||
avatar.Certifications += FortificationEngineering
|
||||
avatar.Certifications += AssaultEngineering
|
||||
AwardBattleExperiencePoints(avatar, 1000000L)
|
||||
player = new Player(avatar)
|
||||
//player.Position = Vector3(3561.0f, 2854.0f, 90.859375f) //home3, HART C
|
||||
|
|
@ -1812,9 +1823,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
//player.Orientation = Vector3(0f, 0f, 132.1875f)
|
||||
// player.ExoSuit = ExoSuitType.MAX //TODO strange issue; divide number above by 10 when uncommenting
|
||||
player.Slot(0).Equipment = SimpleItem(remote_electronics_kit) //Tool(GlobalDefinitions.StandardPistol(player.Faction))
|
||||
player.Slot(2).Equipment = Tool(mini_chaingun) //punisher //suppressor
|
||||
player.Slot(2).Equipment = Tool(nano_dispenser) //punisher //suppressor
|
||||
player.Slot(4).Equipment = Tool(GlobalDefinitions.StandardMelee(player.Faction))
|
||||
player.Slot(6).Equipment = AmmoBox(bullet_9mm, 20) //bullet_9mm
|
||||
player.Slot(6).Equipment = AmmoBox(upgrade_canister) //bullet_9mm
|
||||
player.Slot(9).Equipment = AmmoBox(rocket, 11) //bullet_9mm
|
||||
player.Slot(12).Equipment = AmmoBox(frag_cartridge) //bullet_9mm
|
||||
player.Slot(33).Equipment = AmmoBox(bullet_9mm_AP)
|
||||
|
|
@ -2056,6 +2067,45 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case _ => ;
|
||||
}
|
||||
})
|
||||
|
||||
//base turrets
|
||||
continent.Map.TurretToWeapon.foreach({ case((turret_guid, weapon_guid)) =>
|
||||
val parent_guid = PlanetSideGUID(turret_guid)
|
||||
continent.GUID(turret_guid) match {
|
||||
case Some(turret : MannedTurret) =>
|
||||
//attached weapon
|
||||
turret.ControlledWeapon(1) match {
|
||||
case Some(obj : Tool) =>
|
||||
val objDef = obj.Definition
|
||||
sendResponse(
|
||||
ObjectCreateMessage(
|
||||
objDef.ObjectId,
|
||||
obj.GUID,
|
||||
ObjectCreateMessageParent(parent_guid, 1),
|
||||
objDef.Packet.ConstructorData(obj).get
|
||||
)
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
//reserved ammunition?
|
||||
//TODO need to register if it exists
|
||||
//seat turret occupant
|
||||
turret.Seats(0).Occupant match {
|
||||
case Some(tplayer) =>
|
||||
val tdefintion = tplayer.Definition
|
||||
sendResponse(
|
||||
ObjectCreateMessage(
|
||||
tdefintion.ObjectId,
|
||||
tplayer.GUID,
|
||||
ObjectCreateMessageParent(parent_guid, 0),
|
||||
tdefintion.Packet.ConstructorData(tplayer).get
|
||||
)
|
||||
)
|
||||
case None => ;
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
})
|
||||
StopBundlingPackets()
|
||||
self ! SetCurrentAvatar(player)
|
||||
|
||||
|
|
@ -2079,33 +2129,22 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
|
||||
case msg @ ChildObjectStateMessage(object_guid, pitch, yaw) =>
|
||||
//the majority of the following check retrieves information to determine if we are in control of the child
|
||||
player.VehicleSeated match {
|
||||
case Some(vehicle_guid) =>
|
||||
continent.GUID(vehicle_guid) match {
|
||||
case Some(obj : Vehicle) =>
|
||||
obj.PassengerInSeat(player) match {
|
||||
case Some(seat_num) =>
|
||||
obj.WeaponControlledFromSeat(seat_num) match {
|
||||
case Some(tool) =>
|
||||
if(tool.GUID == object_guid) {
|
||||
//TODO set tool orientation?
|
||||
player.Orientation = Vector3(0f, pitch, yaw)
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw))
|
||||
}
|
||||
case None =>
|
||||
log.warn(s"ChildObjectState: player $player is not using stated controllable agent")
|
||||
}
|
||||
case None =>
|
||||
log.warn(s"ChildObjectState: player ${player.GUID} is not in a position to use controllable agent")
|
||||
}
|
||||
case _ =>
|
||||
log.warn(s"ChildObjectState: player $player's controllable agent not available in scope")
|
||||
FindContainedWeapon match {
|
||||
case (Some(_), Some(tool)) =>
|
||||
if(tool.GUID == object_guid) {
|
||||
//TODO set tool orientation?
|
||||
player.Orientation = Vector3(0f, pitch, yaw)
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw))
|
||||
}
|
||||
case None =>
|
||||
//TODO status condition of "playing getting out of vehicle to allow for late packets without warning
|
||||
//log.warn(s"ChildObjectState: player $player not related to anything with a controllable agent")
|
||||
else {
|
||||
log.warn(s"ChildObjectState: ${player.Name} is using a different controllable agent than #${object_guid.guid}")
|
||||
}
|
||||
case (Some(obj), None) =>
|
||||
log.warn(s"ChildObjectState: ${player.Name} can not find any controllable agent, let alone #${object_guid.guid}")
|
||||
case (None, _) => ;
|
||||
//TODO status condition of "playing getting out of vehicle to allow for late packets without warning
|
||||
//log.warn(s"ChildObjectState: player $player not related to anything with a controllable agent")
|
||||
}
|
||||
//log.info("ChildObjectState: " + msg)
|
||||
|
||||
case msg @ VehicleStateMessage(vehicle_guid, unk1, pos, ang, vel, unk5, unk6, unk7, wheels, unk9, unkA) =>
|
||||
continent.GUID(vehicle_guid) match {
|
||||
|
|
@ -2299,9 +2338,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
FindContainedWeapon match {
|
||||
case (Some(obj), Some(tool : Tool)) =>
|
||||
val originalAmmoType = tool.AmmoType
|
||||
val fullMagazine = tool.MaxMagazine
|
||||
do {
|
||||
val requestedAmmoType = tool.NextAmmoType
|
||||
val fullMagazine = tool.MaxMagazine
|
||||
if(requestedAmmoType != tool.AmmoSlot.Box.AmmoType) {
|
||||
FindEquipmentStock(obj, FindAmmoBoxThatUses(requestedAmmoType), fullMagazine, CountAmmunition).reverse match {
|
||||
case Nil => ;
|
||||
|
|
@ -2823,14 +2862,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.warn(s"Player ${player.GUID} - ${player.Faction} tried to refill silo ${resourceSilo.GUID} - ${resourceSilo.Faction} belonging to another empire")
|
||||
}
|
||||
|
||||
|
||||
case Some(panel : IFFLock) =>
|
||||
if(panel.Faction != player.Faction && panel.HackedBy.isEmpty) {
|
||||
player.Slot(player.DrawnSlot).Equipment match {
|
||||
case Some(tool : SimpleItem) =>
|
||||
if(tool.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||
progressBarValue = Some(-GetPlayerHackSpeed())
|
||||
self ! WorldSessionActor.ItemHacking(player, panel, tool.GUID, GetPlayerHackSpeed(), FinishHacking(panel, 1114636288L))
|
||||
self ! WorldSessionActor.HackingProgress(1, player, panel, tool.GUID, GetPlayerHackSpeed(), FinishHacking(panel, 1114636288L))
|
||||
log.info("Hacking a door~")
|
||||
}
|
||||
case _ => ;
|
||||
|
|
@ -2892,7 +2930,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case Some(tool: SimpleItem) =>
|
||||
if (tool.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||
progressBarValue = Some(-GetPlayerHackSpeed())
|
||||
self ! WorldSessionActor.ItemHacking(player, obj, tool.GUID, GetPlayerHackSpeed(), FinishHacking(obj, 3212836864L))
|
||||
self ! WorldSessionActor.HackingProgress(1, player, obj, tool.GUID, GetPlayerHackSpeed(), FinishHacking(obj, 3212836864L))
|
||||
log.info("Hacking a locker")
|
||||
}
|
||||
case _ => ;
|
||||
|
|
@ -2907,6 +2945,32 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.info(s"UseItem: not $player's locker")
|
||||
}
|
||||
|
||||
case Some(obj : MannedTurret) =>
|
||||
player.Slot(player.DrawnSlot).Equipment match {
|
||||
case Some(tool : Tool) =>
|
||||
if(tool.Definition == GlobalDefinitions.nano_dispenser && tool.Magazine > 0) {
|
||||
val ammo = tool.AmmoType
|
||||
if(ammo == Ammo.upgrade_canister && obj.Seats.values.count(_.isOccupied) == 0) {
|
||||
progressBarValue = Some(-1.25f)
|
||||
self ! WorldSessionActor.HackingProgress(
|
||||
2,
|
||||
player,
|
||||
obj,
|
||||
tool.GUID,
|
||||
1.25f,
|
||||
FinishUpgradingMannedTurret(obj, tool, TurretUpgrade(unk2.toInt))
|
||||
)
|
||||
}
|
||||
else if(ammo == Ammo.armor_canister && obj.Health < obj.MaxHealth) {
|
||||
//repair turret
|
||||
}
|
||||
}
|
||||
else if(tool.Definition == GlobalDefinitions.trek) {
|
||||
//infect turret with virus
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
case Some(obj : Vehicle) =>
|
||||
val equipment = player.Slot(player.DrawnSlot).Equipment
|
||||
if(player.Faction == obj.Faction) {
|
||||
|
|
@ -2969,7 +3033,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case Some(tool: SimpleItem) =>
|
||||
if (tool.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||
progressBarValue = Some(-GetPlayerHackSpeed())
|
||||
self ! WorldSessionActor.ItemHacking(player, obj, tool.GUID, GetPlayerHackSpeed(), FinishHacking(obj, 3212836864L))
|
||||
self ! WorldSessionActor.HackingProgress(1, player, obj, tool.GUID, GetPlayerHackSpeed(), FinishHacking(obj, 3212836864L))
|
||||
log.info("Hacking a terminal")
|
||||
}
|
||||
case _ => ;
|
||||
|
|
@ -2979,7 +3043,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
// Otherwise allow the faction that owns the terminal to use it
|
||||
sendResponse(UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case Some(obj : SpawnTube) =>
|
||||
|
|
@ -3853,7 +3916,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
/**
|
||||
* The process of hacking an object is completed
|
||||
* The process of hacking an object is completed.
|
||||
* Pass the message onto the hackable object and onto the local events system.
|
||||
* @param target the `Hackable` object that has been hacked
|
||||
* @param unk na;
|
||||
|
|
@ -3862,16 +3925,33 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
*/
|
||||
//TODO add params here depending on which params in HackMessage are important
|
||||
private def FinishHacking(target : PlanetSideServerObject with Hackable, unk : Long)() : Unit = {
|
||||
log.info(s"Hacked a $target")
|
||||
// Wait for the target actor to set the HackedBy property, otherwise LocalAction.HackTemporarily will not complete properly
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
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))
|
||||
localService ! LocalServiceMessage(continent.Id, LocalAction.HackTemporarily(player.GUID, continent, target, unk))
|
||||
case scala.util.Failure(_) => log.warn(s"Hack message failed on target guid: ${target.GUID}")
|
||||
}
|
||||
localService ! LocalServiceMessage(continent.Id, LocalAction.HackTemporarily(player.GUID, continent, target, unk))
|
||||
case scala.util.Failure(_) =>
|
||||
log.warn(s"Hack message failed on target guid: ${target.GUID}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The process of upgrading a turret's weapon(s) is completed.
|
||||
* Pass the message onto the turret and onto the vehicle events system.
|
||||
* Additionally, force-deplete the ammunition count of the nano-dispenser used to perform the upgrade.
|
||||
* @param target the turret
|
||||
* @param tool the nano-dispenser that was used to perform this upgrade
|
||||
* @param upgrade the new upgrade state
|
||||
*/
|
||||
private def FinishUpgradingMannedTurret(target : MannedTurret, tool : Tool, upgrade : TurretUpgrade.Value)() : Unit = {
|
||||
log.info(s"Converting manned wall turret weapon to $upgrade")
|
||||
tool.Magazine = 0
|
||||
sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, tool.GUID, 0))
|
||||
vehicleService ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), continent))
|
||||
vehicleService ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, continent, upgrade))
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary function that iterates over vehicle permissions and turns them into `PlanetsideAttributeMessage` packets.<br>
|
||||
|
|
@ -3887,7 +3967,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
* Occasionally, during deployment, local(?) vehicle seat access permissions may change.
|
||||
* This results in players being locked into their own vehicle.
|
||||
* Reloading vehicle permissions supposedly ensures the seats will be properly available.
|
||||
* This is considered a client issue; but, somehow, it also impacts server operation somehow.
|
||||
* This is considered a client issue; but, somehow, it also impacts server operation somehow.<br>
|
||||
* <br>
|
||||
* 22 June 2018:<br>
|
||||
* I think vehicle ownership works properly now.
|
||||
* @param vehicle the `Vehicle`
|
||||
*/
|
||||
def ReloadVehicleAccessPermissions(vehicle : Vehicle) : Unit = {
|
||||
|
|
@ -4025,7 +4108,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
player.VehicleSeated match {
|
||||
case Some(vehicle_guid) => //weapon is vehicle turret?
|
||||
continent.GUID(vehicle_guid) match {
|
||||
case Some(vehicle : Vehicle) =>
|
||||
case Some(vehicle : Mountable with MountedWeapons with Container) =>
|
||||
vehicle.PassengerInSeat(player) match {
|
||||
case Some(seat_num) =>
|
||||
(Some(vehicle), vehicle.WeaponControlledFromSeat(seat_num))
|
||||
|
|
@ -5312,6 +5395,34 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common activities/procedure when a player mounts a valid object.
|
||||
* @param tplayer the player
|
||||
* @param obj the mountable object
|
||||
* @param seatNum the seat into which the player is mounting
|
||||
*/
|
||||
def MountingAction(tplayer : Player, obj : PlanetSideGameObject with Mountable, seatNum : Int) : Unit = {
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
val obj_guid : PlanetSideGUID = obj.GUID
|
||||
PlayerActionsToCancel()
|
||||
log.info(s"MountVehicleMsg: $player_guid mounts $obj @ $seatNum")
|
||||
sendResponse(ObjectAttachMessage(obj_guid, player_guid, seatNum))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seatNum))
|
||||
}
|
||||
|
||||
/**
|
||||
* Common activities/procedure when a player dismounts a valid object.
|
||||
* @param tplayer the player
|
||||
* @param obj the mountable object
|
||||
* @param seatNum the seat out of which which the player is disembarking
|
||||
*/
|
||||
def DismountAction(tplayer : Player, obj : PlanetSideGameObject with Mountable, seatNum : Int) : Unit = {
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
log.info(s"DismountVehicleMsg: ${tplayer.Name} dismounts $obj from $seatNum")
|
||||
sendResponse(DismountVehicleMsg(player_guid, BailType.Normal, false))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, BailType.Normal, false))
|
||||
}
|
||||
|
||||
def failWithError(error : String) = {
|
||||
log.error(error)
|
||||
sendResponse(ConnectionClose())
|
||||
|
|
@ -5470,9 +5581,12 @@ object WorldSessionActor {
|
|||
|
||||
|
||||
/**
|
||||
* A message that indicates the user is using a remote electronics kit to hack some server object.
|
||||
* A message that indicates the user is using a remote electronics kit to hack some server object.<br>
|
||||
* <br>
|
||||
* Each time this message is sent for a given hack attempt counts as a single "tick" of progress.
|
||||
* The process of "making progress" with a hack involves sending this message repeatedly until the progress is 100 or more.
|
||||
* To calculate the actual amount of change in the progress `delta`,
|
||||
* start with 100, divide by the length of time in seconds, then divide once more by 4.
|
||||
* @param tplayer the player
|
||||
* @param target the object being hacked
|
||||
* @param tool_guid the REK
|
||||
|
|
@ -5480,12 +5594,13 @@ object WorldSessionActor {
|
|||
* @param completeAction a custom action performed once the hack is completed
|
||||
* @param tickAction an optional action is is performed for each tick of progress
|
||||
*/
|
||||
private final case class ItemHacking(tplayer : Player,
|
||||
target : PlanetSideServerObject,
|
||||
tool_guid : PlanetSideGUID,
|
||||
delta : Float,
|
||||
completeAction : () => Unit,
|
||||
tickAction : Option[() => Unit] = None)
|
||||
private final case class HackingProgress(progressType : Int,
|
||||
tplayer : Player,
|
||||
target : PlanetSideServerObject,
|
||||
tool_guid : PlanetSideGUID,
|
||||
delta : Float,
|
||||
completeAction : () => Unit,
|
||||
tickAction : Option[() => Unit] = None)
|
||||
|
||||
private final case class NtuCharging(tplayer: Player,
|
||||
vehicle: Vehicle)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue