Merge branch 'master' into adv-regen

This commit is contained in:
Fate-JH 2021-07-01 22:11:47 -04:00 committed by GitHub
commit 6d13ae972e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 112 additions and 25 deletions

View file

@ -66,7 +66,7 @@ lazy val psforeverSettings = Seq(
"io.kamon" %% "kamon-apm-reporter" % "2.1.20", "io.kamon" %% "kamon-apm-reporter" % "2.1.20",
"org.json4s" %% "json4s-native" % "4.0.1", "org.json4s" %% "json4s-native" % "4.0.1",
"io.getquill" %% "quill-jasync-postgres" % "3.7.2", "io.getquill" %% "quill-jasync-postgres" % "3.7.2",
"org.flywaydb" % "flyway-core" % "7.10.0", "org.flywaydb" % "flyway-core" % "7.11.0",
"org.postgresql" % "postgresql" % "42.2.22", "org.postgresql" % "postgresql" % "42.2.22",
"com.typesafe" % "config" % "1.4.1", "com.typesafe" % "config" % "1.4.1",
"com.github.pureconfig" %% "pureconfig" % "0.16.0", "com.github.pureconfig" %% "pureconfig" % "0.16.0",

View file

@ -142,6 +142,9 @@ object AvatarActor {
/** Deinitialize implants (before zoning or respawning) */ /** Deinitialize implants (before zoning or respawning) */
final case class DeinitializeImplants() extends Command final case class DeinitializeImplants() extends Command
/** Deinitialize a certain implant, then initialize it again */
final case class ResetImplant(implant: ImplantType) extends Command
/** Shorthand for DeinitializeImplants and InitializeImplants */ /** Shorthand for DeinitializeImplants and InitializeImplants */
final case class ResetImplants() extends Command final case class ResetImplants() extends Command
@ -174,7 +177,7 @@ object AvatarActor {
private case class ServiceManagerLookupResult(result: ServiceManager.LookupResult) extends Command private case class ServiceManagerLookupResult(result: ServiceManager.LookupResult) extends Command
private case class SetStamina(stamina: Int) extends Command final case class SetStamina(stamina: Int) extends Command
private case class SetImplantInitialized(implantType: ImplantType) extends Command private case class SetImplantInitialized(implantType: ImplantType) extends Command
@ -869,8 +872,7 @@ class AvatarActor(
Behaviors.same Behaviors.same
case RestoreStamina(stamina) => case RestoreStamina(stamina) =>
assert(stamina > 0) if (stamina > 0 && session.get.player.HasGUID) {
if (session.get.player.HasGUID) {
val totalStamina = math.min(avatar.maxStamina, avatar.stamina + stamina) val totalStamina = math.min(avatar.maxStamina, avatar.stamina + stamina)
val fatigued = if (avatar.fatigued && totalStamina >= 20) { val fatigued = if (avatar.fatigued && totalStamina >= 20) {
avatar.implants.zipWithIndex.foreach { avatar.implants.zipWithIndex.foreach {
@ -892,8 +894,11 @@ class AvatarActor(
Behaviors.same Behaviors.same
case ConsumeStamina(stamina) => case ConsumeStamina(stamina) =>
assert(stamina > 0, s"consumed stamina must be larger than 0, but is: $stamina") if (stamina > 0) {
consumeThisMuchStamina(stamina) consumeThisMuchStamina(stamina)
} else {
log.warn(s"consumed stamina must be larger than 0, but is: $stamina")
}
Behaviors.same Behaviors.same
case SuspendStaminaRegeneration(duration) => case SuspendStaminaRegeneration(duration) =>
@ -915,6 +920,10 @@ class AvatarActor(
deinitializeImplants() deinitializeImplants()
Behaviors.same Behaviors.same
case ResetImplant(implantType) =>
resetAnImplant(implantType)
Behaviors.same
case ResetImplants() => case ResetImplants() =>
deinitializeImplants() deinitializeImplants()
initializeImplants() initializeImplants()
@ -1138,6 +1147,42 @@ class AvatarActor(
}) })
} }
def resetAnImplant(implantType: ImplantType): Unit = {
avatar.implants.zipWithIndex.find {
case (Some(imp), _) => imp.definition.implantType == implantType
case (None, _) => false
} match {
case Some((Some(imp), index)) =>
//deactivate
if (imp.active) {
deactivateImplant(implantType)
}
//deinitialize
session.get.zone.AvatarEvents ! AvatarServiceMessage(
session.get.zone.id,
AvatarAction.SendResponse(
Service.defaultPlayerGUID,
AvatarImplantMessage(session.get.player.GUID, ImplantAction.Initialization, index, 0)
)
)
avatar = avatar.copy(
implants = avatar.implants.updated(index, Some(imp.copy(initialized = false, active = false)))
)
//restart initialization process
implantTimers(index).cancel()
implantTimers(index) = context.scheduleOnce(
imp.definition.InitializationDuration.seconds,
context.self,
SetImplantInitialized(implantType)
)
session.get.zone.AvatarEvents ! AvatarServiceMessage(
avatar.name,
AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(index + 6, 0))
)
case _ => ;
}
}
def deactivateImplant(implantType: ImplantType): Unit = { def deactivateImplant(implantType: ImplantType): Unit = {
avatar.implants.zipWithIndex.collectFirst { avatar.implants.zipWithIndex.collectFirst {
case (Some(implant), index) if implant.definition.implantType == implantType => (implant, index) case (Some(implant), index) if implant.definition.implantType == implantType => (implant, index)

View file

@ -7710,19 +7710,32 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
None None
} else { } else {
projectile.Resolve() projectile.Resolve()
val outProjectile = if (projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated)) { val outProjectile =
val quality = projectile.profile.Aggravated match { if (projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated)) {
case Some(aggravation) //aggravated
if aggravation.targets.exists(validation => validation.test(target)) && val quality = projectile.profile.Aggravated match {
aggravation.info.exists(_.damage_type == AggravatedDamage.basicDamageType(resolution)) => case Some(aggravation)
ProjectileQuality.AggravatesTarget if aggravation.targets.exists(validation => validation.test(target)) &&
case _ => aggravation.info.exists(_.damage_type == AggravatedDamage.basicDamageType(resolution)) =>
ProjectileQuality.Normal 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)) Some(DamageInteraction(SourceEntry(target), ProjectileReason(resolution, outProjectile, target.DamageModel), pos))
} }
} }

View file

@ -2415,7 +2415,7 @@ object GlobalDefinitions {
chainblade_projectile.InitialVelocity = 100 chainblade_projectile.InitialVelocity = 100
chainblade_projectile.Lifespan = .02f chainblade_projectile.Lifespan = .02f
ProjectileDefinition.CalculateDerivedFields(chainblade_projectile) ProjectileDefinition.CalculateDerivedFields(chainblade_projectile)
chainblade_projectile.Modifiers = MaxDistanceCutoff chainblade_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff)
colossus_100mm_projectile.Name = "colossus_100mm_projectile" colossus_100mm_projectile.Name = "colossus_100mm_projectile"
colossus_100mm_projectile.Damage0 = 58 colossus_100mm_projectile.Damage0 = 58
@ -2766,7 +2766,7 @@ object GlobalDefinitions {
forceblade_projectile.InitialVelocity = 100 forceblade_projectile.InitialVelocity = 100
forceblade_projectile.Lifespan = .02f forceblade_projectile.Lifespan = .02f
ProjectileDefinition.CalculateDerivedFields(forceblade_projectile) ProjectileDefinition.CalculateDerivedFields(forceblade_projectile)
forceblade_projectile.Modifiers = MaxDistanceCutoff forceblade_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff)
frag_cartridge_projectile.Name = "frag_cartridge_projectile" frag_cartridge_projectile.Name = "frag_cartridge_projectile"
// TODO for later, maybe : set_resource_parent frag_cartridge_projectile game_objects frag_grenade_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.InitialVelocity = 100
magcutter_projectile.Lifespan = .02f magcutter_projectile.Lifespan = .02f
ProjectileDefinition.CalculateDerivedFields(magcutter_projectile) ProjectileDefinition.CalculateDerivedFields(magcutter_projectile)
magcutter_projectile.Modifiers = MaxDistanceCutoff magcutter_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff)
melee_ammo_projectile.Name = "melee_ammo_projectile" melee_ammo_projectile.Name = "melee_ammo_projectile"
melee_ammo_projectile.Damage0 = 25 melee_ammo_projectile.Damage0 = 25
@ -3252,7 +3252,7 @@ object GlobalDefinitions {
melee_ammo_projectile.InitialVelocity = 100 melee_ammo_projectile.InitialVelocity = 100
melee_ammo_projectile.Lifespan = .02f melee_ammo_projectile.Lifespan = .02f
ProjectileDefinition.CalculateDerivedFields(melee_ammo_projectile) ProjectileDefinition.CalculateDerivedFields(melee_ammo_projectile)
melee_ammo_projectile.Modifiers = MaxDistanceCutoff melee_ammo_projectile.Modifiers = List(MeleeBoosted, MaxDistanceCutoff)
meteor_common.Name = "meteor_common" meteor_common.Name = "meteor_common"
meteor_common.DamageAtEdge = .1f meteor_common.DamageAtEdge = .1f

View file

@ -748,8 +748,22 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
} }
//choose //choose
if (target.Health > 0) { if (target.Health > 0) {
//alive
if (target.Health <= 25 && target.Health + damageToHealth > 25 &&
(player.avatar.implants.flatten.find { _.definition.implantType == ImplantType.SecondWind } match {
case Some(wind) => wind.initialized
case _ => false
})) {
//activate second wind
player.Health += 25
player.History(HealFromImplant(PlayerSource(player), 25, ImplantType.SecondWind))
avatarActor ! AvatarActor.ResetImplant(ImplantType.SecondWind)
avatarActor ! AvatarActor.RestoreStamina(25)
}
//take damage/update
DamageAwareness(target, cause, damageToHealth, damageToArmor, damageToStamina, damageToCapacitor) DamageAwareness(target, cause, damageToHealth, damageToArmor, damageToStamina, damageToCapacitor)
} else { } else {
//ded
DestructionAwareness(target, cause) DestructionAwareness(target, cause)
} }
} }

View file

@ -28,6 +28,8 @@ object DamageResolution extends Enumeration {
AggravatedDirectBurn, //continuous direct hit aggravated damage AggravatedDirectBurn, //continuous direct hit aggravated damage
AggravatedSplash, //splashed aggravated damage AggravatedSplash, //splashed aggravated damage
AggravatedSplashBurn, //continuous splashed aggravated damage AggravatedSplashBurn, //continuous splashed aggravated damage
Explosion //area of effect damage caused by an internal mechanism; unrelated to Splash Explosion, //area of effect damage caused by an internal mechanism; unrelated to Splash
Environmental, //died to environmental causes
Suicide //i don't want to be the one the battles always choose
= Value = Value
} }

View file

@ -17,7 +17,7 @@ import net.psforever.objects.vital.{NoResistanceSelection, SimpleResolutions, Vi
* @param against for the purposes of damage, what kind of target is being acted upon * @param against for the purposes of damage, what kind of target is being acted upon
*/ */
final case class EnvironmentReason(body: PieceOfEnvironment, against: DamageCalculations.Selector) extends DamageReason { final case class EnvironmentReason(body: PieceOfEnvironment, against: DamageCalculations.Selector) extends DamageReason {
def resolution: DamageResolution.Value = DamageResolution.Hit def resolution: DamageResolution.Value = DamageResolution.Environmental
def source: DamageProperties = EnvironmentReason.selectDamage(body) def source: DamageProperties = EnvironmentReason.selectDamage(body)

View file

@ -33,7 +33,7 @@ final case class SuicideReason()
*/ */
def source: DamageProperties = SuicideReason.damageProperties def source: DamageProperties = SuicideReason.damageProperties
def resolution: DamageResolution.Value = DamageResolution.Resolved def resolution: DamageResolution.Value = DamageResolution.Suicide
def same(test: DamageReason): Boolean = { def same(test: DamageReason): Boolean = {
test.source eq source test.source eq source

View file

@ -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 */ /* Functions */
object ProjectileDamageModifierFunctions { object ProjectileDamageModifierFunctions {
/** /**