Implant initialization fixes

This commit is contained in:
Jakob Gillich 2021-04-16 21:37:20 +02:00
parent cfeff70c6b
commit 92a0b1dfaa
2 changed files with 368 additions and 337 deletions

View file

@ -207,6 +207,8 @@ object AvatarActor {
private case class SetStamina(stamina: Int) extends Command private case class SetStamina(stamina: Int) extends Command
private case class SetImplantInitialized(implantType: ImplantType) extends Command
final case class AvatarResponse(avatar: Avatar) final case class AvatarResponse(avatar: Avatar)
final case class AvatarLoginResponse(avatar: Avatar) final case class AvatarLoginResponse(avatar: Avatar)
@ -777,10 +779,9 @@ class AvatarActor(
Behaviors.same Behaviors.same
case ActivateImplant(implantType) => case ActivateImplant(implantType) =>
val res = 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)
} } match {
res match {
case Some((implant, slot)) => case Some((implant, slot)) =>
if (!implant.initialized) { if (!implant.initialized) {
log.error(s"requested activation of uninitialized implant $implant") log.error(s"requested activation of uninitialized implant $implant")
@ -831,6 +832,31 @@ class AvatarActor(
} }
Behaviors.same Behaviors.same
case SetImplantInitialized(implantType) =>
avatar.implants.zipWithIndex.collectFirst {
case (Some(implant), index) if implant.definition.implantType == implantType => index
} match {
case Some(index) =>
sessionActor ! SessionActor.SendResponse(
AvatarImplantMessage(session.get.player.GUID, ImplantAction.Initialization, index, 1)
)
avatar = avatar.copy(implants = avatar.implants.map {
case Some(implant) if implant.definition.implantType == implantType =>
Some(implant.copy(initialized = true))
case other => other
})
// automatic targeting implant activation is a client side feature
// For some reason it doesn't always work with 100% reliability, so we're also activating it server side
// Must be delayed by a bit or the client will toggle it off again
if (implantType == ImplantType.Targeting) {
context.scheduleOnce(2.seconds, context.self, ActivateImplant(implantType))
}
case None => log.error(s"set initialized called for unknown implant $implantType")
}
Behaviors.same
case DeactivateImplant(implantType) => case DeactivateImplant(implantType) =>
deactivateImplant(implantType) deactivateImplant(implantType)
Behaviors.same Behaviors.same
@ -1054,17 +1080,10 @@ class AvatarActor(
) )
implantTimers.get(slot).foreach(_.cancel()) implantTimers.get(slot).foreach(_.cancel())
implantTimers(slot) = context.system.scheduler.scheduleOnce( implantTimers(slot) = context.scheduleOnce(
implant.definition.InitializationDuration.seconds, implant.definition.InitializationDuration.seconds,
() => { context.self,
avatar = avatar.copy(implants = avatar.implants.map { SetImplantInitialized(implant.definition.implantType)
case Some(implant) => Some(implant.copy(initialized = true))
case None => None
})
sessionActor ! SessionActor.SendResponse(
AvatarImplantMessage(session.get.player.GUID, ImplantAction.Initialization, slot, 1)
)
}
) )
case (None, _) => ; case (None, _) => ;

View file

@ -20,7 +20,12 @@ import net.psforever.objects.serverobject.painbox.PainboxDefinition
import net.psforever.objects.serverobject.terminals._ import net.psforever.objects.serverobject.terminals._
import net.psforever.objects.serverobject.tube.SpawnTubeDefinition import net.psforever.objects.serverobject.tube.SpawnTubeDefinition
import net.psforever.objects.serverobject.resourcesilo.ResourceSiloDefinition import net.psforever.objects.serverobject.resourcesilo.ResourceSiloDefinition
import net.psforever.objects.serverobject.structures.{AmenityDefinition, AutoRepairStats, BuildingDefinition, WarpGateDefinition} import net.psforever.objects.serverobject.structures.{
AmenityDefinition,
AutoRepairStats,
BuildingDefinition,
WarpGateDefinition
}
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalDefinition import net.psforever.objects.serverobject.terminals.capture.CaptureTerminalDefinition
import net.psforever.objects.serverobject.terminals.implant.{ImplantTerminalDefinition, ImplantTerminalMechDefinition} import net.psforever.objects.serverobject.terminals.implant.{ImplantTerminalDefinition, ImplantTerminalMechDefinition}
import net.psforever.objects.serverobject.turret.{FacilityTurretDefinition, TurretUpgrade} import net.psforever.objects.serverobject.turret.{FacilityTurretDefinition, TurretUpgrade}
@ -5888,7 +5893,10 @@ object GlobalDefinitions {
Modifiers = ExplodingRadialDegrade Modifiers = ExplodingRadialDegrade
} }
twomanhoverbuggy.DrownAtMaxDepth = true twomanhoverbuggy.DrownAtMaxDepth = true
twomanhoverbuggy.UnderwaterLifespan(suffocation = 45000L, recovery = 5000L) //but the thresher hovers over water, so ...? twomanhoverbuggy.UnderwaterLifespan(
suffocation = 45000L,
recovery = 5000L
) //but the thresher hovers over water, so ...?
twomanhoverbuggy.Geometry = GeometryForm.representByCylinder(radius = 2.1875f, height = 2.01563f) twomanhoverbuggy.Geometry = GeometryForm.representByCylinder(radius = 2.1875f, height = 2.01563f)
mediumtransport.Name = "mediumtransport" // Deliverer mediumtransport.Name = "mediumtransport" // Deliverer
@ -6541,7 +6549,10 @@ object GlobalDefinitions {
} }
switchblade.DrownAtMaxDepth = true switchblade.DrownAtMaxDepth = true
switchblade.MaxDepth = 2 switchblade.MaxDepth = 2
switchblade.UnderwaterLifespan(suffocation = 45000L, recovery = 5000L) //but the switchblade hovers over water, so ...? switchblade.UnderwaterLifespan(
suffocation = 45000L,
recovery = 5000L
) //but the switchblade hovers over water, so ...?
switchblade.Geometry = GeometryForm.representByCylinder(radius = 2.4335f, height = 2.73438f) switchblade.Geometry = GeometryForm.representByCylinder(radius = 2.4335f, height = 2.73438f)
flail.Name = "flail" flail.Name = "flail"
@ -7477,7 +7488,8 @@ object GlobalDefinitions {
implant_terminal_interface.MaxHealth = 500 implant_terminal_interface.MaxHealth = 500
implant_terminal_interface.Damageable = false //TODO true implant_terminal_interface.Damageable = false //TODO true
implant_terminal_interface.Repairable = true implant_terminal_interface.Repairable = true
implant_terminal_interface.autoRepair = AutoRepairStats(1, 5000, 200, 1) //TODO amount and drain are default? undefined? implant_terminal_interface.autoRepair =
AutoRepairStats(1, 5000, 200, 1) //TODO amount and drain are default? undefined?
implant_terminal_interface.RepairIfDestroyed = true implant_terminal_interface.RepairIfDestroyed = true
//TODO will need geometry when Damageable = true //TODO will need geometry when Damageable = true