mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-02-25 01:23:36 +00:00
moved aggravation damage into damage implementations of turrets and vehicles, rather than directly into ther immediate control agencies; revamp projectile quality modifiers; comet now does initial damage and one less tick of aggravation; the implementation progression of damageable entities is different now
This commit is contained in:
parent
89d7aea633
commit
fc89355acf
22 changed files with 570 additions and 315 deletions
|
|
@ -0,0 +1,36 @@
|
|||
//Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.ballistics
|
||||
|
||||
/**
|
||||
* Projectile quality is an external aspect of projectiles
|
||||
* that is not dependent on hard-coded definitions of the entities
|
||||
* used to compose the projectile such as the knowlegde of the emitting `Tool` (weapon).
|
||||
* A flag or a damage modifier, depending on use.
|
||||
* To the extent that it can be used as a numeric modifier,
|
||||
* insists on defining a numeric modifier component rather to what it is trying to express.
|
||||
* That numeric modifier does not have to be used for anything.
|
||||
*/
|
||||
sealed trait ProjectileQuality {
|
||||
def mod: Float
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the numeric modifier with as one.
|
||||
*/
|
||||
sealed trait SameAsQuality extends ProjectileQuality {
|
||||
def mod: Float = 1f
|
||||
}
|
||||
|
||||
object ProjectileQuality {
|
||||
/** Standard projectile quality. More of a flag than a modifier. */
|
||||
case object Normal extends SameAsQuality
|
||||
|
||||
/** Quality that flags the first stage of aggravation (setup). */
|
||||
case object AggravatesTarget extends SameAsQuality
|
||||
|
||||
/** The complete lack of quality. Even the numeric modifier is zeroed. */
|
||||
case object Zeroed extends ProjectileQuality { def mod = 0f }
|
||||
|
||||
/** Assign a custom numeric qualifier value, usually to be applied to damage calculations. */
|
||||
case class Modified(mod: Float) extends ProjectileQuality
|
||||
}
|
||||
|
|
@ -38,8 +38,18 @@ trait AuraEffectBehavior {
|
|||
id
|
||||
}
|
||||
|
||||
def StartAuraEffect(effect: Aura, duration: Long): Long = {
|
||||
StartAuraEffect(GetUnusedEffectId, effect, duration)
|
||||
def StartAuraEffect(effect: Aura, duration: Long): Option[Long] = {
|
||||
val obj = AuraTargetObject
|
||||
val auraEffects = obj.Aura
|
||||
if (obj.Aura.contains(effect)) {
|
||||
effectToEntryId.getOrElse(effect, List[Long](AuraEffectBehavior.InvalidEffectId)).headOption //grab an available active effect id
|
||||
}
|
||||
else if(obj.AddEffectToAura(effect).diff(auraEffects).contains(effect)) {
|
||||
Some(StartAuraEffect(GetUnusedEffectId, effect, duration))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def StartAuraEffect(id: Long, effect: Aura, duration: Long): Long = {
|
||||
|
|
@ -130,6 +140,8 @@ trait AuraEffectBehavior {
|
|||
object AuraEffectBehavior {
|
||||
type Target = PlanetSideServerObject with AuraContainer
|
||||
|
||||
final val InvalidEffectId = -1
|
||||
|
||||
final case class StartEffect(effect: Aura, duration: Long)
|
||||
|
||||
final case class EndEffect(id: Option[Long], aura: Option[Aura])
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.serverobject.aggravated
|
||||
package net.psforever.objects.serverobject.damage
|
||||
|
||||
import akka.actor.{Actor, Cancellable}
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.serverobject.aura.{Aura, AuraEffectBehavior}
|
||||
import net.psforever.objects.serverobject.damage.Damageable
|
||||
import net.psforever.objects.serverobject.aura.Aura
|
||||
import net.psforever.objects.vital.{DamageType, Vitality}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -17,31 +16,33 @@ trait AggravatedBehavior {
|
|||
mutable.LongMap.empty[AggravatedBehavior.Entry]
|
||||
private val aggravationToTimer: mutable.LongMap[Cancellable] =
|
||||
mutable.LongMap.empty[Cancellable]
|
||||
/** ongoing flag to indicate whether the target is being afflicted by any form of aggravated damage */
|
||||
private var ongoingAggravated: Boolean = false
|
||||
|
||||
def AggravatedObject: AggravatedBehavior.Target
|
||||
|
||||
def TryAggravationEffect(data: ResolvedProjectile): Option[AggravatedDamage] = {
|
||||
data.projectile.profile.Aggravated match {
|
||||
def TryAggravationEffectActivate(data: ResolvedProjectile): Option[AggravatedDamage] = {
|
||||
val projectile = data.projectile
|
||||
projectile.profile.Aggravated match {
|
||||
case Some(damage)
|
||||
if data.projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated) &&
|
||||
if projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated) &&
|
||||
damage.effect_type != Aura.Nothing &&
|
||||
damage.targets.exists(validation => validation.test(AggravatedObject)) =>
|
||||
TryAggravationEffect(damage, data)
|
||||
(projectile.quality == ProjectileQuality.AggravatesTarget ||
|
||||
damage.targets.exists(validation => validation.test(AggravatedObject))) =>
|
||||
TryAggravationEffectActivate(damage, data)
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
private def TryAggravationEffect(aggravation: AggravatedDamage, data: ResolvedProjectile): Option[AggravatedDamage] = {
|
||||
private def TryAggravationEffectActivate(
|
||||
aggravation: AggravatedDamage,
|
||||
data: ResolvedProjectile
|
||||
): Option[AggravatedDamage] = {
|
||||
val effect = aggravation.effect_type
|
||||
val obj = AggravatedObject
|
||||
if(CheckForUniqueUnqueuedProjectile(data.projectile)) {
|
||||
val auraEffects = obj.Aura
|
||||
if(auraEffects.contains(effect) && aggravation.cumulative_damage_degrade) {
|
||||
SetupAggravationEntry(aggravation, data)
|
||||
Some(aggravation)
|
||||
}
|
||||
else if(obj.AddEffectToAura(effect).diff(auraEffects).contains(effect)) {
|
||||
val sameEffect = entryIdToEntry.values.filter(entry => entry.effect == effect)
|
||||
if(sameEffect.isEmpty || sameEffect.nonEmpty && aggravation.cumulative_damage_degrade) {
|
||||
SetupAggravationEntry(aggravation, data)
|
||||
Some(aggravation)
|
||||
}
|
||||
|
|
@ -91,6 +92,7 @@ trait AggravatedBehavior {
|
|||
PairIdWithAggravationEntry(id, effect, tick, data, data.target, qualityPerTick)
|
||||
//pair id with timer
|
||||
aggravationToTimer += id -> context.system.scheduler.scheduleOnce(tick milliseconds, self, AggravatedBehavior.Aggravate(id, iterations))
|
||||
ongoingAggravated = true
|
||||
true
|
||||
case _ =>
|
||||
false
|
||||
|
|
@ -156,6 +158,7 @@ trait AggravatedBehavior {
|
|||
def RemoveAggravatedEntry(id: Long): Aura = {
|
||||
entryIdToEntry.remove(id) match {
|
||||
case Some(entry) =>
|
||||
ongoingAggravated = entryIdToEntry.nonEmpty
|
||||
entry.data.projectile.profile.Aggravated.get.effect_type
|
||||
case _ =>
|
||||
Aura.Nothing
|
||||
|
|
@ -181,22 +184,24 @@ trait AggravatedBehavior {
|
|||
aggravationToTimer.clear
|
||||
}
|
||||
|
||||
def AggravatedReaction: Boolean = ongoingAggravated
|
||||
|
||||
private def PerformAggravation(entry: AggravatedBehavior.Entry, tick: Int = 0): Unit = {
|
||||
val data = entry.data
|
||||
val model = data.damage_model
|
||||
val aggravatedProjectileData = ResolvedProjectile(
|
||||
data.resolution,
|
||||
data.projectile.quality(entry.qualityPerTick(tick)),
|
||||
data.projectile.quality(ProjectileQuality.Modified(entry.qualityPerTick(tick))),
|
||||
data.target,
|
||||
model,
|
||||
data.hit_pos
|
||||
)
|
||||
TakesDamage.apply(Vitality.Damage(model.Calculate(aggravatedProjectileData)))
|
||||
takesDamage.apply(Vitality.Damage(model.Calculate(aggravatedProjectileData)))
|
||||
}
|
||||
}
|
||||
|
||||
object AggravatedBehavior {
|
||||
type Target = AuraEffectBehavior.Target with Vitality
|
||||
type Target = Damageable.Target
|
||||
|
||||
private case class Entry(id: Long, effect: Aura, retime: Long, data: ResolvedProjectile, qualityPerTick: List[Float])
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue