mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
You Can (Not) Hold (#1034)
* dropping the medical applicator on rejoin logins; not actually a bug fix, but a bug mitigation * narrowing the scope of the guard boolean; correcting an issue with purchase timers
This commit is contained in:
parent
690d7ec948
commit
0b8ff5a4ce
|
|
@ -1446,9 +1446,8 @@ class AvatarActor(
|
|||
name,
|
||||
cooldown.toSeconds,
|
||||
item match {
|
||||
case t: ToolDefinition => GlobalDefinitions.isMaxArms(t)
|
||||
case _: VehicleDefinition => true
|
||||
case _ => false
|
||||
case _: KitDefinition => false
|
||||
case _ => true
|
||||
}
|
||||
)
|
||||
case _ => ;
|
||||
|
|
@ -2573,9 +2572,8 @@ class AvatarActor(
|
|||
name,
|
||||
cooldown.toSeconds - secondsSincePurchase,
|
||||
obj match {
|
||||
case t: ToolDefinition => GlobalDefinitions.isMaxArms(t)
|
||||
case _: VehicleDefinition => true
|
||||
case _ => false
|
||||
case _: KitDefinition => false
|
||||
case _ => true
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -2591,9 +2589,9 @@ class AvatarActor(
|
|||
}
|
||||
}
|
||||
|
||||
def updatePurchaseTimer(name: String, time: Long, isActuallyAMachine: Boolean): Unit = {
|
||||
def updatePurchaseTimer(name: String, time: Long, isNotAMedKit: Boolean): Unit = {
|
||||
sessionActor ! SessionActor.SendResponse(
|
||||
AvatarVehicleTimerMessage(session.get.player.GUID, name, time, isActuallyAMachine)
|
||||
AvatarVehicleTimerMessage(session.get.player.GUID, name, time, isNotAMedKit)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import akka.actor.typed.scaladsl.adapter._
|
|||
import akka.actor.{ActorContext, ActorRef, Cancellable, typed}
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import net.psforever.login.WorldSession
|
||||
import net.psforever.objects.inventory.InventoryItem
|
||||
import net.psforever.objects.serverobject.mount.Seat
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource}
|
||||
|
|
@ -559,19 +561,15 @@ class ZoningOperations(
|
|||
|
||||
zone.Buildings.foreach({ case (_, building) => initBuilding(continentNumber, building.MapId, building) })
|
||||
sendResponse(ZonePopulationUpdateMessage(continentNumber, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
||||
//TODO should actually not claim that the sanctuary or VR zones are locked by their respective empire
|
||||
if (continentNumber == 11)
|
||||
sendResponse(
|
||||
ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.NC)
|
||||
) // "The NC have captured the NC Sanctuary."
|
||||
sendResponse(ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.NC))
|
||||
else if (continentNumber == 12)
|
||||
sendResponse(
|
||||
ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.TR)
|
||||
) // "The TR have captured the TR Sanctuary."
|
||||
sendResponse(ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.TR))
|
||||
else if (continentNumber == 13)
|
||||
sendResponse(
|
||||
ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.VS)
|
||||
) // "The VS have captured the VS Sanctuary."
|
||||
else sendResponse(ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.NEUTRAL))
|
||||
sendResponse(ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.VS))
|
||||
else
|
||||
sendResponse(ContinentalLockUpdateMessage(continentNumber, PlanetSideEmpire.NEUTRAL))
|
||||
//CaptureFlagUpdateMessage()
|
||||
//VanuModuleUpdateMessage()
|
||||
//ModuleLimitsMessage()
|
||||
|
|
@ -1804,6 +1802,7 @@ class ZoningOperations(
|
|||
session = session.copy(player = p, avatar = a)
|
||||
sessionData.persist()
|
||||
setupAvatarFunc = AvatarRejoin
|
||||
dropMedicalApplicators(p)
|
||||
avatarActor ! AvatarActor.ReplaceAvatar(a)
|
||||
avatarLoginResponse(a)
|
||||
|
||||
|
|
@ -1813,6 +1812,7 @@ class ZoningOperations(
|
|||
deadState = DeadState.Dead
|
||||
session = session.copy(player = p, avatar = a)
|
||||
sessionData.persist()
|
||||
dropMedicalApplicators(p)
|
||||
HandleReleaseAvatar(p, inZone)
|
||||
avatarActor ! AvatarActor.ReplaceAvatar(a)
|
||||
avatarLoginResponse(a)
|
||||
|
|
@ -1894,8 +1894,12 @@ class ZoningOperations(
|
|||
}
|
||||
|
||||
def handleNewPlayerLoaded(tplayer: Player): Unit = {
|
||||
//new zone
|
||||
log.info(s"${tplayer.Name} has spawned into ${session.zone.id}")
|
||||
/* new zone, might be on `tplayer.Zone` but should definitely be on `session` */
|
||||
val zone = session.zone
|
||||
val id = zone.id
|
||||
val map = zone.map
|
||||
val mapName = map.name
|
||||
log.info(s"${tplayer.Name} has spawned into $id")
|
||||
sessionData.oldRefsMap.clear()
|
||||
sessionData.persist = UpdatePersistenceAndRefs
|
||||
tplayer.avatar = avatar
|
||||
|
|
@ -1903,18 +1907,8 @@ class ZoningOperations(
|
|||
avatarActor ! AvatarActor.CreateImplants()
|
||||
avatarActor ! AvatarActor.InitializeImplants()
|
||||
//LoadMapMessage causes the client to send BeginZoningMessage, eventually leading to SetCurrentAvatar
|
||||
val weaponsEnabled =
|
||||
session.zone.map.name != "map11" && session.zone.map.name != "map12" && session.zone.map.name != "map13"
|
||||
sendResponse(
|
||||
LoadMapMessage(
|
||||
session.zone.map.name,
|
||||
session.zone.id,
|
||||
40100,
|
||||
25,
|
||||
weaponsEnabled,
|
||||
session.zone.map.checksum
|
||||
)
|
||||
)
|
||||
val weaponsEnabled = !(mapName.equals("map11") || mapName.equals("map12") || mapName.equals("map13"))
|
||||
sendResponse(LoadMapMessage(mapName, id, 40100, 25, weaponsEnabled, map.checksum))
|
||||
if (isAcceptableNextSpawnPoint) {
|
||||
//important! the LoadMapMessage must be processed by the client before the avatar is created
|
||||
setupAvatarFunc()
|
||||
|
|
@ -1934,7 +1928,7 @@ class ZoningOperations(
|
|||
} else {
|
||||
//look for different spawn point in same zone
|
||||
cluster ! ICS.GetNearbySpawnPoint(
|
||||
session.zone.Number,
|
||||
zone.Number,
|
||||
tplayer,
|
||||
Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS),
|
||||
context.self
|
||||
|
|
@ -1974,6 +1968,25 @@ class ZoningOperations(
|
|||
|
||||
/* support functions */
|
||||
|
||||
private def dropMedicalApplicators(p: Player): Unit = {
|
||||
WorldSession.DropLeftovers(p)(
|
||||
(p.Holsters().zipWithIndex.collect { case (slot, index) if slot.Equipment.nonEmpty => InventoryItem(slot.Equipment.get, index) } ++
|
||||
p.Inventory.Items ++
|
||||
p.FreeHand.Equipment.flatMap { item => Some(InventoryItem(item, Player.FreeHandSlot)) }.toList)
|
||||
.collect {
|
||||
case entry @ InventoryItem(equipment, index)
|
||||
if equipment.Definition == GlobalDefinitions.medicalapplicator && p.DrawnSlot == index =>
|
||||
p.Slot(index).Equipment = None
|
||||
p.DrawnSlot = Player.HandsDownSlot
|
||||
entry
|
||||
case entry @ InventoryItem(equipment, index)
|
||||
if equipment.Definition == GlobalDefinitions.medicalapplicator =>
|
||||
p.Slot(index).Equipment = None
|
||||
entry
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
def isAcceptableNextSpawnPoint: Boolean = isAcceptableSpawnPoint(nextSpawnPoint)
|
||||
|
||||
def isAcceptableSpawnPoint(spawnPoint: SpawnPoint): Boolean = isAcceptableSpawnPoint(Some(spawnPoint))
|
||||
|
|
|
|||
|
|
@ -959,7 +959,7 @@ object WorldSession {
|
|||
* @param container the original object that contained the items
|
||||
* @param drops the items to be dropped on the ground
|
||||
*/
|
||||
def DropLeftovers(container: PlanetSideServerObject with Container)(drops: List[InventoryItem]): Unit = {
|
||||
def DropLeftovers(container: PlanetSideServerObject with Container)(drops: Iterable[InventoryItem]): Unit = {
|
||||
//drop or retire
|
||||
val zone = container.Zone
|
||||
val pos = container.Position
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@ import scodec.Codec
|
|||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* @param player_guid player guid
|
||||
* @param text internal name of the item or vehicle name, e.g., medkit, fury, trhev_antipersonnel
|
||||
* @param time cooldown/delay in seconds
|
||||
* @param unk `true` for vehicles and max exo-suits; `false` for other items
|
||||
* @param player_guid player guid
|
||||
* @param text internal name of the item or vehicle name, e.g., medkit, fury, trhev_antipersonnel
|
||||
* @param time cooldown/delay in seconds
|
||||
* @param unk unk;
|
||||
* most likely has to do with the visibility of the timer in equipment purchasing;
|
||||
* `false` for kit items;
|
||||
* `true` for almost everything else
|
||||
*/
|
||||
final case class AvatarVehicleTimerMessage(player_guid: PlanetSideGUID, text: String, time: Long, unk: Boolean)
|
||||
extends PlanetSideGamePacket {
|
||||
|
|
|
|||
|
|
@ -6,22 +6,29 @@ import scodec.Codec
|
|||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* map_name and nav_map_name should match (unless you want to be lost :))
|
||||
*
|
||||
* ex:
|
||||
* map13 & home3 = vs sanc
|
||||
* map10 & z10 = amerish
|
||||
* map07 & z7 = esamir
|
||||
*/
|
||||
* Dispatched from server to client to instigate a zone change.
|
||||
* The client should respond with a `BeginZoningMessage` packet.
|
||||
* `map_name` and `zone_id` should correspond or the final product will be disorienting, even if it works.
|
||||
* @param map_name designation of the physical zone;
|
||||
* determines the (deployment) map screen
|
||||
* @param zone_id designation of the entirety of the zone;
|
||||
* determines the loading screen
|
||||
* @param unk1 na;
|
||||
* seems to match the initial projectile index (that can be assigned)
|
||||
* @param unk2 na;
|
||||
* seems to match the total number of unique projectile indices (that can be assigned) (before looping)
|
||||
* @param weapons_unlocked live fire is permissible;
|
||||
* restricts all actions instigated by that key bind
|
||||
* @param checksum challenge number so that client can confirm server is using the correct version of this zone
|
||||
*/
|
||||
final case class LoadMapMessage(
|
||||
map_name: String,
|
||||
nav_map_name: String, // Also determines loading screen
|
||||
unk1: Int,
|
||||
unk2: Long,
|
||||
weapons_unlocked: Boolean,
|
||||
checksum: Long
|
||||
) //?
|
||||
extends PlanetSideGamePacket {
|
||||
map_name: String,
|
||||
zone_id: String, // Also determines loading screen
|
||||
unk1: Int,
|
||||
unk2: Long,
|
||||
weapons_unlocked: Boolean,
|
||||
checksum: Long
|
||||
) extends PlanetSideGamePacket {
|
||||
type Packet = LoadMapMessage
|
||||
def opcode = GamePacketOpcode.LoadMapMessage
|
||||
def encode = LoadMapMessage.encode(this)
|
||||
|
|
@ -29,8 +36,8 @@ final case class LoadMapMessage(
|
|||
|
||||
object LoadMapMessage extends Marshallable[LoadMapMessage] {
|
||||
implicit val codec: Codec[LoadMapMessage] = (
|
||||
("map_name" | PacketHelpers.encodedString) :: // TODO: Implement encodedStringWithLimit
|
||||
("nav_map_name" | PacketHelpers.encodedString) :: //TODO: Implement encodedStringWithLimit
|
||||
("map_name" | PacketHelpers.encodedString) :: // TODO: Implement encodedStringWithLimit
|
||||
("zone_id" | PacketHelpers.encodedString) :: //TODO: Implement encodedStringWithLimit
|
||||
("unk1" | uint16L) ::
|
||||
("unk2" | uint32L) ::
|
||||
("weapons_unlocked" | bool) ::
|
||||
|
|
|
|||
Loading…
Reference in a new issue