using the boomer trigger now causes boomers to explode and harm targets

This commit is contained in:
Jason_DiDonato@yahoo.com 2021-01-12 23:01:08 -05:00
parent c22033675e
commit f557ecc13d
4 changed files with 138 additions and 26 deletions

View file

@ -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

View file

@ -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()

View file

@ -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)

View file

@ -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
}
}