diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index b4c9cd46..78bc2458 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -374,16 +374,18 @@ class AvatarActor( implants = implants.map(implant => Some(Implant(implant.toImplantDefinition))).padTo(3, None), locker = locker ) - staminaRegenTimer.cancel() staminaRegenTimer = defaultStaminaRegen() replyTo ! AvatarLoginResponse(avatar) - case Failure(e) => log.error(e)("db failure") + case Failure(e) => + log.error(e)("db failure") } Behaviors.same case ReplaceAvatar(newAvatar) => replaceAvatar(newAvatar) + staminaRegenTimer.cancel() + staminaRegenTimer = defaultStaminaRegen() Behaviors.same case AddFirstTimeEvent(event) => diff --git a/src/main/scala/net/psforever/actors/session/SessionActor.scala b/src/main/scala/net/psforever/actors/session/SessionActor.scala index 73d67cd5..7dd530d4 100644 --- a/src/main/scala/net/psforever/actors/session/SessionActor.scala +++ b/src/main/scala/net/psforever/actors/session/SessionActor.scala @@ -431,9 +431,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con accountPersistence ! AccountPersistenceService.Login(avatar.name) case AvatarActor.AvatarLoginResponse(avatar) => - session = session.copy(avatar = avatar) - Deployables.InitializeDeployableQuantities(avatar) - cluster ! ICS.FilterZones(_ => true, context.self) + avatarLoginResponse(avatar) case packet: PlanetSideGamePacket => handleGamePkt(packet) @@ -1390,7 +1388,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con deadState = DeadState.RespawnTime session = session.copy(player = new Player(avatar)) - //ay-coordinates indicate sanctuary spawn bias: + //xy-coordinates indicate sanctuary spawn bias: player.Position = math.abs(scala.util.Random.nextInt() % avatar.name.hashCode % 4) match { case 0 => Vector3(8192, 8192, 0) //NE case 1 => Vector3(8192, 0, 0) //SE @@ -1418,22 +1416,22 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con //rejoin current avatar/player log.info(s"LoginInfo: player $playerName is alive") deadState = DeadState.Alive - session = session.copy(player = p) + session = session.copy(player = p, avatar = a) persist() setupAvatarFunc = AvatarRejoin avatarActor ! AvatarActor.ReplaceAvatar(a) - avatarActor ! AvatarActor.LoginAvatar(context.self) + avatarLoginResponse(a) case (Some(a), Some(p)) => //convert player to a corpse (unless in vehicle); automatic recall to closest spawn point log.info(s"LoginInfo: player $playerName is dead") deadState = DeadState.Dead - session = session.copy(player = p) + session = session.copy(player = p, avatar = a) persist() player.Zone = inZone HandleReleaseAvatar(p, inZone) avatarActor ! AvatarActor.ReplaceAvatar(a) - avatarActor ! AvatarActor.LoginAvatar(context.self) + avatarLoginResponse(a) case (Some(a), None) => //respawn avatar as a new player; automatic recall to closest spawn point @@ -1449,10 +1447,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con tplayer.Release //for proper respawn tplayer.Zone = inZone tplayer - } + }, avatar = a ) avatarActor ! AvatarActor.ReplaceAvatar(a) - avatarActor ! AvatarActor.LoginAvatar(context.self) + avatarLoginResponse(a) case _ => //fall back to sanctuary/prior? @@ -9378,6 +9376,18 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con heightLast = zHeight } + /** + * During login, when the avatar is set, the response code sets up session and deployable toolbox stats. + * Immediately contact the interstellar cluster to deal with zoning conditions. + * Only call this once during login and never any time after that. + * @param avatar the avatar being set as the current one belonging to this session + */ + def avatarLoginResponse(avatar: Avatar): Unit = { + session = session.copy(avatar = avatar) + Deployables.InitializeDeployableQuantities(avatar) + cluster ! ICS.FilterZones(_ => true, context.self) + } + def failWithError(error: String) = { log.error(error) middlewareActor ! MiddlewareActor.Teardown() diff --git a/src/main/scala/net/psforever/objects/locker/LockerEquipment.scala b/src/main/scala/net/psforever/objects/locker/LockerEquipment.scala index cded00c9..b69fc1e5 100644 --- a/src/main/scala/net/psforever/objects/locker/LockerEquipment.scala +++ b/src/main/scala/net/psforever/objects/locker/LockerEquipment.scala @@ -8,7 +8,7 @@ import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID} /** * A wrapper class that allows a player-facing locker component - * to be treated standard `Equipment` object in the player's fifth (sixth) slot. + * to be treated like a standard `Equipment` object in the player's fifth (sixth) slot. * (The opposite is not true - the equipment does not get treated as a locker component.) * During packet conversion and registration and general access in terms of holsters or "equipment slots", * the component may be be treated the same as other existing objects at the same level.