mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-19 18:44:45 +00:00
Merge pull request #1146 from ScrawnyRonnie/jammer
Keep the jam going & other misc fixes
This commit is contained in:
commit
c99e170a26
|
|
@ -8926,7 +8926,7 @@
|
|||
"AbsY": 3742.29175,
|
||||
"AbsZ": 42.3043633,
|
||||
"Yaw": 198.0,
|
||||
"GUID": 713,
|
||||
"GUID": 715,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
|
|
@ -8939,7 +8939,7 @@
|
|||
"AbsY": 3729.643,
|
||||
"AbsZ": 42.3043633,
|
||||
"Yaw": 288.0,
|
||||
"GUID": 714,
|
||||
"GUID": 713,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
|
|
@ -8952,7 +8952,7 @@
|
|||
"AbsY": 3729.643,
|
||||
"AbsZ": 49.8043633,
|
||||
"Yaw": 108.0,
|
||||
"GUID": 715,
|
||||
"GUID": 714,
|
||||
"MapID": null,
|
||||
"IsChildObject": true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import net.psforever.actors.zone.ZoneActor
|
|||
import net.psforever.objects.avatar.scoring.{Assist, Death, EquipmentStat, KDAStat, Kill, Life, ScoreCard, SupportActivity}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.sourcing.VehicleSource
|
||||
import net.psforever.objects.vital.InGameHistory
|
||||
import net.psforever.objects.vital.{InGameHistory, ReconstructionActivity}
|
||||
import net.psforever.objects.vehicles.MountedWeapons
|
||||
import net.psforever.types.{ChatMessageType, StatisticalCategory, StatisticalElement}
|
||||
import org.joda.time.{LocalDateTime, Seconds}
|
||||
|
|
@ -235,7 +235,7 @@ object AvatarActor {
|
|||
|
||||
final case class SetStamina(stamina: Int) extends Command
|
||||
|
||||
private case class SetImplantInitialized(implantType: ImplantType) extends Command
|
||||
final case class SetImplantInitialized(implantType: ImplantType) extends Command
|
||||
|
||||
final case class MemberListRequest(action: MemberAction.Value, name: String) extends Command
|
||||
|
||||
|
|
@ -1588,8 +1588,68 @@ class AvatarActor(
|
|||
Behaviors.same
|
||||
|
||||
case ResetImplants() =>
|
||||
deinitializeImplants()
|
||||
initializeImplants()
|
||||
val player = session.get.player
|
||||
// Get time of when you spawned after a deconstruction or zoning activity.
|
||||
val lastDecon: Long = player.History.findLast {entry => entry.isInstanceOf[ReconstructionActivity]} match {
|
||||
case Some(entry) => entry.time
|
||||
case _ => 0L
|
||||
}
|
||||
// Get time of when you entered the world or respawned after death.
|
||||
val lastRespawn: Long = player.History.findLast {entry => entry.isInstanceOf[SpawningActivity]} match {
|
||||
case Some(entry) => entry.time
|
||||
case _ => 0L
|
||||
}
|
||||
// You didn't die. You deconstructed or changed zones via warpgate/IA/recall.
|
||||
// When you respawn after death, it does both recon and spawn activities, hence the minus 3000 to make sure
|
||||
// this doesn't happen at respawn after death.
|
||||
if (lastDecon - 3000 > lastRespawn) {
|
||||
deinitializeImplants()
|
||||
val implants = avatar.implants
|
||||
implants.zipWithIndex.foreach {
|
||||
case (Some(implant), slot) =>
|
||||
sessionActor ! SessionActor.SendResponse(
|
||||
CreateShortcutMessage(
|
||||
session.get.player.GUID,
|
||||
slot + 2,
|
||||
Some(implant.definition.implantType.shortcut)
|
||||
)
|
||||
)
|
||||
// If the amount of time that has passed since you entered the world or died is > how long it takes to
|
||||
// initialize this implant, initialize it after 1 second.
|
||||
if ((System.currentTimeMillis() / 1000) - (lastRespawn / 1000) > implant.definition.InitializationDuration) {
|
||||
implantTimers.get(slot).foreach(_.cancel())
|
||||
implantTimers(slot) = context.scheduleOnce(
|
||||
1.seconds,
|
||||
context.self,
|
||||
SetImplantInitialized(implant.definition.implantType)
|
||||
)
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
avatar.name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, 0))
|
||||
)
|
||||
}
|
||||
// If the implant initialization timer hasn't quite finished, calculate a reduced timer based on last spawn activity
|
||||
else {
|
||||
val remainingTime = (lastRespawn / 1000).seconds - (System.currentTimeMillis() / 1000).seconds + implant.definition.InitializationDuration.seconds
|
||||
implantTimers.get(slot).foreach(_.cancel())
|
||||
implantTimers(slot) = context.scheduleOnce(
|
||||
remainingTime,
|
||||
context.self,
|
||||
SetImplantInitialized(implant.definition.implantType)
|
||||
)
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
avatar.name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, 0))
|
||||
)
|
||||
}
|
||||
case (None, _) =>
|
||||
}
|
||||
}
|
||||
// You just entered the world or died. Implants reset and timers start from scratch
|
||||
else {
|
||||
deinitializeImplants()
|
||||
initializeImplants()
|
||||
}
|
||||
Behaviors.same
|
||||
|
||||
case UpdateToolDischarge(stats) =>
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class SessionData(
|
|||
if (isMovingPlus) {
|
||||
if (zoning.zoningStatus == Zoning.Status.Deconstructing) {
|
||||
stopDeconstructing()
|
||||
} else {
|
||||
} else if (zoning.zoningStatus != Zoning.Status.None) {
|
||||
zoning.CancelZoningProcessWithDescriptiveReason("cancel_motion")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.actors.session.support
|
||||
|
||||
import akka.actor.{ActorContext, typed}
|
||||
import net.psforever.objects.zones.Zoning
|
||||
import net.psforever.objects.zones.exp.ToDatabase
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -50,7 +51,8 @@ private[support] class WeaponAndProjectileOperations(
|
|||
private[support] var shotsWhileDead: Int = 0
|
||||
private val projectiles: Array[Option[Projectile]] =
|
||||
Array.fill[Option[Projectile]](Projectile.rangeUID - Projectile.baseUID)(None)
|
||||
|
||||
private var zoningOpt: Option[ZoningOperations] = None
|
||||
def zoning: ZoningOperations = zoningOpt.orNull
|
||||
/* packets */
|
||||
|
||||
def handleWeaponFire(pkt: WeaponFireMessage): Unit = {
|
||||
|
|
@ -536,7 +538,9 @@ private[support] class WeaponAndProjectileOperations(
|
|||
weaponGUID: PlanetSideGUID,
|
||||
projectileGUID: PlanetSideGUID
|
||||
): (Option[PlanetSideGameObject with Container], Option[Tool]) = {
|
||||
sessionData.zoning.CancelZoningProcessWithDescriptiveReason("cancel_fire")
|
||||
if (player.ZoningRequest != Zoning.Method.None) {
|
||||
sessionData.zoning.CancelZoningProcessWithDescriptiveReason("cancel_fire")
|
||||
}
|
||||
if (player.isShielded) {
|
||||
// Cancel NC MAX shield if it's active
|
||||
sessionData.toggleMaxSpecialState(enable = false)
|
||||
|
|
|
|||
|
|
@ -889,7 +889,7 @@ class ZoningOperations(
|
|||
def beginZoningCountdown(runnable: Runnable): Unit = {
|
||||
val descriptor = zoningType.toString.toLowerCase
|
||||
if (zoningStatus == Zoning.Status.Request) {
|
||||
avatarActor ! AvatarActor.DeinitializeImplants()
|
||||
avatarActor ! AvatarActor.DeactivateActiveImplants()
|
||||
zoningStatus = Zoning.Status.Countdown
|
||||
val (time, origin) = ZoningStartInitialMessageAndTimer()
|
||||
zoningCounter = time
|
||||
|
|
@ -2300,18 +2300,8 @@ class ZoningOperations(
|
|||
//vehicle and driver/passenger
|
||||
val vdef = vehicle.Definition
|
||||
val vguid = vehicle.GUID
|
||||
val vdata = if (seat == 0) {
|
||||
val seat = vehicle.Seats(0)
|
||||
seat.unmount(player)
|
||||
val _vdata = vdef.Packet.ConstructorData(vehicle).get
|
||||
sendResponse(ObjectCreateMessage(vehicle.Definition.ObjectId, vguid, _vdata))
|
||||
seat.mount(player)
|
||||
_vdata
|
||||
} else {
|
||||
val _vdata = vdef.Packet.ConstructorData(vehicle).get
|
||||
sendResponse(ObjectCreateMessage(vehicle.Definition.ObjectId, vguid, _vdata))
|
||||
_vdata
|
||||
}
|
||||
val vdata = vdef.Packet.ConstructorData(vehicle).get
|
||||
sendResponse(ObjectCreateMessage(vehicle.Definition.ObjectId, vguid, vdata))
|
||||
Vehicles.ReloadAccessPermissions(vehicle, continent.id)
|
||||
log.debug(s"AvatarCreate (vehicle): ${player.Name}'s ${vehicle.Definition.Name}")
|
||||
log.trace(s"AvatarCreate (vehicle): ${player.Name}'s ${vehicle.Definition.Name} - $vguid -> $vdata")
|
||||
|
|
@ -2777,10 +2767,7 @@ class ZoningOperations(
|
|||
}
|
||||
val originalDeadState = deadState
|
||||
deadState = DeadState.Alive
|
||||
if (originalDeadState != DeadState.Alive) {
|
||||
avatarActor ! AvatarActor.ResetImplants()
|
||||
}
|
||||
|
||||
avatarActor ! AvatarActor.ResetImplants()
|
||||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 82, 0))
|
||||
initializeShortcutsAndBank(guid)
|
||||
//Favorites lists
|
||||
|
|
|
|||
|
|
@ -7568,7 +7568,7 @@ object GlobalDefinitions {
|
|||
apc_tr.UnderwaterLifespan(suffocation = 15000L, recovery = 7500L)
|
||||
apc_tr.Geometry = apcForm
|
||||
apc_tr.MaxCapacitor = 300
|
||||
apc_tr.CapacitorRecharge = 10
|
||||
apc_tr.CapacitorRecharge = 1
|
||||
apc_tr.collision.avatarCollisionDamageMax = 300
|
||||
apc_tr.collision.xy = CollisionXYData(Array((0.1f, 1), (0.25f, 10), (0.5f, 40), (0.75f, 70), (1f, 110)))
|
||||
apc_tr.collision.z = CollisionZData(Array((2f, 1), (6f, 50), (10f, 300), (12f, 1000), (13f, 3000)))
|
||||
|
|
@ -7638,7 +7638,7 @@ object GlobalDefinitions {
|
|||
apc_nc.UnderwaterLifespan(suffocation = 15000L, recovery = 7500L)
|
||||
apc_nc.Geometry = apcForm
|
||||
apc_nc.MaxCapacitor = 300
|
||||
apc_nc.CapacitorRecharge = 10
|
||||
apc_nc.CapacitorRecharge = 1
|
||||
apc_nc.collision.avatarCollisionDamageMax = 300
|
||||
apc_nc.collision.xy = CollisionXYData(Array((0.1f, 1), (0.25f, 10), (0.5f, 40), (0.75f, 70), (1f, 110)))
|
||||
apc_nc.collision.z = CollisionZData(Array((2f, 1), (6f, 50), (10f, 300), (12f, 1000), (13f, 3000)))
|
||||
|
|
@ -7708,7 +7708,7 @@ object GlobalDefinitions {
|
|||
apc_vs.UnderwaterLifespan(suffocation = 15000L, recovery = 7500L)
|
||||
apc_vs.Geometry = apcForm
|
||||
apc_vs.MaxCapacitor = 300
|
||||
apc_vs.CapacitorRecharge = 10
|
||||
apc_vs.CapacitorRecharge = 1
|
||||
apc_vs.collision.avatarCollisionDamageMax = 300
|
||||
apc_vs.collision.xy = CollisionXYData(Array((0.1f, 1), (0.25f, 10), (0.5f, 40), (0.75f, 70), (1f, 110)))
|
||||
apc_vs.collision.z = CollisionZData(Array((2f, 1), (6f, 50), (10f, 300), (12f, 1000), (13f, 3000)))
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class SensorDeployableControl(sensor: SensorDeployable)
|
|||
|
||||
override def StartJammeredStatus(target: Any, dur: Int): Unit =
|
||||
target match {
|
||||
case obj: PlanetSideServerObject with JammableUnit if !obj.Jammed =>
|
||||
case obj: PlanetSideServerObject with JammableUnit =>
|
||||
val zone = obj.Zone
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.id,
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable)
|
|||
|
||||
override def StartJammeredStatus(target: Any, dur: Int): Unit =
|
||||
target match {
|
||||
case obj: PlanetSideServerObject with JammableUnit if !obj.Jammed =>
|
||||
case obj: PlanetSideServerObject with JammableUnit =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
obj.Zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1)
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ object Vehicles {
|
|||
val factionChannel = s"${vehicle.Faction}"
|
||||
(0 to 2).foreach(group => {
|
||||
vehicle.PermissionGroup(group, empire)
|
||||
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
/*vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
factionChannel,
|
||||
VehicleAction.SeatPermissions(Service.defaultPlayerGUID, guid, group, empire)
|
||||
)
|
||||
)*/
|
||||
})
|
||||
ReloadAccessPermissions(vehicle, player.Name)
|
||||
Some(vehicle)
|
||||
|
|
@ -135,10 +135,10 @@ object Vehicles {
|
|||
val empire = VehicleLockState.Empire.id
|
||||
(0 to 2).foreach(group => {
|
||||
vehicle.PermissionGroup(group, empire)
|
||||
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
/*vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
s"${vehicle.Faction}",
|
||||
VehicleAction.SeatPermissions(pguid, vguid, group, empire)
|
||||
)
|
||||
)*/
|
||||
})
|
||||
ReloadAccessPermissions(vehicle, player.Name)
|
||||
Some(vehicle)
|
||||
|
|
|
|||
|
|
@ -1309,7 +1309,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
* @param data additional interaction information, if applicable
|
||||
*/
|
||||
def doInteractingWithDeath(obj: PlanetSideServerObject, body: PieceOfEnvironment, data: Option[OxygenStateTarget]): Unit = {
|
||||
suicide()
|
||||
player.History.findLast { entry => entry.isInstanceOf[ReconstructionActivity] } match {
|
||||
case Some(entry) if System.currentTimeMillis() - entry.time > 4000L => suicide()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection ScalaUnusedSymbol
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ trait JammableMountedWeapons extends JammableBehavior {
|
|||
|
||||
override def StartJammeredStatus(target: Any, dur: Int): Unit = {
|
||||
target match {
|
||||
case obj: PlanetSideServerObject with MountedWeapons with JammableUnit if !obj.Jammed =>
|
||||
case obj: PlanetSideServerObject with MountedWeapons with JammableUnit =>
|
||||
JammableMountedWeaponsJammeredStatus(obj, statusCode = 1)
|
||||
super.StartJammeredStatus(target, dur)
|
||||
case _ => ;
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ object DamageableMountable {
|
|||
.values
|
||||
.flatMap { _.occupant }
|
||||
.collect { case player if player.isAlive =>
|
||||
//make llu visible to others in zone if passenger is carrying one
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem())
|
||||
//player.LogActivity(cause)
|
||||
player.Actor ! Player.Die(
|
||||
DamageInteraction(interaction.resolution, SourceEntry(player), interaction.cause, interaction.hitPos)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import net.psforever.objects.serverobject.terminals.Terminal
|
|||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource}
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
||||
import net.psforever.objects.vital.{DamagingActivity, InGameActivity, ShieldCharge, SpawningActivity, VehicleDismountActivity, VehicleMountActivity}
|
||||
import net.psforever.objects.vital.{DamagingActivity, InGameActivity, ReconstructionActivity, ShieldCharge, SpawningActivity, VehicleDismountActivity, VehicleMountActivity}
|
||||
import net.psforever.objects.vital.environment.EnvironmentReason
|
||||
import net.psforever.objects.vital.etc.SuicideReason
|
||||
import net.psforever.objects.zones._
|
||||
|
|
@ -679,14 +679,18 @@ class VehicleControl(vehicle: Vehicle)
|
|||
*/
|
||||
def doInteractingWithDeath(obj: PlanetSideServerObject, body: PieceOfEnvironment, data: Option[OxygenStateTarget]): Unit = {
|
||||
if (!obj.Destroyed) {
|
||||
PerformDamage(
|
||||
vehicle,
|
||||
DamageInteraction(
|
||||
VehicleSource(vehicle),
|
||||
SuicideReason(),
|
||||
vehicle.Position
|
||||
).calculate()
|
||||
)
|
||||
vehicle.History.findLast { entry => entry.isInstanceOf[ReconstructionActivity] } match {
|
||||
case Some(entry) if System.currentTimeMillis() - entry.time > 4000L =>
|
||||
PerformDamage(
|
||||
vehicle,
|
||||
DamageInteraction(
|
||||
VehicleSource(vehicle),
|
||||
SuicideReason(),
|
||||
vehicle.Position
|
||||
).calculate()
|
||||
)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -859,10 +863,8 @@ class VehicleControl(vehicle: Vehicle)
|
|||
override def StartJammeredStatus(target: Any, dur: Int): Unit = {
|
||||
super.StartJammeredStatus(target, dur)
|
||||
val subsystems = vehicle.Subsystems()
|
||||
if (!subsystems.exists { _.Jammed }) {
|
||||
subsystems.foreach { _.jam() }
|
||||
vehicleSubsystemMessages(subsystems.flatMap { _.changedMessages(vehicle) })
|
||||
}
|
||||
}
|
||||
|
||||
override def CancelJammeredStatus(target: Any): Unit = {
|
||||
|
|
|
|||
|
|
@ -365,6 +365,8 @@ class PersistenceMonitor(
|
|||
def PerformLogout(): Unit = {
|
||||
(inZone.Players.find(p => p.name == name), inZone.LivePlayers.find(p => p.Name == name)) match {
|
||||
case (Some(avatar), Some(player)) if player.VehicleSeated.nonEmpty =>
|
||||
//in case the player is holding the llu and disconnects
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem())
|
||||
//alive or dead in a vehicle
|
||||
//if the avatar is dead while in a vehicle, they haven't released yet
|
||||
AvatarActor.saveAvatarData(avatar)
|
||||
|
|
@ -381,6 +383,8 @@ class PersistenceMonitor(
|
|||
PlayerAvatarLogout(avatar, player)
|
||||
|
||||
case (Some(avatar), Some(player)) =>
|
||||
//in case the player is holding the llu and disconnects
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem())
|
||||
//alive or dead, as standard Infantry
|
||||
AvatarActor.saveAvatarData(avatar)
|
||||
AvatarActor.finalSavePlayerData(player)
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ class CaptureFlagManager(zone: Zone) extends Actor {
|
|||
case CaptureFlagManager.DropFlag(flag: CaptureFlag) =>
|
||||
flag.Carrier match {
|
||||
case Some(player: Player) =>
|
||||
val newFlag = flag
|
||||
// Set the flag position to where the player is that dropped it
|
||||
flag.Position = player.Position
|
||||
// Remove attached player from flag
|
||||
|
|
@ -121,6 +122,27 @@ class CaptureFlagManager(zone: Zone) extends Actor {
|
|||
flag.Zone.LocalEvents ! LocalServiceMessage(flag.Zone.id, LocalAction.SendPacket(ObjectDetachMessage(player.GUID, flag.GUID, player.Position, 0, 0, 0)))
|
||||
// Send dropped chat message
|
||||
ChatBroadcast(flag.Zone, CaptureFlagChatMessageStrings.CTF_FlagDropped(player.Name, player.Faction, flag.Owner.asInstanceOf[Building].Name), fanfare = false)
|
||||
HandleFlagDespawn(flag)
|
||||
// Register LLU object create task and callback to create on clients
|
||||
val replacementLlu = CaptureFlag.Constructor(
|
||||
newFlag.Position,
|
||||
newFlag.Orientation,
|
||||
newFlag.Target,
|
||||
newFlag.Owner,
|
||||
player.Faction
|
||||
)
|
||||
// Add the flag as an amenity and track it internally
|
||||
val socket = newFlag.Owner.asInstanceOf[Building].GetFlagSocket.get
|
||||
socket.captureFlag = replacementLlu
|
||||
TrackFlag(replacementLlu)
|
||||
TaskWorkflow.execute(WorldSession.CallBackForTask(
|
||||
GUIDTask.registerObject(socket.Zone.GUID, replacementLlu),
|
||||
socket.Zone.LocalEvents,
|
||||
LocalServiceMessage(
|
||||
socket.Zone.id,
|
||||
LocalAction.LluSpawned(Service.defaultPlayerGUID, replacementLlu)
|
||||
)
|
||||
))
|
||||
case _ =>
|
||||
log.warn("Tried to drop flag but flag has no carrier")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue