From c4f5dc4dbfaec33328c9dccc2c7534b33b11bd3c Mon Sep 17 00:00:00 2001 From: "Jason_DiDonato@yahoo.com" Date: Sun, 23 May 2021 08:08:04 -0400 Subject: [PATCH] moved medkit resolution into the player control agency and callbacks/blockers added to the session --- .../actors/session/SessionActor.scala | 161 ++++-------------- .../objects/avatar/PlayerControl.scala | 77 +++++++++ .../services/avatar/AvatarService.scala | 18 ++ .../avatar/AvatarServiceMessage.scala | 2 + .../avatar/AvatarServiceResponse.scala | 2 + 5 files changed, 133 insertions(+), 127 deletions(-) diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 5fa59aca..ce95e440 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -198,6 +198,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con var updateSquad: () => Unit = NoSquadUpdates var recentTeleportAttempt: Long = 0 var lastTerminalOrderFulfillment: Boolean = true + var kitToBeUsed: Option[PlanetSideGUID] = None var shiftPosition: Option[Vector3] = None var shiftOrientation: Option[Vector3] = None var nextSpawnPoint: Option[SpawnPoint] = None @@ -2216,6 +2217,29 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con //redraw handled by callback } + case AvatarResponse.UseKit(kguid, kObjId) => + kitToBeUsed = None + sendResponse( + UseItemMessage( + tplayer_guid, + kguid, + tplayer_guid, + 4294967295L, + false, + Vector3.Zero, + Vector3.Zero, + 126, + 0, //sequence time? + 137, + kObjId + ) + ) + sendResponse(ObjectDeleteMessage(kguid, 0)) + + case AvatarResponse.KitNotUsed(_, msg) => + kitToBeUsed = None + sendResponse(ChatMsg(ChatMessageType.UNK_225, false, "", msg, None)) + case _ => ; } } @@ -4732,133 +4756,15 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con AccessContainer(obj) } } else if (!unk3 && player.isAlive) { //potential kit use - ValidObject(item_used_guid) match { - case Some(kit: Kit) => - player.avatar.useCooldown(kit.Definition) match { - case Some(cooldown) => - sendResponse( - ChatMsg( - ChatMessageType.UNK_225, - false, - "", - s"@TimeUntilNextUse^${cooldown.getStandardSeconds}", - None - ) - ) - - case None => - val indexOpt = player.Find(kit) - val kitIsUsed = indexOpt match { - case Some(index) => - if (kit.Definition == GlobalDefinitions.medkit) { - if (player.Health == player.MaxHealth) { - sendResponse(ChatMsg(ChatMessageType.UNK_225, false, "", "@HealComplete", None)) - false - } else { - player.History(HealFromKit(PlayerSource(player), 25, kit.Definition)) - player.Health = player.Health + 25 - sendResponse(PlanetsideAttributeMessage(avatar_guid, 0, player.Health)) - continent.AvatarEvents ! AvatarServiceMessage( - continent.id, - AvatarAction.PlanetsideAttribute(avatar_guid, 0, player.Health) - ) - true - } - } else if (kit.Definition == GlobalDefinitions.super_medkit) { - if (player.Health == player.MaxHealth) { - sendResponse(ChatMsg(ChatMessageType.UNK_225, false, "", "@HealComplete", None)) - false - } else { - player.History(HealFromKit(PlayerSource(player), 100, kit.Definition)) - player.Health = player.Health + 100 - sendResponse(PlanetsideAttributeMessage(avatar_guid, 0, player.Health)) - continent.AvatarEvents ! AvatarServiceMessage( - continent.id, - AvatarAction.PlanetsideAttribute(avatar_guid, 0, player.Health) - ) - true - } - } else if (kit.Definition == GlobalDefinitions.super_armorkit) { - if (player.Armor == player.MaxArmor) { - sendResponse( - ChatMsg( - ChatMessageType.UNK_225, - false, - "", - "Armor at maximum - No repairing required.", - None - ) - ) - false - } else { - player.History(RepairFromKit(PlayerSource(player), 200, kit.Definition)) - player.Armor = player.Armor + 200 - sendResponse(PlanetsideAttributeMessage(avatar_guid, 4, player.Armor)) - continent.AvatarEvents ! AvatarServiceMessage( - continent.id, - AvatarAction.PlanetsideAttribute(avatar_guid, 4, player.Armor) - ) - true - } - } else if (kit.Definition == GlobalDefinitions.super_staminakit) { - if (player.avatar.staminaFull) { - sendResponse( - ChatMsg( - ChatMessageType.UNK_225, - false, - "", - "Stamina at maximum - No recharge required.", - None - ) - ) - false - } else { - avatarActor ! AvatarActor.RestoreStamina(100) - // TODO do we need this? this used to always send the old stamina amount... - /* - sendResponse(PlanetsideAttributeMessage(avatar_guid, 2, player.Stamina)) - */ - true - } - } else { - log.warn(s"UseItem: Your $kit behavior is not supported, ${player.Name}") - false - } - - case None => - log.error(s"UseItem: Anticipated a $kit for ${player.Name}, but can't find it") - false - } - if (kitIsUsed) { - //kit was found belonging to player and was used - avatarActor ! AvatarActor.UpdateUseTime(kit.Definition) - player.Slot(indexOpt.get).Equipment = - None //remove from slot immediately; must exist on client for next packet - sendResponse( - UseItemMessage( - avatar_guid, - item_used_guid, - object_guid, - 0, - unk3, - unk4, - unk5, - unk6, - unk7, - unk8, - itemType - ) - ) - sendResponse(ObjectDeleteMessage(kit.GUID, 0)) - continent.tasks ! GUIDTask.UnregisterEquipment(kit)(continent.GUID) - } - } - - case Some(item) => - log.warn(s"UseItem: ${player.Name} looking for Kit to use, but found $item instead") - case None => - log.error(s"UseItem: anticipated a Kit $item_used_guid for ${player.Name}, but can't find it") - } + (continent.GUID(item_used_guid), kitToBeUsed) match { + case (Some(kit: Kit), None) => + kitToBeUsed = Some(item_used_guid) + player.Actor ! CommonMessages.Use(player, Some(kit)) + case (Some(_: Kit), Some(_)) | (None, Some(_)) => ; //a kit is already queued to be used; ignore this request + case (Some(item), _) => + log.error(s"UseItem: ${player.Name} looking for Kit to use, but found $item instead") + case (None, None) => + log.warn(s"UseItem: anticipated a Kit $item_used_guid for ${player.Name}, but can't find it") } } else if (itemType == ObjectClass.avatar && unk3) { equipment match { case Some(tool: Tool) if tool.Definition == GlobalDefinitions.bank => @@ -7095,6 +7001,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con progressBarUpdate.cancel() progressBarValue = None lastTerminalOrderFulfillment = true + kitToBeUsed = None accessedContainer match { case Some(v: Vehicle) => val vguid = v.GUID diff --git a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala index cde96181..d018b418 100644 --- a/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala +++ b/src/main/scala/net/psforever/objects/avatar/PlayerControl.scala @@ -6,6 +6,7 @@ import net.psforever.actors.session.AvatarActor import net.psforever.objects.{Player, _} import net.psforever.objects.ballistics.PlayerSource import net.psforever.objects.equipment._ +import net.psforever.objects.guid.GUIDTask import net.psforever.objects.inventory.{GridInventory, InventoryItem} import net.psforever.objects.loadouts.Loadout import net.psforever.objects.serverobject.aura.{Aura, AuraEffectBehavior} @@ -221,6 +222,82 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm } } + case CommonMessages.Use(_, Some(kit: Kit)) if player.isAlive => + val kdef = kit.Definition + val (thisKitIsUsed, attribute, value, msg): (Option[Int], Int, Long, String) = player.avatar.useCooldown(kdef) match { + case Some(cooldown) => + (None, 0, 0, s"@TimeUntilNextUse^${cooldown.getStandardSeconds}") + + case None => + val indexOpt = player.Find(kit) + indexOpt match { + case Some(index) => + if (kdef == GlobalDefinitions.medkit) { + if (player.Health == player.MaxHealth) { + (None, 0, 0, "@HealComplete") + } else { + player.History(HealFromKit(PlayerSource(player), 25, kdef)) + player.Health = player.Health + 25 + (Some(index), 0, player.Health, "") + } + } else if (kdef == GlobalDefinitions.super_medkit) { + if (player.Health == player.MaxHealth) { + (None, 0, 0, "@HealComplete") + } else { + player.History(HealFromKit(PlayerSource(player), 100, kdef)) + player.Health = player.Health + 100 + (Some(index), 0, player.Health, "") + } + } else if (kdef == GlobalDefinitions.super_armorkit) { + if (player.Armor == player.MaxArmor) { + (None, 0, 0, "Armor at maximum - No repairing required.") + } else { + player.History(RepairFromKit(PlayerSource(player), 200, kdef)) + player.Armor = player.Armor + 200 + (Some(index), 4, player.Armor, "") + } + } else if (kdef == GlobalDefinitions.super_staminakit) { + if (player.avatar.staminaFull) { + (None, 0, 0, "Stamina at maximum - No recharge required.") + } else { + avatarActor ! AvatarActor.RestoreStamina(100) + //(Some(index), 2, player.avatar.stamina, "") + (None, 0, 0, "") + } + } else { + log.warn(s"UseItem: Your $kit behavior is not supported, ${player.Name}") + (None, 0, 0, "") + } + + case None => + log.error(s"UseItem: Anticipated a $kit for ${player.Name}, but can't find it") + (None, 0, 0, "") + } + } + thisKitIsUsed match { + case Some(slot) => + //kit was found belonging to player and is to be used + val kguid = kit.GUID + val zone = player.Zone + avatarActor ! AvatarActor.UpdateUseTime(kdef) + player.Slot(slot).Equipment = None //remove from slot immediately; must exist on client for now + zone.tasks ! GUIDTask.UnregisterEquipment(kit)(zone.GUID) + zone.AvatarEvents ! AvatarServiceMessage( + zone.id, + AvatarAction.PlanetsideAttributeToAll(player.GUID, attribute, value) + ) + zone.AvatarEvents ! AvatarServiceMessage( + player.Name, + AvatarAction.UseKit(kguid, kdef.ObjectId) + ) + case None if msg.length > 0 => + player.Zone.AvatarEvents ! AvatarServiceMessage( + player.Name, + AvatarAction.KitNotUsed(kit.GUID, msg) + ) + case None => ; + } + case PlayerControl.SetExoSuit(exosuit: ExoSuitType.Value, subtype: Int) => setExoSuit(exosuit, subtype) diff --git a/src/main/scala/net/psforever/services/avatar/AvatarService.scala b/src/main/scala/net/psforever/services/avatar/AvatarService.scala index d02a6824..589fb6ee 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarService.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarService.scala @@ -411,6 +411,24 @@ class AvatarService(zone: Zone) extends Actor { case AvatarAction.DropSpecialItem() => AvatarEvents.publish(AvatarServiceResponse(s"/$forChannel/Avatar", Service.defaultPlayerGUID, AvatarResponse.DropSpecialItem())) + case AvatarAction.UseKit(kit_guid, kit_objid) => + AvatarEvents.publish( + AvatarServiceResponse( + s"/$forChannel/Avatar", + Service.defaultPlayerGUID, + AvatarResponse.UseKit(kit_guid, kit_objid) + ) + ) + + case AvatarAction.KitNotUsed(kit_guid, msg) => + AvatarEvents.publish( + AvatarServiceResponse( + s"/$forChannel/Avatar", + Service.defaultPlayerGUID, + AvatarResponse.KitNotUsed(kit_guid, msg) + ) + ) + case _ => ; } diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala index af5ebf44..e475a068 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceMessage.scala @@ -150,6 +150,8 @@ object AvatarAction { drop: List[InventoryItem] ) extends Action final case class DropSpecialItem() extends Action + final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends Action + final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends Action final case class TeardownConnection() extends Action // final case class PlayerStateShift(killer : PlanetSideGUID, victim : PlanetSideGUID) extends Action diff --git a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala index ed249af2..fb06956a 100644 --- a/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala +++ b/src/main/scala/net/psforever/services/avatar/AvatarServiceResponse.scala @@ -121,4 +121,6 @@ object AvatarResponse { final case class TeardownConnection() extends Response // final case class PlayerStateShift(itemID : PlanetSideGUID) extends Response + final case class UseKit(kit_guid: PlanetSideGUID, kit_objid: Int) extends Response + final case class KitNotUsed(kit_guid: PlanetSideGUID, msg: String) extends Response }