mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
Gating Fixes (#254)
* rescheduling of passenger gating summons to increase chances of detecting passengers joining same zone; short-circuit new spawn requests and new warp gate requests while a previous request is already being processed * changing respawn delays for warp gate spawn points * adjusting how warp gates store broadcast data and how broadcast gates are declared in packets; activating TR sanctuary warp gates and making Solsar warp gates broadcast for the TR * changes to vehicle disowning and what happens to an AMS when it is unloaded
This commit is contained in:
parent
6399963e68
commit
5209f9ec21
|
|
@ -1039,14 +1039,12 @@ object GlobalDefinitions {
|
|||
val warpgate : ObjectDefinition with SpawnPointDefinition = new ObjectDefinition(993) with SpawnPointDefinition
|
||||
warpgate.Name = "warpgate"
|
||||
warpgate.UseRadius = 301.8713f
|
||||
warpgate.Delay = 10
|
||||
warpgate.VehicleAllowance = true
|
||||
warpgate.SpecificPointFunc = SpawnPoint.Gate
|
||||
|
||||
val hst : ObjectDefinition with SpawnPointDefinition = new ObjectDefinition(402) with SpawnPointDefinition
|
||||
hst.Name = "hst"
|
||||
hst.UseRadius = 20.4810f
|
||||
hst.Delay = 10
|
||||
hst.VehicleAllowance = true
|
||||
hst.NoWarp += dropship
|
||||
hst.NoWarp += galaxy_gunship
|
||||
|
|
@ -1062,7 +1060,6 @@ object GlobalDefinitions {
|
|||
val warpgate_cavern : ObjectDefinition with SpawnPointDefinition = new ObjectDefinition(994) with SpawnPointDefinition
|
||||
warpgate_cavern.Name = "warpgate_cavern"
|
||||
warpgate_cavern.UseRadius = 55.0522f
|
||||
warpgate_cavern.Delay = 10
|
||||
warpgate_cavern.VehicleAllowance = true
|
||||
warpgate_cavern.SpecificPointFunc = SpawnPoint.Gate
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,15 @@ import net.psforever.objects.zones.Zone
|
|||
import net.psforever.packet.game.{Additional1, Additional2, Additional3, PlanetSideGeneratorState}
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WarpGate(building_guid : Int, map_id : Int, zone : Zone, buildingDefinition : ObjectDefinition with SpawnPointDefinition)
|
||||
extends Building(building_guid, map_id, zone, StructureType.WarpGate, buildingDefinition)
|
||||
with SpawnPoint {
|
||||
/** can this building be used as an active warp gate */
|
||||
private var active : Boolean = true
|
||||
private var broadcast : Boolean = false
|
||||
/** what faction views this warp gate as a broadcast gate */
|
||||
private var broadcast : mutable.Set[PlanetSideEmpire.Value] = mutable.Set.empty[PlanetSideEmpire.Value]
|
||||
|
||||
override def Info : (
|
||||
Int,
|
||||
|
|
@ -48,18 +52,105 @@ class WarpGate(building_guid : Int, map_id : Int, zone : Zone, buildingDefinitio
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* If a warp gate is active, it can be used to transport faction-affiliated forces between other gates.
|
||||
* For transportation of faction-opposed forces, use broadcast logic for that faction.
|
||||
* @return `true`, if the warp gate can be used for transport;
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def Active : Boolean = active
|
||||
|
||||
/**
|
||||
* Control whether a warp gate is usable for transporting faction-affiliated forces between other gates.
|
||||
* @param state `true`, to activate the gate;
|
||||
* `false`, otherwise
|
||||
* @return `true`, if the gate is active;
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def Active_=(state : Boolean) : Boolean = {
|
||||
active = state
|
||||
Active
|
||||
}
|
||||
|
||||
def Broadcast : Boolean = Active && broadcast
|
||||
/**
|
||||
* Determine whether any faction interacts with this warp gate as "broadcast."
|
||||
* The gate must be active first.
|
||||
* @return `true`, if some faction sees this warp gate as a "broadcast gate";
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def Broadcast : Boolean = Active && broadcast.nonEmpty
|
||||
|
||||
def Broadcast_=(cast : Boolean) : Boolean = {
|
||||
broadcast = cast
|
||||
Broadcast
|
||||
/**
|
||||
* Determine whether a specific faction interacts with this warp gate as "broadcast."
|
||||
* The warp gate being `NEUTRAL` should allow for any polled faction to interact.
|
||||
* The gate must be active first.
|
||||
* @return `true`, if the given faction interacts with this warp gate as a "broadcast gate";
|
||||
* `false`, otherwise
|
||||
*/
|
||||
def Broadcast(faction : PlanetSideEmpire.Value) : Boolean = {
|
||||
Active && (broadcast.contains(faction) || broadcast.contains(PlanetSideEmpire.NEUTRAL))
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle whether the warp gate's faction-affiliated force interacts with this warp gate as "broadcast."
|
||||
* Other "broadcast" associations are not affected.
|
||||
* The gate must be active first.
|
||||
* @param bcast `true`, if the faction-affiliated force interacts with this gate as broadcast;
|
||||
* `false`, if not
|
||||
* @return the set of all factions who interact with this warp gate as "broadcast"
|
||||
*/
|
||||
def Broadcast_=(bcast : Boolean) : Set[PlanetSideEmpire.Value] = {
|
||||
if(Active) {
|
||||
if(bcast) {
|
||||
broadcast += Faction
|
||||
}
|
||||
else {
|
||||
broadcast -= Faction
|
||||
}
|
||||
}
|
||||
broadcast.toSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Which factions interact with this warp gate as "broadcast?"
|
||||
* @return the set of all factions who interact with this warp gate as "broadcast"
|
||||
*/
|
||||
def BroadcastFor : Set[PlanetSideEmpire.Value] = broadcast.toSet
|
||||
|
||||
/**
|
||||
* Allow a faction to interact with a given warp gate as "broadcast" if it is active.
|
||||
* @param bcast the faction
|
||||
* @return the set of all factions who interact with this warp gate as "broadcast"
|
||||
*/
|
||||
def BroadcastFor_=(bcast : PlanetSideEmpire.Value) : Set[PlanetSideEmpire.Value] = {
|
||||
(broadcast += bcast).toSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow some factions to interact with a given warp gate as "broadcast" if it is active.
|
||||
* @param bcast the factions
|
||||
* @return the set of all factions who interact with this warp gate as "broadcast"
|
||||
*/
|
||||
def BroadcastFor_=(bcast : Set[PlanetSideEmpire.Value]) : Set[PlanetSideEmpire.Value] = {
|
||||
(broadcast ++= bcast).toSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow a faction to interact with a given warp gate as "broadcast."
|
||||
* @param bcast the faction
|
||||
* @return the set of all factions who interact with this warp gate as "broadcast"
|
||||
*/
|
||||
def StopBroadcastFor_=(bcast : PlanetSideEmpire.Value) : Set[PlanetSideEmpire.Value] = {
|
||||
(broadcast -= bcast).toSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow some factions to interact with a given warp gate as "broadcast."
|
||||
* @param bcast the factions
|
||||
* @return the set of all factions who interact with this warp gate as "broadcast"
|
||||
*/
|
||||
def StopBroadcastFor_=(bcast : Set[PlanetSideEmpire.Value]) : Set[PlanetSideEmpire.Value] = {
|
||||
(broadcast --= bcast).toSet
|
||||
}
|
||||
|
||||
def Owner : PlanetSideServerObject = this
|
||||
|
|
|
|||
|
|
@ -6,28 +6,26 @@ import scodec.Codec
|
|||
import scodec.codecs._
|
||||
|
||||
/**
|
||||
* Promotes a warpgate's "broadcast" functionality.<br>
|
||||
* Dispatched by the server to promote a warp gate's broadcast functionality.<br>
|
||||
* <br>
|
||||
* Change the map name of a warpgate into "Broadcast" when the proper state is set.
|
||||
* If a proper warpgate is not designated, nothing happens.
|
||||
* If not set, the map name of the warpgate will default to whatever is normally written on the map.
|
||||
* The map designation of geowarps is not affected by this packet.<br>
|
||||
* <br>
|
||||
* Exploration:<br>
|
||||
* I believe these `Boolean` values actually indicate some measure of warpgate operation.
|
||||
* Geowarps, for example, though their appearance does not change, recieve this packet.
|
||||
* Moreover, they can operate as a receiving-end broadcast gate.
|
||||
* @param continent_id the zone
|
||||
* @param building_id the warp gate (see `BuildingInfoUpdateMessage`)
|
||||
* @param unk1 na
|
||||
* @param unk2 na
|
||||
* @param broadcast if true, the gate replaces its destination text with "Broadcast"
|
||||
* Changes the map name of a warp gate into "Broadcast"
|
||||
* and allow a given faction to access the gate's intercontinental transport functionality to/from that gate,
|
||||
* even if the gate is not properly owned.
|
||||
* If an actual warp gate is not designated, nothing happens.
|
||||
* If not set, the map name of the warp gate will default to whatever is normally written on the map.
|
||||
* The map designation of geowarps is not affected by this packet.
|
||||
* @see `BuildingInfoUpdateMessage`
|
||||
* @param zone_id the zone ordinal number
|
||||
* @param building_id the warp gate map id
|
||||
* @param tr players belonging to the Terran Republic interact with this warp gate as a "broadcast gate"
|
||||
* @param nc players belonging to the New Conglomerate interact with this warp gate as a "broadcast gate"
|
||||
* @param vs players belonging to the Vanu Sovereignty interact with this warp gate as a "broadcast gate"
|
||||
*/
|
||||
final case class BroadcastWarpgateUpdateMessage(continent_id : Int,
|
||||
final case class BroadcastWarpgateUpdateMessage(zone_id : Int,
|
||||
building_id : Int,
|
||||
unk1 : Boolean,
|
||||
unk2 : Boolean,
|
||||
broadcast : Boolean)
|
||||
tr : Boolean,
|
||||
nc : Boolean,
|
||||
vs : Boolean)
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = BroadcastWarpgateUpdateMessage
|
||||
def opcode = GamePacketOpcode.BroadcastWarpgateUpdateMessage
|
||||
|
|
@ -36,10 +34,10 @@ final case class BroadcastWarpgateUpdateMessage(continent_id : Int,
|
|||
|
||||
object BroadcastWarpgateUpdateMessage extends Marshallable[BroadcastWarpgateUpdateMessage] {
|
||||
implicit val codec : Codec[BroadcastWarpgateUpdateMessage] = (
|
||||
("continent_id" | uint16L) ::
|
||||
("zone_id" | uint16L) ::
|
||||
("building_id" | uint16L) ::
|
||||
("unk1" | bool) ::
|
||||
("unk2" | bool) ::
|
||||
("broadcast" | bool)
|
||||
("tr" | bool) ::
|
||||
("nc" | bool) ::
|
||||
("vs" | bool)
|
||||
).as[BroadcastWarpgateUpdateMessage]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
//quickly and briefly kill player to avoid disembark animation
|
||||
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player_guid, 0, 0))
|
||||
DismountVehicleOnLogOut()
|
||||
DisownVehicle()
|
||||
}
|
||||
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player_guid, player_guid))
|
||||
taskResolver ! GUIDTask.UnregisterAvatar(player)(continent.GUID)
|
||||
|
|
@ -207,14 +208,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
* Vehicle cleanup that is specific to log out behavior.
|
||||
*/
|
||||
def DismountVehicleOnLogOut() : Unit = {
|
||||
(player.VehicleSeated match {
|
||||
case Some(vehicle_guid) =>
|
||||
continent.GUID(vehicle_guid)
|
||||
case None =>
|
||||
None
|
||||
(continent.GUID(player.VehicleSeated) match {
|
||||
case Some(obj : Mountable) =>
|
||||
(Some(obj), obj.PassengerInSeat(player))
|
||||
case _ =>
|
||||
(None, None)
|
||||
}) match {
|
||||
case Some(mobj : Mountable) =>
|
||||
mobj.Seat(mobj.PassengerInSeat(player).get).get.Occupant = None
|
||||
case (Some(mountObj), Some(seatIndex)) =>
|
||||
mountObj.Seats(seatIndex).Occupant = None
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -2733,6 +2734,19 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
})
|
||||
StopBundlingPackets()
|
||||
drawDeloyableIcon = DontRedrawIcons
|
||||
//if driver of a vehicle, summon any passengers and cargo vehicles left behind on previous continent
|
||||
GetVehicleAndSeat() match {
|
||||
case (Some(vehicle), Some(0)) =>
|
||||
LoadZoneTransferPassengerMessages(
|
||||
guid,
|
||||
continent.Id,
|
||||
TransportVehicleChannelName(vehicle),
|
||||
vehicle,
|
||||
interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID)
|
||||
)
|
||||
interstellarFerryTopLevelGUID = None
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def handleControlPkt(pkt : PlanetSideControlPacket) = {
|
||||
|
|
@ -3028,16 +3042,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
})
|
||||
//our vehicle would have already been loaded; see NewPlayerLoaded/AvatarCreate
|
||||
usedVehicle.headOption match {
|
||||
case Some(vehicle) if vehicle.PassengerInSeat(player).contains(0) =>
|
||||
//if driver of vehicle, summon any passengers and cargo vehicles left behind on previous continent
|
||||
LoadZoneTransferPassengerMessages(
|
||||
guid,
|
||||
continentId,
|
||||
TransportVehicleChannelName(vehicle),
|
||||
vehicle,
|
||||
interstellarFerryTopLevelGUID.orElse(player.VehicleSeated).getOrElse(PlanetSideGUID(0))
|
||||
)
|
||||
case Some(vehicle) =>
|
||||
case Some(vehicle) if !vehicle.PassengerInSeat(player).contains(0) =>
|
||||
//if passenger, attempt to depict any other passengers already in this zone
|
||||
val vguid = vehicle.GUID
|
||||
vehicle.Seats
|
||||
|
|
@ -3054,7 +3059,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
)
|
||||
)
|
||||
})
|
||||
case _ => ; //no vehicle
|
||||
case _ => ; //driver, or no vehicle
|
||||
}
|
||||
//vehicle wreckages
|
||||
wreckages.foreach(vehicle => {
|
||||
|
|
@ -3287,7 +3292,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
|
||||
case msg @ SpawnRequestMessage(u1, spawn_type, u3, u4, zone_number) =>
|
||||
log.info(s"SpawnRequestMessage: $msg")
|
||||
cluster ! Zone.Lattice.RequestSpawnPoint(zone_number.toInt, player, spawn_type.id.toInt)
|
||||
if(deadState != DeadState.RespawnTime) {
|
||||
deadState = DeadState.RespawnTime
|
||||
cluster ! Zone.Lattice.RequestSpawnPoint(zone_number.toInt, player, spawn_type.id.toInt)
|
||||
}
|
||||
else {
|
||||
log.warn("SpawnRequestMessage: request consumed; already respawning ...")
|
||||
}
|
||||
|
||||
case msg @ SetChatFilterMessage(send_channel, origin, whitelist) =>
|
||||
//log.info("SetChatFilters: " + msg)
|
||||
|
|
@ -3332,18 +3343,22 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
PlayerActionsToCancel()
|
||||
continent.GUID(player.VehicleSeated) match {
|
||||
case Some(vehicle : Vehicle) =>
|
||||
vehicle.Position = pos
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.UnloadVehicle(player.GUID, continent, vehicle, vehicle.GUID))
|
||||
LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0)
|
||||
vehicle.PassengerInSeat(player) match {
|
||||
case Some(0) =>
|
||||
vehicle.Position = pos
|
||||
LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0)
|
||||
case _ => //not seated as the driver, in which case we can't move
|
||||
deadState = DeadState.Alive
|
||||
}
|
||||
case None =>
|
||||
player.Position = pos
|
||||
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player.GUID, player.GUID))
|
||||
//avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player.GUID, player.GUID))
|
||||
LoadZonePhysicalSpawnPoint(zone, pos, Vector3.Zero, 0)
|
||||
case _ => //seated in something that is not a vehicle, in which case we can't move
|
||||
case _ => //seated in something that is not a vehicle, or we're dead, in which case we can't move
|
||||
deadState = DeadState.Alive
|
||||
}
|
||||
|
||||
case (false, _, _) => ;
|
||||
case (_, _, _) => ;
|
||||
}
|
||||
|
||||
CSRWarp.read(traveler, msg) match {
|
||||
|
|
@ -3351,17 +3366,23 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
deadState = DeadState.Release //cancel movement updates
|
||||
PlayerActionsToCancel()
|
||||
continent.GUID(player.VehicleSeated) match {
|
||||
case Some(vehicle : Vehicle) =>
|
||||
LoadZonePhysicalSpawnPoint(continent.Id, pos, Vector3.z(vehicle.Orientation.z), 0)
|
||||
case Some(vehicle : Vehicle) if player.isAlive =>
|
||||
vehicle.PassengerInSeat(player) match {
|
||||
case Some(0) =>
|
||||
vehicle.Position = pos
|
||||
LoadZonePhysicalSpawnPoint(continent.Id, pos, Vector3.z(vehicle.Orientation.z), 0)
|
||||
case _ => //not seated as the driver, in which case we can't move
|
||||
deadState = DeadState.Alive
|
||||
}
|
||||
case None =>
|
||||
player.Position = pos
|
||||
sendResponse(PlayerStateShiftMessage(ShiftState(0, pos, player.Orientation.z, None)))
|
||||
deadState = DeadState.Alive //must be set here
|
||||
case _ => //seated in something that is not a vehicle, in which case we can't move
|
||||
case _ => //seated in something that is not a vehicle, or we're dead, in which case we can't move
|
||||
deadState = DeadState.Alive
|
||||
}
|
||||
|
||||
case (false, _) => ;
|
||||
case (_, _) => ;
|
||||
}
|
||||
|
||||
// TODO: Prevents log spam, but should be handled correctly
|
||||
|
|
@ -4485,17 +4506,23 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
|
||||
case msg @ WarpgateRequest(continent_guid, building_guid, dest_building_guid, dest_continent_guid, unk1, unk2) =>
|
||||
log.info(s"WarpgateRequest: $msg")
|
||||
continent.Buildings.values.find(building => building.GUID == building_guid) match {
|
||||
case Some(wg : WarpGate) if(wg.Active && (GetKnownVehicleAndSeat() match {
|
||||
case (Some(vehicle), _) =>
|
||||
wg.Definition.VehicleAllowance && !wg.Definition.NoWarp.contains(vehicle.Definition)
|
||||
case _ =>
|
||||
true
|
||||
})) =>
|
||||
cluster ! Zone.Lattice.RequestSpecificSpawnPoint(dest_continent_guid.guid, player, dest_building_guid)
|
||||
if(deadState != DeadState.RespawnTime) {
|
||||
deadState = DeadState.RespawnTime
|
||||
continent.Buildings.values.find(building => building.GUID == building_guid) match {
|
||||
case Some(wg : WarpGate) if (wg.Active && (GetKnownVehicleAndSeat() match {
|
||||
case (Some(vehicle), _) =>
|
||||
wg.Definition.VehicleAllowance && !wg.Definition.NoWarp.contains(vehicle.Definition)
|
||||
case _ =>
|
||||
true
|
||||
})) =>
|
||||
cluster ! Zone.Lattice.RequestSpecificSpawnPoint(dest_continent_guid.guid, player, dest_building_guid)
|
||||
|
||||
case _ =>
|
||||
RequestSanctuaryZoneSpawn(player, continent.Number)
|
||||
case _ =>
|
||||
RequestSanctuaryZoneSpawn(player, continent.Number)
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("WarpgateRequest: request consumed; already respawning ...")
|
||||
}
|
||||
|
||||
case msg @ MountVehicleMsg(player_guid, mountable_guid, entry_point) =>
|
||||
|
|
@ -5332,7 +5359,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
* @param vehicle the discovered vehicle
|
||||
*/
|
||||
private def SpecialCaseVehicleDespawn(tplayer : Player, vehicle : Vehicle) : Option[Vehicle] = {
|
||||
if(vehicle.Owner.contains(tplayer.GUID) || !vehicle.Seats(0).isOccupied) {
|
||||
if(vehicle.Owner.contains(tplayer.GUID)) {
|
||||
vehicle.Owner = None
|
||||
vehicleService ! VehicleServiceMessage.Decon(RemoverActor.ClearSpecific(List(vehicle), continent))
|
||||
vehicle.CargoHolds.values
|
||||
|
|
@ -5345,7 +5372,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
vehicle,
|
||||
ferry.GUID,
|
||||
ferry,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
|
|
@ -6357,7 +6384,16 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
)
|
||||
)
|
||||
sendResponse(DensityLevelUpdateMessage(continentNumber, buildingNumber, List(0,0, 0,0, 0,0, 0,0)))
|
||||
sendResponse(BroadcastWarpgateUpdateMessage(continentNumber, buildingNumber, false, false, wg.Broadcast))
|
||||
//TODO one faction knows which gates are broadcast for another faction?
|
||||
sendResponse(
|
||||
BroadcastWarpgateUpdateMessage(
|
||||
continentNumber,
|
||||
buildingNumber,
|
||||
wg.Broadcast(PlanetSideEmpire.TR),
|
||||
wg.Broadcast(PlanetSideEmpire.NC),
|
||||
wg.Broadcast(PlanetSideEmpire.VS)
|
||||
)
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -6598,15 +6634,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case _ =>
|
||||
vehicle.MountedIn = None
|
||||
}
|
||||
//call for passengers across the expanse
|
||||
LoadZoneTransferPassengerMessages(
|
||||
player.GUID,
|
||||
continent.Id,
|
||||
TransportVehicleChannelName(vehicle),
|
||||
vehicle,
|
||||
interstellarFerryTopLevelGUID.orElse(player.VehicleSeated).getOrElse(PlanetSideGUID(0))
|
||||
)
|
||||
interstellarFerryTopLevelGUID = None
|
||||
}
|
||||
else {
|
||||
//if passenger;
|
||||
|
|
@ -7875,7 +7902,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
* does not factor in any time required for loading zone or game objects
|
||||
*/
|
||||
def LoadZonePhysicalSpawnPoint(zone_id : String, pos : Vector3, ori : Vector3, respawnTime : Long) : Unit = {
|
||||
log.info(s"Load in zone $zone_id at position $pos")
|
||||
log.info(s"Load in zone $zone_id at position $pos in $respawnTime seconds")
|
||||
respawnTimer.cancel
|
||||
reviveTimer.cancel
|
||||
val backpack = player.isBackpack
|
||||
|
|
@ -7940,7 +7967,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
else {
|
||||
LoadZoneCommonTransferActivity()
|
||||
val original = player
|
||||
if(tplayer.isBackpack) {
|
||||
if(player.isBackpack) {
|
||||
//unregister avatar locker + GiveWorld
|
||||
player = tplayer
|
||||
(taskResolver, TaskBeforeZoneChange(GUIDTask.UnregisterLocker(original.Locker)(continent.GUID), zone_id))
|
||||
|
|
@ -8381,7 +8408,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
*/
|
||||
def BeforeUnloadVehicle(vehicle : Vehicle) : Unit = {
|
||||
vehicle.Definition match {
|
||||
case GlobalDefinitions.ams if vehicle.Faction == player.Faction =>
|
||||
log.info("BeforeUnload: cleaning up after a mobile spawn vehicle ...")
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.UpdateAmsSpawnPoint(continent))
|
||||
None
|
||||
case GlobalDefinitions.router =>
|
||||
//this may repeat for multiple players on the same continent but that's okay(?)
|
||||
log.info("BeforeUnload: cleaning up after a router ...")
|
||||
(vehicle.Utility(UtilityType.internal_router_telepad_deployable) match {
|
||||
case Some(util : Utility.InternalTelepad) =>
|
||||
|
|
@ -8566,7 +8598,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
/**
|
||||
* Given an origin and a destination, determine how long the process of traveling should take in reconstruction time.
|
||||
* For most destinations, the unit of receiving ("spawn point") determines the reconstruction time.
|
||||
* In a special consideration, travel from any sanctuary or sanctuary-special zone should be as immediate as zone loading.
|
||||
* In a special consideration, travel to any sanctuary or sanctuary-special zone should be as immediate as zone loading.
|
||||
* @param toZoneId the zone where the target is headed
|
||||
* @param toSpawnPoint the unit the target is using as a destination
|
||||
* @param fromZoneId the zone where the target current is located
|
||||
|
|
@ -8574,12 +8606,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
*/
|
||||
def CountSpawnDelay(toZoneId : String, toSpawnPoint : SpawnPoint, fromZoneId : String) : Long = {
|
||||
val sanctuaryZoneId = Zones.SanctuaryZoneId(player.Faction)
|
||||
if(sanctuaryZoneId.equals(fromZoneId)) { //TODO includes traveing zones
|
||||
if(sanctuaryZoneId.equals(toZoneId)) { //to sanctuary
|
||||
0L
|
||||
}
|
||||
else if(sanctuaryZoneId.equals(toZoneId)) {
|
||||
10L
|
||||
}
|
||||
else if(!player.isAlive) {
|
||||
toSpawnPoint.Definition.Delay //TODO +cumulative death penalty
|
||||
}
|
||||
|
|
@ -8601,8 +8630,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
.sortBy(tube => Vector3.DistanceSquared(tube.Position, player.Position))
|
||||
.headOption match {
|
||||
case Some(tube) =>
|
||||
log.info("DrawCurrentAmsSpawnPoint - new @ams spawn point drawn")
|
||||
sendResponse(BindPlayerMessage(BindStatus.Available, "@ams", true, false, SpawnGroup.AMS, continent.Number, 5, tube.Position))
|
||||
case None =>
|
||||
log.info("DrawCurrentAmsSpawnPoint - no @ams spawn point drawn")
|
||||
sendResponse(BindPlayerMessage(BindStatus.Unavailable, "@ams", false, false, SpawnGroup.AMS, continent.Number, 0, Vector3.Zero))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,16 @@ import net.psforever.objects.zones.Zone
|
|||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
object Zones {
|
||||
val z1 = new Zone("z1", Maps.map1, 1)
|
||||
val z1 = new Zone("z1", Maps.map1, 1) {
|
||||
override def Init(implicit context : ActorContext) : Unit = {
|
||||
super.Init(context)
|
||||
|
||||
BuildingByMapId(1).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR
|
||||
BuildingByMapId(2).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR
|
||||
BuildingByMapId(3).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR
|
||||
BuildingByMapId(4).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.TR
|
||||
}
|
||||
}
|
||||
|
||||
val z2 = new Zone("z2", Maps.map2, 2)
|
||||
|
||||
|
|
@ -101,10 +110,10 @@ object Zones {
|
|||
}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
BuildingByMapId(2).get.Faction = PlanetSideEmpire.VS
|
||||
BuildingByMapId(10).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
BuildingByMapId(11).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
BuildingByMapId(12).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
BuildingByMapId(13).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
BuildingByMapId(10).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS
|
||||
BuildingByMapId(11).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS
|
||||
BuildingByMapId(12).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS
|
||||
BuildingByMapId(13).get.asInstanceOf[WarpGate].BroadcastFor = PlanetSideEmpire.VS
|
||||
BuildingByMapId(48).get.Faction = PlanetSideEmpire.VS
|
||||
BuildingByMapId(49).get.Faction = PlanetSideEmpire.VS
|
||||
BuildingByMapId(18657).get.asInstanceOf[WarpGate].Active = false
|
||||
|
|
@ -135,6 +144,9 @@ object Zones {
|
|||
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
Buildings.values.foreach { _.Faction = PlanetSideEmpire.TR }
|
||||
BuildingByMapId(1).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
BuildingByMapId(2).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
BuildingByMapId(3).get.asInstanceOf[WarpGate].Broadcast = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue