Skip to content

Commit

Permalink
corrected various issues identified in the comments of PR#1247
Browse files Browse the repository at this point in the history
  • Loading branch information
Fate-JH committed Oct 29, 2024
1 parent 186f568 commit 720bc97
Show file tree
Hide file tree
Showing 21 changed files with 535 additions and 429 deletions.
12 changes: 8 additions & 4 deletions src/main/scala/net/psforever/actors/session/AvatarActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,11 @@ class AvatarActor(
var supportExperienceTimer: Cancellable = Default.Cancellable
var experienceDebt: Long = 0L

private def setSession(newSession: Session): Unit = {
session = Some(newSession)
_avatar = Option(newSession.avatar)
}

def avatar: Avatar = _avatar.get

def avatar_=(avatar: Avatar): Unit = {
Expand All @@ -1156,8 +1161,7 @@ class AvatarActor(
postLoginBehaviour()

case SetSession(newSession) =>
session = Some(newSession)
_avatar = Option(newSession.avatar)
setSession(newSession)
postLoginBehaviour()

case other =>
Expand All @@ -1177,7 +1181,7 @@ class AvatarActor(
Behaviors
.receiveMessage[Command] {
case SetSession(newSession) =>
session = Some(newSession)
setSession(newSession)
Behaviors.same

case SetLookingForSquad(lfs) =>
Expand Down Expand Up @@ -1330,7 +1334,7 @@ class AvatarActor(
Behaviors
.receiveMessagePartial[Command] {
case SetSession(newSession) =>
session = Some(newSession)
setSession(newSession)
Behaviors.same

case ReplaceAvatar(newAvatar) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ package net.psforever.actors.session.csr

import akka.actor.{ActorContext, typed}
import net.psforever.actors.session.support.AvatarHandlerFunctions
import net.psforever.login.WorldSession.PutLoadoutEquipmentInInventory
import net.psforever.objects.PlanetSideGameObject
import net.psforever.objects.definition.converter.OCM
import net.psforever.objects.inventory.Container
import net.psforever.objects.serverobject.containable.ContainableBehavior
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.packet.game.{AvatarImplantMessage, CreateShortcutMessage, ImplantAction}
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.types.ImplantType

//
Expand Down Expand Up @@ -382,7 +387,9 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
slot = 0
))
}
sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, player, holsters ++ inventory)
(holsters ++ inventory).foreach { case InventoryItem(item, slot) =>
TaskWorkflow.execute(PutLoadoutEquipmentInInventory(player)(item, slot))
}
DropLeftovers(player)(drops)

case AvatarResponse.ChangeLoadout(target, armor, exosuit, subtype, slot, _, oldHolsters, _, _, _, _) =>
Expand Down Expand Up @@ -431,6 +438,8 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))

case AvatarResponse.Killed(mount) =>
val pguid = player.GUID
val avatarId = player.Definition.ObjectId
//pure logic
sessionLogic.shooting.shotsWhileDead = 0
sessionLogic.zoning.CancelZoningProcess()
Expand All @@ -456,12 +465,16 @@ class AvatarHandlerLogic(val ops: SessionAvatarHandlers, implicit val context: A
case obj: Vehicle if obj.Destroyed =>
sessionLogic.vehicles.ConditionalDriverVehicleControl(obj)
sessionLogic.general.unaccessContainer(obj)
player.VehicleSeated = None
sendResponse(OCM.detailed(player))
case _: Vehicle =>
player.VehicleSeated = None
sendResponse(OCM.detailed(player))
case obj: PlanetSideGameObject with Mountable with Container if obj.Destroyed =>
sessionLogic.general.unaccessContainer(obj)
case _ => ()
}
player.VehicleSeated = None
sendResponse(OCM.detailed(player))
continent.AvatarEvents ! AvatarServiceMessage(
continent.id,
AvatarAction.LoadPlayer(pguid, avatarId, pguid, player.Definition.Packet.ConstructorData(player).get, None)
)
sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR MODE"))

case AvatarResponse.Release(tplayer) if isNotSameTarget =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
// Copyright (c) 2024 PSForever
package net.psforever.actors.session.csr

import net.psforever.actors.session.SessionActor
import net.psforever.actors.session.support.{ChatFunctions, GalaxyHandlerFunctions, GeneralFunctions, LocalHandlerFunctions, ModeLogic, MountHandlerFunctions, PlayerMode, SessionData, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
import net.psforever.objects.{Deployables, Session, Vehicle}
import net.psforever.objects.{Deployables, PlanetSideGameObject, Player, Session, Vehicle}
import net.psforever.objects.avatar.Certification
import net.psforever.packet.PlanetSidePacket
import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage}
import net.psforever.packet.game.objectcreate.{ObjectCreateMessageParent, RibbonBars}
import net.psforever.objects.serverobject.ServerObject
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.objects.vital.Vitality
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage, PlanetsideAttributeMessage}
import net.psforever.packet.game.objectcreate.RibbonBars
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.chat.{CustomerServiceChannel, SpectatorChannel}
import net.psforever.types.{ChatMessageType, MeritCommendation}
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import net.psforever.types.{ChatMessageType, MeritCommendation, PlanetSideGUID}

class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
val avatarResponse: AvatarHandlerLogic = AvatarHandlerLogic(data.avatarResponse)
Expand All @@ -32,8 +35,8 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
val player = session.player
val avatar = session.avatar
val continent = session.zone
val sendResponse: PlanetSidePacket=>Unit = data.sendResponse
//
data.zoning.displayZoningMessageWhenCancelled = false
if (oldCertifications.isEmpty) {
oldCertifications = avatar.certifications
oldRibbons = avatar.decoration.ribbonBars
Expand All @@ -47,92 +50,143 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
))
)
player.avatar = newAvatar
data.context.self ! SessionActor.SetAvatar(newAvatar)
data.session = session.copy(avatar = newAvatar, player = player)
Deployables.InitializeDeployableQuantities(newAvatar)
}
val vehicleAndSeat = data.vehicles.GetMountableAndSeat(None, player, continent) match {
case (Some(obj: Vehicle), Some(seatNum)) =>
Some(ObjectCreateMessageParent(obj.GUID, seatNum))
case _ =>
None
}
requireDismount(continent, player)
data.keepAlivePersistenceFunc = keepAlivePersistanceCSR
//
val pguid = player.GUID
val definition = player.Definition
val objectClass = definition.ObjectId
val packet = definition.Packet
sendResponse(ObjectCreateDetailedMessage(
0L,
objectClass,
pguid,
vehicleAndSeat,
packet.DetailedConstructorData(player).get
))
data.zoning.spawn.HandleSetCurrentAvatar(player)
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.LoadPlayer(
pguid,
objectClass,
pguid,
packet.ConstructorData(player).get,
vehicleAndSeat
))
CustomerServiceRepresentativeMode.renderPlayer(data, continent, player)
if (player.silenced) {
data.chat.commandIncomingSilence(session, ChatMsg(ChatMessageType.CMT_SILENCE, "player 0"))
}
data.chat.JoinChannel(SpectatorChannel)
data.chat.JoinChannel(CustomerServiceChannel)
sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR MODE ON"))
data.sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR MODE ON"))
}

override def switchFrom(session: Session): Unit = {
val player = session.player
val avatar = session.avatar
val continent = session.zone
val sendResponse: PlanetSidePacket => Unit = data.sendResponse
//
data.zoning.displayZoningMessageWhenCancelled = true
val newAvatar = avatar.copy(
certifications = oldCertifications,
decoration = avatar.decoration.copy(ribbonBars = oldRibbons)
)
oldCertifications = Set()
oldRibbons = RibbonBars()
player.avatar = newAvatar
data.context.self ! SessionActor.SetAvatar(newAvatar)
val vehicleAndSeat = data.vehicles.GetMountableAndSeat(None, player, continent) match {
case (Some(obj: Vehicle), Some(seatNum)) =>
Some(ObjectCreateMessageParent(obj.GUID, seatNum))
case _ =>
None
}
data.session = session.copy(avatar = newAvatar, player = player)
Deployables.InitializeDeployableQuantities(newAvatar)
//
requireDismount(continent, player)
data.keepAlivePersistenceFunc = data.keepAlivePersistence
//
CustomerServiceRepresentativeMode.renderPlayer(data, continent, player)
data.chat.LeaveChannel(SpectatorChannel)
data.chat.LeaveChannel(CustomerServiceChannel)
data.sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR MODE OFF"))
}

private def requireDismount(zone: Zone, player: Player): Unit = {
data.vehicles.GetMountableAndSeat(None, player, zone) match {
case (Some(obj: Vehicle), Some(seatNum)) if seatNum == 0 =>
data.vehicles.ServerVehicleOverrideStop(obj)
obj.Actor ! ServerObject.AttributeMsg(10, 3) //faction-accessible driver seat
obj.Actor ! Mountable.TryDismount(player, seatNum)
player.VehicleSeated = None
case (Some(obj), Some(seatNum)) =>
obj.Actor ! Mountable.TryDismount(player, seatNum)
player.VehicleSeated = None
case _ =>
player.VehicleSeated = None
}
}

private def keepAlivePersistanceCSR(): Unit = {
data.keepAlivePersistence()
topOffHealthOfPlayer(data.player)
data.continent.GUID(data.player.VehicleSeated)
.collect {
case obj: PlanetSideGameObject with Vitality => topOffHealth(obj)
}
}

private def topOffHealth(obj: PlanetSideGameObject with Vitality): Unit = {
obj match {
case p: Player => topOffHealthOfPlayer(p)
case v: Vehicle => topOffHealthOfVehicle(v)
case o: PlanetSideGameObject with Vitality => topOffHealthOfGeneric(o)
case _ => ()
}
}

private def topOffHealthOfPlayer(player: Player): Unit = {
//driver below half health, full heal
val maxHealthOfPlayer = player.MaxHealth.toLong
if (player.Health < maxHealthOfPlayer * 0.5f) {
player.Health = maxHealthOfPlayer.toInt
player.LogActivity(player.ClearHistory().head)
data.sendResponse(PlanetsideAttributeMessage(player.GUID, 0, maxHealthOfPlayer))
data.continent.AvatarEvents ! AvatarServiceMessage(data.zoning.zoneChannel, AvatarAction.PlanetsideAttribute(player.GUID, 0, maxHealthOfPlayer))
}
}

private def topOffHealthOfVehicle(vehicle: Vehicle): Unit = {
topOffHealthOfGeneric(vehicle)
//vehicle shields below half, full shields
val maxShieldsOfVehicle = vehicle.MaxShields.toLong
val shieldsUi = vehicle.Definition.shieldUiAttribute
if (vehicle.Shields < maxShieldsOfVehicle) {
val guid = vehicle.GUID
vehicle.Shields = maxShieldsOfVehicle.toInt
data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle))
data.continent.VehicleEvents ! VehicleServiceMessage(
data.continent.id,
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, shieldsUi, maxShieldsOfVehicle)
)
}
}

private def topOffHealthOfGeneric(obj: PlanetSideGameObject with Vitality): Unit = {
//below half health, full heal
val guid = obj.GUID
val maxHealthOf = obj.MaxHealth.toLong
if (obj.Health < maxHealthOf) {
obj.Health = maxHealthOf.toInt
data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf))
data.continent.VehicleEvents ! VehicleServiceMessage(
data.continent.id,
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, 0, maxHealthOf)
)
}
}
}

case object CustomerServiceRepresentativeMode extends PlayerMode {
def setup(data: SessionData): ModeLogic = {
new CustomerServiceRepresentativeMode(data)
}

private[csr] def renderPlayer(data: SessionData, zone: Zone, player: Player): Unit = {
val pguid = player.GUID
val definition = player.Definition
val objectClass = definition.ObjectId
val packet = definition.Packet
sendResponse(ObjectCreateDetailedMessage(
0L,
data.sendResponse(ObjectCreateDetailedMessage(
objectClass,
pguid,
vehicleAndSeat,
packet.DetailedConstructorData(player).get
))
data.zoning.spawn.HandleSetCurrentAvatar(player)
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.LoadPlayer(
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.LoadPlayer(
pguid,
objectClass,
pguid,
packet.ConstructorData(player).get,
vehicleAndSeat
None
))
data.chat.LeaveChannel(SpectatorChannel)
data.chat.LeaveChannel(CustomerServiceChannel)
sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR MODE OFF"))
}
}

case object CustomerServiceRepresentativeMode extends PlayerMode {
def setup(data: SessionData): ModeLogic = {
new CustomerServiceRepresentativeMode(data)
}
}
Loading

0 comments on commit 720bc97

Please sign in to comment.