mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
using the boomer trigger now causes boomers to explode and harm targets
This commit is contained in:
parent
c22033675e
commit
f557ecc13d
|
|
@ -1,7 +1,7 @@
|
|||
add_property ace allowed false
|
||||
add_property ace allowed true
|
||||
add_property ace equiptime 500
|
||||
add_property ace holstertime 500
|
||||
add_property ace_deployable allowed false
|
||||
add_property ace_deployable allowed true
|
||||
add_property ace_deployable equiptime 500
|
||||
add_property ace_deployable holstertime 500
|
||||
add_property advanced_ace equiptime 750
|
||||
|
|
|
|||
|
|
@ -2184,6 +2184,17 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
if (player.HasGUID) player.GUID
|
||||
else PlanetSideGUID(0)
|
||||
reply match {
|
||||
case LocalResponse.AlertDestroyDeployable(obj: BoomerDeployable) =>
|
||||
//the (former) owner (obj.OwnerName) should process this message
|
||||
obj.Trigger match {
|
||||
case Some(item: BoomerTrigger) =>
|
||||
FindEquipmentToDelete(item.GUID, item)
|
||||
item.Companion = None
|
||||
case _ => ;
|
||||
}
|
||||
avatar.deployables.Remove(obj)
|
||||
UpdateDeployableUIElements(avatar.deployables.UpdateUIElement(obj.Definition.Item))
|
||||
|
||||
case LocalResponse.AlertDestroyDeployable(obj) =>
|
||||
//the (former) owner (obj.OwnerName) should process this message
|
||||
avatar.deployables.Remove(obj)
|
||||
|
|
@ -2194,17 +2205,17 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo))
|
||||
}
|
||||
|
||||
case LocalResponse.Detonate(guid, obj: BoomerDeployable) =>
|
||||
sendResponse(TriggerEffectMessage(guid, "detonate_boomer"))
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 29, 1))
|
||||
sendResponse(ObjectDeleteMessage(guid, 0))
|
||||
case LocalResponse.Detonate(dguid, obj: BoomerDeployable) =>
|
||||
sendResponse(TriggerEffectMessage(dguid, "detonate_boomer"))
|
||||
sendResponse(PlanetsideAttributeMessage(dguid, 29, 1))
|
||||
sendResponse(ObjectDeleteMessage(dguid, 0))
|
||||
|
||||
case LocalResponse.Detonate(guid, obj: ExplosiveDeployable) =>
|
||||
sendResponse(GenericObjectActionMessage(guid, 19))
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 29, 1))
|
||||
sendResponse(ObjectDeleteMessage(guid, 0))
|
||||
case LocalResponse.Detonate(dguid, obj: ExplosiveDeployable) =>
|
||||
sendResponse(GenericObjectActionMessage(dguid, 19))
|
||||
sendResponse(PlanetsideAttributeMessage(dguid, 29, 1))
|
||||
sendResponse(ObjectDeleteMessage(dguid, 0))
|
||||
|
||||
case LocalResponse.Detonate(guid, obj) =>
|
||||
case LocalResponse.Detonate(_, obj) =>
|
||||
log.warn(s"LocalResponse.Detonate: ${obj.Definition.Name} not configured to explode correctly")
|
||||
|
||||
case LocalResponse.DoorOpens(door_guid) =>
|
||||
|
|
@ -4039,13 +4050,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
)
|
||||
continent.GUID(trigger.Companion) match {
|
||||
case Some(boomer: BoomerDeployable) =>
|
||||
boomer.Destroyed = true
|
||||
continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.Detonate(boomer.GUID, boomer))
|
||||
Deployables.AnnounceDestroyDeployable(boomer, Some(500 milliseconds))
|
||||
boomer.Actor ! CommonMessages.Use(player, Some(trigger))
|
||||
case Some(_) | None => ;
|
||||
}
|
||||
FindEquipmentToDelete(item_guid, trigger)
|
||||
trigger.Companion = None
|
||||
case _ => ;
|
||||
}
|
||||
progressBarUpdate.cancel()
|
||||
|
|
|
|||
|
|
@ -2,16 +2,18 @@
|
|||
package net.psforever.objects
|
||||
|
||||
import akka.actor.{Actor, ActorContext, Props}
|
||||
import net.psforever.objects.ballistics.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.ce._
|
||||
import net.psforever.objects.definition.{ComplexDeployableDefinition, SimpleDeployableDefinition}
|
||||
import net.psforever.objects.definition.converter.SmallDeployableConverter
|
||||
import net.psforever.objects.equipment.JammableUnit
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.serverobject.damage.{Damageable, DamageableEntity}
|
||||
import net.psforever.objects.serverobject.damage.Damageable.Target
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations.Output
|
||||
import net.psforever.objects.vital.SimpleResolutions
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.objects.vital.etc.TriggerUsedReason
|
||||
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
||||
import net.psforever.objects.vital.projectile.ProjectileReason
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.Vector3
|
||||
|
|
@ -21,7 +23,9 @@ import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
|||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class ExplosiveDeployable(cdef: ExplosiveDeployableDefinition) extends ComplexDeployable(cdef) with JammableUnit {
|
||||
class ExplosiveDeployable(cdef: ExplosiveDeployableDefinition)
|
||||
extends ComplexDeployable(cdef)
|
||||
with JammableUnit {
|
||||
|
||||
override def Definition: ExplosiveDeployableDefinition = cdef
|
||||
}
|
||||
|
|
@ -63,6 +67,24 @@ class ExplosiveDeployableControl(mine: ExplosiveDeployable) extends Actor with D
|
|||
def receive: Receive =
|
||||
takesDamage
|
||||
.orElse {
|
||||
case CommonMessages.Use(player, Some(trigger: BoomerTrigger)) if {
|
||||
mine match {
|
||||
case boomer: BoomerDeployable => boomer.Trigger.contains(trigger) && mine.Definition.Damageable
|
||||
case _ => false
|
||||
}
|
||||
} =>
|
||||
// the mine damages itself, which sets it off, which causes an explosion
|
||||
// think of this as an initiator to the proper explosion
|
||||
mine.Destroyed = true
|
||||
ExplosiveDeployableControl.DamageResolution(
|
||||
mine,
|
||||
DamageInteraction(
|
||||
SourceEntry(mine),
|
||||
TriggerUsedReason(PlayerSource(player), trigger),
|
||||
mine.Position
|
||||
).calculate()(mine),
|
||||
damage = 0
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
|
|
@ -84,9 +106,18 @@ class ExplosiveDeployableControl(mine: ExplosiveDeployable) extends Actor with D
|
|||
}
|
||||
|
||||
object ExplosiveDeployableControl {
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
* @param cause na
|
||||
* @param damage na
|
||||
*/
|
||||
def DamageResolution(target: ExplosiveDeployable, cause: DamageResult, damage: Int): Unit = {
|
||||
target.History(cause)
|
||||
if (target.Health == 0) {
|
||||
if (cause.interaction.cause.source.SympatheticExplosion) {
|
||||
explodes(target, cause)
|
||||
DestructionAwareness(target, cause)
|
||||
} else if (target.Health == 0) {
|
||||
DestructionAwareness(target, cause)
|
||||
} else if (!target.Jammed && Damageable.CanJammer(target, cause.interaction)) {
|
||||
if ( {
|
||||
|
|
@ -99,17 +130,27 @@ object ExplosiveDeployableControl {
|
|||
}
|
||||
}
|
||||
) {
|
||||
if (cause.interaction.cause.source.SympatheticExplosion || target.Definition.DetonateOnJamming) {
|
||||
val zone = target.Zone
|
||||
zone.Activity ! Zone.HotSpot.Activity(cause)
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.Detonate(target.GUID, target))
|
||||
Zone.causeExplosion(zone, target, Some(cause))
|
||||
if (target.Definition.DetonateOnJamming) {
|
||||
explodes(target, cause)
|
||||
}
|
||||
DestructionAwareness(target, cause)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
* @param cause na
|
||||
*/
|
||||
def explodes(target: Damageable.Target, cause: DamageResult): Unit = {
|
||||
target.Health = 1 // short-circuit logic in DestructionAwareness
|
||||
val zone = target.Zone
|
||||
zone.Activity ! Zone.HotSpot.Activity(cause)
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.Detonate(target.GUID, target))
|
||||
Zone.causeExplosion(zone, target, Some(cause))
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
|
|
@ -118,8 +159,11 @@ object ExplosiveDeployableControl {
|
|||
def DestructionAwareness(target: ExplosiveDeployable, cause: DamageResult): Unit = {
|
||||
val zone = target.Zone
|
||||
val attribution = DamageableEntity.attributionTo(cause, target.Zone)
|
||||
Deployables.AnnounceDestroyDeployable(
|
||||
target,
|
||||
Some(if (target.Jammed || target.Destroyed) 0 seconds else 500 milliseconds)
|
||||
)
|
||||
target.Destroyed = true
|
||||
Deployables.AnnounceDestroyDeployable(target, Some(if (target.Jammed) 0 seconds else 500 milliseconds))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.Destroy(target.GUID, attribution, Service.defaultPlayerGUID, target.Position)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.vital.etc
|
||||
|
||||
import net.psforever.objects.BoomerTrigger
|
||||
import net.psforever.objects.ballistics.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vital.{NoResistanceSelection, SimpleResolutions}
|
||||
import net.psforever.objects.vital.base.{DamageReason, DamageResolution}
|
||||
import net.psforever.objects.vital.damage.DamageCalculations.AgainstExoSuit
|
||||
import net.psforever.objects.vital.prop.DamageProperties
|
||||
import net.psforever.objects.vital.resolution.{DamageAndResistance, DamageResistanceModel}
|
||||
|
||||
/**
|
||||
* A wrapper for a "damage source" in damage calculations
|
||||
* that parameterizes information necessary to explain a `BoomerDeployable` being detonated
|
||||
* using its complementary trigger.
|
||||
* Should be applied as the reason applied to the Boomer
|
||||
* in `DamageInteractions` that lead up to the Boomer exploding
|
||||
* which will carry the trigger as the reason and the user as the culprit.
|
||||
* Due to faction affiliation complicity between the user and the Boomer, however,
|
||||
* normal `Damageable` functionality would have to interject in a way where the trigger works anyway.
|
||||
* @see `BoomerDeployable`
|
||||
* @see `BoomerTrigger`
|
||||
* @see `DamageCalculations`
|
||||
* @see `VitalityDefinition.DamageableByFriendlyFire`
|
||||
* @param user the player who is holding the trigger
|
||||
* @param item the trigger
|
||||
*/
|
||||
final case class TriggerUsedReason(user: PlayerSource, item: BoomerTrigger)
|
||||
extends DamageReason {
|
||||
def source: DamageProperties = TriggerUsedReason.triggered
|
||||
|
||||
def resolution: DamageResolution.Value = DamageResolution.Resolved
|
||||
|
||||
def same(test: DamageReason): Boolean = test match {
|
||||
case tur: TriggerUsedReason => tur.item eq item
|
||||
case _ => false
|
||||
}
|
||||
|
||||
/** lay the blame on the player who caused this explosion to occur */
|
||||
def adversary: Option[SourceEntry] = Some(user)
|
||||
|
||||
override def damageModel : DamageAndResistance = TriggerUsedReason.drm
|
||||
|
||||
/** while weird, the trigger was accredited as the method of death on Gemini Live;
|
||||
* even though its icon looks like an misshapen AMS */
|
||||
override def attribution: Int = item.Definition.ObjectId
|
||||
}
|
||||
|
||||
object TriggerUsedReason {
|
||||
private val triggered = new DamageProperties {
|
||||
Damage0 = 1 //token damage
|
||||
SympatheticExplosion = true //sets off a boomer
|
||||
}
|
||||
|
||||
/** basic damage, no resisting, quick and simple */
|
||||
private val drm = new DamageResistanceModel {
|
||||
DamageUsing = AgainstExoSuit
|
||||
ResistUsing = NoResistanceSelection
|
||||
Model = SimpleResolutions.calculate
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue