diff --git a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala index 812bf74af..be9b44261 100644 --- a/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/GeneralLogic.scala @@ -36,6 +36,7 @@ import net.psforever.objects.vital.{VehicleDismountActivity, VehicleMountActivit import net.psforever.objects.vital.collision.{CollisionReason, CollisionWithReason} import net.psforever.objects.vital.etc.SuicideReason import net.psforever.objects.vital.interaction.DamageInteraction +import net.psforever.objects.zones.blockmap.BlockMapEntity import net.psforever.objects.zones.{Zone, ZoneProjectile, Zoning} import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game.objectcreate.ObjectClass @@ -116,9 +117,9 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex } } ops.fallHeightTracker(pos.z) - // if (isCrouching && !player.Crouching) { - // //dev stuff goes here - // } +// if (isCrouching && !player.Crouching) { +// //dev stuff goes here +// } player.Position = pos player.Velocity = vel player.Orientation = Vector3(player.Orientation.x, pitch, yaw) @@ -821,19 +822,18 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex continent .GUID(vehicleGuid) .foreach { - case obj: Vehicle if !obj.Destroyed && obj.MountedIn.isEmpty => // vehicle will try to charge even if destroyed & cargo vehicles need to be excluded - obj.Actor ! CommonMessages.ChargeShields( - 15, - Some(continent.blockMap.sector(obj).buildingList.maxBy(_.Definition.SOIRadius)) - ) - case obj: Vehicle if obj.MountedIn.nonEmpty => - false + case obj: Vitality if obj.Destroyed => () //some entities will try to charge even if destroyed + case obj: Vehicle if obj.MountedIn.nonEmpty => () //cargo vehicles need to be excluded + case obj: Vehicle => + commonFacilityShieldCharging(obj) + case obj: TurretDeployable => + commonFacilityShieldCharging(obj) case _ if vehicleGuid.nonEmpty => log.warn( - s"FacilityBenefitShieldChargeRequest: ${player.Name} can not find vehicle ${vehicleGuid.get.guid} in zone ${continent.id}" + s"FacilityBenefitShieldChargeRequest: ${player.Name} can not find chargeable entity ${vehicleGuid.get.guid} in ${continent.id}" ) case _ => - log.warn(s"FacilityBenefitShieldChargeRequest: ${player.Name} is not seated in a vehicle") + log.warn(s"FacilityBenefitShieldChargeRequest: ${player.Name} is not seated in anything") } } @@ -1514,4 +1514,11 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex ) ) } + + private def commonFacilityShieldCharging(obj: PlanetSideServerObject with BlockMapEntity): Unit = { + obj.Actor ! CommonMessages.ChargeShields( + 15, + Some(continent.blockMap.sector(obj).buildingList.maxBy(_.Definition.SOIRadius)) + ) + } } diff --git a/src/main/scala/net/psforever/objects/TurretDeployable.scala b/src/main/scala/net/psforever/objects/TurretDeployable.scala index 18ed2fe37..8d3f91a0c 100644 --- a/src/main/scala/net/psforever/objects/TurretDeployable.scala +++ b/src/main/scala/net/psforever/objects/TurretDeployable.scala @@ -2,25 +2,26 @@ package net.psforever.objects import akka.actor.{Actor, ActorContext, ActorRef, Props} -import net.psforever.objects.ce.{Deployable, DeployableBehavior, DeployedItem, InteractWithTurrets} -import net.psforever.objects.definition.DeployableDefinition +import net.psforever.objects.ce.{Deployable, DeployableBehavior, DeployableCategory, DeployedItem, InteractWithTurrets} +import net.psforever.objects.definition.{DeployableDefinition, WithShields} import net.psforever.objects.definition.converter.SmallTurretConverter import net.psforever.objects.equipment.JammableUnit import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} -import net.psforever.objects.serverobject.PlanetSideServerObject -import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior +import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} +import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior} import net.psforever.objects.serverobject.damage.Damageable -import net.psforever.objects.serverobject.hackable.Hackable +import net.psforever.objects.serverobject.hackable.{GenericHackables, Hackable} import net.psforever.objects.serverobject.mount.{InteractWithRadiationCloudsSeatedInEntity, Mountable} import net.psforever.objects.serverobject.turret.auto.AutomatedTurret.Target import net.psforever.objects.serverobject.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret, AutomatedTurretBehavior} -import net.psforever.objects.serverobject.turret.{MountableTurretControl, TurretDefinition, WeaponTurret} +import net.psforever.objects.serverobject.turret.{MountableTurretControl, TurretDefinition, WeaponTurret, WeaponTurrets} import net.psforever.objects.sourcing.{PlayerSource, SourceEntry} import net.psforever.objects.vital.damage.DamageCalculations import net.psforever.objects.vital.interaction.DamageResult import net.psforever.objects.vital.resistance.StandardResistanceProfile -import net.psforever.objects.vital.{SimpleResolutions, StandardVehicleResistance} +import net.psforever.objects.vital.{InGameActivity, ShieldCharge, SimpleResolutions, StandardVehicleResistance} import net.psforever.objects.zones.InteractsWithZone +import net.psforever.packet.game.TriggeredSound import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.types.PlanetSideGUID @@ -34,6 +35,9 @@ class TurretDeployable(tdef: TurretDeployableDefinition) with InteractsWithZone with StandardResistanceProfile with Hackable { + HackSound = TriggeredSound.HackVehicle + HackDuration = Array(0, 20, 10, 5) + if (tdef.Seats.nonEmpty) { interaction(new InteractWithTurrets()) interaction(new InteractWithRadiationCloudsSeatedInEntity(obj = this, range = 100f)) @@ -50,6 +54,10 @@ class TurretDeployable(tdef: TurretDeployableDefinition) .getOrElse(SourceEntry(this)) } + override def MaxShields: Int = { + Definition.MaxShields + } + override def Definition: TurretDeployableDefinition = tdef } @@ -112,6 +120,20 @@ class TurretControl(turret: TurretDeployable) .orElse(automatedTurretBehavior) .orElse(takeAutomatedDamage) .orElse { + case CommonMessages.Use(player, Some(item: SimpleItem)) + if item.Definition == GlobalDefinitions.remote_electronics_kit && + turret.Definition.DeployCategory == DeployableCategory.FieldTurrets && + turret.Faction != player.Faction => + sender() ! CommonMessages.Progress( + GenericHackables.GetHackSpeed(player, turret), + WeaponTurrets.FinishHackingTurretDeployable(turret, player), + GenericHackables.HackingTickAction(progressType = 1, player, turret, item.GUID) + ) + + case CommonMessages.ChargeShields(amount, motivator) + if turret.Definition.DeployCategory == DeployableCategory.FieldTurrets=> + chargeShields(amount, motivator.collect { case o: PlanetSideGameObject with FactionAffinity => SourceEntry(o) }) + case _ => () } @@ -252,4 +274,22 @@ class TurretControl(turret: TurretDeployable) val zone = obj.Zone TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(zone.GUID, turret)) } + + //make certain vehicles don't charge shields too quickly + def canChargeShields: Boolean = { + val func: InGameActivity => Boolean = WithShields.LastShieldChargeOrDamage(System.currentTimeMillis(), turret.Definition) + turret.Health > 0 && turret.Shields < turret.MaxShields && + turret.History.findLast(func).isEmpty + } + + def chargeShields(amount: Int, motivator: Option[SourceEntry]): Unit = { + if (canChargeShields) { + turret.LogActivity(ShieldCharge(amount, motivator)) + turret.Shields = turret.Shields + amount + turret.Zone.VehicleEvents ! VehicleServiceMessage( + s"${turret.Actor}", + VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields) + ) + } + } } diff --git a/src/main/scala/net/psforever/objects/ce/Deployable.scala b/src/main/scala/net/psforever/objects/ce/Deployable.scala index 0a4664945..a77989c20 100644 --- a/src/main/scala/net/psforever/objects/ce/Deployable.scala +++ b/src/main/scala/net/psforever/objects/ce/Deployable.scala @@ -31,9 +31,7 @@ trait BaseDeployable Shields } - def MaxShields: Int = { - 0 //Definition.MaxShields - } + def MaxShields: Int = 0 def MaxHealth: Int diff --git a/src/main/scala/net/psforever/objects/definition/WithShields.scala b/src/main/scala/net/psforever/objects/definition/WithShields.scala index 0d5b1b378..2bb29d61c 100644 --- a/src/main/scala/net/psforever/objects/definition/WithShields.scala +++ b/src/main/scala/net/psforever/objects/definition/WithShields.scala @@ -1,5 +1,7 @@ package net.psforever.objects.definition +import net.psforever.objects.vital.{DamagingActivity, InGameActivity, ShieldCharge} + trait WithShields { /** ... */ var shieldUiAttribute: Int = 68 @@ -7,6 +9,7 @@ trait WithShields { private var defaultShields : Option[Int] = None /** maximum vehicle shields (generally: 20% of health) * for normal vehicles, offered through amp station facility benefits + * for omft, gained in friendly soi (in which the turret may not be constructed) * for BFR's, it charges naturally **/ private var maxShields: Int = 0 @@ -79,3 +82,20 @@ trait WithShields { ShieldDrain } } + +object WithShields { + /** + * Determine if a given activity entry would invalidate the act of charging shields this tick. + * @param now the current time (in milliseconds) + * @param act a `VitalsActivity` entry to test + * @return `true`, if the shield charge would be blocked; + * `false`, otherwise + */ + def LastShieldChargeOrDamage(now: Long, vdef: WithShields)(act: InGameActivity): Boolean = { + act match { + case dact: DamagingActivity => now - dact.time < vdef.ShieldDamageDelay //damage delays next charge + case vsc: ShieldCharge => now - vsc.time < vdef.ShieldPeriodicDelay //previous charge delays next + case _ => false + } + } +} diff --git a/src/main/scala/net/psforever/objects/global/GlobalDefinitionsDeployable.scala b/src/main/scala/net/psforever/objects/global/GlobalDefinitionsDeployable.scala index da633d60a..bef8243dc 100644 --- a/src/main/scala/net/psforever/objects/global/GlobalDefinitionsDeployable.scala +++ b/src/main/scala/net/psforever/objects/global/GlobalDefinitionsDeployable.scala @@ -317,6 +317,7 @@ object GlobalDefinitionsDeployable { portable_manned_turret.Damageable = true portable_manned_turret.Repairable = true portable_manned_turret.RepairIfDestroyed = false + portable_manned_turret.MaxShields = 0//200 portable_manned_turret.WeaponPaths += 1 -> new mutable.HashMap() portable_manned_turret.WeaponPaths(1) += TurretUpgrade.None -> energy_gun portable_manned_turret.Seats += 0 -> new SeatDefinition() @@ -351,6 +352,7 @@ object GlobalDefinitionsDeployable { portable_manned_turret_nc.Damageable = true portable_manned_turret_nc.Repairable = true portable_manned_turret_nc.RepairIfDestroyed = false + portable_manned_turret_nc.MaxShields = 0//200 portable_manned_turret_nc.WeaponPaths += 1 -> new mutable.HashMap() portable_manned_turret_nc.WeaponPaths(1) += TurretUpgrade.None -> energy_gun_nc portable_manned_turret_nc.Seats += 0 -> new SeatDefinition() @@ -384,6 +386,7 @@ object GlobalDefinitionsDeployable { portable_manned_turret_tr.Damageable = true portable_manned_turret_tr.Repairable = true portable_manned_turret_tr.RepairIfDestroyed = false + portable_manned_turret_tr.MaxShields = 0//200 portable_manned_turret_tr.WeaponPaths += 1 -> new mutable.HashMap() portable_manned_turret_tr.WeaponPaths(1) += TurretUpgrade.None -> energy_gun_tr portable_manned_turret_tr.Seats += 0 -> new SeatDefinition() @@ -417,6 +420,7 @@ object GlobalDefinitionsDeployable { portable_manned_turret_vs.Damageable = true portable_manned_turret_vs.Repairable = true portable_manned_turret_vs.RepairIfDestroyed = false + portable_manned_turret_vs.MaxShields = 0//200 portable_manned_turret_vs.WeaponPaths += 1 -> new mutable.HashMap() portable_manned_turret_vs.WeaponPaths(1) += TurretUpgrade.None -> energy_gun_vs portable_manned_turret_vs.Seats += 0 -> new SeatDefinition() diff --git a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala index 5565bf13e..ed83e5ce0 100644 --- a/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala +++ b/src/main/scala/net/psforever/objects/serverobject/hackable/GenericHackables.scala @@ -1,7 +1,6 @@ // Copyright (c) 2020 PSForever package net.psforever.objects.serverobject.hackable -import net.psforever.objects.serverobject.turret.FacilityTurret import net.psforever.objects.{Player, Vehicle} import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.packet.game.{HackMessage, HackState} @@ -45,18 +44,18 @@ object GenericHackables { case hackable: Hackable => hackable.HackDuration(playerHackLevel).toFloat case _ => log.warn( - s"${player.Name} tried to hack an object that has no hack time defined - ${obj.Definition.Name}#${obj.GUID} on ${obj.Zone.id}" + s"${player.Name} tried to hack an object that has no hack time defined - ${obj.Definition.Name}@${obj.GUID.guid} in ${obj.Zone.id}" ) 0f } if (timeToHack == 0) { log.warn( - s"${player.Name} tried to hack an object that they don't have the correct hacking level for - ${obj.Definition.Name}#${obj.GUID} on ${obj.Zone.id}" + s"${player.Name} tried to hack an object that they don't have the correct hacking level for - ${obj.Definition.Name}@${obj.GUID.guid} in ${obj.Zone.id}" ) 0f } else { //timeToHack is in seconds; progress is measured in quarters of a second (250ms) - (100f / timeToHack) / 4 + 25f / timeToHack } } @@ -108,43 +107,6 @@ object GenericHackables { vis != HackState.Cancelled } - /** - * Evaluate the progress of the user applying a tool to upgrade a facility turret. - * This action is using the nano dispenser and requires separate handling from REK hacking. - * Largely a copy/paste of the above, but some of it was removed as it doesn't work/apply with upgrading a turret. - * @see `HackMessage` - * @see `HackState` - * @param progressType 1 - remote electronics kit hack (various ...); - * 2 - nano dispenser (upgrade canister) turret upgrade - * @param tplayer the player performing the action - * @param turret the object being affected - * @param tool_guid the tool being used to affest the object - * @param progress the current progress value - * @return `true`, if the next cycle of progress should occur; - * `false`, otherwise - */ - def TurretUpgradingTickAction(progressType: Int, tplayer: Player, turret: FacilityTurret, tool_guid: PlanetSideGUID)( - progress: Float - ): Boolean = { - //hack state for progress bar visibility - val vis = if (progress <= 0L) { - HackState.Start - } else if (progress >= 100L) { - HackState.Finished - } else { - updateTurretUpgradeTime() - HackState.Ongoing - } - turret.Zone.AvatarEvents ! AvatarServiceMessage( - tplayer.Name, - AvatarAction.SendResponse( - Service.defaultPlayerGUID, - HackMessage(progressType, turret.GUID, tplayer.GUID, progress.toInt, 0L, vis, 8L) - ) - ) - vis != HackState.Cancelled - } - /** * The process of hacking an object is completed. * Pass the message onto the hackable object and onto the local events system. diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala index 433356f63..e0dec604c 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/FacilityTurretControl.scala @@ -67,7 +67,7 @@ class FacilityTurretControl(turret: FacilityTurret) sender() ! CommonMessages.Progress( 1.25f, WeaponTurrets.FinishUpgradingMannedTurret(TurretObject, player, item, upgrade), - GenericHackables.TurretUpgradingTickAction(progressType = 2, player, TurretObject, item.GUID) + WeaponTurrets.TurretUpgradingTickAction(progressType = 2, player, TurretObject, item.GUID) ) } case TurretUpgrader.UpgradeCompleted(_) => diff --git a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala index ef3e9d78d..ae839f0e3 100644 --- a/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala +++ b/src/main/scala/net/psforever/objects/serverobject/turret/WeaponTurrets.scala @@ -1,12 +1,17 @@ // Copyright (c) 2020 PSForever package net.psforever.objects.serverobject.turret -import net.psforever.objects.{Player, Tool} -import net.psforever.packet.game.InventoryStateMessage +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, InventoryStateMessage} import net.psforever.services.Service import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} -import net.psforever.services.vehicle.VehicleServiceMessage +import net.psforever.services.local.{LocalAction, LocalServiceMessage} +import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage} import net.psforever.services.vehicle.support.TurretUpgrader +import net.psforever.types.PlanetSideGUID object WeaponTurrets { private val log = org.log4s.getLogger("WeaponTurrets") @@ -52,4 +57,76 @@ object WeaponTurrets { events ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(target), zone)) events ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(target, zone, upgrade)) } + + /** + * Evaluate the progress of the user applying a tool to upgrade a facility turret. + * This action is using the nano dispenser and requires separate handling from REK hacking. + * Largely a copy/paste of the above, but some of it was removed as it doesn't work/apply with upgrading a turret. + * @see `HackMessage` + * @see `HackState` + * @param progressType 1 - remote electronics kit hack (various ...); + * 2 - nano dispenser (upgrade canister) turret upgrade + * @param tplayer the player performing the action + * @param turret the object being affected + * @param tool_guid the tool being used to affest the object + * @param progress the current progress value + * @return `true`, if the next cycle of progress should occur; + * `false`, otherwise + */ + def TurretUpgradingTickAction(progressType: Int, tplayer: Player, turret: FacilityTurret, tool_guid: PlanetSideGUID)( + progress: Float + ): Boolean = { + //hack state for progress bar visibility + val vis = if (progress <= 0L) { + HackState.Start + } else if (progress >= 100L) { + HackState.Finished + } else { + updateTurretUpgradeTime() + HackState.Ongoing + } + turret.Zone.AvatarEvents ! AvatarServiceMessage( + tplayer.Name, + AvatarAction.SendResponse( + Service.defaultPlayerGUID, + HackMessage(progressType, turret.GUID, tplayer.GUID, progress.toInt, 0L, vis, 8L) + ) + ) + vis != HackState.Cancelled + } + + def FinishHackingTurretDeployable(target: TurretDeployable, hacker: Player)(): Unit = { + org.log4s.getLogger("TurretDeployable").info(s"${hacker.Name} has jacked a ${target.Definition.Name}") + val zone = target.Zone + val certs = hacker.avatar.certifications + if (certs.contains(Certification.ExpertHacking) || certs.contains(Certification.ElectronicsExpert)) { + // Forcefully dismount all seated occupants from the turret + target.Seats.values.foreach { seat => + seat.occupant.collect { + player: Player => + seat.unmount(player) + player.VehicleSeated = None + zone.VehicleEvents ! VehicleServiceMessage( + zone.id, + VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, target.GUID) + ) + } + } + //hacker owns the deployable now + target.OwnerGuid = None + target.Actor ! Deployable.Ownership(hacker) + //convert faction + zone.AvatarEvents ! AvatarServiceMessage( + zone.id, + AvatarAction.SetEmpire(Service.defaultPlayerGUID, target.GUID, hacker.Faction) + ) + zone.LocalEvents ! LocalServiceMessage( + zone.id, + LocalAction.TriggerSound(hacker.GUID, target.HackSound, target.Position, 30, 0.49803925f) + ) + } else { + //deconstruct + target.Actor ! Deployable.Deconstruct() + } + } } diff --git a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala index 3ede78821..dc4862b73 100644 --- a/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala +++ b/src/main/scala/net/psforever/objects/vehicles/control/VehicleControl.scala @@ -4,7 +4,7 @@ package net.psforever.objects.vehicles.control import akka.actor.Cancellable import net.psforever.actors.zone.ZoneActor import net.psforever.objects._ -import net.psforever.objects.definition.VehicleDefinition +import net.psforever.objects.definition.{VehicleDefinition, WithShields} import net.psforever.objects.definition.converter.OCM import net.psforever.objects.entity.WorldEntity import net.psforever.objects.equipment.{ArmorSiphonBehavior, Equipment, EquipmentSlot, JammableMountedWeapons} @@ -27,7 +27,7 @@ import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource} import net.psforever.objects.vehicles._ import net.psforever.objects.vehicles.interaction.WithWater import net.psforever.objects.vital.interaction.DamageResult -import net.psforever.objects.vital.{DamagingActivity, InGameActivity, ShieldCharge, SpawningActivity, VehicleDismountActivity, VehicleMountActivity} +import net.psforever.objects.vital.{InGameActivity, ShieldCharge, SpawningActivity, VehicleDismountActivity, VehicleMountActivity} import net.psforever.objects.zones._ import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.game._ @@ -571,7 +571,7 @@ class VehicleControl(vehicle: Vehicle) //make certain vehicles don't charge shields too quickly def canChargeShields: Boolean = { - val func: InGameActivity => Boolean = VehicleControl.LastShieldChargeOrDamage(System.currentTimeMillis(), vehicle.Definition) + val func: InGameActivity => Boolean = WithShields.LastShieldChargeOrDamage(System.currentTimeMillis(), vehicle.Definition) vehicle.Health > 0 && vehicle.Shields < vehicle.MaxShields && vehicle.History.findLast(func).isEmpty } @@ -714,8 +714,6 @@ class VehicleControl(vehicle: Vehicle) } object VehicleControl { - import net.psforever.objects.vital.ShieldCharge - private case class PrepareForDeletion() final case class Disable(kickPassengers: Boolean = false) @@ -725,19 +723,4 @@ object VehicleControl { private case object RadiationTick final case class AssignOwnership(player: Option[Player]) - - /** - * Determine if a given activity entry would invalidate the act of charging vehicle shields this tick. - * @param now the current time (in milliseconds) - * @param act a `VitalsActivity` entry to test - * @return `true`, if the shield charge would be blocked; - * `false`, otherwise - */ - def LastShieldChargeOrDamage(now: Long, vdef: VehicleDefinition)(act: InGameActivity): Boolean = { - act match { - case dact: DamagingActivity => now - dact.time < vdef.ShieldDamageDelay //damage delays next charge - case vsc: ShieldCharge => now - vsc.time < vdef.ShieldPeriodicDelay //previous charge delays next - case _ => false - } - } }