mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-23 14:20:45 +00:00
corrected death by force dome contact, for all players; corrected reset of force dome protection field condition
This commit is contained in:
parent
c7368d47a4
commit
f5d7fed1cf
10 changed files with 171 additions and 185 deletions
|
|
@ -110,7 +110,7 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
|
|||
private def keepAlivePersistanceCSR(): Unit = {
|
||||
val player = data.player
|
||||
player.allowInteraction = false
|
||||
topOffHealthOfPlayer(player)
|
||||
CustomerServiceRepresentativeMode.topOffHealthOfPlayer(data, player)
|
||||
data.zoning.spawn.interimUngunnedVehicle = None
|
||||
data.keepAlivePersistence()
|
||||
if (player.HasGUID) {
|
||||
|
|
@ -119,63 +119,13 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
|
|||
data.continent
|
||||
.GUID(player.VehicleSeated)
|
||||
.collect { case obj: PlanetSideGameObject with Vitality =>
|
||||
topOffHealth(obj)
|
||||
CustomerServiceRepresentativeMode.topOffHealth(data, obj)
|
||||
}
|
||||
data.squad.updateSquad()
|
||||
} else {
|
||||
data.turnCounterFunc(PlanetSideGUID(0))
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealth(obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
obj match {
|
||||
case p: Player => topOffHealthOfPlayer(p)
|
||||
case v: Vehicle => topOffHealthOfVehicle(v)
|
||||
case o: PlanetSideGameObject with Vitality => topOffHealthOfGeneric(o)
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealthOfPlayer(player: Player): Unit = {
|
||||
//driver below half health, full heal
|
||||
val maxHealthOfPlayer = player.MaxHealth.toLong
|
||||
if (player.Health < maxHealthOfPlayer * 0.5f) {
|
||||
player.Health = maxHealthOfPlayer.toInt
|
||||
player.LogActivity(player.ClearHistory().head)
|
||||
data.sendResponse(PlanetsideAttributeMessage(player.GUID, 0, maxHealthOfPlayer))
|
||||
data.continent.AvatarEvents ! AvatarServiceMessage(data.zoning.zoneChannel, AvatarAction.PlanetsideAttribute(player.GUID, 0, maxHealthOfPlayer))
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealthOfVehicle(vehicle: Vehicle): Unit = {
|
||||
topOffHealthOfGeneric(vehicle)
|
||||
//vehicle shields below half, full shields
|
||||
val maxShieldsOfVehicle = vehicle.MaxShields.toLong
|
||||
val shieldsUi = vehicle.Definition.shieldUiAttribute
|
||||
if (vehicle.Shields < maxShieldsOfVehicle) {
|
||||
val guid = vehicle.GUID
|
||||
vehicle.Shields = maxShieldsOfVehicle.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle))
|
||||
data.continent.VehicleEvents ! VehicleServiceMessage(
|
||||
data.continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, shieldsUi, maxShieldsOfVehicle)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealthOfGeneric(obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
//below half health, full heal
|
||||
val guid = obj.GUID
|
||||
val maxHealthOf = obj.MaxHealth.toLong
|
||||
if (obj.Health < maxHealthOf) {
|
||||
obj.Health = maxHealthOf.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf))
|
||||
data.continent.VehicleEvents ! VehicleServiceMessage(
|
||||
data.continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, 0, maxHealthOf)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case object CustomerServiceRepresentativeMode extends PlayerMode {
|
||||
|
|
@ -202,4 +152,66 @@ case object CustomerServiceRepresentativeMode extends PlayerMode {
|
|||
None
|
||||
))
|
||||
}
|
||||
|
||||
def topOffHealth(data: SessionData, obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
obj match {
|
||||
case p: Player => topOffHealthOfPlayer(data, p)
|
||||
case v: Vehicle => topOffHealthOfVehicle(data, v)
|
||||
case o: PlanetSideGameObject with Vitality => topOffHealthOfGeneric(data, o)
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
def topOffHealthOfPlayer(data: SessionData, player: Player): Unit = {
|
||||
//below half health, full heal
|
||||
val maxHealthOfPlayer = player.MaxHealth.toLong
|
||||
val guid = player.GUID
|
||||
val zoneid = data.zoning.zoneChannel
|
||||
if (player.Health < maxHealthOfPlayer * 0.5f) {
|
||||
if (player.Health == 0) {
|
||||
player.Revive
|
||||
}
|
||||
player.Health = maxHealthOfPlayer.toInt
|
||||
player.LogActivity(player.ClearHistory().head)
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOfPlayer))
|
||||
data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, AvatarAction.PlanetsideAttribute(guid, 0, maxHealthOfPlayer))
|
||||
}
|
||||
//below half armor, full armor
|
||||
val maxArmor = player.MaxArmor.toLong
|
||||
if (player.Armor < maxArmor) {
|
||||
player.Armor = maxArmor.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 4, maxArmor))
|
||||
data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, AvatarAction.PlanetsideAttribute(guid, 4, maxArmor))
|
||||
}
|
||||
}
|
||||
|
||||
def topOffHealthOfVehicle(data: SessionData, vehicle: Vehicle): Unit = {
|
||||
topOffHealthOfGeneric(data, vehicle)
|
||||
//vehicle shields below half, full shields
|
||||
val maxShieldsOfVehicle = vehicle.MaxShields.toLong
|
||||
val shieldsUi = vehicle.Definition.shieldUiAttribute
|
||||
if (vehicle.Shields < maxShieldsOfVehicle) {
|
||||
val guid = vehicle.GUID
|
||||
vehicle.Shields = maxShieldsOfVehicle.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle))
|
||||
data.continent.VehicleEvents ! VehicleServiceMessage(
|
||||
data.continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, shieldsUi, maxShieldsOfVehicle)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def topOffHealthOfGeneric(data: SessionData, obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
//below half health, full heal
|
||||
val guid = obj.GUID
|
||||
val maxHealthOf = obj.MaxHealth.toLong
|
||||
if (obj.Health < maxHealthOf) {
|
||||
obj.Health = maxHealthOf.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf))
|
||||
data.continent.VehicleEvents ! VehicleServiceMessage(
|
||||
data.continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, 0, maxHealthOf)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,8 @@ import net.psforever.objects.serverobject.terminals.{ProximityUnit, Terminal}
|
|||
import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.serverobject.turret.FacilityTurret
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.vital.etc.ForceDomeExposure
|
||||
import net.psforever.objects.vital.interaction.DamageInteraction
|
||||
import net.psforever.objects.zones.{ZoneProjectile, Zoning}
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1}
|
||||
|
|
@ -40,8 +37,8 @@ import net.psforever.services.RemoverActor
|
|||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import scodec.bits.ByteVector
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.Success
|
||||
|
||||
object GeneralLogic {
|
||||
|
|
@ -81,28 +78,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(avatarGuid)
|
||||
sessionLogic.updateBlockMap(player, pos)
|
||||
//below half health, full heal
|
||||
val maxHealth = player.MaxHealth.toLong
|
||||
if (player.Health < maxHealth) {
|
||||
player.Health = maxHealth.toInt
|
||||
player.LogActivity(player.ClearHistory().head)
|
||||
sendResponse(PlanetsideAttributeMessage(avatarGuid, 0, maxHealth))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.PlanetsideAttribute(avatarGuid, 0, maxHealth))
|
||||
}
|
||||
//below half stamina, full stamina
|
||||
val avatar = player.avatar
|
||||
val maxStamina = avatar.maxStamina
|
||||
if (avatar.stamina < maxStamina) {
|
||||
avatarActor ! AvatarActor.RestoreStamina(maxStamina)
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 2, maxStamina.toLong))
|
||||
}
|
||||
//below half armor, full armor
|
||||
val maxArmor = player.MaxArmor.toLong
|
||||
if (player.Armor < maxArmor) {
|
||||
player.Armor = maxArmor.toInt
|
||||
sendResponse(PlanetsideAttributeMessage(avatarGuid, 4, maxArmor))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.PlanetsideAttribute(avatarGuid, 4, maxArmor))
|
||||
}
|
||||
topOffHealthOfPlayer()
|
||||
//expected
|
||||
val isMoving = WorldEntity.isMoving(vel)
|
||||
val isMovingPlus = isMoving || isJumping || jumpThrust
|
||||
|
|
@ -559,20 +535,19 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
v.BailProtection = false
|
||||
case (CollisionIs.OfAircraft, Some(v: Vehicle))
|
||||
if v.Definition.CanFly && v.Seats(0).occupant.contains(player) => ()
|
||||
case (CollisionIs.BetweenThings, Some(field: ForceDomePhysics)) /*if field.Energized*/ =>
|
||||
val target = sessionLogic
|
||||
.vehicles
|
||||
.findLocalVehicle
|
||||
.getOrElse(player)
|
||||
target.Actor ! Vitality.Damage(
|
||||
DamageInteraction(
|
||||
PlayerSource(player),
|
||||
ForceDomeExposure(SourceEntry(field)),
|
||||
player.Position
|
||||
).calculate()
|
||||
)
|
||||
target.BailProtection = false
|
||||
player.BailProtection = false
|
||||
case (CollisionIs.BetweenThings, Some(v: Vehicle)) =>
|
||||
v.Actor ! Vehicle.Deconstruct(Some(1 millisecond))
|
||||
continent.GUID(t) match {
|
||||
case Some(_: ForceDomePhysics) =>
|
||||
player.Actor ! Player.Die()
|
||||
case _ => ()
|
||||
}
|
||||
case (CollisionIs.BetweenThings, Some(_: Player)) =>
|
||||
continent.GUID(t) match {
|
||||
case Some(_: ForceDomePhysics) =>
|
||||
player.Actor ! Player.Die()
|
||||
case _ => ()
|
||||
}
|
||||
case (CollisionIs.BetweenThings, _) =>
|
||||
log.warn(s"GenericCollision: CollisionIs.BetweenThings detected - no handling case for obj id:${t.guid}")
|
||||
case _ => ()
|
||||
|
|
@ -823,4 +798,16 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
player.CapacitorState = CapacitorStateType.Idle
|
||||
}
|
||||
}
|
||||
|
||||
def topOffHealthOfPlayer(): Unit = {
|
||||
//below half health, full heal
|
||||
CustomerServiceRepresentativeMode.topOffHealthOfPlayer(sessionLogic, player)
|
||||
//below half stamina, full stamina
|
||||
val avatar = player.avatar
|
||||
val maxStamina = avatar.maxStamina
|
||||
if (avatar.stamina < maxStamina) {
|
||||
avatarActor ! AvatarActor.RestoreStamina(maxStamina)
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 2, maxStamina.toLong))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,15 @@ import akka.actor.{ActorContext, typed}
|
|||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.session.support.{SessionData, VehicleFunctions, VehicleOperations}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle, Vehicles}
|
||||
import net.psforever.objects.{PlanetSideGameObject, Vehicle, Vehicles}
|
||||
import net.psforever.objects.serverobject.deploy.Deployment
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vehicles.control.BfrFlight
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, PlanetsideAttributeMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.types.{DriveState, PlanetSideGUID, Vector3}
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
|
||||
object VehicleLogic {
|
||||
def apply(ops: VehicleOperations): VehicleLogic = {
|
||||
|
|
@ -51,8 +49,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
sessionLogic.zoning.spawn.tryQueuedActivity(vel)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealth(obj)
|
||||
CustomerServiceRepresentativeMode.topOffHealthOfPlayer(sessionLogic, player)
|
||||
CustomerServiceRepresentativeMode.topOffHealth(sessionLogic, obj)
|
||||
val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match {
|
||||
case Some(v: Vehicle) =>
|
||||
(pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false)
|
||||
|
|
@ -134,8 +132,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
sessionLogic.zoning.spawn.tryQueuedActivity(vel)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealth(obj)
|
||||
CustomerServiceRepresentativeMode.topOffHealthOfPlayer(sessionLogic, player)
|
||||
CustomerServiceRepresentativeMode.topOffHealth(sessionLogic, obj)
|
||||
val (position, angle, velocity, notMountedState) = continent.GUID(obj.MountedIn) match {
|
||||
case Some(v: Vehicle) =>
|
||||
(pos, v.Orientation - Vector3.z(value = 90f) * Vehicles.CargoOrientation(obj).toFloat, v.Velocity, false)
|
||||
|
|
@ -217,8 +215,8 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
sessionLogic.zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
sessionLogic.persist()
|
||||
sessionLogic.turnCounterFunc(player.GUID)
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealth(entity)
|
||||
CustomerServiceRepresentativeMode.topOffHealthOfPlayer(sessionLogic, player)
|
||||
CustomerServiceRepresentativeMode.topOffHealth(sessionLogic, entity)
|
||||
sessionLogic.squad.updateSquad()
|
||||
case _ => //we can't disprove that COSM is our primary upstream packet, it's just that we may be missing some details
|
||||
sessionLogic.zoning.spawn.tryQueuedActivity(player.Velocity)
|
||||
|
|
@ -336,56 +334,4 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealth(obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
obj match {
|
||||
case _: Player => topOffHealthOfPlayer()
|
||||
case v: Vehicle => topOffHealthOfVehicle(v)
|
||||
case o: PlanetSideGameObject with Vitality => topOffHealthOfGeneric(o)
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealthOfPlayer(): Unit = {
|
||||
//driver below half health, full heal
|
||||
val maxHealthOfPlayer = player.MaxHealth.toLong
|
||||
if (player.Health < maxHealthOfPlayer * 0.5f) {
|
||||
player.Health = maxHealthOfPlayer.toInt
|
||||
player.LogActivity(player.ClearHistory().head)
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 0, maxHealthOfPlayer))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(sessionLogic.zoning.zoneChannel, AvatarAction.PlanetsideAttribute(player.GUID, 0, maxHealthOfPlayer))
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealthOfVehicle(vehicle: Vehicle): Unit = {
|
||||
topOffHealthOfPlayer()
|
||||
topOffHealthOfGeneric(vehicle)
|
||||
//vehicle shields below half, full shields
|
||||
val maxShieldsOfVehicle = vehicle.MaxShields.toLong
|
||||
val shieldsUi = vehicle.Definition.shieldUiAttribute
|
||||
if (vehicle.Shields < maxShieldsOfVehicle) {
|
||||
val guid = vehicle.GUID
|
||||
vehicle.Shields = maxShieldsOfVehicle.toInt
|
||||
sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, shieldsUi, maxShieldsOfVehicle)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def topOffHealthOfGeneric(obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
topOffHealthOfPlayer()
|
||||
//vehicle below half health, full heal
|
||||
val guid = obj.GUID
|
||||
val maxHealthOf = obj.MaxHealth.toLong
|
||||
if (obj.Health < maxHealthOf) {
|
||||
obj.Health = maxHealthOf.toInt
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, 0, maxHealthOf)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import net.psforever.objects.inventory.Container
|
|||
import net.psforever.objects.serverobject.{PlanetSideServerObject, ServerObject}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.containable.Containable
|
||||
import net.psforever.objects.serverobject.damage.Damageable
|
||||
import net.psforever.objects.serverobject.dome.ForceDomePhysics
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.generator.Generator
|
||||
|
|
@ -23,6 +24,7 @@ import net.psforever.objects.serverobject.interior.Sidedness.OutsideOf
|
|||
import net.psforever.objects.serverobject.llu.CaptureFlag
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
import net.psforever.objects.serverobject.mblocker.Locker
|
||||
import net.psforever.objects.serverobject.mount.MountableEntity
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.structures.WarpGate
|
||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
|
||||
|
|
@ -637,25 +639,15 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
case (CollisionIs.OfAircraft, out @ Some(v: Vehicle))
|
||||
if v.Definition.CanFly && v.Seats(0).occupant.contains(player) =>
|
||||
(out, sessionLogic.validObject(t, decorator = "GenericCollision/Aircraft"), false, pv)
|
||||
case (CollisionIs.BetweenThings, Some(field: ForceDomePhysics)) /*if field.Energized*/ =>
|
||||
val target = sessionLogic
|
||||
.vehicles
|
||||
.findLocalVehicle
|
||||
.getOrElse(player)
|
||||
target.Actor ! Vitality.Damage(
|
||||
DamageInteraction(
|
||||
PlayerSource(player),
|
||||
ForceDomeExposure(SourceEntry(field)),
|
||||
player.Position
|
||||
).calculate()
|
||||
)
|
||||
case (CollisionIs.BetweenThings, out @ Some(target: PlanetSideServerObject with MountableEntity)) =>
|
||||
target.BailProtection = false
|
||||
player.BailProtection = false
|
||||
(out, sessionLogic.validObject(t, decorator = "GenericCollision/Surface"), false, pv)
|
||||
case (_, Some(obj)) =>
|
||||
log.error(s"GenericCollision: $ctype detected: no handling case for ${obj.Definition.Name}")
|
||||
(None, None, false, Vector3.Zero)
|
||||
case (CollisionIs.BetweenThings, _) =>
|
||||
log.warn("GenericCollision: CollisionIs.BetweenThings detected - no handling case")
|
||||
(None, None, false, Vector3.Zero)
|
||||
case _ =>
|
||||
case (_, None) =>
|
||||
log.error(s"GenericCollision: $ctype detected: no entity detected as 'Primary'")
|
||||
(None, None, false, Vector3.Zero)
|
||||
}
|
||||
val curr = System.currentTimeMillis()
|
||||
|
|
@ -677,6 +669,16 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
}
|
||||
|
||||
case (Some(us: PlanetSideServerObject with Vitality with FactionAffinity), _, Some(field: ForceDomePhysics)) =>
|
||||
us.Actor ! Damageable.MakeVulnerable
|
||||
us.Actor ! Vitality.Damage(
|
||||
DamageInteraction(
|
||||
PlayerSource(player),
|
||||
ForceDomeExposure(SourceEntry(field)),
|
||||
player.Position
|
||||
).calculate()
|
||||
)
|
||||
|
||||
case (Some(us: Vehicle), _, Some(victim: SensorDeployable)) =>
|
||||
collisionBetweenVehicleAndFragileDeployable(us, ppos, victim, tpos, velocity - tv, fallHeight, curr)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,15 +9,18 @@ import net.psforever.objects.avatar.{Avatar, Implant}
|
|||
import net.psforever.objects.ballistics.Projectile
|
||||
import net.psforever.objects.definition.{BasicDefinition, KitDefinition, SpecialExoSuitDefinition}
|
||||
import net.psforever.objects.serverobject.containable.Containable
|
||||
import net.psforever.objects.serverobject.dome.ForceDomePhysics
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
import net.psforever.objects.zones.ZoneProjectile
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.services.account.AccountPersistenceService
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.types.{ExoSuitType, Vector3}
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
|
||||
object GeneralLogic {
|
||||
def apply(ops: GeneralOperations): GeneralLogic = {
|
||||
new GeneralLogic(ops, ops.context)
|
||||
|
|
@ -283,7 +286,34 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
}
|
||||
|
||||
def handleGenericCollision(pkt: GenericCollisionMsg): Unit = { /* intentionally blank */ }
|
||||
def handleGenericCollision(pkt: GenericCollisionMsg): Unit = {
|
||||
player.BailProtection = false
|
||||
val GenericCollisionMsg(ctype, p, _, _, pv, t, _, _, _, _, _, _) = pkt
|
||||
if (pv.z * pv.z >= (pv.x * pv.x + pv.y * pv.y) * 0.5f) {
|
||||
if (ops.heightTrend) {
|
||||
ops.heightHistory = ops.heightLast
|
||||
}
|
||||
else {
|
||||
ops.heightLast = ops.heightHistory
|
||||
}
|
||||
}
|
||||
(ctype, sessionLogic.validObject(p, decorator = "GenericCollision/Primary")) match {
|
||||
case (CollisionIs.BetweenThings, Some(v: Vehicle)) =>
|
||||
v.Actor ! Vehicle.Deconstruct(Some(1 millisecond))
|
||||
continent.GUID(t) match {
|
||||
case Some(_: ForceDomePhysics) =>
|
||||
player.Actor ! Player.Die()
|
||||
case _ => ()
|
||||
}
|
||||
case (CollisionIs.BetweenThings, Some(_: Player)) =>
|
||||
continent.GUID(t) match {
|
||||
case Some(_: ForceDomePhysics) =>
|
||||
player.Actor ! Player.Die()
|
||||
case _ => ()
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
def handleAvatarFirstTimeEvent(pkt: AvatarFirstTimeEventMessage): Unit = { /* intentionally blank */ }
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class InteractWithForceDomeProtection
|
|||
case Some(dome)
|
||||
if dome.Perimeter.isEmpty ||
|
||||
target.Zone != dome.Zone ||
|
||||
!ForceDomeControl.TargetUnderForceDome(dome.Perimeter)(target, dome, maxDistance = 0f) =>
|
||||
!ForceDomeControl.TargetUnderForceDome(dome.Perimeter)(dome, target, maxDistance = 0f) =>
|
||||
resetInteraction(target)
|
||||
case Some(_) =>
|
||||
() //no action
|
||||
|
|
@ -69,7 +69,7 @@ class InteractWithForceDomeProtection
|
|||
case _ => None
|
||||
}
|
||||
.find { dome =>
|
||||
ForceDomeControl.TargetUnderForceDome(dome.Perimeter)(target, dome, maxDistance = 0f)
|
||||
ForceDomeControl.TargetUnderForceDome(dome.Perimeter)(dome, target, maxDistance = 0f)
|
||||
}
|
||||
.map { dome =>
|
||||
applyProtection(target, dome)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ object ArmorSiphonBehavior {
|
|||
val after = item.Discharge()
|
||||
if (before > after) {
|
||||
v.Actor ! ArmorSiphonBehavior.Recharge(iguid)
|
||||
PerformDamage(
|
||||
PerformDamageIfVulnerable(
|
||||
obj,
|
||||
DamageInteraction(
|
||||
VehicleSource(obj),
|
||||
|
|
|
|||
|
|
@ -38,10 +38,7 @@ trait Damageable {
|
|||
isVulnerable = false
|
||||
|
||||
case Vitality.Damage(damage_func) =>
|
||||
val obj = DamageableObject
|
||||
if (isVulnerable && obj.CanDamage) {
|
||||
PerformDamage(obj, damage_func)
|
||||
}
|
||||
PerformDamageIfVulnerable(DamageableObject, damage_func)
|
||||
}
|
||||
|
||||
/** a duplicate of the core implementation for the default mixin hook, for use in overriding */
|
||||
|
|
@ -53,10 +50,20 @@ trait Damageable {
|
|||
isVulnerable = false
|
||||
|
||||
case Vitality.Damage(damage_func) =>
|
||||
val obj = DamageableObject
|
||||
if (isVulnerable && obj.CanDamage) {
|
||||
PerformDamage(obj, damage_func)
|
||||
}
|
||||
PerformDamageIfVulnerable(DamageableObject, damage_func)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess if the target is vulnerable to damage.
|
||||
* If so, attempt damage calculations.
|
||||
* @see `ResolutionCalculations.Output`
|
||||
* @param obj the entity to be damaged
|
||||
* @param applyDamageTo the function that applies the damage to the target in a target-tailored fashion
|
||||
*/
|
||||
def PerformDamageIfVulnerable(obj: Damageable.Target, applyDamageTo: ResolutionCalculations.Output): Unit = {
|
||||
if (isVulnerable && obj.CanDamage) {
|
||||
PerformDamage(obj, applyDamageTo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -479,6 +479,8 @@ class ForceDomeControl(dome: ForceDomePhysics)
|
|||
//dome activating
|
||||
context.system.scheduler.scheduleOnce(delay = 1500 milliseconds, self, ForceDomeControl.Purge)
|
||||
context.system.scheduler.scheduleOnce(delay = 4000 milliseconds, self, ForceDomeControl.ApplyProtection)
|
||||
} else if (oldState && !newState) {
|
||||
context.system.scheduler.scheduleOnce(delay = 1500 milliseconds, self, ForceDomeControl.RemoveProtection)
|
||||
}
|
||||
newState
|
||||
case Some(state)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ trait AffectedByAutomaticTurretFire extends Damageable {
|
|||
ProjectileReason(DamageResolution.Hit, modProjectile, target.DamageModel),
|
||||
correctedTargetPosition
|
||||
)
|
||||
PerformDamage(target, resolvedProjectile.calculate())
|
||||
PerformDamageIfVulnerable(target, resolvedProjectile.calculate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue