mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Scorpion Death Message (#1044)
* correction to scorpion sub-projectile death message * redirected the definition fields * output method of demise to chat; chat will answer us the mystery * finally attributes the scorpion as the method of demise
This commit is contained in:
parent
36c7a1e520
commit
ae66f86f63
|
|
@ -2,8 +2,6 @@
|
||||||
package net.psforever.actors.session.support
|
package net.psforever.actors.session.support
|
||||||
|
|
||||||
import akka.actor.{ActorContext, typed}
|
import akka.actor.{ActorContext, typed}
|
||||||
import net.psforever.objects.avatar.scoring.EquipmentStat
|
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
import scala.concurrent.Future
|
import scala.concurrent.Future
|
||||||
|
|
@ -11,6 +9,7 @@ import scala.concurrent.duration._
|
||||||
//
|
//
|
||||||
import net.psforever.actors.session.{AvatarActor, ChatActor, SessionActor}
|
import net.psforever.actors.session.{AvatarActor, ChatActor, SessionActor}
|
||||||
import net.psforever.login.WorldSession.{CountAmmunition, CountGrenades, FindAmmoBoxThatUses, FindEquipmentStock, FindToolThatUses, PutEquipmentInInventoryOrDrop, PutNewEquipmentInInventoryOrDrop, RemoveOldEquipmentFromInventory}
|
import net.psforever.login.WorldSession.{CountAmmunition, CountGrenades, FindAmmoBoxThatUses, FindEquipmentStock, FindToolThatUses, PutEquipmentInInventoryOrDrop, PutNewEquipmentInInventoryOrDrop, RemoveOldEquipmentFromInventory}
|
||||||
|
import net.psforever.objects.avatar.scoring.EquipmentStat
|
||||||
import net.psforever.objects.ballistics.{Projectile, ProjectileQuality}
|
import net.psforever.objects.ballistics.{Projectile, ProjectileQuality}
|
||||||
import net.psforever.objects.entity.SimpleWorldEntity
|
import net.psforever.objects.entity.SimpleWorldEntity
|
||||||
import net.psforever.objects.equipment.{ChargeFireModeDefinition, Equipment, EquipmentSize, FireModeSwitch}
|
import net.psforever.objects.equipment.{ChargeFireModeDefinition, Equipment, EquipmentSize, FireModeSwitch}
|
||||||
|
|
@ -22,6 +21,7 @@ import net.psforever.objects.serverobject.turret.FacilityTurret
|
||||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||||
import net.psforever.objects.vital.Vitality
|
import net.psforever.objects.vital.Vitality
|
||||||
import net.psforever.objects.vital.base.{DamageResolution, DamageType}
|
import net.psforever.objects.vital.base.{DamageResolution, DamageType}
|
||||||
|
import net.psforever.objects.vital.etc.OicwLilBuddyReason
|
||||||
import net.psforever.objects.vital.interaction.DamageInteraction
|
import net.psforever.objects.vital.interaction.DamageInteraction
|
||||||
import net.psforever.objects.vital.projectile.ProjectileReason
|
import net.psforever.objects.vital.projectile.ProjectileReason
|
||||||
import net.psforever.objects.zones.{Zone, ZoneProjectile}
|
import net.psforever.objects.zones.{Zone, ZoneProjectile}
|
||||||
|
|
@ -1186,13 +1186,10 @@ private[support] class WeaponAndProjectileOperations(
|
||||||
|
|
||||||
def HandleDamageProxyLittleBuddyExplosion(proxy: Projectile, orientation: Vector3, distance: Float): Unit = {
|
def HandleDamageProxyLittleBuddyExplosion(proxy: Projectile, orientation: Vector3, distance: Float): Unit = {
|
||||||
//explosion
|
//explosion
|
||||||
val obj = DummyExplodingEntity(proxy)
|
val obj = new DummyExplodingEntity(proxy, proxy.owner.Faction)
|
||||||
obj.Position = obj.Position + orientation * distance
|
obj.Position = obj.Position + orientation * distance
|
||||||
context.system.scheduler.scheduleOnce(500.milliseconds) {
|
val explosionFunc: ()=>Unit = WeaponAndProjectileOperations.detonateLittleBuddy(continent, obj, proxy, proxy.owner)
|
||||||
val c = continent
|
context.system.scheduler.scheduleOnce(500.milliseconds) { explosionFunc() }
|
||||||
val o = obj
|
|
||||||
Zone.serverSideDamage(c, o, Zone.explosionDamage(None, o.Position))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1246,3 +1243,50 @@ private[support] class WeaponAndProjectileOperations(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object WeaponAndProjectileOperations {
|
||||||
|
/**
|
||||||
|
* Preparation for explosion damage that utilizes the Scorpion's little buddy sub-projectiles.
|
||||||
|
* The main difference from "normal" server-side explosion
|
||||||
|
* is that the owner of the projectile must be clarified explicitly.
|
||||||
|
* @see `Zone::serverSideDamage`
|
||||||
|
* @param zone where the explosion is taking place
|
||||||
|
* (`source` contains the coordinate location)
|
||||||
|
* @param source a game object that represents the source of the explosion
|
||||||
|
* @param owner who or what to accredit damage from the explosion to;
|
||||||
|
* clarifies a normal `SourceEntry(source)` accreditation
|
||||||
|
*/
|
||||||
|
private def detonateLittleBuddy(
|
||||||
|
zone: Zone,
|
||||||
|
source: PlanetSideGameObject with FactionAffinity with Vitality,
|
||||||
|
proxy: Projectile,
|
||||||
|
owner: SourceEntry
|
||||||
|
)(): Unit = {
|
||||||
|
Zone.serverSideDamage(zone, source, littleBuddyExplosionDamage(owner, proxy.id, source.Position))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preparation for explosion damage that utilizes the Scorpion's little buddy sub-projectiles.
|
||||||
|
* The main difference from "normal" server-side explosion
|
||||||
|
* is that the owner of the projectile must be clarified explicitly.
|
||||||
|
* The sub-projectiles will be the product of a normal projectile rather than a standard game object
|
||||||
|
* so a custom `source` entity must wrap around it and fulfill the requirements of the field.
|
||||||
|
* @see `Zone::explosionDamage`
|
||||||
|
* @param owner who or what to accredit damage from the explosion to
|
||||||
|
* @param explosionPosition where the explosion will be positioned in the game world
|
||||||
|
* @param source a game object that represents the source of the explosion
|
||||||
|
* @param target a game object that is affected by the explosion
|
||||||
|
* @return a `DamageInteraction` object
|
||||||
|
*/
|
||||||
|
private def littleBuddyExplosionDamage(
|
||||||
|
owner: SourceEntry,
|
||||||
|
projectileId: Long,
|
||||||
|
explosionPosition: Vector3
|
||||||
|
)
|
||||||
|
(
|
||||||
|
source: PlanetSideGameObject with FactionAffinity with Vitality,
|
||||||
|
target: PlanetSideGameObject with FactionAffinity with Vitality
|
||||||
|
): DamageInteraction = {
|
||||||
|
DamageInteraction(SourceEntry(target), OicwLilBuddyReason(owner, projectileId, target.DamageModel), explosionPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,13 +180,14 @@ class ZoningOperations(
|
||||||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 112, 0)) // disable festive backpacks
|
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 112, 0)) // disable festive backpacks
|
||||||
|
|
||||||
//find and reclaim own deployables, if any
|
//find and reclaim own deployables, if any
|
||||||
val foundDeployables =
|
val foundDeployables = continent.DeployableList.filter {
|
||||||
continent.DeployableList.filter(obj => obj.OwnerName.contains(player.Name) && obj.Health > 0)
|
case _: BoomerDeployable => false //if we do find boomers for any reason, ignore them
|
||||||
foundDeployables.foreach(obj => {
|
case dobj => dobj.OwnerName.contains(player.Name) && dobj.Health > 0
|
||||||
if (avatar.deployables.AddOverLimit(obj)) {
|
}
|
||||||
|
foundDeployables.collect {
|
||||||
|
case obj if avatar.deployables.AddOverLimit(obj) =>
|
||||||
obj.Actor ! Deployable.Ownership(player)
|
obj.Actor ! Deployable.Ownership(player)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
//render deployable objects
|
//render deployable objects
|
||||||
val (turrets, normal) = continent.DeployableList.partition(obj =>
|
val (turrets, normal) = continent.DeployableList.partition(obj =>
|
||||||
DeployableToolbox.UnifiedType(obj.Definition.Item) == DeployedItem.portable_manned_turret
|
DeployableToolbox.UnifiedType(obj.Definition.Item) == DeployedItem.portable_manned_turret
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
// Copyright (c) 2022 PSForever
|
// Copyright (c) 2022 PSForever
|
||||||
package net.psforever.objects
|
package net.psforever.objects
|
||||||
|
|
||||||
|
import net.psforever.objects.ballistics.Projectile
|
||||||
import net.psforever.objects.definition.{ObjectDefinition, ProjectileDefinition}
|
import net.psforever.objects.definition.{ObjectDefinition, ProjectileDefinition}
|
||||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||||
import net.psforever.objects.vital.resolution.{DamageAndResistance, DamageResistanceModel}
|
import net.psforever.objects.vital.resolution.{DamageAndResistance, DamageResistanceModel}
|
||||||
import net.psforever.objects.vital.{Vitality, VitalityDefinition}
|
import net.psforever.objects.vital.{Vitality, VitalityDefinition}
|
||||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
|
|
||||||
class DummyExplodingEntity(
|
class DummyExplodingEntity(
|
||||||
private val obj: PlanetSideGameObject,
|
private val obj: PlanetSideGameObject,
|
||||||
|
|
@ -14,7 +15,7 @@ class DummyExplodingEntity(
|
||||||
extends PlanetSideGameObject
|
extends PlanetSideGameObject
|
||||||
with FactionAffinity
|
with FactionAffinity
|
||||||
with Vitality {
|
with Vitality {
|
||||||
override def GUID = obj.GUID
|
override def GUID: PlanetSideGUID = obj.GUID
|
||||||
|
|
||||||
override def Position: Vector3 = {
|
override def Position: Vector3 = {
|
||||||
if (super.Position == Vector3.Zero) {
|
if (super.Position == Vector3.Zero) {
|
||||||
|
|
@ -41,20 +42,29 @@ class DummyExplodingEntity(
|
||||||
def DamageModel: DamageAndResistance = DummyExplodingEntity.DefaultDamageResistanceModel
|
def DamageModel: DamageAndResistance = DummyExplodingEntity.DefaultDamageResistanceModel
|
||||||
|
|
||||||
def Definition: ObjectDefinition with VitalityDefinition = {
|
def Definition: ObjectDefinition with VitalityDefinition = {
|
||||||
new DefinitionWrappedInVitality(obj.Definition)
|
new DefinitionWrappedInVitality(obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DefinitionWrappedInVitality(definition: ObjectDefinition)
|
private class DefinitionWrappedInVitality(private val entity: PlanetSideGameObject)
|
||||||
extends ObjectDefinition(definition.ObjectId)
|
extends ObjectDefinition(entity.Definition.ObjectId)
|
||||||
with VitalityDefinition {
|
with VitalityDefinition {
|
||||||
innateDamage = definition match {
|
private val internalDefinition = entity.Definition
|
||||||
|
|
||||||
|
innateDamage = internalDefinition match {
|
||||||
case v: VitalityDefinition if v.innateDamage.nonEmpty => v.innateDamage.get
|
case v: VitalityDefinition if v.innateDamage.nonEmpty => v.innateDamage.get
|
||||||
case p: ProjectileDefinition => p
|
case p: ProjectileDefinition => p
|
||||||
case _ => GlobalDefinitions.no_projectile
|
case _ => GlobalDefinitions.no_projectile
|
||||||
}
|
}
|
||||||
Name = { definition.Name }
|
|
||||||
|
Name = internalDefinition.Name
|
||||||
|
|
||||||
DefaultHealth = 1 //just cuz
|
DefaultHealth = 1 //just cuz
|
||||||
|
|
||||||
|
override def ObjectId: Int = entity match {
|
||||||
|
case p: Projectile => p.tool_def.ObjectId //projectiles point back to the weapon of origin
|
||||||
|
case _ => internalDefinition.ObjectId //what are we?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object DummyExplodingEntity {
|
object DummyExplodingEntity {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package net.psforever.objects.vital.etc
|
||||||
|
|
||||||
|
import net.psforever.objects.GlobalDefinitions
|
||||||
|
import net.psforever.objects.sourcing.SourceEntry
|
||||||
|
import net.psforever.objects.vital.base.{DamageReason, DamageResolution}
|
||||||
|
import net.psforever.objects.vital.prop.DamageProperties
|
||||||
|
import net.psforever.objects.vital.resolution.DamageAndResistance
|
||||||
|
|
||||||
|
case class OicwLilBuddyReason(
|
||||||
|
entity: SourceEntry,
|
||||||
|
projectileId: Long,
|
||||||
|
damageModel: DamageAndResistance
|
||||||
|
) extends DamageReason {
|
||||||
|
def resolution: DamageResolution.Value = DamageResolution.Explosion
|
||||||
|
|
||||||
|
def same(test: DamageReason): Boolean = test match {
|
||||||
|
case eer: OicwLilBuddyReason => eer.projectileId == projectileId
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
|
||||||
|
def adversary: Option[SourceEntry] = Some(entity)
|
||||||
|
|
||||||
|
def source: DamageProperties = GlobalDefinitions.oicw_little_buddy
|
||||||
|
|
||||||
|
override def attribution: Int = GlobalDefinitions.oicw.ObjectId
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue