Revert VR zone invulnerability, replace with friendly-fire immunity

This commit is contained in:
Subsonic154 2026-04-07 04:21:44 -04:00
parent 5c8bb04d66
commit 92c9e19a06
12 changed files with 50 additions and 85 deletions

View file

@ -1059,6 +1059,12 @@ class GeneralOperations(
sendResponse(ChatMsg(ChatMessageType.UNK_227, wideContents=false, "", "@charsaved", None)) sendResponse(ChatMsg(ChatMessageType.UNK_227, wideContents=false, "", "@charsaved", None))
} }
def trainingGriefWarning(): Unit = {
//don't know the correct ChatMessageType for this one yet;
//it's supposed to use a pop-up that takes 5 seconds before you are allowed to close it, so disabled for now
//sendResponse(ChatMsg(ChatMessageType.CMT_QUIT, wideContents=true, "", "@TrainingGriefWarning", None))
}
def noVoicedChat(pkt: PlanetSideGamePacket): Unit = { def noVoicedChat(pkt: PlanetSideGamePacket): Unit = {
log.debug(s"$pkt") log.debug(s"$pkt")
sendResponse(VoiceHostKill()) sendResponse(VoiceHostKill())

View file

@ -422,7 +422,12 @@ class SessionData(
if (obj.spectator && obj != player) { if (obj.spectator && obj != player) {
administrativeKick(player) administrativeKick(player)
} else { } else {
obj.Actor ! Vitality.Damage(func) if (obj.IsInVRZone && obj.Faction == player.Faction && obj.CharId != player.CharId) {
//don't do friendly-fire in VR zones
general.trainingGriefWarning()
} else {
obj.Actor ! Vitality.Damage(func)
}
} }
case obj: Vehicle if obj.CanDamage => case obj: Vehicle if obj.CanDamage =>
@ -433,10 +438,20 @@ class SessionData(
} else { } else {
log.info(s"$name is attacking $ownerName's ${obj.Definition.Name}") log.info(s"$name is attacking $ownerName's ${obj.Definition.Name}")
} }
obj.Actor ! Vitality.Damage(func) if (obj.IsInVRZone && obj.Faction == player.Faction && !ownerName.equals(name)) {
//don't do friendly-fire in VR zones
general.trainingGriefWarning()
} else {
obj.Actor ! Vitality.Damage(func)
}
case obj: Amenity if obj.CanDamage => case obj: Amenity if obj.CanDamage =>
obj.Actor ! Vitality.Damage(func) if (obj.IsInVRZone && obj.Faction == player.Faction) {
//don't do friendly-fire in VR zones
general.trainingGriefWarning()
} else {
obj.Actor ! Vitality.Damage(func)
}
case obj: Deployable if obj.CanDamage => case obj: Deployable if obj.CanDamage =>
val name = player.Name val name = player.Name
@ -446,7 +461,12 @@ class SessionData(
} else { } else {
log.info(s"$name is attacking $ownerName's ${obj.Definition.Name}") log.info(s"$name is attacking $ownerName's ${obj.Definition.Name}")
} }
obj.Actor ! Vitality.Damage(func) if (obj.IsInVRZone && obj.Faction == player.Faction && !ownerName.equals(name)) {
//don't do friendly-fire in VR zones
general.trainingGriefWarning()
} else {
obj.Actor ! Vitality.Damage(func)
}
case _ => () case _ => ()
} }

View file

@ -993,6 +993,7 @@ class ZoningOperations(
if (player.Faction == PlanetSideEmpire.NC) Zoning.Time.Friendly else Zoning.Time.None if (player.Faction == PlanetSideEmpire.NC) Zoning.Time.Friendly else Zoning.Time.None
case "tzshvs" | "tzdrvs" | "tzcovs" => case "tzshvs" | "tzdrvs" | "tzcovs" =>
if (player.Faction == PlanetSideEmpire.VS) Zoning.Time.Friendly else Zoning.Time.None if (player.Faction == PlanetSideEmpire.VS) Zoning.Time.Friendly else Zoning.Time.None
case _ => Zoning.Time.None
} }
} else { } else {
ZoningOperations.findBuildingsBySoiOccupancy(continent, player.Position) match { ZoningOperations.findBuildingsBySoiOccupancy(continent, player.Position) match {

View file

@ -575,11 +575,7 @@ class Player(var avatar: Avatar)
} }
override def CanDamage: Boolean = { override def CanDamage: Boolean = {
if (IsInVRZone && !Definition.DamageableInVr) { death_by < 1 && super.CanDamage
false
} else {
death_by < 1 && super.CanDamage
}
} }
def DamageModel: DamageResistanceModel = exosuit.asInstanceOf[DamageResistanceModel] def DamageModel: DamageResistanceModel = exosuit.asInstanceOf[DamageResistanceModel]

View file

@ -512,14 +512,6 @@ class Vehicle(private val vehicleDef: VehicleDefinition)
def PreviousGatingManifest(): Option[VehicleManifest] = previousVehicleGatingManifest def PreviousGatingManifest(): Option[VehicleManifest] = previousVehicleGatingManifest
override def CanDamage: Boolean = {
if (IsInVRZone && !Definition.DamageableInVr) {
false
} else {
!Destroyed && super.CanDamage
}
}
def DamageModel: DamageResistanceModel = Definition.asInstanceOf[DamageResistanceModel] def DamageModel: DamageResistanceModel = Definition.asInstanceOf[DamageResistanceModel]
override def BailProtection_=(protect: Boolean): Boolean = { override def BailProtection_=(protect: Boolean): Boolean = {

View file

@ -42,14 +42,6 @@ trait BaseDeployable
Faction Faction
} }
override def CanDamage: Boolean = {
if (IsInVRZone && !Definition.DamageableInVr) {
false
} else {
super.CanDamage
}
}
def DamageModel: DamageResistanceModel = Definition.asInstanceOf[DamageResistanceModel] def DamageModel: DamageResistanceModel = Definition.asInstanceOf[DamageResistanceModel]
def Definition: DeployableDefinition def Definition: DeployableDefinition

View file

@ -37,7 +37,6 @@ object GlobalDefinitionsDeployable {
boomer.MaxHealth = 50 boomer.MaxHealth = 50
boomer.Damageable = true boomer.Damageable = true
boomer.DamageableByFriendlyFire = false boomer.DamageableByFriendlyFire = false
boomer.DamageableInVr = true
boomer.Repairable = false boomer.Repairable = false
boomer.DeployCategory = DeployableCategory.Boomers boomer.DeployCategory = DeployableCategory.Boomers
boomer.DeployTime = Duration.create(1000, "ms") boomer.DeployTime = Duration.create(1000, "ms")
@ -63,7 +62,6 @@ object GlobalDefinitionsDeployable {
he_mine.MaxHealth = 25 he_mine.MaxHealth = 25
he_mine.Damageable = true he_mine.Damageable = true
he_mine.DamageableByFriendlyFire = false he_mine.DamageableByFriendlyFire = false
he_mine.DamageableInVr = true
he_mine.Repairable = false he_mine.Repairable = false
he_mine.DeployTime = Duration.create(1000, "ms") he_mine.DeployTime = Duration.create(1000, "ms")
he_mine.deployAnimation = DeployAnimation.Standard he_mine.deployAnimation = DeployAnimation.Standard
@ -88,7 +86,6 @@ object GlobalDefinitionsDeployable {
jammer_mine.MaxHealth = 50 jammer_mine.MaxHealth = 50
jammer_mine.Damageable = true jammer_mine.Damageable = true
jammer_mine.DamageableByFriendlyFire = false jammer_mine.DamageableByFriendlyFire = false
jammer_mine.DamageableInVr = true
jammer_mine.Repairable = false jammer_mine.Repairable = false
jammer_mine.DeployTime = Duration.create(1000, "ms") jammer_mine.DeployTime = Duration.create(1000, "ms")
jammer_mine.deployAnimation = DeployAnimation.Standard jammer_mine.deployAnimation = DeployAnimation.Standard
@ -132,7 +129,6 @@ object GlobalDefinitionsDeployable {
spitfire_turret.Descriptor = "Spitfires" spitfire_turret.Descriptor = "Spitfires"
spitfire_turret.MaxHealth = 100 spitfire_turret.MaxHealth = 100
spitfire_turret.Damageable = true spitfire_turret.Damageable = true
spitfire_turret.DamageableInVr = true
spitfire_turret.Repairable = true spitfire_turret.Repairable = true
spitfire_turret.RepairIfDestroyed = false spitfire_turret.RepairIfDestroyed = false
spitfire_turret.WeaponPaths += 1 -> new mutable.HashMap() spitfire_turret.WeaponPaths += 1 -> new mutable.HashMap()
@ -178,7 +174,6 @@ object GlobalDefinitionsDeployable {
spitfire_cloaked.Descriptor = "CloakingSpitfires" spitfire_cloaked.Descriptor = "CloakingSpitfires"
spitfire_cloaked.MaxHealth = 100 spitfire_cloaked.MaxHealth = 100
spitfire_cloaked.Damageable = true spitfire_cloaked.Damageable = true
spitfire_cloaked.DamageableInVr = true
spitfire_cloaked.Repairable = true spitfire_cloaked.Repairable = true
spitfire_cloaked.RepairIfDestroyed = false spitfire_cloaked.RepairIfDestroyed = false
spitfire_cloaked.WeaponPaths += 1 -> new mutable.HashMap() spitfire_cloaked.WeaponPaths += 1 -> new mutable.HashMap()
@ -230,7 +225,6 @@ object GlobalDefinitionsDeployable {
spitfire_aa.Descriptor = "FlakSpitfires" spitfire_aa.Descriptor = "FlakSpitfires"
spitfire_aa.MaxHealth = 100 spitfire_aa.MaxHealth = 100
spitfire_aa.Damageable = true spitfire_aa.Damageable = true
spitfire_aa.DamageableInVr = true
spitfire_aa.Repairable = true spitfire_aa.Repairable = true
spitfire_aa.RepairIfDestroyed = false spitfire_aa.RepairIfDestroyed = false
spitfire_aa.WeaponPaths += 1 -> new mutable.HashMap() spitfire_aa.WeaponPaths += 1 -> new mutable.HashMap()
@ -273,7 +267,6 @@ object GlobalDefinitionsDeployable {
motionalarmsensor.Descriptor = "MotionSensors" motionalarmsensor.Descriptor = "MotionSensors"
motionalarmsensor.MaxHealth = 100 motionalarmsensor.MaxHealth = 100
motionalarmsensor.Damageable = true motionalarmsensor.Damageable = true
motionalarmsensor.DamageableInVr = true
motionalarmsensor.Repairable = true motionalarmsensor.Repairable = true
motionalarmsensor.RepairIfDestroyed = false motionalarmsensor.RepairIfDestroyed = false
motionalarmsensor.DeployTime = Duration.create(1000, "ms") motionalarmsensor.DeployTime = Duration.create(1000, "ms")
@ -285,7 +278,6 @@ object GlobalDefinitionsDeployable {
sensor_shield.Descriptor = "SensorShields" sensor_shield.Descriptor = "SensorShields"
sensor_shield.MaxHealth = 100 sensor_shield.MaxHealth = 100
sensor_shield.Damageable = true sensor_shield.Damageable = true
sensor_shield.DamageableInVr = true
sensor_shield.Repairable = true sensor_shield.Repairable = true
sensor_shield.RepairIfDestroyed = false sensor_shield.RepairIfDestroyed = false
sensor_shield.DeployTime = Duration.create(5000, "ms") sensor_shield.DeployTime = Duration.create(5000, "ms")
@ -297,7 +289,6 @@ object GlobalDefinitionsDeployable {
tank_traps.Descriptor = "TankTraps" tank_traps.Descriptor = "TankTraps"
tank_traps.MaxHealth = 5000 tank_traps.MaxHealth = 5000
tank_traps.Damageable = true tank_traps.Damageable = true
tank_traps.DamageableInVr = true
tank_traps.Repairable = true tank_traps.Repairable = true
tank_traps.RepairIfDestroyed = false tank_traps.RepairIfDestroyed = false
tank_traps.DeployCategory = DeployableCategory.TankTraps tank_traps.DeployCategory = DeployableCategory.TankTraps
@ -462,7 +453,6 @@ object GlobalDefinitionsDeployable {
deployable_shield_generator.Descriptor = "ShieldGenerators" deployable_shield_generator.Descriptor = "ShieldGenerators"
deployable_shield_generator.MaxHealth = 1700 deployable_shield_generator.MaxHealth = 1700
deployable_shield_generator.Damageable = true deployable_shield_generator.Damageable = true
deployable_shield_generator.DamageableInVr = true
deployable_shield_generator.Repairable = true deployable_shield_generator.Repairable = true
deployable_shield_generator.RepairIfDestroyed = false deployable_shield_generator.RepairIfDestroyed = false
deployable_shield_generator.DeployTime = Duration.create(6000, "ms") deployable_shield_generator.DeployTime = Duration.create(6000, "ms")

View file

@ -1,13 +1,11 @@
// Copyright (c) 2024 PSForever // Copyright (c) 2024 PSForever
package net.psforever.objects.serverobject.environment.interaction.common package net.psforever.objects.serverobject.environment.interaction.common
import net.psforever.objects.{Player, Vehicle}
import net.psforever.objects.serverobject.damage.DamageableVehicle
import net.psforever.objects.serverobject.environment.interaction.InteractionWith import net.psforever.objects.serverobject.environment.interaction.InteractionWith
import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, EnvironmentTrait, PieceOfEnvironment} import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, EnvironmentTrait, PieceOfEnvironment}
import net.psforever.objects.sourcing.{SourceEntry, VehicleSource} import net.psforever.objects.sourcing.SourceEntry
import net.psforever.objects.vital.etc.SuicideReason import net.psforever.objects.vital.etc.SuicideReason
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult} import net.psforever.objects.vital.interaction.DamageInteraction
import net.psforever.objects.vital.{IncarnationActivity, Vitality} import net.psforever.objects.vital.{IncarnationActivity, Vitality}
import net.psforever.objects.zones.interaction.InteractsWithZone import net.psforever.objects.zones.interaction.InteractsWithZone
@ -33,31 +31,13 @@ class WithDeath()
if (!obj.Destroyed) { if (!obj.Destroyed) {
obj.History.findLast { entry => entry.isInstanceOf[IncarnationActivity] } match { obj.History.findLast { entry => entry.isInstanceOf[IncarnationActivity] } match {
case Some(entry) if System.currentTimeMillis() - entry.time > 4000L => case Some(entry) if System.currentTimeMillis() - entry.time > 4000L =>
obj match { obj.Actor ! Vitality.Damage(
//bypass the damagable property, kill players and destroy vehicles directly; needed for map edge kill planes to work in VR zones DamageInteraction(
case player: Player => SourceEntry(obj),
player.Actor ! Player.Die() SuicideReason(),
case vehicle: Vehicle => obj.Position
vehicle.Actor ! DamageableVehicle.Destruction( ).calculate()
DamageResult( )
VehicleSource(vehicle),
VehicleSource(vehicle),
DamageInteraction(
SourceEntry(vehicle),
SuicideReason(),
vehicle.Position
)
)
)
case _ =>
obj.Actor ! Vitality.Damage(
DamageInteraction(
SourceEntry(obj),
SuicideReason(),
obj.Position
).calculate()
)
}
case _ => case _ =>
} }
} }

View file

@ -87,14 +87,6 @@ abstract class Amenity
LocationOffset LocationOffset
} }
override def CanDamage: Boolean = {
if (IsInVRZone && !Definition.DamageableInVr) {
false
} else {
super.CanDamage
}
}
def DamageModel: DamageAndResistance = Definition.asInstanceOf[DamageAndResistance] def DamageModel: DamageAndResistance = Definition.asInstanceOf[DamageAndResistance]
def Definition: AmenityDefinition def Definition: AmenityDefinition

View file

@ -49,9 +49,6 @@ trait VitalityDefinition extends DamageModifiers {
*/ */
private var damageableByFriendlyFire: Boolean = true private var damageableByFriendlyFire: Boolean = true
/** whether the object type accepts damage in VR training zones */
private var damageableInVr: Boolean = false
/** at what `Health` value the object type is considered "destroyed" */ /** at what `Health` value the object type is considered "destroyed" */
private var damageDestroysAt: Int = 0 private var damageDestroysAt: Int = 0
@ -74,13 +71,6 @@ trait VitalityDefinition extends DamageModifiers {
DamageableByFriendlyFire DamageableByFriendlyFire
} }
def DamageableInVr: Boolean = damageableInVr
def DamageableInVr_=(state: Boolean): Boolean = {
damageableInVr = state
DamageableInVr
}
def DamageDisablesAt: Int = damageDisablesAt.getOrElse(MaxHealth / 2) def DamageDisablesAt: Int = damageDisablesAt.getOrElse(MaxHealth / 2)
def DamageDisablesAt_=(value: Int): Int = DamageDisablesAt_=(Some(value)) def DamageDisablesAt_=(value: Int): Int = DamageDisablesAt_=(Some(value))

View file

@ -312,7 +312,7 @@ case object MapInfo extends StringEnum[MapInfo] {
checksum = 4276645952L, checksum = 4276645952L,
scale = MapScale.Dim1024, scale = MapScale.Dim1024,
hotSpotSpan = 0, hotSpotSpan = 0,
environment = List(SeaLevel(EnvironmentAttribute.Water, 9.95f)) ++ environment = List(SeaLevel(EnvironmentAttribute.Water, 10)) ++
MapEnvironment.dim1024MapEdgeKillPlanes MapEnvironment.dim1024MapEdgeKillPlanes
) )
@ -322,7 +322,7 @@ case object MapInfo extends StringEnum[MapInfo] {
checksum = 3628825458L, checksum = 3628825458L,
scale = MapScale.Dim4096, scale = MapScale.Dim4096,
hotSpotSpan = 0, hotSpotSpan = 0,
environment = List(SeaLevel(EnvironmentAttribute.Water, 7.98f)) ++ environment = List(SeaLevel(EnvironmentAttribute.Water, 8)) ++
MapEnvironment.dim4096MapEdgeKillPlanes MapEnvironment.dim4096MapEdgeKillPlanes
) )

View file

@ -1871,7 +1871,13 @@ object Zone {
val allAffectedTargets = pssos.filter { target => testTargetsFromZone(source, target, radius) } val allAffectedTargets = pssos.filter { target => testTargetsFromZone(source, target, radius) }
//inform remaining targets that they have suffered damage //inform remaining targets that they have suffered damage
allAffectedTargets allAffectedTargets
.foreach { target => target.Actor ! Vitality.Damage(createInteraction(source, target).calculate()) } .foreach { target =>
if (zone.id.startsWith("tz") && source.Faction == target.Faction) {
//do not perform friendly-fire in VR zones
} else {
target.Actor ! Vitality.Damage(createInteraction(source, target).calculate())
}
}
allAffectedTargets allAffectedTargets
} }