mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
* omft jacking functional; omft shields have been wired but remain disabled * breaking up classes related to different kinds of turret deployables
129 lines
4.7 KiB
Scala
129 lines
4.7 KiB
Scala
// Copyright (c) 2017 PSForever
|
|
package net.psforever.objects
|
|
|
|
import akka.actor.Actor
|
|
import net.psforever.objects.ce.{Deployable, DeployableBehavior, InteractWithTurrets}
|
|
import net.psforever.objects.definition.DeployableDefinition
|
|
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.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.turret.auto.{AffectedByAutomaticTurretFire, AutomatedTurret}
|
|
import net.psforever.objects.serverobject.turret.{TurretControl, TurretDefinition, WeaponTurret}
|
|
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.zones.InteractsWithZone
|
|
import net.psforever.packet.game.TriggeredSound
|
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
|
|
|
import scala.concurrent.duration.FiniteDuration
|
|
|
|
class TurretDeployable(tdef: TurretDeployableDefinition)
|
|
extends Deployable(tdef)
|
|
with AutomatedTurret
|
|
with WeaponTurret
|
|
with JammableUnit
|
|
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))
|
|
}
|
|
WeaponTurret.LoadDefinition(turret = this)
|
|
|
|
def TurretOwner: SourceEntry = {
|
|
Seats
|
|
.values
|
|
.headOption
|
|
.flatMap(_.occupant)
|
|
.map(p => PlayerSource.inSeat(PlayerSource(p), SourceEntry(this), seatNumber=0))
|
|
.orElse(Owners.map(PlayerSource(_, Position)))
|
|
.getOrElse(SourceEntry(this))
|
|
}
|
|
|
|
override def MaxShields: Int = Definition.MaxShields
|
|
|
|
override def Definition: TurretDeployableDefinition = tdef
|
|
}
|
|
|
|
abstract class TurretDeployableDefinition(private val objectId: Int)
|
|
extends DeployableDefinition(objectId)
|
|
with TurretDefinition {
|
|
Name = "turret_deployable"
|
|
Packet = new SmallTurretConverter
|
|
DamageUsing = DamageCalculations.AgainstVehicle
|
|
ResistUsing = StandardVehicleResistance
|
|
Model = SimpleResolutions.calculate
|
|
|
|
//override to clarify inheritance conflict
|
|
override def MaxHealth: Int = super[DeployableDefinition].MaxHealth
|
|
//override to clarify inheritance conflict
|
|
override def MaxHealth_=(max: Int): Int = super[DeployableDefinition].MaxHealth_=(max)
|
|
}
|
|
|
|
/** control actors */
|
|
|
|
abstract class TurretDeployableControl
|
|
extends Actor
|
|
with DeployableBehavior
|
|
with FactionAffinityBehavior.Check
|
|
with TurretControl
|
|
with AffectedByAutomaticTurretFire {
|
|
|
|
override def postStop(): Unit = {
|
|
super.postStop()
|
|
deployableBehaviorPostStop()
|
|
}
|
|
|
|
override def commonBehavior: Receive =
|
|
super.commonBehavior
|
|
.orElse(deployableBehavior)
|
|
.orElse(checkBehavior)
|
|
.orElse(takeAutomatedDamage)
|
|
|
|
override protected def DestructionAwareness(target: Damageable.Target, cause: DamageResult): Unit = {
|
|
super.DestructionAwareness(target, cause)
|
|
Deployables.AnnounceDestroyDeployable(DeployableObject, None)
|
|
}
|
|
|
|
override def deconstructDeployable(time: Option[FiniteDuration]) : Unit = {
|
|
val zone = TurretObject.Zone
|
|
val seats = TurretObject.Seats.values
|
|
//either we have no seats or no one gets to sit
|
|
val retime = if (seats.count(_.isOccupied) > 0) {
|
|
//it's possible to request deconstruction of one's own field turret while seated in it
|
|
val wasKickedByDriver = false
|
|
seats.foreach { seat =>
|
|
seat.occupant.collect {
|
|
case player: Player =>
|
|
seat.unmount(player)
|
|
player.VehicleSeated = None
|
|
zone.VehicleEvents ! VehicleServiceMessage(
|
|
zone.id,
|
|
VehicleAction.KickPassenger(player.GUID, 4, wasKickedByDriver, TurretObject.GUID)
|
|
)
|
|
}
|
|
}
|
|
Some(time.getOrElse(Deployable.cleanup) + Deployable.cleanup)
|
|
} else {
|
|
time
|
|
}
|
|
super.deconstructDeployable(retime)
|
|
}
|
|
|
|
override def unregisterDeployable(obj: Deployable): Unit = {
|
|
val zone = obj.Zone
|
|
TaskWorkflow.execute(GUIDTask.unregisterDeployableTurret(zone.GUID, TurretObject))
|
|
}
|
|
}
|