diff --git a/common/src/test/scala/objects/terminal/MedicalTerminalTest.scala b/common/src/test/scala/objects/terminal/MedicalTerminalTest.scala
index 89efb86f..86b39fe3 100644
--- a/common/src/test/scala/objects/terminal/MedicalTerminalTest.scala
+++ b/common/src/test/scala/objects/terminal/MedicalTerminalTest.scala
@@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.terminals.{MedicalTerminalDefinition, ProximityTerminal, Terminal}
-import net.psforever.objects.{GlobalDefinitions, Player}
+import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType}
import org.specs2.mutable.Specification
@@ -64,14 +64,14 @@ class MedicalTerminalTest extends Specification {
ProximityTerminal(GlobalDefinitions.medical_terminal).Actor mustEqual ActorRef.noSender
}
- "can add a a player to a list of users" in {
+ "can add a player to a list of users" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.NumberUsers mustEqual 0
terminal.AddUser(PlanetSideGUID(10))
terminal.NumberUsers mustEqual 1
}
- "can remove a a player to a list of users" in {
+ "can remove a player from a list of users" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
terminal.AddUser(PlanetSideGUID(10))
terminal.NumberUsers mustEqual 1
@@ -81,7 +81,7 @@ class MedicalTerminalTest extends Specification {
"player can not interact with the proximity terminal normally (buy)" in {
val terminal = ProximityTerminal(GlobalDefinitions.medical_terminal)
- val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
+ val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
diff --git a/common/src/test/scala/objects/terminal/ProximityTerminalControlTest.scala b/common/src/test/scala/objects/terminal/ProximityTerminalControlTest.scala
index d288ff11..f817be6a 100644
--- a/common/src/test/scala/objects/terminal/ProximityTerminalControlTest.scala
+++ b/common/src/test/scala/objects/terminal/ProximityTerminalControlTest.scala
@@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.{ActorSystem, Props}
import net.psforever.objects.serverobject.CommonMessages
-import net.psforever.objects.{GlobalDefinitions, Player}
+import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals._
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{CharacterGender, PlanetSideEmpire}
@@ -35,7 +35,7 @@ class MedicalTerminalControl1Test extends ActorTest() {
"ProximityTerminalControl sends a message to the first new user only" in {
val (player, terminal) = ProximityTerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
player.GUID = PlanetSideGUID(10)
- val player2 = Player("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
+ val player2 = Player(Avatar("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
player2.GUID = PlanetSideGUID(11)
terminal.Actor ! CommonMessages.Use(player)
@@ -58,7 +58,7 @@ class MedicalTerminalControl2Test extends ActorTest() {
"ProximityTerminalControl sends a message to the last user only" in {
val (player, terminal) : (Player, ProximityTerminal) = ProximityTerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
player.GUID = PlanetSideGUID(10)
- val player2 = Player("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
+ val player2 = Player(Avatar("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
player2.GUID = PlanetSideGUID(11)
terminal.Actor ! CommonMessages.Use(player)
@@ -87,7 +87,7 @@ class MedicalTerminalControl3Test extends ActorTest() {
"ProximityTerminalControl sends a message to the last user only (confirmation of test #2)" in {
val (player, terminal) : (Player, ProximityTerminal) = ProximityTerminalControlTest.SetUpAgents(GlobalDefinitions.medical_terminal, PlanetSideEmpire.TR)
player.GUID = PlanetSideGUID(10)
- val player2 = Player("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
+ val player2 = Player(Avatar("someothertest", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
player2.GUID = PlanetSideGUID(11)
terminal.Actor ! CommonMessages.Use(player)
@@ -116,6 +116,6 @@ object ProximityTerminalControlTest {
def SetUpAgents(tdef : MedicalTerminalDefinition, faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, ProximityTerminal) = {
val terminal = ProximityTerminal(tdef)
terminal.Actor = system.actorOf(Props(classOf[ProximityTerminalControl], terminal), "test-term")
- (Player("test", faction, CharacterGender.Male, 0, 0), terminal)
+ (Player(Avatar("test", faction, CharacterGender.Male, 0, 0)), terminal)
}
}
diff --git a/pslogin/src/main/scala/Maps.scala b/pslogin/src/main/scala/Maps.scala
index 2bdf50e8..8b9351b1 100644
--- a/pslogin/src/main/scala/Maps.scala
+++ b/pslogin/src/main/scala/Maps.scala
@@ -100,6 +100,8 @@ object Maps {
LocalObject(1186, Locker.Constructor)
LocalObject(1187, Locker.Constructor)
LocalObject(1188, Locker.Constructor)
+ LocalObject(1492, ProximityTerminal.Constructor(medical_terminal)) //lobby
+ LocalObject(1494, ProximityTerminal.Constructor(medical_terminal)) //kitchen
LocalObject(1564, Terminal.Constructor(order_terminal))
LocalObject(1568, Terminal.Constructor(order_terminal))
LocalObject(1569, Terminal.Constructor(order_terminal))
@@ -200,6 +202,8 @@ object Maps {
ObjectToBuilding(1186, 2)
ObjectToBuilding(1187, 2)
ObjectToBuilding(1188, 2)
+ ObjectToBuilding(1492, 2)
+ ObjectToBuilding(1494, 2)
ObjectToBuilding(1564, 2)
ObjectToBuilding(1568, 2)
ObjectToBuilding(1569, 2)
diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala
index b2e4b6bf..46fe9aef 100644
--- a/pslogin/src/main/scala/WorldSessionActor.scala
+++ b/pslogin/src/main/scala/WorldSessionActor.scala
@@ -85,6 +85,18 @@ class WorldSessionActor extends Actor with MDCContextAware {
LivePlayerList.Remove(sessionId)
if(player != null && player.HasGUID) {
val player_guid = player.GUID
+ //proximity vehicle terminals must be considered too
+ delayedProximityTerminalResets.foreach({case(_, task) => task.cancel})
+ usingProximityTerminal.foreach(term_guid => {
+ continent.GUID(term_guid) match {
+ case Some(obj : ProximityTerminal) =>
+ if(obj.NumberUsers > 0 && obj.RemoveUser(player_guid) == 0) { //refer to ProximityTerminalControl when modernizng
+ localService ! LocalServiceMessage(continent.Id, LocalAction.ProximityTerminalEffect(player_guid, term_guid, false))
+ }
+ case _ => ;
+ }
+ })
+
if(player.isAlive) {
//actually being alive or manually deconstructing
player.VehicleSeated match {
@@ -93,17 +105,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
case None => ;
}
- delayedProximityTerminalResets.foreach({case(_, task) => task.cancel})
- usingProximityTerminal.foreach(term_guid => {
- continent.GUID(term_guid) match {
- case Some(obj : ProximityTerminal) =>
- if(obj.RemoveUser(player_guid) == 0) { //manual; see ProximityTerminalControl
- localService ! LocalServiceMessage(continent.Id, LocalAction.ProximityTerminalEffect(player_guid, term_guid, false))
- }
- case _ => ;
- }
- })
-
continent.Population ! Zone.Population.Release(avatar)
player.Position = Vector3.Zero //save character before doing this
avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.ObjectDelete(player_guid, player_guid))
@@ -989,7 +990,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
localService ! LocalServiceMessage(continent.Id, LocalAction.ProximityTerminalEffect(player_guid, term_guid, false))
case Terminal.NoDeal() =>
- log.warn(s"$tplayer made a request but the terminal rejected the order $msg")
+ val order : String = if(msg == null) {
+ s"order $msg"
+ }
+ else {
+ "missing order"
+ }
+ log.warn(s"${tplayer.Name} made a request but the terminal rejected the $order")
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, msg.transaction_type, false))
}
@@ -2203,6 +2210,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(obj : SpawnTube) =>
//deconstruction
PlayerActionsToCancel()
+ CancelAllProximityUnits()
player.Release
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, player.Faction, true))
continent.Population ! Zone.Population.Release(avatar)
@@ -2228,7 +2236,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
SelectProximityUnit(obj)
}
else {
- //obj.Actor ! ProximityTerminal.Use(player)
StartUsingProximityUnit(obj)
}
case Some(obj) => ;
@@ -3462,7 +3469,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(HackMessage(3, PlanetSideGUID(building.ModelId), PlanetSideGUID(0), 0, 3212836864L, HackState.HackCleared, 8))
})
}
-
+
/**
* The player has lost all his vitality and must be killed.
*
@@ -3493,6 +3500,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player_guid, 29, 1))
}
PlayerActionsToCancel()
+ CancelAllProximityUnits()
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
@@ -3536,7 +3544,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
if(speed > 1) {
sendResponse(ChatMsg(ChatMessageType.CMT_SPEED, false, "", "1.000", None))
- speed = 1f
+ speed = 1f
}
}
@@ -3548,6 +3556,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
def AvatarCreate() : Unit = {
player.Spawn
player.Health = 50 //TODO temp
+ player.Armor = 25
val packet = player.Definition.Packet
val dcdata = packet.DetailedConstructorData(player).get
sendResponse(ObjectCreateDetailedMessage(ObjectClass.avatar, player.GUID, dcdata))
@@ -3671,30 +3680,32 @@ class WorldSessionActor extends Actor with MDCContextAware {
def StartUsingProximityUnit(terminal : ProximityTerminal) : Unit = {
val term_guid = terminal.GUID
if(!usingProximityTerminal.contains(term_guid)) {
+ usingProximityTerminal += term_guid
terminal.Definition match {
case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal =>
usingMedicalTerminal = Some(term_guid)
- case _ => ;
+ case _ =>
+ SetDelayedProximityUnitReset(terminal)
}
- usingProximityTerminal += term_guid
- SetDelayedProximityUnitReset(terminal)
terminal.Actor ! CommonMessages.Use(player)
}
}
/**
* Stop using a proximity-base service.
- * Special note is warranted in the case of a medical terminal or an advanced medical terminal.
+ * Special note is warranted when determining the identity of the proximity terminal.
+ * Medical terminals of both varieties can be cancelled by movement.
+ * Other sorts of proximity-based units are put on a timer.
* @param terminal the proximity-based unit
*/
def StopUsingProximityUnit(terminal : ProximityTerminal) : Unit = {
val term_guid = terminal.GUID
if(usingProximityTerminal.contains(term_guid)) {
+ usingProximityTerminal -= term_guid
+ ClearDelayedProximityUnitReset(term_guid)
if(usingMedicalTerminal.contains(term_guid)) {
usingMedicalTerminal = None
}
- usingProximityTerminal -= term_guid
- ClearDelayedProximityUnitReset(term_guid)
terminal.Actor ! CommonMessages.Unuse(player)
}
}
@@ -3729,18 +3740,35 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
}
+ /**
+ * Cease all current interactions with proximity-based units.
+ * Pair with `PlayerActionsToCancel`, except when logging out (stopping).
+ * This operations may invoke callback messages.
+ * @see `postStop`
+ * `Terminal.StopProximityEffects`
+ */
+ def CancelAllProximityUnits() : Unit = {
+ delayedProximityTerminalResets.foreach({case(term_guid, task) =>
+ task.cancel
+ delayedProximityTerminalResets -= term_guid
+ })
+ usingProximityTerminal.foreach(term_guid => {
+ StopUsingProximityUnit(continent.GUID(term_guid).get.asInstanceOf[ProximityTerminal])
+ })
+ }
+
/**
* Determine which functionality to pursue, by being given a generic proximity-functional unit
* and determinig which kind of unit is being utilized.
* @param terminal the proximity-based unit
*/
def SelectProximityUnit(terminal : ProximityTerminal) : Unit = {
- SetDelayedProximityUnitReset(terminal)
terminal.Definition match {
case GlobalDefinitions.adv_med_terminal | GlobalDefinitions.medical_terminal =>
ProximityMedicalTerminal(terminal)
case GlobalDefinitions.crystals_health_a | GlobalDefinitions.crystals_health_b =>
+ SetDelayedProximityUnitReset(terminal)
ProximityHealCrystal(terminal)
case _ => ;