diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index bc5dcb31e..445216b83 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -864,8 +864,11 @@ class AvatarActor( Behaviors.same case ConsumeStamina(stamina) => - assert(stamina > 0, s"consumed stamina must be larger than 0, but is: $stamina") - consumeStamina(stamina) + if (stamina > 0) { + consumeStamina(stamina) + } else { + log.warn(s"consumed stamina must be larger than 0, but is: $stamina") + } Behaviors.same case SuspendStaminaRegeneration(duration) => diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 31ed92b05..a7a6a7f5e 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -7710,19 +7710,32 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con None } else { projectile.Resolve() - val outProjectile = if (projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated)) { - val quality = projectile.profile.Aggravated match { - case Some(aggravation) - if aggravation.targets.exists(validation => validation.test(target)) && - aggravation.info.exists(_.damage_type == AggravatedDamage.basicDamageType(resolution)) => - ProjectileQuality.AggravatesTarget - case _ => - ProjectileQuality.Normal + val outProjectile = + if (projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated)) { + //aggravated + val quality = projectile.profile.Aggravated match { + case Some(aggravation) + if aggravation.targets.exists(validation => validation.test(target)) && + aggravation.info.exists(_.damage_type == AggravatedDamage.basicDamageType(resolution)) => + ProjectileQuality.AggravatesTarget + case _ => + ProjectileQuality.Normal + } + projectile.quality(quality) + } else if (projectile.tool_def.Size == EquipmentSize.Melee) { + //melee + val quality = player.avatar.implants.flatten.find { entry => entry.definition == GlobalDefinitions.melee_booster } match { + case Some(booster) if booster.active && player.avatar.stamina > 9 => + avatarActor ! AvatarActor.ConsumeStamina(10) + ProjectileQuality.Modified(25f) + case _ => + ProjectileQuality.Normal + } + projectile.quality(quality) + } else { + //normal + projectile } - projectile.quality(quality) - } else { - projectile - } Some(DamageInteraction(SourceEntry(target), ProjectileReason(resolution, outProjectile, target.DamageModel), pos)) } } diff --git a/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/src/main/scala/net/psforever/objects/GlobalDefinitions.scala index 6d6bfa971..0f5f8840e 100644 --- a/src/main/scala/net/psforever/objects/GlobalDefinitions.scala +++ b/src/main/scala/net/psforever/objects/GlobalDefinitions.scala @@ -2415,7 +2415,7 @@ object GlobalDefinitions { chainblade_projectile.InitialVelocity = 100 chainblade_projectile.Lifespan = .02f ProjectileDefinition.CalculateDerivedFields(chainblade_projectile) - chainblade_projectile.Modifiers = MaxDistanceCutoff + chainblade_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff) colossus_100mm_projectile.Name = "colossus_100mm_projectile" colossus_100mm_projectile.Damage0 = 58 @@ -2766,7 +2766,7 @@ object GlobalDefinitions { forceblade_projectile.InitialVelocity = 100 forceblade_projectile.Lifespan = .02f ProjectileDefinition.CalculateDerivedFields(forceblade_projectile) - forceblade_projectile.Modifiers = MaxDistanceCutoff + forceblade_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff) frag_cartridge_projectile.Name = "frag_cartridge_projectile" // TODO for later, maybe : set_resource_parent frag_cartridge_projectile game_objects frag_grenade_projectile @@ -3243,7 +3243,7 @@ object GlobalDefinitions { magcutter_projectile.InitialVelocity = 100 magcutter_projectile.Lifespan = .02f ProjectileDefinition.CalculateDerivedFields(magcutter_projectile) - magcutter_projectile.Modifiers = MaxDistanceCutoff + magcutter_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff) melee_ammo_projectile.Name = "melee_ammo_projectile" melee_ammo_projectile.Damage0 = 25 @@ -3252,7 +3252,7 @@ object GlobalDefinitions { melee_ammo_projectile.InitialVelocity = 100 melee_ammo_projectile.Lifespan = .02f ProjectileDefinition.CalculateDerivedFields(melee_ammo_projectile) - melee_ammo_projectile.Modifiers = MaxDistanceCutoff + melee_ammo_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff) meteor_common.Name = "meteor_common" meteor_common.DamageAtEdge = .1f diff --git a/src/main/scala/net/psforever/objects/vital/projectile/ProjectileDamageModifierFunctions.scala b/src/main/scala/net/psforever/objects/vital/projectile/ProjectileDamageModifierFunctions.scala index 4a4b532ec..d8411ea90 100644 --- a/src/main/scala/net/psforever/objects/vital/projectile/ProjectileDamageModifierFunctions.scala +++ b/src/main/scala/net/psforever/objects/vital/projectile/ProjectileDamageModifierFunctions.scala @@ -293,6 +293,19 @@ case object FlakBurst extends ProjectileDamageModifiers.Mod { } } +/** + * If the damage is resolved by way of a melee weapon, + * the damage might be increased if the attack was initiated + * while the attacker was under the effect of an active Melee Boost implant. + * @see `GlobalDefinitions.melee_booster` + * @see `ProjectileQuality` + */ +case object MeleeBoosted extends ProjectileDamageModifiers.Mod { + override def calculate(damage: Int, data: DamageInteraction, cause: ProjectileReason): Int = { + cause.projectile.quality.mod.toInt + damage + } +} + /* Functions */ object ProjectileDamageModifierFunctions { /**