mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-23 22:29:10 +00:00
force dome provides damage protection to certain amenities, e.g., the generator, the turrets, and any implant machines (cryo); force dome will also suspend hacking attempts under it's envelope, but counter-hacking (resecure) should still be possible; operated turret deployables gain protection while manned; turrets no longer share knowledge of each other's upgrade cycles
This commit is contained in:
parent
94bd315354
commit
73f352490c
17 changed files with 154 additions and 44 deletions
|
|
@ -166,7 +166,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.MountingAction(tplayer, obj, seatNumber)
|
||||
|
||||
case Mountable.CanMount(obj: FacilityTurret, seatNumber, _)
|
||||
if !obj.isUpgrading || System.currentTimeMillis() - GenericHackables.getTurretUpgradeTime >= 1500L =>
|
||||
if !obj.isUpgrading || System.currentTimeMillis() - obj.CheckTurretUpgradeTime >= 1500L =>
|
||||
obj.setMiddleOfUpgrade(false)
|
||||
sessionLogic.zoning.CancelZoningProcess()
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health))
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.MountingAction(tplayer, obj, seatNumber)
|
||||
|
||||
case Mountable.CanMount(obj: FacilityTurret, seatNumber, _)
|
||||
if !obj.isUpgrading || System.currentTimeMillis() - GenericHackables.getTurretUpgradeTime >= 1500L =>
|
||||
if !obj.isUpgrading || System.currentTimeMillis() - obj.CheckTurretUpgradeTime >= 1500L =>
|
||||
log.info(s"${player.Name} mounts the ${obj.Definition.Name}")
|
||||
obj.setMiddleOfUpgrade(false)
|
||||
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_mount")
|
||||
|
|
|
|||
|
|
@ -109,11 +109,16 @@ case object MajorFacilityLogic
|
|||
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||
case dome: ForceDomePhysics =>
|
||||
val building = details.building
|
||||
// The force dome being expanded modifies the NTU drain rate
|
||||
// The protection of the force dome modifies the NTU drain rate
|
||||
val multiplier: Float = calculateNtuDrainMultiplierFrom(details.building, domeOpt = Some(dome))
|
||||
building.NtuSource.foreach(_.Actor ! ResourceSiloControl.DrainMultiplier(multiplier))
|
||||
// The force dome being expanded marks the generator as being invulnerable; it can be damaged otherwise
|
||||
building.Generator.foreach { _.Actor ! Damageable.Vulnerability(dome.Energized) }
|
||||
// The protection of the force dome marks the generator (and some other amenities) as being invulnerable
|
||||
val msg = Damageable.Vulnerability(dome.Perimeter.nonEmpty)
|
||||
val applicable = dome.Definition.ApplyProtectionTo
|
||||
building
|
||||
.Amenities
|
||||
.filter(amenity => applicable.contains(amenity.Definition))
|
||||
.foreach { _.Actor ! msg }
|
||||
case _ =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
|
|||
import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior
|
||||
import net.psforever.objects.serverobject.damage.Damageable
|
||||
import net.psforever.objects.serverobject.hackable.Hackable
|
||||
import net.psforever.objects.serverobject.mount.InteractWithRadiationCloudsSeatedInEntity
|
||||
import net.psforever.objects.serverobject.mount.{InteractWithForceDomeProtectionSeatedInEntity, InteractWithRadiationCloudsSeatedInEntity}
|
||||
import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret}
|
||||
import net.psforever.objects.serverobject.turret.{TurretControl, TurretDefinition, WeaponTurret}
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry}
|
||||
|
|
@ -36,6 +36,7 @@ class TurretDeployable(tdef: TurretDeployableDefinition)
|
|||
HackDuration = Array(0, 20, 10, 5)
|
||||
|
||||
if (tdef.Seats.nonEmpty) {
|
||||
interaction(new InteractWithForceDomeProtectionSeatedInEntity)
|
||||
interaction(new InteractWithTurrets())
|
||||
interaction(new InteractWithRadiationCloudsSeatedInEntity(obj = this, range = 100f))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import net.psforever.objects.serverobject.hackable.Hackable
|
|||
import net.psforever.objects.serverobject.interior.{InteriorAwareFromInteraction, Sidedness}
|
||||
import net.psforever.objects.serverobject.structures.AmenityOwner
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vehicles.interaction.{TriggerOnVehicleRule, WithLava, WithWater}
|
||||
import net.psforever.objects.vehicles.interaction.{InteractWithForceDomeProtectionSeatedInVehicle, TriggerOnVehicleRule, WithLava, WithWater}
|
||||
import net.psforever.objects.vital.resistance.StandardResistanceProfile
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.vital.resolution.DamageResistanceModel
|
||||
|
|
@ -94,6 +94,7 @@ class Vehicle(private val vehicleDef: VehicleDefinition)
|
|||
with AuraContainer
|
||||
with MountableEntity
|
||||
with InteriorAwareFromInteraction {
|
||||
interaction(new InteractWithForceDomeProtectionSeatedInVehicle)
|
||||
interaction(environment.interaction.InteractWithEnvironment(Seq(
|
||||
new WithEntrance(),
|
||||
new WithWater(),
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class InteractWithForceDomeProtection
|
|||
}
|
||||
}
|
||||
|
||||
protected def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
|
||||
def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
|
||||
protectedBy = Some(dome)
|
||||
target.Actor ! Damageable.MakeInvulnerable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -965,6 +965,7 @@ object GlobalDefinitionsMiscellaneous {
|
|||
Vector3(-90.328125f, -106.90625f, 0f),
|
||||
Vector3(83.05469f, -106.90625f, 0f)
|
||||
)
|
||||
force_dome_amp_physics.ApplyProtectionTo = List(generator, manned_turret)
|
||||
|
||||
force_dome_comm_physics.Name = "force_dome_comm_physics"
|
||||
force_dome_comm_physics.UseRadius = 121.8149f
|
||||
|
|
@ -976,6 +977,7 @@ object GlobalDefinitionsMiscellaneous {
|
|||
Vector3(-83.640625f, 45.601562f, 0f),
|
||||
Vector3(-83.640625f, -89.859375f, 0f)
|
||||
)
|
||||
force_dome_comm_physics.ApplyProtectionTo = List(generator, manned_turret)
|
||||
|
||||
force_dome_cryo_physics.Name = "force_dome_cryo_physics"
|
||||
force_dome_cryo_physics.UseRadius = 127.9241f //127.7963f
|
||||
|
|
@ -986,6 +988,7 @@ object GlobalDefinitionsMiscellaneous {
|
|||
Vector3(-74.73426f, -103.47f, 0),
|
||||
Vector3(72.75476f, -103.47f, 0)
|
||||
)
|
||||
force_dome_cryo_physics.ApplyProtectionTo = List(generator, implant_terminal_mech, manned_turret)
|
||||
|
||||
force_dome_dsp_physics.Name = "force_dome_dsp_physics"
|
||||
force_dome_dsp_physics.UseRadius = 175.8838f //175.7081f
|
||||
|
|
@ -997,10 +1000,11 @@ object GlobalDefinitionsMiscellaneous {
|
|||
Vector3(130.44531f, 188.26562f, 0f),
|
||||
Vector3(130.44531f, -93.28125f, 0f)
|
||||
)
|
||||
force_dome_dsp_physics.ApplyProtectionTo = List(generator, manned_turret)
|
||||
|
||||
force_dome_tech_physics.Name = "force_dome_tech_physics"
|
||||
force_dome_tech_physics.UseRadius = 150.1284f
|
||||
force_dome_tech_physics.PerimeterOffsets = List( //todo double-check eisa, esamir
|
||||
force_dome_tech_physics.PerimeterOffsets = List( //todo double-check, e.g., eisa, esamir
|
||||
Vector3(130.14636f, -95.20665f, 0f),
|
||||
Vector3(130.14636f, 34.441734f, 0f),
|
||||
Vector3(103.98575f, 52.58408f, 0f),
|
||||
|
|
@ -1011,5 +1015,6 @@ object GlobalDefinitionsMiscellaneous {
|
|||
Vector3(-73.64424f, -114.65837f, 0f),
|
||||
Vector3(102.12191f, -114.65837f, 0f)
|
||||
)
|
||||
force_dome_tech_physics.ApplyProtectionTo = List(generator, manned_turret)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@ object ForceDomeControl {
|
|||
val energizedState = dome.Energized
|
||||
CheckForceDomeStatus(building, dome).exists {
|
||||
case true if !energizedState =>
|
||||
dome.Owner.Actor ! BuildingActor.MapUpdate()
|
||||
ChangeDomeEnergizedState(dome, activationState = true)
|
||||
dome.Owner.Actor ! BuildingActor.MapUpdate()
|
||||
true
|
||||
case false if energizedState =>
|
||||
ChangeDomeEnergizedState(dome, activationState = false)
|
||||
|
|
@ -247,7 +247,7 @@ object ForceDomeControl {
|
|||
* @param segments ground-level perimeter of the force dome is defined by these segments (as vertex pairs)
|
||||
* @param obj1 a game entity, should be the force dome
|
||||
* @param obj2 a game entity, should be a damageable target of the force dome's wrath
|
||||
* @param maxDistance ot applicable
|
||||
* @param maxDistance not applicable
|
||||
* @return `true`, if target is detected within the force dome kill region
|
||||
* `false`, otherwise
|
||||
*/
|
||||
|
|
@ -260,12 +260,12 @@ object ForceDomeControl {
|
|||
@unused maxDistance: Float
|
||||
): Boolean = {
|
||||
val centerPos @ Vector3(centerX, centerY, centerZ) = obj1.Position
|
||||
val Vector3(targetX, targetY, targetZ) = obj2.Position - centerPos //deltas of segment of target to dome
|
||||
val checkForIntersection = segments.exists { case (point1, point2) =>
|
||||
val Vector3(targetX, targetY, _) = obj2.Position.xy - centerPos.xy //deltas of segment of target to dome
|
||||
lazy val checkForIntersection = segments.exists { case (point1, point2) =>
|
||||
//want targets within the perimeter; if there's an intersection, target is outside of the perimeter
|
||||
segmentIntersectionTestPerSegment(centerX, centerY, targetX, targetY, point1.x, point1.y, point2.x, point2.y)
|
||||
}
|
||||
!checkForIntersection && (targetZ < centerZ || Zone.distanceCheck(obj1, obj2, math.pow(obj1.Definition.UseRadius, 2).toFloat))
|
||||
segments.nonEmpty && !checkForIntersection && (obj2.Position.z <= centerZ || Zone.distanceCheck(obj1, obj2, math.pow(obj1.Definition.UseRadius, 2).toFloat))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -402,9 +402,11 @@ class ForceDomeControl(dome: ForceDomePhysics)
|
|||
case ForceDomeControl.ApplyProtection
|
||||
if dome.Energized =>
|
||||
dome.Perimeter = perimeterSegments
|
||||
dome.Owner.Actor ! BuildingActor.AmenityStateChange(dome)
|
||||
|
||||
case ForceDomeControl.RemoveProtection =>
|
||||
dome.Perimeter = List.empty
|
||||
dome.Owner.Actor ! BuildingActor.AmenityStateChange(dome)
|
||||
|
||||
case ForceDomeControl.Purge =>
|
||||
ForceDomeControl.ForceDomeKills(dome, perimeterSegments)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package net.psforever.objects.serverobject.dome
|
|||
|
||||
import net.psforever.objects.geometry.d3.{Sphere, VolumetricGeometry}
|
||||
import net.psforever.objects.serverobject.structures.AmenityDefinition
|
||||
import net.psforever.objects.sourcing.SourceEntry
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
class ForceDomeDefinition(objectId: Int)
|
||||
|
|
@ -22,6 +21,19 @@ class ForceDomeDefinition(objectId: Int)
|
|||
perimeter = points
|
||||
PerimeterOffsets
|
||||
}
|
||||
|
||||
private var protects: List[AmenityDefinition] = List()
|
||||
|
||||
def ApplyProtectionTo: List[AmenityDefinition] = protects
|
||||
|
||||
def ApplyProtectionTo_=(protect: AmenityDefinition): List[AmenityDefinition] = {
|
||||
ApplyProtectionTo_=(List(protect))
|
||||
}
|
||||
|
||||
def ApplyProtectionTo_=(protect: List[AmenityDefinition]): List[AmenityDefinition] = {
|
||||
protects = protect
|
||||
ApplyProtectionTo
|
||||
}
|
||||
}
|
||||
|
||||
object ForceDomeDefinition {
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
package net.psforever.objects.serverobject.hackable
|
||||
|
||||
import net.psforever.actors.zone.BuildingActor
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.dome.ForceDomeControl
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||
import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.services.Service
|
||||
|
|
@ -17,23 +19,7 @@ import scala.util.{Failure, Success}
|
|||
|
||||
object GenericHackables {
|
||||
private val log = org.log4s.getLogger("HackableBehavior")
|
||||
private var turretUpgradeTime: Long = System.currentTimeMillis()
|
||||
private var turretUpgradeTimeSet: Boolean = false
|
||||
|
||||
def updateTurretUpgradeTime(): Long = {
|
||||
turretUpgradeTime = System.currentTimeMillis()
|
||||
turretUpgradeTimeSet = true
|
||||
turretUpgradeTime
|
||||
}
|
||||
|
||||
// Used for checking the time without updating it
|
||||
def getTurretUpgradeTime: Long = {
|
||||
if (!turretUpgradeTimeSet) {
|
||||
turretUpgradeTime = System.currentTimeMillis()
|
||||
turretUpgradeTimeSet = true
|
||||
}
|
||||
turretUpgradeTime
|
||||
}
|
||||
/**
|
||||
* na
|
||||
*
|
||||
|
|
@ -79,7 +65,13 @@ object GenericHackables {
|
|||
* @return `true`, if the next cycle of progress should occur;
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def HackingTickAction(progressType: HackState1, hacker: Player, target: PlanetSideServerObject, tool_guid: PlanetSideGUID)(
|
||||
def HackingTickAction(
|
||||
progressType: HackState1,
|
||||
hacker: Player,
|
||||
target: PlanetSideServerObject,
|
||||
tool_guid: PlanetSideGUID,
|
||||
additionalCancellationTests: (PlanetSideServerObject, Player) => Boolean = ForceDomeProtectsFromHacking
|
||||
)(
|
||||
progress: Float
|
||||
): Boolean = {
|
||||
//hack state for progress bar visibility
|
||||
|
|
@ -87,9 +79,7 @@ object GenericHackables {
|
|||
(HackState.Start, 0)
|
||||
} else if (progress >= 100L) {
|
||||
(HackState.Finished, 100)
|
||||
} else if (target.isMoving(test = 1f) || target.Destroyed || !target.HasGUID) {
|
||||
(HackState.Cancelled, 0)
|
||||
} else if (target.isInstanceOf[CaptureTerminal] && EndHackProgress(target, hacker)) {
|
||||
} else if (target.isMoving(test = 1f) || target.Destroyed || !target.HasGUID || additionalCancellationTests(target, hacker)) {
|
||||
(HackState.Cancelled, 0)
|
||||
} else {
|
||||
(HackState.Ongoing, progress.toInt)
|
||||
|
|
@ -104,6 +94,31 @@ object GenericHackables {
|
|||
progressState != HackState.Cancelled
|
||||
}
|
||||
|
||||
/**
|
||||
* The force dome prevents hacking if its protection has been declared over a capitol.
|
||||
* Under normal circumstances, the dome will be visible in the sky at his point,
|
||||
* blocking enemy encounter within its boundaries,
|
||||
* so anything that can be hacked is on that boundary perimeter,
|
||||
* or an alternate method of entry (Router) has been compromised.
|
||||
* @see `ForceDomeControl.TargetUnderForceDome`
|
||||
* @see `Sector`
|
||||
* @param target the `Hackable` object that has been hacked
|
||||
* @param hacker the player performing the action
|
||||
* @return `true`, if the target is within boundary of a working force dome and thus protected;
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def ForceDomeProtectsFromHacking(target: PlanetSideServerObject, hacker: Player): Boolean = {
|
||||
//explicitly allow friendly hacking which is typically clearing a hack
|
||||
target.Faction != hacker.Faction &&
|
||||
(target match {
|
||||
case obj: Amenity => obj.Owner.asInstanceOf[Building].ForceDome.toList
|
||||
case obj: BlockMapEntity => target.Zone.blockMap.sector(obj).buildingList.flatMap(_.ForceDome)
|
||||
case _ => List()
|
||||
})
|
||||
.filter(_.Perimeter.nonEmpty)
|
||||
.exists(dome => ForceDomeControl.TargetUnderForceDome(dome.Perimeter)(dome, target, maxDistance = 0f))
|
||||
}
|
||||
|
||||
/**
|
||||
* The process of hacking an object is completed.
|
||||
* Pass the message onto the hackable object and onto the local events system.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class InteractWithForceDomeProtectionSeatedInEntity
|
|||
extends InteractWithForceDomeProtection {
|
||||
override def range: Float = 30f
|
||||
|
||||
override protected def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
|
||||
override def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
|
||||
super.applyProtection(target, dome)
|
||||
target
|
||||
.asInstanceOf[Mountable]
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class CaptureTerminalControl(terminal: CaptureTerminal)
|
|||
sender() ! CommonMessages.Progress(
|
||||
GenericHackables.GetHackSpeed(player, terminal),
|
||||
CaptureTerminals.FinishHackingCaptureConsole(terminal, player, unk = -1),
|
||||
GenericHackables.HackingTickAction(HackState1.Unk1, player, terminal, item.GUID)
|
||||
GenericHackables.HackingTickAction(HackState1.Unk1, player, terminal, item.GUID, CaptureTerminals.EndHackProgress)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
// Copyright (c) 2021 PSForever
|
||||
package net.psforever.objects.serverobject.terminals.capture
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.hackable.GenericHackables
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.sourcing.PlayerSource
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
object CaptureTerminals {import scala.concurrent.duration._
|
||||
object CaptureTerminals {
|
||||
private val log = org.log4s.getLogger("CaptureTerminals")
|
||||
|
||||
/**
|
||||
|
|
@ -55,4 +60,47 @@ object CaptureTerminals {import scala.concurrent.duration._
|
|||
log.warn(s"Hack message failed on target guid: ${target.GUID}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the state of connected facilities has changed since the hack progress began. It accounts for a friendly facility
|
||||
* on the other side of a warpgate as well in case there are no friendly facilities in the same zone
|
||||
* @param target the `Hackable` object that has been hacked
|
||||
* @param hacker the player performing the action
|
||||
* @return `true`, if the hack should be ended; `false`, otherwise
|
||||
*/
|
||||
def EndHackProgress(target: PlanetSideServerObject, hacker: Player): Boolean = {
|
||||
val building = target.asInstanceOf[CaptureTerminal].Owner.asInstanceOf[Building]
|
||||
val hackerFaction = hacker.Faction
|
||||
if (GenericHackables.ForceDomeProtectsFromHacking(target, hacker)) {
|
||||
true
|
||||
} else if (building.Faction == PlanetSideEmpire.NEUTRAL ||
|
||||
building.BuildingType == StructureType.Tower ||
|
||||
building.Faction == hackerFaction) {
|
||||
false
|
||||
} else {
|
||||
val stopHackingCount = building.Neighbours match {
|
||||
case Some(neighbors) =>
|
||||
neighbors.count {
|
||||
case wg: WarpGate if wg.Faction == hackerFaction =>
|
||||
true
|
||||
case wg: WarpGate =>
|
||||
val friendlyBaseOpt = for {
|
||||
otherWg <- wg.Neighbours.flatMap(_.find(_.isInstanceOf[WarpGate]))
|
||||
friendly <- otherWg.Neighbours.flatMap(_.collectFirst { case b: Building if !b.isInstanceOf[WarpGate] => b })
|
||||
} yield friendly
|
||||
friendlyBaseOpt.exists { fb =>
|
||||
fb.Faction == hackerFaction &&
|
||||
!fb.CaptureTerminalIsHacked &&
|
||||
fb.NtuLevel > 0
|
||||
}
|
||||
case b =>
|
||||
b.Faction == hackerFaction &&
|
||||
!b.CaptureTerminalIsHacked &&
|
||||
b.NtuLevel > 0
|
||||
}
|
||||
case None => 0
|
||||
}
|
||||
stopHackingCount == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,28 @@ class FacilityTurret(tDef: FacilityTurretDefinition)
|
|||
WeaponTurret.LoadDefinition(turret = this)
|
||||
WhichSide = Sidedness.OutsideOf
|
||||
|
||||
private var turretUpgradeTime: Long = System.currentTimeMillis()
|
||||
private var turretUpgradeTimeSet: Boolean = false
|
||||
|
||||
def UpdateTurretUpgradeTime(): Long = {
|
||||
turretUpgradeTime = System.currentTimeMillis()
|
||||
turretUpgradeTimeSet = true
|
||||
turretUpgradeTime
|
||||
}
|
||||
|
||||
// Used for checking the time without updating it
|
||||
def CheckTurretUpgradeTime: Long = {
|
||||
if (!turretUpgradeTimeSet) {
|
||||
turretUpgradeTime = System.currentTimeMillis()
|
||||
turretUpgradeTimeSet = true
|
||||
}
|
||||
turretUpgradeTime
|
||||
}
|
||||
|
||||
def FinishedTurretUpgradeReset(): Unit = {
|
||||
turretUpgradeTimeSet = false
|
||||
}
|
||||
|
||||
def TurretOwner: SourceEntry = {
|
||||
Seats
|
||||
.headOption
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class FacilityTurretControl(turret: FacilityTurret)
|
|||
seatNumber: Int,
|
||||
player: Player): Boolean = {
|
||||
super.mountTest(obj, seatNumber, player) &&
|
||||
(!TurretObject.isUpgrading || System.currentTimeMillis() - GenericHackables.getTurretUpgradeTime >= 1500L)
|
||||
(!TurretObject.isUpgrading || System.currentTimeMillis() - TurretObject.CheckTurretUpgradeTime >= 1500L)
|
||||
}
|
||||
|
||||
override protected def tryMount(obj: PlanetSideServerObject with Mountable, seatNumber: Int, player: Player): Boolean = {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package net.psforever.objects.serverobject.turret
|
|||
|
||||
import net.psforever.objects.avatar.Certification
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.hackable.GenericHackables.updateTurretUpgradeTime
|
||||
import net.psforever.objects.{Player, Tool, TurretDeployable}
|
||||
import net.psforever.packet.game.{HackMessage, HackState, HackState1, HackState7, InventoryStateMessage}
|
||||
import net.psforever.services.Service
|
||||
|
|
@ -83,7 +82,7 @@ object WeaponTurrets {
|
|||
} else if (turret.Destroyed) {
|
||||
(HackState.Cancelled, 0)
|
||||
} else {
|
||||
updateTurretUpgradeTime()
|
||||
turret.UpdateTurretUpgradeTime()
|
||||
(HackState.Ongoing, progress.toInt)
|
||||
}
|
||||
turret.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import net.psforever.objects.zones.InteractsWithZone
|
|||
|
||||
class InteractWithForceDomeProtectionSeatedInVehicle
|
||||
extends InteractWithForceDomeProtectionSeatedInEntity {
|
||||
override protected def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
|
||||
override def applyProtection(target: InteractsWithZone, dome: ForceDomePhysics): Unit = {
|
||||
super.applyProtection(target, dome)
|
||||
target
|
||||
.asInstanceOf[Vehicle]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue