reactivating oicw availability; no more discrepancy checks on secondary projectiles; code for maelstrom chain lashing

This commit is contained in:
Fate-JH 2025-12-01 16:19:02 -05:00
parent 64b86a984e
commit 56cf816a7f
3 changed files with 31 additions and 22 deletions

View file

@ -68,7 +68,7 @@ add_property mini_chaingun equiptime 750
add_property mini_chaingun holstertime 750
add_property nano_dispenser equiptime 750
add_property nano_dispenser holstertime 750
add_property oicw allowed false
add_property oicw allowed true
add_property pellet_gun equiptime 600
add_property pellet_gun holstertime 600
add_property peregrine_flight requirement_award0 false

View file

@ -141,18 +141,18 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
}
def handleDirectHit(pkt: HitMessage): Unit = {
val projectileGuid = pkt.projectile_guid
val list = ops.composeDirectDamageInformation(pkt)
.collect {
case (target, projectile, hitPos, _) =>
ops.checkForHitPositionDiscrepancy(projectile.GUID, hitPos, target)
ops.checkForHitPositionDiscrepancy(projectileGuid, hitPos, target)
ops.resolveProjectileInteraction(target, projectile, DamageResolution.Hit, hitPos)
projectile
}
//...
if (list.isEmpty) {
ops.handleProxyDamage(pkt.projectile_guid, pkt.hit_info.map(_.hit_pos).getOrElse(Vector3.Zero)).foreach {
ops.handleProxyDamage(projectileGuid, pkt.hit_info.map(_.hit_pos).getOrElse(Vector3.Zero)).foreach {
case (target, proxy, hitPos, _) =>
ops.checkForHitPositionDiscrepancy(proxy.GUID, hitPos, target)
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Hit, hitPos)
}
}
@ -180,7 +180,6 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
}
others.foreach {
case (target, _, hitPos, _) =>
ops.checkForHitPositionDiscrepancy(projectileGuid, hitPos, target)
ops.resolveProjectileInteraction(target, projectile, resolution2, hitPos)
}
//...
@ -207,7 +206,6 @@ class WeaponAndProjectileLogic(val ops: WeaponAndProjectileOperations, implicit
//...
ops.handleProxyDamage(pkt.projectile_uid, pkt.projectile_pos).foreach {
case (target, proxy, hitPos, _) =>
ops.checkForHitPositionDiscrepancy(proxy.GUID, hitPos, target)
ops.resolveProjectileInteraction(target, proxy, DamageResolution.Splash, hitPos)
}
}

View file

@ -9,7 +9,7 @@ import net.psforever.objects.ballistics.ProjectileQuality
import net.psforever.objects.definition.{ProjectileDefinition, SpecialExoSuitDefinition}
import net.psforever.objects.entity.SimpleWorldEntity
import net.psforever.objects.equipment.{ChargeFireModeDefinition, Equipment, FireModeSwitch}
import net.psforever.objects.geometry.d3.Point
import net.psforever.objects.geometry.d3.{Point, VolumetricGeometry}
import net.psforever.objects.guid.{GUIDTask, TaskBundle, TaskWorkflow}
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
import net.psforever.objects.serverobject.affinity.FactionAffinity
@ -696,33 +696,43 @@ class WeaponAndProjectileOperations(
case list =>
setupDamageProxyLittleBuddy(list, hitPos)
WeaponAndProjectileOperations.updateProjectileSidednessAfterHit(continent, projectile, hitPos)
val projectileSide = projectile.WhichSide
list.flatMap { proxy =>
if (proxy.profile.ExistsOnRemoteClients) {
proxy.Position = hitPos
proxy.WhichSide = projectileSide
proxy.WhichSide = projectile.WhichSide
continent.Projectile ! ZoneProjectile.Add(player.GUID, proxy)
Nil
} else if (proxy.tool_def == GlobalDefinitions.maelstrom) {
//server-side maelstrom grenade target selection
val radius = proxy.profile.LashRadius
val hitPosVolGeo = Point(hitPos)
val (chainLashTargets, outputTargets) = sessionLogic
.localSector
.livePlayerList
.filter { target => Zone.distanceCheck(hitPosVolGeo, target, radius * radius) }
.map { target =>
(target.GUID, (target, proxy, hitPos, target.Position))
}.unzip
//chainlash is separated from the actual damage application for convenience
//for convenience purposes, all resulting chain lashing is handled here and resolves in one pass
proxy.WhichSide = Sidedness.StrictlyBetweenSides
val radiusSquared = proxy.profile.LashRadius * proxy.profile.LashRadius
var availableTargets = sessionLogic.localSector.livePlayerList
var unresolvedChainLashHits: Seq[VolumetricGeometry] = Seq(Point(hitPos))
var uniqueChainLashTargets: Seq[(PlanetSideGameObject with FactionAffinity with Vitality, Projectile)] = Seq()
while (unresolvedChainLashHits.nonEmpty) {
val newChainLashTargets = unresolvedChainLashHits.flatMap { availableCarrier =>
val proxyCopy = proxy.copy(shot_origin = availableCarrier.center.asVector3)
val (hits, misses) = availableTargets.partition { target => Zone.distanceCheck(availableCarrier, target, radiusSquared) }
availableTargets = misses
hits.map(t => (t, proxyCopy))
}
uniqueChainLashTargets = uniqueChainLashTargets ++ newChainLashTargets
unresolvedChainLashHits = newChainLashTargets.map { case (t, _) => t.Definition.Geometry(t) }
}
val (guidRefs, outputRefs) = uniqueChainLashTargets.map { case (target, proxyCopy) =>
(target.GUID, (target, proxyCopy, proxyCopy.shot_origin, target.Position))
}.unzip
//chain lash effect
continent.AvatarEvents ! AvatarServiceMessage(
continent.id,
AvatarAction.SendResponse(
PlanetSideGUID(0),
ChainLashMessage(hitPos, projectile.profile.ObjectId, chainLashTargets)
ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList)
)
)
outputTargets
//chain lash target output
outputRefs.toList
} else {
Nil
}
@ -1568,7 +1578,8 @@ object WeaponAndProjectileOperations {
def updateProjectileSidednessAfterHit(zone: Zone, projectile: Projectile, hitPosition: Vector3): Unit = {
val origin = projectile.Position
val distance = Vector3.Magnitude(hitPosition - origin)
zone.blockMap
zone
.blockMap
.sector(hitPosition, distance)
.environmentList
.collect { case o: InteriorDoorPassage =>