diff --git a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
index d52d183b..924c14ce 100644
--- a/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
+++ b/common/src/main/scala/net/psforever/objects/GlobalDefinitions.scala
@@ -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
diff --git a/common/src/main/scala/net/psforever/objects/serverobject/structures/WarpGate.scala b/common/src/main/scala/net/psforever/objects/serverobject/structures/WarpGate.scala
index eca8a29f..25a2255d 100644
--- a/common/src/main/scala/net/psforever/objects/serverobject/structures/WarpGate.scala
+++ b/common/src/main/scala/net/psforever/objects/serverobject/structures/WarpGate.scala
@@ -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
diff --git a/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala b/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala
index 89dac67f..ab685621 100644
--- a/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala
+++ b/common/src/main/scala/net/psforever/packet/game/BroadcastWarpgateUpdateMessage.scala
@@ -6,28 +6,26 @@ import scodec.Codec
import scodec.codecs._
/**
- * Promotes a warpgate's "broadcast" functionality.
+ * Dispatched by the server to promote a warp gate's broadcast functionality.
*
- * 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.
- *
- * Exploration:
- * 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]
}
diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala
index 61b7f6b0..2873338c 100644
--- a/pslogin/src/main/scala/WorldSessionActor.scala
+++ b/pslogin/src/main/scala/WorldSessionActor.scala
@@ -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))
}
}
diff --git a/pslogin/src/main/scala/Zones.scala b/pslogin/src/main/scala/Zones.scala
index 3b959866..15dc2b0a 100644
--- a/pslogin/src/main/scala/Zones.scala
+++ b/pslogin/src/main/scala/Zones.scala
@@ -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
}
}