mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-20 02:54:46 +00:00
commit
fb1c365bc2
|
|
@ -9,6 +9,8 @@ import net.psforever.objects.equipment._
|
|||
import net.psforever.objects.inventory.InventoryTile
|
||||
import net.psforever.objects.serverobject.implantmech.ImplantTerminalMechDefinition
|
||||
import net.psforever.objects.serverobject.locks.IFFLockDefinition
|
||||
import net.psforever.objects.serverobject.mblocker.LockerDefinition
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPadDefinition
|
||||
import net.psforever.objects.serverobject.terminals._
|
||||
import net.psforever.objects.vehicles.SeatArmorRestriction
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
|
@ -498,9 +500,9 @@ object GlobalDefinitions {
|
|||
|
||||
val vehicle_terminal_combined = new VehicleTerminalCombinedDefinition
|
||||
|
||||
val spawn_pad = new ObjectDefinition(800) { Name = "spawn_pad" }
|
||||
val spawn_pad = new VehicleSpawnPadDefinition
|
||||
|
||||
val mb_locker = new ObjectDefinition(524) { Name = "mb_locker" }
|
||||
val mb_locker = new LockerDefinition
|
||||
|
||||
val lock_external = new IFFLockDefinition
|
||||
|
||||
|
|
@ -827,10 +829,10 @@ object GlobalDefinitions {
|
|||
bullet_9mm_AP.Capacity = 50
|
||||
bullet_9mm_AP.Tile = InventoryTile.Tile33
|
||||
|
||||
shotgun_shell.Capacity = 32
|
||||
shotgun_shell.Capacity = 16
|
||||
shotgun_shell.Tile = InventoryTile.Tile33
|
||||
|
||||
shotgun_shell_AP.Capacity = 32
|
||||
shotgun_shell_AP.Capacity = 16
|
||||
shotgun_shell_AP.Tile = InventoryTile.Tile33
|
||||
|
||||
energy_cell.Capacity = 50
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ import net.psforever.packet.game.PlanetSideGUID
|
|||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
/**
|
||||
* The companion of a `Locker` that is carried with a player
|
||||
* masquerading as their sixth `EquipmentSlot` object and a sub-inventory item.
|
||||
* The `Player` class refers to it as the "fifth slot" as its permanent slot number is encoded as `0x85`.
|
||||
* The inventory of this object is accessed using a game world `Locker` object (`mb_locker`).
|
||||
*/
|
||||
class LockerContainer extends Equipment with Container {
|
||||
private val inventory = GridInventory(30, 20)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package net.psforever.objects
|
|||
import net.psforever.objects.definition.{AvatarDefinition, ImplantDefinition}
|
||||
import net.psforever.objects.equipment.{Equipment, EquipmentSize}
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types._
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ class Player(private val name : String,
|
|||
private val sex : CharacterGender.Value,
|
||||
private val head : Int,
|
||||
private val voice : Int
|
||||
) extends PlanetSideGameObject with Container {
|
||||
) extends PlanetSideGameObject with FactionAffinity with Container {
|
||||
private var alive : Boolean = false
|
||||
private var backpack : Boolean = false
|
||||
private var health : Int = 0
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ package net.psforever.objects
|
|||
import net.psforever.objects.definition.VehicleDefinition
|
||||
import net.psforever.objects.equipment.{Equipment, EquipmentSize}
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem, InventoryTile}
|
||||
import net.psforever.objects.mount.Mountable
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.vehicles.{AccessPermissionGroup, Seat, Utility, VehicleLockState}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate.DriveState
|
||||
|
|
@ -27,7 +28,10 @@ import scala.collection.mutable
|
|||
* stores and unloads pertinent information about the `Vehicle`'s configuration;
|
||||
* used in the initialization process (`loadVehicleDefinition`)
|
||||
*/
|
||||
class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServerObject with Mountable with Container {
|
||||
class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServerObject
|
||||
with FactionAffinity
|
||||
with Mountable
|
||||
with Container {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.TR
|
||||
private var owner : Option[PlanetSideGUID] = None
|
||||
private var health : Int = 1
|
||||
|
|
@ -63,7 +67,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
this.faction
|
||||
}
|
||||
|
||||
def Faction_=(faction : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
|
||||
override def Faction_=(faction : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
|
||||
this.faction = faction
|
||||
faction
|
||||
}
|
||||
|
|
@ -465,11 +469,17 @@ object Vehicle {
|
|||
|
||||
/**
|
||||
* The `Vehicle` will become unresponsive to player activity.
|
||||
* Usually, it does this to await deconstruction and clean-up
|
||||
* Usually, it does this to await deconstruction and clean-up.
|
||||
* @see `VehicleControl`
|
||||
*/
|
||||
final case class PrepareForDeletion()
|
||||
|
||||
/**
|
||||
* The `Vehicle` will resume previous unresponsiveness to player activity.
|
||||
* @see `VehicleControl`
|
||||
*/
|
||||
final case class Reactivate()
|
||||
|
||||
/**
|
||||
* Overloaded constructor.
|
||||
* @param vehicleDef the vehicle's definition entry
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.mount
|
||||
|
||||
import akka.actor.Actor
|
||||
|
||||
/**
|
||||
* The logic governing `Mountable` objects that use the `TryMount` message.
|
||||
* This is a mix-in trait for combining the `Receive` logic.
|
||||
* @see `Seat`
|
||||
* @see `Mountable`
|
||||
*/
|
||||
trait MountableBehavior {
|
||||
this : Actor =>
|
||||
|
||||
def MountableObject : Mountable
|
||||
|
||||
val mountableBehavior : Receive = {
|
||||
case Mountable.TryMount(user, seat_num) =>
|
||||
MountableObject.Seat(seat_num) match {
|
||||
case Some(seat) =>
|
||||
if((seat.Occupant = user).contains(user)) {
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanMount(MountableObject, seat_num))
|
||||
}
|
||||
else {
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanNotMount(MountableObject, seat_num))
|
||||
}
|
||||
case None =>
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanNotMount(MountableObject, seat_num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,13 @@ package net.psforever.objects.serverobject
|
|||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.PlanetSideGameObject
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
|
||||
/**
|
||||
* An object layered on top of the standard game object class that maintains an internal `ActorRef`.
|
||||
* A measure of synchronization can be managed using this `Actor`.
|
||||
*/
|
||||
abstract class PlanetSideServerObject extends PlanetSideGameObject {
|
||||
abstract class PlanetSideServerObject extends PlanetSideGameObject with FactionAffinity {
|
||||
private var actor = ActorRef.noSender
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.affinity
|
||||
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* Keep track of the allegiance of the object in terms of its association to a `PlanetSideEmpire` value.
|
||||
*/
|
||||
trait FactionAffinity {
|
||||
def Faction : PlanetSideEmpire.Value
|
||||
|
||||
def Faction_=(fac : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = Faction
|
||||
}
|
||||
|
||||
object FactionAffinity {
|
||||
/**
|
||||
* Message that makes the server object transmit IFF feedback.
|
||||
* @see AssertFactionAffinity
|
||||
*/
|
||||
final case class ConfirmFactionAffinity()
|
||||
/**
|
||||
* Message that makes the server object change allegiance to the specified faction value.
|
||||
* Transmit IFF feedback when done.
|
||||
* @param faction the allegiance to which to change
|
||||
*/
|
||||
final case class ConvertFactionAffinity(faction : PlanetSideEmpire.Value)
|
||||
/**
|
||||
* Message that responds to an IFF feedback request.
|
||||
* Transmit IFF feedback when done.
|
||||
* @see ConfirmFactionAffinity
|
||||
* @param obj the governed object
|
||||
* @param faction the allegiance to which the object belongs
|
||||
*/
|
||||
final case class AssertFactionAffinity(obj : FactionAffinity, faction : PlanetSideEmpire.Value)
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.affinity
|
||||
|
||||
import akka.actor.Actor
|
||||
|
||||
object FactionAffinityBehavior {
|
||||
|
||||
/**
|
||||
* A `trait` for inheritance of common implementable methods.
|
||||
*/
|
||||
sealed trait BasicAffinity {
|
||||
def FactionObject : FactionAffinity
|
||||
}
|
||||
|
||||
/**
|
||||
* The logic governing `FactionAffinity` objects that use the `ConvertFactionAffinity` message.
|
||||
* This is a mix-in trait for combining with existing `Receive` logic.
|
||||
*/
|
||||
trait Convert extends BasicAffinity {
|
||||
this : Actor =>
|
||||
|
||||
val convertBehavior : Receive = {
|
||||
case FactionAffinity.ConvertFactionAffinity(faction) =>
|
||||
FactionObject.Faction = faction
|
||||
sender ! FactionAffinity.AssertFactionAffinity(FactionObject, faction)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The logic governing `FactionAffinity` objects that use the `ConfirmFactionAffinity` message.
|
||||
* A case exists to catch `AssertFactionAffinity` messages for the same ends though they should not be used this way.
|
||||
* This is a mix-in trait for combining with existing `Receive` logic.
|
||||
*/
|
||||
trait Check extends BasicAffinity {
|
||||
this : Actor =>
|
||||
|
||||
val checkBehavior : Receive = {
|
||||
case FactionAffinity.ConfirmFactionAffinity() | FactionAffinity.AssertFactionAffinity(_, _) =>
|
||||
sender ! FactionAffinity.AssertFactionAffinity(FactionObject, FactionObject.Faction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.doors
|
||||
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* A temporary class to represent "facilities" and "structures."
|
||||
* @param id the map id of the base
|
||||
*/
|
||||
class Base(private val id : Int) {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
|
||||
def Id : Int = id
|
||||
|
||||
def Faction : PlanetSideEmpire.Value = faction
|
||||
|
||||
def Faction_=(emp : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
|
||||
faction = emp
|
||||
Faction
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.doors
|
||||
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.UseItemMessage
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ import net.psforever.types.Vector3
|
|||
* A structure-owned server object that is a "door" that can open and can close.
|
||||
* @param ddef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class Door(private val ddef : DoorDefinition) extends PlanetSideServerObject {
|
||||
class Door(private val ddef : DoorDefinition) extends Amenity {
|
||||
private var openState : Option[Player] = None
|
||||
/** a vector in the direction of the "outside" of a room;
|
||||
* typically, any locking utility is on that same "outside" */
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@
|
|||
package net.psforever.objects.serverobject.doors
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Door`.
|
||||
* @param door the `Door` object being governed
|
||||
*/
|
||||
class DoorControl(door : Door) extends Actor {
|
||||
def receive : Receive = {
|
||||
class DoorControl(door : Door) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = door
|
||||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case Door.Use(player, msg) =>
|
||||
sender ! Door.DoorMessage(player, msg, door.Use(player, msg))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package net.psforever.objects.serverobject.implantmech
|
|||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.mount.Mountable
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.vehicles.Seat
|
||||
|
||||
/**
|
||||
|
|
@ -12,7 +12,7 @@ import net.psforever.objects.vehicles.Seat
|
|||
* For the most part, it merely implements the support data structures indicated by `Mountable`.
|
||||
* @param idef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class ImplantTerminalMech(private val idef : ImplantTerminalMechDefinition) extends PlanetSideServerObject with Mountable {
|
||||
class ImplantTerminalMech(private val idef : ImplantTerminalMechDefinition) extends Amenity with Mountable {
|
||||
private val seats : Map[Int, Seat] = Map( 0 -> new Seat(idef.Seats(0)) )
|
||||
|
||||
def Seats : Map[Int, Seat] = seats
|
||||
|
|
|
|||
|
|
@ -2,16 +2,23 @@
|
|||
package net.psforever.objects.serverobject.implantmech
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.mount.MountableBehavior
|
||||
import net.psforever.objects.serverobject.mount.MountableBehavior
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `ImplantTerminalMech`.
|
||||
* @param mech the "mech" object being governed
|
||||
*/
|
||||
class ImplantTerminalMechControl(mech : ImplantTerminalMech) extends Actor with MountableBehavior {
|
||||
override def MountableObject = mech
|
||||
class ImplantTerminalMechControl(mech : ImplantTerminalMech) extends Actor with FactionAffinityBehavior.Check
|
||||
with MountableBehavior.Mount with MountableBehavior.Dismount {
|
||||
def MountableObject = mech //do not add type!
|
||||
|
||||
def receive : Receive = mountableBehavior.orElse {
|
||||
case _ => ;
|
||||
}
|
||||
def FactionObject : FactionAffinity = mech
|
||||
|
||||
def receive : Receive = checkBehavior
|
||||
.orElse(mountBehavior)
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.objects.serverobject.locks
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ import net.psforever.types.Vector3
|
|||
* The `IFFLock` is ideally associated with a server map object - a `Door` - to which it acts as a gatekeeper.
|
||||
* @param idef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class IFFLock(private val idef : IFFLockDefinition) extends PlanetSideServerObject {
|
||||
class IFFLock(private val idef : IFFLockDefinition) extends Amenity {
|
||||
/**
|
||||
* An entry that maintains a reference to the `Player`, and the player's GUID and location when the message was received.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,14 +3,17 @@ package net.psforever.objects.serverobject.locks
|
|||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `IFFLock`.
|
||||
* @param lock the `IFFLock` object being governed
|
||||
* @see `CommonMessages`
|
||||
*/
|
||||
class IFFLockControl(lock : IFFLock) extends Actor {
|
||||
def receive : Receive = {
|
||||
class IFFLockControl(lock : IFFLock) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = lock
|
||||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case CommonMessages.Hack(player) =>
|
||||
lock.HackedBy = player
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.mblocker
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import akka.actor.{ActorContext, Props}
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
|
||||
class Locker extends PlanetSideServerObject {
|
||||
def Definition : ObjectDefinition = GlobalDefinitions.mb_locker
|
||||
class Locker extends Amenity {
|
||||
def Definition : LockerDefinition = GlobalDefinitions.mb_locker
|
||||
}
|
||||
|
||||
object Locker {
|
||||
/**
|
||||
* Overloaded constructor.
|
||||
* @return a `VehicleSpawnPad` object
|
||||
* @return the `Locker` object
|
||||
*/
|
||||
def apply() : Locker = {
|
||||
new Locker()
|
||||
|
|
@ -28,6 +27,7 @@ object Locker {
|
|||
*/
|
||||
def Constructor(id : Int, context : ActorContext) : Locker = {
|
||||
val obj = Locker()
|
||||
obj.Actor = context.actorOf(Props(classOf[LockerControl], obj), s"${obj.Definition.Name}_$id")
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.mblocker
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Locker`.
|
||||
* @param locker the `Locker` object being governed
|
||||
*/
|
||||
class LockerControl(locker : Locker) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = locker
|
||||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.mblocker
|
||||
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
|
||||
/**
|
||||
* The definition for any `Locker`.
|
||||
* Object Id 524.
|
||||
*/
|
||||
class LockerDefinition extends ObjectDefinition(524) {
|
||||
Name = "mb_locker"
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.mount
|
||||
package net.psforever.objects.serverobject.mount
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.Player
|
||||
|
|
@ -62,6 +62,8 @@ object Mountable {
|
|||
*/
|
||||
final case class TryMount(player : Player, seat_num : Int)
|
||||
|
||||
final case class TryDismount(player : Player, seat_num : Int)
|
||||
|
||||
/**
|
||||
* A basic `Trait` connecting all of the actionable `Mountable` response messages.
|
||||
*/
|
||||
|
|
@ -89,4 +91,19 @@ object Mountable {
|
|||
* @param seat_num the seat index
|
||||
*/
|
||||
final case class CanNotMount(obj : Mountable, seat_num : Int) extends Exchange
|
||||
|
||||
/**
|
||||
* Message sent in response to the player succeeding to disembark a `Mountable` object.
|
||||
* The player was previously seated at the given index.
|
||||
* @param obj the `Mountable` object
|
||||
* @param seat_num the seat index
|
||||
*/
|
||||
final case class CanDismount(obj : Mountable, seat_num : Int) extends Exchange
|
||||
/**
|
||||
* Message sent in response to the player failing to disembark a `Mountable` object.
|
||||
* The player is still seated at the given index.
|
||||
* @param obj the `Mountable` object
|
||||
* @param seat_num the seat index
|
||||
*/
|
||||
final case class CanNotDismount(obj : Mountable, seat_num : Int) extends Exchange
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.mount
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.entity.{Identifiable, WorldEntity}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
object MountableBehavior {
|
||||
/**
|
||||
* The logic governing `Mountable` objects that use the `TryMount` message.
|
||||
* This is a mix-in trait for combining with existing `Receive` logic.
|
||||
* @see `Seat`
|
||||
* @see `Mountable`
|
||||
*/
|
||||
trait Mount {
|
||||
this : Actor =>
|
||||
|
||||
def MountableObject : Mountable with Identifiable with WorldEntity with FactionAffinity
|
||||
|
||||
val mountBehavior : Receive = {
|
||||
case Mountable.TryMount(user, seat_num) =>
|
||||
val obj = MountableObject
|
||||
obj.Seat(seat_num) match {
|
||||
case Some(seat) =>
|
||||
if(user.Faction == obj.Faction && (seat.Occupant = user).contains(user)) {
|
||||
user.VehicleSeated = obj.GUID
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanMount(obj, seat_num))
|
||||
}
|
||||
else {
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanNotMount(obj, seat_num))
|
||||
}
|
||||
case None =>
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanNotMount(obj, seat_num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The logic governing `Mountable` objects that use the `TryDismount` message.
|
||||
* This is a mix-in trait for combining with existing `Receive` logic.
|
||||
* @see `Seat`
|
||||
* @see `Mountable`
|
||||
*/
|
||||
trait Dismount {
|
||||
this : Actor =>
|
||||
|
||||
def MountableObject : Mountable with Identifiable with WorldEntity with FactionAffinity
|
||||
|
||||
val dismountBehavior : Receive = {
|
||||
case Mountable.TryDismount(user, seat_num) =>
|
||||
val obj = MountableObject
|
||||
obj.Seat(seat_num) match {
|
||||
case Some(seat) =>
|
||||
if(seat.Bailable || obj.Velocity.isEmpty || Vector3.MagnitudeSquared(obj.Velocity.get).toInt == 0) {
|
||||
seat.Occupant = None
|
||||
user.VehicleSeated = None
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanDismount(obj, seat_num))
|
||||
}
|
||||
else {
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanNotDismount(obj, seat_num))
|
||||
}
|
||||
case None =>
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanNotDismount(obj, seat_num))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.objects.serverobject.pad
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Cancellable}
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.{DefaultCancellable, Player, Vehicle}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ import scala.concurrent.duration._
|
|||
* 3. a callback location for sending messages.
|
||||
* @param pad the `VehicleSpawnPad` object being governed
|
||||
*/
|
||||
class VehicleSpawnControl(pad : VehicleSpawnPad) extends Actor {
|
||||
class VehicleSpawnControl(pad : VehicleSpawnPad) extends Actor with FactionAffinityBehavior.Check {
|
||||
/** an executor for progressing a vehicle order through the normal spawning logic */
|
||||
private var process : Cancellable = DefaultCancellable.obj
|
||||
/** a list of vehicle orders that have been submitted for this spawn pad */
|
||||
|
|
@ -41,8 +42,9 @@ class VehicleSpawnControl(pad : VehicleSpawnPad) extends Actor {
|
|||
private[this] val log = org.log4s.getLogger
|
||||
private[this] def trace(msg : String) : Unit = log.trace(msg)
|
||||
|
||||
def FactionObject : FactionAffinity = pad
|
||||
|
||||
def receive : Receive = {
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case VehicleSpawnPad.VehicleOrder(player, vehicle) =>
|
||||
trace(s"order from $player for $vehicle received")
|
||||
orders = orders :+ VehicleSpawnControl.OrderEntry(player, vehicle, sender)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
package net.psforever.objects.serverobject.pad
|
||||
|
||||
import net.psforever.objects.{Player, Vehicle}
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
|
||||
/**
|
||||
|
|
@ -16,8 +15,8 @@ import net.psforever.packet.game.PlanetSideGUID
|
|||
* @param spDef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
* @see `VehicleSpawnControl`
|
||||
*/
|
||||
class VehicleSpawnPad(spDef : ObjectDefinition) extends PlanetSideServerObject {
|
||||
def Definition : ObjectDefinition = spDef
|
||||
class VehicleSpawnPad(spDef : VehicleSpawnPadDefinition) extends Amenity {
|
||||
def Definition : VehicleSpawnPadDefinition = spDef
|
||||
}
|
||||
|
||||
object VehicleSpawnPad {
|
||||
|
|
@ -83,7 +82,7 @@ object VehicleSpawnPad {
|
|||
* @param spDef the spawn pad's definition entry
|
||||
* @return a `VehicleSpawnPad` object
|
||||
*/
|
||||
def apply(spDef : ObjectDefinition) : VehicleSpawnPad = {
|
||||
def apply(spDef : VehicleSpawnPadDefinition) : VehicleSpawnPad = {
|
||||
new VehicleSpawnPad(spDef)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.pad
|
||||
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
|
||||
/**
|
||||
* The definition for any `VehicleSpawnPad`.
|
||||
* Object Id 800.
|
||||
*/
|
||||
class VehicleSpawnPadDefinition extends ObjectDefinition(800) {
|
||||
Name = "spawn_pad"
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* Amenities are elements of the game that belong to other elements of the game.<br>
|
||||
* <br>
|
||||
* Normal `PlanetSideServerObject` entities (server objects) tend to have properties that are completely internalized.
|
||||
* An `Amenity` is a server object that maintains a fixed association with another server object.
|
||||
* This association strips away at the internalization and redirects a reference to some properties somewhere else.
|
||||
* An `Amenity` object belongs to its `Owner` object;
|
||||
* the `Amenity` objects looks to its `Owner` object for some of its properties.
|
||||
* @see `FactionAffinity`
|
||||
*/
|
||||
abstract class Amenity extends PlanetSideServerObject {
|
||||
private var owner : PlanetSideServerObject = Building.NoBuilding
|
||||
|
||||
def Faction : PlanetSideEmpire.Value = Owner.Faction
|
||||
|
||||
/**
|
||||
* Reference the object that is in direct association with (is superior to) this one.
|
||||
* @return the object associated as this object's "owner"
|
||||
*/
|
||||
def Owner : PlanetSideServerObject = owner
|
||||
|
||||
/**
|
||||
* Set an object to have a direct association with (be superior to) this one.
|
||||
* @see `Amenity.AmenityTarget`
|
||||
* @param obj the object trying to become associated as this object's "owner"
|
||||
* @tparam T a validation of the type of object that can be an owner
|
||||
* @return the object associated as this object's "owner"
|
||||
*/
|
||||
def Owner_=[T : Amenity.AmenityTarget](obj : T) : PlanetSideServerObject = {
|
||||
owner = obj.asInstanceOf[PlanetSideServerObject]
|
||||
Owner
|
||||
}
|
||||
}
|
||||
|
||||
object Amenity {
|
||||
/**
|
||||
* A `trait` for validating the type of object that can be allowed to become an `Amenity` object's `Owner`.<br>
|
||||
* <br>
|
||||
* The `Owner` defaults to a type of `PlanetSideServerObject` in reference type;
|
||||
* but, that distinction is mainly to allow for a common ancestor with appropriate methods.
|
||||
* Only certain types of `PlanetSideServerObject` are formally allowed to be owners.
|
||||
* In execution, the `T` is the type of object that implicitly converts into an acceptable type of sub-object.
|
||||
* The companion object maintains the hardcoded conversions.
|
||||
* If such an implicit conversion does not exist, the assignment is unacceptable at compile time.
|
||||
* @tparam T the permitted type of object
|
||||
*/
|
||||
sealed trait AmenityTarget[T]
|
||||
|
||||
object AmenityTarget {
|
||||
import net.psforever.objects.Vehicle
|
||||
implicit object BuildingTarget extends AmenityTarget[Building] { }
|
||||
implicit object VehicleTarget extends AmenityTarget[Vehicle] { }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
class Building(private val id : Int, private val zone : Zone) extends PlanetSideServerObject {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
private var amenities : List[Amenity] = List.empty
|
||||
GUID = PlanetSideGUID(0)
|
||||
|
||||
def Id : Int = id
|
||||
|
||||
def Faction : PlanetSideEmpire.Value = faction
|
||||
|
||||
override def Faction_=(fac : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
|
||||
faction = fac
|
||||
Faction
|
||||
}
|
||||
|
||||
def Amenities : List[Amenity] = amenities
|
||||
|
||||
def Amenities_=(obj : Amenity) : List[Amenity] = {
|
||||
amenities = amenities :+ obj
|
||||
obj.Owner = this
|
||||
amenities
|
||||
}
|
||||
|
||||
def Zone : Zone = zone
|
||||
|
||||
def Definition: ObjectDefinition = Building.BuildingDefinition
|
||||
}
|
||||
|
||||
object Building {
|
||||
final val NoBuilding : Building = new Building(0, Zone.Nowhere) {
|
||||
override def Faction_=(faction : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
override def Amenities_=(obj : Amenity) : List[Amenity] = Nil
|
||||
}
|
||||
|
||||
final val BuildingDefinition : ObjectDefinition = new ObjectDefinition(0) { Name = "building" }
|
||||
|
||||
def apply(id : Int, zone : Zone) : Building = {
|
||||
new Building(id, zone)
|
||||
}
|
||||
|
||||
def Structure(id : Int, zone : Zone, context : ActorContext) : Building = {
|
||||
import akka.actor.Props
|
||||
val obj = new Building(id, zone)
|
||||
obj.Actor = context.actorOf(Props(classOf[BuildingControl], obj), s"$id-building")
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
class BuildingControl(building : Building) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = building
|
||||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case FactionAffinity.ConvertFactionAffinity(faction) =>
|
||||
val originalAffinity = building.Faction
|
||||
if(originalAffinity != (building.Faction = faction)) {
|
||||
building.Amenities.foreach(_.Actor forward FactionAffinity.ConfirmFactionAffinity())
|
||||
}
|
||||
sender ! FactionAffinity.AssertFactionAffinity(building, faction)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.structures
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.zones.Zone
|
||||
|
||||
/**
|
||||
* Defer establishment of a `Building` object until the location for the object is correct (in the correct zone)
|
||||
* and a `context` in the proper `Actor` hierarchy of that zone exists in scope.
|
||||
* @see `ServerObjectBuilder`
|
||||
* @see `Building`
|
||||
* @param constructor a curried function that eventually constructs a `Building` object
|
||||
*/
|
||||
class FoundationBuilder(private val constructor : (Int, Zone, ActorContext)=>Building) {
|
||||
def Build(id : Int, zone : Zone)(implicit context : ActorContext = null) : Building = {
|
||||
val obj : Building = constructor(id, zone, context)
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
object FoundationBuilder {
|
||||
/**
|
||||
* Overloaded constructor.
|
||||
* @param constructor a curried function that eventually constructs a `Building` object
|
||||
* @return a `FoundationBuilder` object
|
||||
*/
|
||||
def apply(constructor : (Int, Zone, ActorContext)=>Building) : FoundationBuilder = {
|
||||
new FoundationBuilder(constructor)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{TransactionType, Vector3}
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ import net.psforever.types.{TransactionType, Vector3}
|
|||
* A structure-owned server object that is a "terminal" that can be accessed for amenities and services.
|
||||
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
*/
|
||||
class Terminal(tdef : TerminalDefinition) extends PlanetSideServerObject {
|
||||
class Terminal(tdef : TerminalDefinition) extends Amenity {
|
||||
/** An entry that maintains a reference to the `Player`, and the player's GUID and location when the message was received. */
|
||||
private var hackedBy : Option[(Player, PlanetSideGUID, Vector3)] = None
|
||||
|
||||
|
|
@ -65,18 +65,23 @@ class Terminal(tdef : TerminalDefinition) extends PlanetSideServerObject {
|
|||
* @return an actionable message that explains what resulted from interacting with this `Terminal`
|
||||
*/
|
||||
def Request(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
|
||||
msg.transaction_type match {
|
||||
case TransactionType.Buy | TransactionType.Learn =>
|
||||
tdef.Buy(player, msg)
|
||||
if(Faction == player.Faction || HackedBy.isDefined) {
|
||||
msg.transaction_type match {
|
||||
case TransactionType.Buy | TransactionType.Learn =>
|
||||
tdef.Buy(player, msg)
|
||||
|
||||
case TransactionType.Sell =>
|
||||
tdef.Sell(player, msg)
|
||||
case TransactionType.Sell =>
|
||||
tdef.Sell(player, msg)
|
||||
|
||||
case TransactionType.InfantryLoadout =>
|
||||
tdef.Loadout(player, msg)
|
||||
case TransactionType.InfantryLoadout =>
|
||||
tdef.Loadout(player, msg)
|
||||
|
||||
case _ =>
|
||||
Terminal.NoDeal()
|
||||
case _ =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
else {
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@
|
|||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Terminal`.
|
||||
* @param term the `Terminal` object being governed
|
||||
*/
|
||||
class TerminalControl(term : Terminal) extends Actor {
|
||||
def receive : Receive = {
|
||||
class TerminalControl(term : Terminal) extends Actor with FactionAffinityBehavior.Check {
|
||||
def FactionObject : FactionAffinity = term
|
||||
|
||||
def receive : Receive = checkBehavior.orElse {
|
||||
case Terminal.Request(player, msg) =>
|
||||
sender ! Terminal.TerminalMessage(player, msg, term.Request(player, msg))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ package net.psforever.objects.vehicles
|
|||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.mount.MountableBehavior
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Vehicle`.<br>
|
||||
|
|
@ -12,17 +13,32 @@ import net.psforever.objects.mount.MountableBehavior
|
|||
* The latter is applicable only when the specific vehicle is being deconstructed.
|
||||
* @param vehicle the `Vehicle` object being governed
|
||||
*/
|
||||
class VehicleControl(private val vehicle : Vehicle) extends Actor with MountableBehavior {
|
||||
override def MountableObject = vehicle
|
||||
class VehicleControl(private val vehicle : Vehicle) extends Actor
|
||||
with FactionAffinityBehavior.Check
|
||||
with MountableBehavior.Mount
|
||||
with MountableBehavior.Dismount {
|
||||
def MountableObject = vehicle //do not add type!
|
||||
|
||||
def receive : Receive = mountableBehavior.orElse {
|
||||
case Vehicle.PrepareForDeletion =>
|
||||
context.become(Disabled)
|
||||
def FactionObject : FactionAffinity = vehicle
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
def receive : Receive = Enabled
|
||||
|
||||
def Disabled : Receive = {
|
||||
case _ => ;
|
||||
}
|
||||
def Enabled : Receive = checkBehavior
|
||||
.orElse(mountBehavior)
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
case Vehicle.PrepareForDeletion =>
|
||||
context.become(Disabled)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
def Disabled : Receive = checkBehavior
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
case Vehicle.Reactivate =>
|
||||
context.become(Enabled)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,19 +3,20 @@ package net.psforever.objects.zones
|
|||
|
||||
import akka.actor.{ActorContext, ActorRef, Props}
|
||||
import akka.routing.RandomPool
|
||||
import net.psforever.objects.serverobject.doors.Base
|
||||
import net.psforever.objects.{PlanetSideGameObject, Player, Vehicle}
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.actor.UniqueNumberSystem
|
||||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
||||
import net.psforever.packet.GamePacket
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.collection.immutable.{Map => PairMap}
|
||||
|
||||
/**
|
||||
* A server object representing the one-landmass planets as well as the individual subterranean caverns.<br>
|
||||
|
|
@ -55,7 +56,7 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
/** */
|
||||
private var transport : ActorRef = ActorRef.noSender
|
||||
|
||||
private var bases : List[Base] = List()
|
||||
private var buildings : PairMap[Int, Building] = PairMap.empty[Int, Building]
|
||||
|
||||
/**
|
||||
* Establish the basic accessible conditions necessary for a functional `Zone`.<br>
|
||||
|
|
@ -79,8 +80,8 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
Map.LocalObjects.foreach({ builderObject =>
|
||||
builderObject.Build
|
||||
})
|
||||
|
||||
MakeBases(Map.LocalBases)
|
||||
MakeBuildings(context)
|
||||
AssignAmenities()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,13 +218,20 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
|
||||
def Transport : ActorRef = transport
|
||||
|
||||
def MakeBases(num : Int) : List[Base] = {
|
||||
bases = (1 to num).map(id => new Base(id)).toList
|
||||
bases
|
||||
def Building(id : Int) : Option[Building] = {
|
||||
buildings.get(id)
|
||||
}
|
||||
|
||||
def Base(id : Int) : Option[Base] = {
|
||||
bases.lift(id)
|
||||
private def MakeBuildings(implicit context : ActorContext) : PairMap[Int, Building] = {
|
||||
val buildingList = Map.LocalBuildings
|
||||
buildings = buildingList.map({case(building_id, constructor) => building_id -> constructor.Build(building_id, this) })
|
||||
buildings
|
||||
}
|
||||
|
||||
private def AssignAmenities() : Unit = {
|
||||
Map.ObjectToBuilding.foreach({ case(object_guid, building_id) =>
|
||||
buildings(building_id).Amenities = guid(object_guid).get.asInstanceOf[Amenity]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -264,6 +272,8 @@ class Zone(private val zoneId : String, zoneMap : ZoneMap, zoneNumber : Int) {
|
|||
}
|
||||
|
||||
object Zone {
|
||||
final val Nowhere : Zone = new Zone("nowhere", new ZoneMap("nowhere"), 99)
|
||||
|
||||
/**
|
||||
* Message to initialize the `Zone`.
|
||||
* @see `Zone.Init(implicit ActorContext)`
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
package net.psforever.objects.zones
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.PlanetSideGameObject
|
||||
import org.log4s.Logger
|
||||
|
||||
/**
|
||||
* na
|
||||
|
|
@ -20,14 +22,16 @@ class ZoneActor(zone : Zone) extends Actor {
|
|||
}
|
||||
|
||||
def ZoneSetupCheck(): Unit = {
|
||||
import ZoneActor._
|
||||
def guid(id : Int) = zone.GUID(id)
|
||||
val map = zone.Map
|
||||
val slog = org.log4s.getLogger(s"zone/${zone.Id}/sanity")
|
||||
val validateObject : (Int, (PlanetSideGameObject)=>Boolean, String) => Boolean = ValidateObject(guid, slog)
|
||||
|
||||
//check base to object associations
|
||||
map.ObjectToBase.foreach({ case((object_guid, base_id)) =>
|
||||
if(zone.Base(base_id).isEmpty) {
|
||||
slog.error(s"expected a base #$base_id")
|
||||
map.ObjectToBuilding.foreach({ case((object_guid, base_id)) =>
|
||||
if(zone.Building(base_id).isEmpty) {
|
||||
slog.error(s"expected a building at id #$base_id")
|
||||
}
|
||||
if(guid(object_guid).isEmpty) {
|
||||
slog.error(s"expected object id $object_guid to exist, but it did not")
|
||||
|
|
@ -35,74 +39,80 @@ class ZoneActor(zone : Zone) extends Actor {
|
|||
})
|
||||
|
||||
//check door to lock association
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
map.DoorToLock.foreach({ case((door_guid, lock_guid)) =>
|
||||
try {
|
||||
if(!guid(door_guid).get.isInstanceOf[Door]) {
|
||||
slog.error(s"expected id $door_guid to be a door, but it was not")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
slog.error(s"expected a door at id $door_guid but no object is initialized")
|
||||
}
|
||||
try {
|
||||
if(!guid(lock_guid).get.isInstanceOf[IFFLock]) {
|
||||
slog.error(s"expected id $lock_guid to be an IFF locks but it was not")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
slog.error(s"expected an IFF locks at id $lock_guid but no object is initialized")
|
||||
}
|
||||
validateObject(door_guid, DoorCheck, "door")
|
||||
validateObject(lock_guid, LockCheck, "IFF lock")
|
||||
})
|
||||
|
||||
//check vehicle terminal to spawn pad association
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
map.TerminalToSpawnPad.foreach({ case ((term_guid, pad_guid)) =>
|
||||
try {
|
||||
if(!guid(term_guid).get.isInstanceOf[Terminal]) { //TODO check is vehicle terminal
|
||||
slog.error(s"expected id $term_guid to be a terminal, but it was not")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
slog.error(s"expected a terminal at id $term_guid but no object is initialized")
|
||||
}
|
||||
try {
|
||||
if(!guid(pad_guid).get.isInstanceOf[VehicleSpawnPad]) {
|
||||
slog.error(s"expected id $pad_guid to be a spawn pad, but it was not")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
slog.error(s"expected a spawn pad at id $pad_guid but no object is initialized")
|
||||
}
|
||||
validateObject(term_guid, TerminalCheck, "vehicle terminal")
|
||||
validateObject(pad_guid, VehicleSpawnPadCheck, "vehicle spawn pad")
|
||||
})
|
||||
|
||||
//check implant terminal mech to implant terminal interface association
|
||||
import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
||||
map.TerminalToInterface.foreach({case ((mech_guid, interface_guid)) =>
|
||||
try {
|
||||
if(!guid(mech_guid).get.isInstanceOf[ImplantTerminalMech]) {
|
||||
slog.error(s"expected id $mech_guid to be an implant terminal mech, but it was not")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
slog.error(s"expected a implant terminal mech at id $mech_guid but no object is initialized")
|
||||
}
|
||||
try {
|
||||
if(!guid(interface_guid).get.isInstanceOf[Terminal]) { //TODO check is implant terminal
|
||||
slog.error(s"expected id $interface_guid to be an implant terminal interface, but it was not")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
slog.error(s"expected a implant terminal interface at id $interface_guid but no object is initialized")
|
||||
}
|
||||
validateObject(mech_guid, ImplantMechCheck, "implant terminal mech")
|
||||
validateObject(interface_guid, TerminalCheck, "implant terminal interface")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
object ZoneActor {
|
||||
|
||||
/**
|
||||
* Recover an object from a collection and perform any number of validating tests upon it.
|
||||
* If the object fails any tests, log an error.
|
||||
* @param guid access to an association between unique numbers and objects using some of those unique numbers
|
||||
* @param elog a contraction of "error log;"
|
||||
* accepts `String` data
|
||||
* @param object_guid the unique indentifier being checked against the `guid` access point
|
||||
* @param test a test for the discovered object;
|
||||
* expects at least `Type` checking
|
||||
* @param description an explanation of how the object, if not discovered, should be identified
|
||||
* @return `true` if the object was discovered and validates correctly;
|
||||
* `false` if the object failed any tests
|
||||
*/
|
||||
def ValidateObject(guid : (Int)=>Option[PlanetSideGameObject], elog : Logger)
|
||||
(object_guid : Int, test : (PlanetSideGameObject)=>Boolean, description : String) : Boolean = {
|
||||
try {
|
||||
if(!test(guid(object_guid).get)) {
|
||||
elog.error(s"expected id $object_guid to be a $description, but it was not")
|
||||
false
|
||||
}
|
||||
else {
|
||||
true
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _ : Exception =>
|
||||
elog.error(s"expected a $description at id $object_guid but no object is initialized")
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
def LockCheck(obj : PlanetSideGameObject) : Boolean = {
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
obj.isInstanceOf[IFFLock]
|
||||
}
|
||||
|
||||
def DoorCheck(obj : PlanetSideGameObject) : Boolean = {
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
obj.isInstanceOf[Door]
|
||||
}
|
||||
|
||||
def TerminalCheck(obj : PlanetSideGameObject) : Boolean = {
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
obj.isInstanceOf[Terminal]
|
||||
}
|
||||
|
||||
def ImplantMechCheck(obj : PlanetSideGameObject) : Boolean = {
|
||||
import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
||||
obj.isInstanceOf[ImplantTerminalMech]
|
||||
}
|
||||
|
||||
def VehicleSpawnPadCheck(obj : PlanetSideGameObject) : Boolean = {
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
obj.isInstanceOf[VehicleSpawnPad]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.zones
|
||||
|
||||
import net.psforever.objects.serverobject.structures.FoundationBuilder
|
||||
import net.psforever.objects.serverobject.ServerObjectBuilder
|
||||
|
||||
/**
|
||||
|
|
@ -29,7 +30,7 @@ class ZoneMap(private val name : String) {
|
|||
private var linkTerminalInterface : Map[Int, Int] = Map()
|
||||
private var linkDoorLock : Map[Int, Int] = Map()
|
||||
private var linkObjectBase : Map[Int, Int] = Map()
|
||||
private var numBases : Int = 0
|
||||
private var buildings : Map[Int, FoundationBuilder] = Map()
|
||||
|
||||
def Name : String = name
|
||||
|
||||
|
|
@ -49,19 +50,19 @@ class ZoneMap(private val name : String) {
|
|||
localObjects = localObjects :+ obj
|
||||
}
|
||||
|
||||
def LocalBases : Int = numBases
|
||||
def LocalBuildings : Map[Int, FoundationBuilder] = buildings
|
||||
|
||||
def LocalBases_=(num : Int) : Int = {
|
||||
if(num > 0) {
|
||||
numBases = num
|
||||
def LocalBuilding(building_id : Int, constructor : FoundationBuilder) : Int = {
|
||||
if(building_id > 0) {
|
||||
buildings = buildings ++ Map(building_id -> constructor)
|
||||
}
|
||||
LocalBases
|
||||
buildings.size
|
||||
}
|
||||
|
||||
def ObjectToBase : Map[Int, Int] = linkObjectBase
|
||||
def ObjectToBuilding : Map[Int, Int] = linkObjectBase
|
||||
|
||||
def ObjectToBase(object_guid : Int, base_id : Int) : Unit = {
|
||||
linkObjectBase = linkObjectBase ++ Map(object_guid -> base_id)
|
||||
def ObjectToBuilding(object_guid : Int, building_id : Int) : Unit = {
|
||||
linkObjectBase = linkObjectBase ++ Map(object_guid -> building_id)
|
||||
}
|
||||
|
||||
def DoorToLock : Map[Int, Int] = linkDoorLock
|
||||
|
|
|
|||
169
common/src/test/scala/objects/BuildingTest.scala
Normal file
169
common/src/test/scala/objects/BuildingTest.scala
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.doors.{Door, DoorControl}
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, BuildingControl}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class AmenityTest extends Specification {
|
||||
class AmenityObject extends Amenity {
|
||||
def Definition : ObjectDefinition = null
|
||||
}
|
||||
|
||||
"Amenity" should {
|
||||
"construct" in {
|
||||
val ao = new AmenityObject()
|
||||
ao.Owner mustEqual Building.NoBuilding
|
||||
}
|
||||
|
||||
"can be owned by a building" in {
|
||||
val ao = new AmenityObject()
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
|
||||
ao.Owner = bldg
|
||||
ao.Owner mustEqual bldg
|
||||
}
|
||||
|
||||
"be owned by a vehicle" in {
|
||||
import net.psforever.objects.Vehicle
|
||||
val ao = new AmenityObject()
|
||||
val veh = Vehicle(GlobalDefinitions.quadstealth)
|
||||
|
||||
ao.Owner = veh
|
||||
ao.Owner mustEqual veh
|
||||
}
|
||||
|
||||
"not be owned by an unexpected object" in {
|
||||
val ao = new AmenityObject()
|
||||
//ao.Owner = net.psforever.objects.serverobject.mblocker.Locker() //will not compile
|
||||
ok
|
||||
}
|
||||
|
||||
"confer faction allegiance through ownership" in {
|
||||
//see FactionAffinityTest
|
||||
val ao = new AmenityObject()
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
ao.Owner = bldg
|
||||
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
ao.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
|
||||
bldg.Faction = PlanetSideEmpire.TR
|
||||
bldg.Faction mustEqual PlanetSideEmpire.TR
|
||||
ao.Faction mustEqual PlanetSideEmpire.TR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BuildingTest extends Specification {
|
||||
"Building" should {
|
||||
"construct" in {
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
bldg.Id mustEqual 10
|
||||
bldg.Actor mustEqual ActorRef.noSender
|
||||
bldg.Amenities mustEqual Nil
|
||||
bldg.Zone mustEqual Zone.Nowhere
|
||||
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
}
|
||||
|
||||
"change faction affinity" in {
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
bldg.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
|
||||
bldg.Faction = PlanetSideEmpire.TR
|
||||
bldg.Faction mustEqual PlanetSideEmpire.TR
|
||||
}
|
||||
|
||||
"keep track of amenities" in {
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
val door1 = Door(GlobalDefinitions.door)
|
||||
val door2 = Door(GlobalDefinitions.door)
|
||||
|
||||
bldg.Amenities mustEqual Nil
|
||||
bldg.Amenities = door2
|
||||
bldg.Amenities mustEqual List(door2)
|
||||
bldg.Amenities = door1
|
||||
bldg.Amenities mustEqual List(door2, door1)
|
||||
door1.Owner mustEqual bldg
|
||||
door2.Owner mustEqual bldg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BuildingControl1Test extends ActorTest {
|
||||
"Building Control" should {
|
||||
"construct" in {
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test")
|
||||
assert(bldg.Actor != ActorRef.noSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BuildingControl2Test extends ActorTest {
|
||||
"Building Control" should {
|
||||
"convert and assert faction affinity on convert request" in {
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
bldg.Faction = PlanetSideEmpire.TR
|
||||
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "test")
|
||||
assert(bldg.Faction == PlanetSideEmpire.TR)
|
||||
|
||||
bldg.Actor ! FactionAffinity.ConvertFactionAffinity(PlanetSideEmpire.VS)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[FactionAffinity.AssertFactionAffinity])
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].obj == bldg)
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].faction == PlanetSideEmpire.VS)
|
||||
assert(bldg.Faction == PlanetSideEmpire.VS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BuildingControl3Test extends ActorTest {
|
||||
"Building Control" should {
|
||||
"convert and assert faction affinity on convert request, and for each of its amenities" in {
|
||||
val bldg = Building(10, Zone.Nowhere)
|
||||
bldg.Faction = PlanetSideEmpire.TR
|
||||
bldg.Actor = system.actorOf(Props(classOf[BuildingControl], bldg), "building-test")
|
||||
val door1 = Door(GlobalDefinitions.door)
|
||||
door1.GUID = PlanetSideGUID(1)
|
||||
door1.Actor = system.actorOf(Props(classOf[DoorControl], door1), "door1-test")
|
||||
val door2 = Door(GlobalDefinitions.door)
|
||||
door2.GUID = PlanetSideGUID(2)
|
||||
door2.Actor = system.actorOf(Props(classOf[DoorControl], door2), "door2-test")
|
||||
bldg.Amenities = door2
|
||||
bldg.Amenities = door1
|
||||
assert(bldg.Faction == PlanetSideEmpire.TR)
|
||||
assert(bldg.Amenities.length == 2)
|
||||
assert(bldg.Amenities.head == door2)
|
||||
assert(bldg.Amenities(1) == door1)
|
||||
|
||||
bldg.Actor ! FactionAffinity.ConvertFactionAffinity(PlanetSideEmpire.VS)
|
||||
val reply = receiveN(3, Duration.create(500, "ms"))
|
||||
assert(reply.length == 3)
|
||||
var building_count = 0
|
||||
var door_count = 0
|
||||
reply.foreach(item => {
|
||||
assert(item.isInstanceOf[FactionAffinity.AssertFactionAffinity])
|
||||
val item2 = item.asInstanceOf[FactionAffinity.AssertFactionAffinity]
|
||||
item2.obj match {
|
||||
case _ : Building =>
|
||||
building_count += 1
|
||||
case _ : Door =>
|
||||
door_count += 1
|
||||
case _ =>
|
||||
assert(false)
|
||||
}
|
||||
assert(item2.faction == PlanetSideEmpire.VS)
|
||||
})
|
||||
assert(building_count == 1 && door_count == 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.doors.{Door, DoorControl}
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{PlanetSideGUID, UseItemMessage}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -11,6 +13,8 @@ import org.specs2.mutable.Specification
|
|||
import scala.concurrent.duration.Duration
|
||||
|
||||
class DoorTest extends Specification {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
|
||||
"Door" should {
|
||||
"construct" in {
|
||||
Door(GlobalDefinitions.door)
|
||||
|
|
@ -24,7 +28,6 @@ class DoorTest extends Specification {
|
|||
}
|
||||
|
||||
"be opened and closed (1; manual)" in {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val door = Door(GlobalDefinitions.door)
|
||||
door.isOpen mustEqual false
|
||||
door.Open mustEqual None
|
||||
|
|
@ -39,7 +42,6 @@ class DoorTest extends Specification {
|
|||
}
|
||||
|
||||
"be opened and closed (2; toggle)" in {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val msg = UseItemMessage(PlanetSideGUID(6585), 0, PlanetSideGUID(372), 4294967295L, false, Vector3(5.0f,0.0f,0.0f), Vector3(0.0f,0.0f,0.0f), 11, 25, 0, 364)
|
||||
val door = Door(GlobalDefinitions.door)
|
||||
door.Open mustEqual None
|
||||
|
|
@ -85,9 +87,7 @@ class DoorControl1Test extends ActorTest() {
|
|||
class DoorControl2Test extends ActorTest() {
|
||||
"DoorControl" should {
|
||||
"open on use" in {
|
||||
val door = Door(GlobalDefinitions.door)
|
||||
door.Actor = system.actorOf(Props(classOf[DoorControl], door), "door")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, door) = DoorControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val msg = UseItemMessage(PlanetSideGUID(1), 0, PlanetSideGUID(2), 0L, false, Vector3(0f,0f,0f),Vector3(0f,0f,0f),0,0,0,0L) //faked
|
||||
assert(door.Open.isEmpty)
|
||||
|
||||
|
|
@ -106,8 +106,7 @@ class DoorControl2Test extends ActorTest() {
|
|||
class DoorControl3Test extends ActorTest() {
|
||||
"DoorControl" should {
|
||||
"do nothing if given garbage" in {
|
||||
val door = Door(GlobalDefinitions.door)
|
||||
door.Actor = system.actorOf(Props(classOf[DoorControl], door), "door")
|
||||
val (_, door) = DoorControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
assert(door.Open.isEmpty)
|
||||
|
||||
door.Actor ! "trash"
|
||||
|
|
@ -117,3 +116,13 @@ class DoorControl3Test extends ActorTest() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
object DoorControlTest {
|
||||
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, Door) = {
|
||||
val door = Door(GlobalDefinitions.door)
|
||||
door.Actor = system.actorOf(Props(classOf[DoorControl], door), "door")
|
||||
door.Owner = new Building(0, Zone.Nowhere)
|
||||
door.Owner.Faction = faction
|
||||
(Player("test", faction, CharacterGender.Male, 0, 0), door)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
131
common/src/test/scala/objects/FactionAffinityTest.scala
Normal file
131
common/src/test/scala/objects/FactionAffinityTest.scala
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{Actor, ActorSystem, Props}
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class FactionAffinityTest extends Specification {
|
||||
"FactionAffinity" should {
|
||||
"construct (basic)" in {
|
||||
val obj = new FactionAffinity { def Faction = PlanetSideEmpire.TR }
|
||||
obj.Faction mustEqual PlanetSideEmpire.TR
|
||||
}
|
||||
|
||||
"construct (part of)" in {
|
||||
val obj = new Door(GlobalDefinitions.door)
|
||||
obj.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
}
|
||||
|
||||
"can not change affinity directly (basic)" in {
|
||||
val obj = new FactionAffinity { def Faction = PlanetSideEmpire.TR }
|
||||
(obj.Faction = PlanetSideEmpire.NC) mustEqual PlanetSideEmpire.TR
|
||||
}
|
||||
|
||||
"can not change affinity directly (part of)" in {
|
||||
val obj = new Door(GlobalDefinitions.door)
|
||||
(obj.Faction = PlanetSideEmpire.TR) mustEqual PlanetSideEmpire.NEUTRAL
|
||||
}
|
||||
|
||||
"inherits affinity from owner 1" in {
|
||||
val obj = new Door(GlobalDefinitions.door)
|
||||
obj.Owner.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
(obj.Faction = PlanetSideEmpire.TR) mustEqual PlanetSideEmpire.NEUTRAL
|
||||
}
|
||||
|
||||
"inherits affinity from owner 2" in {
|
||||
val obj = new Door(GlobalDefinitions.door)
|
||||
val bldg = new Building(1, Zone.Nowhere)
|
||||
obj.Owner = bldg
|
||||
obj.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
|
||||
bldg.Faction = PlanetSideEmpire.TR
|
||||
obj.Faction mustEqual PlanetSideEmpire.TR
|
||||
|
||||
bldg.Faction = PlanetSideEmpire.NC
|
||||
obj.Faction mustEqual PlanetSideEmpire.NC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FactionAffinity1Test extends ActorTest() {
|
||||
"FactionAffinity" should {
|
||||
"assert affinity on confirm request" in {
|
||||
val obj = FactionAffinityTest.SetUpAgent
|
||||
obj.Faction = PlanetSideEmpire.VS //object is a type that can be changed directly
|
||||
assert(obj.Faction == PlanetSideEmpire.VS)
|
||||
|
||||
obj.Actor ! FactionAffinity.ConfirmFactionAffinity()
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[FactionAffinity.AssertFactionAffinity])
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].obj == obj)
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].faction == PlanetSideEmpire.VS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FactionAffinity2Test extends ActorTest() {
|
||||
"FactionAffinity" should {
|
||||
"assert affinity on assert request" in {
|
||||
val obj = FactionAffinityTest.SetUpAgent
|
||||
obj.Faction = PlanetSideEmpire.VS //object is a type that can be changed directly
|
||||
assert(obj.Faction == PlanetSideEmpire.VS)
|
||||
|
||||
obj.Actor ! FactionAffinity.AssertFactionAffinity(obj, PlanetSideEmpire.NEUTRAL)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[FactionAffinity.AssertFactionAffinity])
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].obj == obj)
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].faction == PlanetSideEmpire.VS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FactionAffinity3Test extends ActorTest() {
|
||||
"FactionAffinity" should {
|
||||
"convert and assert affinity on convert request" in {
|
||||
val obj = FactionAffinityTest.SetUpAgent
|
||||
obj.Faction = PlanetSideEmpire.VS //object is a type that can be changed directly
|
||||
assert(obj.Faction == PlanetSideEmpire.VS)
|
||||
|
||||
obj.Actor ! FactionAffinity.ConvertFactionAffinity(PlanetSideEmpire.TR)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[FactionAffinity.AssertFactionAffinity])
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].obj == obj)
|
||||
assert(reply.asInstanceOf[FactionAffinity.AssertFactionAffinity].faction == PlanetSideEmpire.TR)
|
||||
assert(obj.Faction == PlanetSideEmpire.TR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object FactionAffinityTest {
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior
|
||||
|
||||
private class AffinityControl(obj : FactionAffinity) extends Actor
|
||||
with FactionAffinityBehavior.Check
|
||||
with FactionAffinityBehavior.Convert {
|
||||
override def FactionObject = obj
|
||||
def receive = checkBehavior.orElse(convertBehavior).orElse { case _ => }
|
||||
}
|
||||
|
||||
def SetUpAgent(implicit system : ActorSystem) = {
|
||||
val obj = new Vehicle(GlobalDefinitions.quadstealth)
|
||||
obj.Actor = system.actorOf(Props(classOf[FactionAffinityTest.AffinityControl], obj), "test")
|
||||
obj
|
||||
}
|
||||
|
||||
def FreeFactionObject : FactionAffinity = new FactionAffinity() {
|
||||
private var faction : PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
def Faction : PlanetSideEmpire.Value = faction
|
||||
override def Faction_=(fac : PlanetSideEmpire.Value) : PlanetSideEmpire.Value = {
|
||||
faction = fac
|
||||
faction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.locks.{IFFLock, IFFLockControl}
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.serverobject.terminals.{Terminal, TerminalControl, TerminalDefinition}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -33,9 +36,7 @@ class IFFLockControl1Test extends ActorTest() {
|
|||
class IFFLockControl2Test extends ActorTest() {
|
||||
"IFFLockControl" should {
|
||||
"can hack" in {
|
||||
val lock = IFFLock(GlobalDefinitions.lock_external)
|
||||
lock.Actor = system.actorOf(Props(classOf[IFFLockControl], lock), "lock-control")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, lock) = IFFLockControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
player.GUID = PlanetSideGUID(1)
|
||||
assert(lock.HackedBy.isEmpty)
|
||||
|
||||
|
|
@ -49,9 +50,7 @@ class IFFLockControl2Test extends ActorTest() {
|
|||
class IFFLockControl3Test extends ActorTest() {
|
||||
"IFFLockControl" should {
|
||||
"can hack" in {
|
||||
val lock = IFFLock(GlobalDefinitions.lock_external)
|
||||
lock.Actor = system.actorOf(Props(classOf[IFFLockControl], lock), "lock-control")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, lock) = IFFLockControlTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
player.GUID = PlanetSideGUID(1)
|
||||
assert(lock.HackedBy.isEmpty)
|
||||
|
||||
|
|
@ -64,3 +63,13 @@ class IFFLockControl3Test extends ActorTest() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
object IFFLockControlTest {
|
||||
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, IFFLock) = {
|
||||
val lock = IFFLock(GlobalDefinitions.lock_external)
|
||||
lock.Actor = system.actorOf(Props(classOf[IFFLockControl], lock), "lock-control")
|
||||
lock.Owner = new Building(0, Zone.Nowhere)
|
||||
lock.Owner.Faction = faction
|
||||
(Player("test", faction, CharacterGender.Male, 0, 0), lock)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
common/src/test/scala/objects/LockerTest.scala
Normal file
36
common/src/test/scala/objects/LockerTest.scala
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.mblocker.{Locker, LockerControl}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import org.specs2.mutable._
|
||||
|
||||
class LockerTest extends Specification {
|
||||
"LockerDefinition" should {
|
||||
"define" in {
|
||||
GlobalDefinitions.mb_locker.ObjectId mustEqual 524
|
||||
GlobalDefinitions.mb_locker.Name mustEqual "mb_locker"
|
||||
}
|
||||
}
|
||||
|
||||
"Locker" should {
|
||||
"construct" in {
|
||||
val locker = new Locker()
|
||||
locker.Actor mustEqual ActorRef.noSender
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LockerControlTest extends ActorTest {
|
||||
"LockerControl" should {
|
||||
"construct" in {
|
||||
val locker = new Locker()
|
||||
locker.Actor = system.actorOf(Props(classOf[LockerControl], locker), "test")
|
||||
locker.Actor ! FactionAffinity.ConfirmFactionAffinity()
|
||||
expectMsg(FactionAffinity.AssertFactionAffinity(locker, PlanetSideEmpire.NEUTRAL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,10 @@ package objects
|
|||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.definition.{ObjectDefinition, SeatDefinition}
|
||||
import net.psforever.objects.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.vehicles.Seat
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire}
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
|
@ -80,12 +81,15 @@ object MountableTest {
|
|||
None
|
||||
}
|
||||
}
|
||||
def Definition : ObjectDefinition = null //eh whatever
|
||||
GUID = PlanetSideGUID(1)
|
||||
//eh whatever
|
||||
def Faction = PlanetSideEmpire.TR
|
||||
def Definition : ObjectDefinition = null
|
||||
}
|
||||
|
||||
class MountableTestControl(obj : Mountable) extends Actor with MountableBehavior {
|
||||
class MountableTestControl(obj : PlanetSideServerObject with Mountable) extends Actor with MountableBehavior.Mount with MountableBehavior.Dismount {
|
||||
override def MountableObject = obj
|
||||
|
||||
def receive : Receive = mountableBehavior
|
||||
def receive : Receive = mountBehavior.orElse(dismountBehavior)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,26 @@ import akka.actor.{Actor, Props}
|
|||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.objects.serverobject.ServerObjectBuilder
|
||||
import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class BuildingBuilderTest extends ActorTest {
|
||||
"Building object" should {
|
||||
"build" in {
|
||||
val actor = system.actorOf(Props(classOf[ServerObjectBuilderTest.BuildingTestActor], 10, Zone.Nowhere), "building")
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Building])
|
||||
assert(reply.asInstanceOf[Building].Id == 10)
|
||||
assert(reply.asInstanceOf[Building].Zone == Zone.Nowhere)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DoorObjectBuilderTest1 extends ActorTest {
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
"Door object" should {
|
||||
|
|
@ -150,4 +166,11 @@ object ServerObjectBuilderTest {
|
|||
sender ! builder.Build(context, hub)
|
||||
}
|
||||
}
|
||||
|
||||
class BuildingTestActor(building_id : Int, zone : Zone) extends Actor {
|
||||
def receive : Receive = {
|
||||
case _ =>
|
||||
sender ! FoundationBuilder(Building.Structure).Build(building_id, zone)(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.vehicles.VehicleControl
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3}
|
||||
|
|
@ -40,22 +42,20 @@ class VehicleSpawnControl1Test extends ActorTest() {
|
|||
class VehicleSpawnControl2Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"spawn a vehicle" in {
|
||||
val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad)
|
||||
obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, pad) = VehicleSpawnPadControl.SetUpAgents(PlanetSideEmpire.TR)
|
||||
player.Spawn
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle")
|
||||
|
||||
obj.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle)
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle)
|
||||
val reply = receiveOne(Duration.create(10000, "ms"))
|
||||
assert(reply == VehicleSpawnPad.ConcealPlayer) //explicit: isInstanceOf does not work
|
||||
|
||||
val reply2 = receiveOne(Duration.create(10000, "ms"))
|
||||
assert(reply2.isInstanceOf[VehicleSpawnPad.LoadVehicle])
|
||||
assert(reply2.asInstanceOf[VehicleSpawnPad.LoadVehicle].vehicle == vehicle)
|
||||
assert(reply2.asInstanceOf[VehicleSpawnPad.LoadVehicle].pad == obj)
|
||||
assert(reply2.asInstanceOf[VehicleSpawnPad.LoadVehicle].pad == pad)
|
||||
|
||||
player.VehicleOwned = Some(vehicle.GUID)
|
||||
val reply3 = receiveOne(Duration.create(10000, "ms"))
|
||||
|
|
@ -78,14 +78,12 @@ class VehicleSpawnControl2Test extends ActorTest() {
|
|||
class VehicleSpawnControl3Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"not spawn a vehicle if player is dead" in {
|
||||
val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad)
|
||||
obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, pad) = VehicleSpawnPadControl.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle")
|
||||
|
||||
obj.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle)
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle)
|
||||
val reply = receiveOne(Duration.create(5000, "ms"))
|
||||
assert(reply == null)
|
||||
}
|
||||
|
|
@ -95,16 +93,24 @@ class VehicleSpawnControl3Test extends ActorTest() {
|
|||
class VehicleSpawnControl4Test extends ActorTest() {
|
||||
"VehicleSpawnControl" should {
|
||||
"not spawn a vehicle if vehicle Actor is missing" in {
|
||||
val obj = VehicleSpawnPad(GlobalDefinitions.spawn_pad)
|
||||
obj.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], obj), "door")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, pad) = VehicleSpawnPadControl.SetUpAgents(PlanetSideEmpire.TR)
|
||||
player.Spawn
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(1)
|
||||
|
||||
obj.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle)
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle)
|
||||
val reply = receiveOne(Duration.create(5000, "ms"))
|
||||
assert(reply == null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object VehicleSpawnPadControl {
|
||||
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, VehicleSpawnPad) = {
|
||||
val pad = VehicleSpawnPad(GlobalDefinitions.spawn_pad)
|
||||
pad.Actor = system.actorOf(Props(classOf[VehicleSpawnControl], pad), "test-pad")
|
||||
pad.Owner = new Building(0, Zone.Nowhere)
|
||||
pad.Owner.Faction = faction
|
||||
(Player("test", faction, CharacterGender.Male, 0, 0), pad)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.definition.SeatDefinition
|
||||
import net.psforever.objects.vehicles.{AccessPermissionGroup, Seat, SeatArmorRestriction, VehicleLockState}
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.{CharacterGender, ExoSuitType, PlanetSideEmpire}
|
||||
import org.specs2.mutable._
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class VehicleTest extends Specification {
|
||||
|
||||
"SeatDefinition" should {
|
||||
|
|
@ -254,3 +258,49 @@ class VehicleTest extends Specification {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControl1Test extends ActorTest {
|
||||
"Vehicle Control" should {
|
||||
"deactivate and stop handling mount messages" in {
|
||||
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
expectNoMsg(Duration.create(200, "ms"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleControl2Test extends ActorTest {
|
||||
"Vehicle Control" should {
|
||||
"reactivate and resume handling mount messages" in {
|
||||
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
player1.GUID = PlanetSideGUID(1)
|
||||
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
player2.GUID = PlanetSideGUID(2)
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
vehicle.GUID = PlanetSideGUID(3)
|
||||
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
|
||||
|
||||
vehicle.Actor ! Mountable.TryMount(player1, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //discard
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
expectNoMsg(Duration.create(200, "ms"))
|
||||
|
||||
vehicle.Actor ! Vehicle.Reactivate
|
||||
vehicle.Actor ! Mountable.TryMount(player2, 1)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,44 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.actor.{ActorContext, ActorRef}
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder}
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
class ZoneTest extends Specification {
|
||||
def test(a: Int, b : Zone, c : ActorContext) : Building = { Building.NoBuilding }
|
||||
|
||||
"ZoneMap" should {
|
||||
//TODO these are temporary tests as the current ZoneMap is a kludge
|
||||
"construct" in {
|
||||
new ZoneMap("map13")
|
||||
ok
|
||||
}
|
||||
|
||||
"references bases by a positive building id (defaults to 0)" in {
|
||||
def test(a: Int, b : Zone, c : ActorContext) : Building = { Building.NoBuilding }
|
||||
|
||||
val map = new ZoneMap("map13")
|
||||
map.LocalBases mustEqual 0
|
||||
map.LocalBases = 10
|
||||
map.LocalBases mustEqual 10
|
||||
map.LocalBases = -1
|
||||
map.LocalBases mustEqual 10
|
||||
map.LocalBuildings mustEqual Map.empty
|
||||
map.LocalBuilding(10, FoundationBuilder(test))
|
||||
map.LocalBuildings.keySet.contains(10) mustEqual true
|
||||
map.LocalBuilding(-1, FoundationBuilder(test))
|
||||
map.LocalBuildings.keySet.contains(10) mustEqual true
|
||||
map.LocalBuildings.keySet.contains(-1) mustEqual false
|
||||
}
|
||||
|
||||
"associates objects to bases (doesn't check numbers)" in {
|
||||
val map = new ZoneMap("map13")
|
||||
map.ObjectToBase mustEqual Nil
|
||||
map.ObjectToBase(1, 2)
|
||||
map.ObjectToBase mustEqual List((1, 2))
|
||||
map.ObjectToBase(3, 4)
|
||||
map.ObjectToBase mustEqual List((1, 2), (3, 4))
|
||||
map.ObjectToBuilding mustEqual Nil
|
||||
map.ObjectToBuilding(1, 2)
|
||||
map.ObjectToBuilding mustEqual Map(1 -> 2)
|
||||
map.ObjectToBuilding(3, 4)
|
||||
map.ObjectToBuilding mustEqual Map(1 -> 2, 3 -> 4)
|
||||
}
|
||||
|
||||
"associates doors to door locks (doesn't check numbers)" in {
|
||||
|
|
@ -65,11 +70,10 @@ class ZoneTest extends Specification {
|
|||
}
|
||||
|
||||
val map13 = new ZoneMap("map13")
|
||||
map13.LocalBases = 10
|
||||
map13.LocalBuilding(10, FoundationBuilder(test))
|
||||
class TestObject extends IdentifiableEntity
|
||||
|
||||
"Zone" should {
|
||||
//TODO these are temporary tests as the current Zone is a kludge
|
||||
"construct" in {
|
||||
val zone = new Zone("home3", map13, 13)
|
||||
zone.GUID mustEqual ActorRef.noSender
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class AirVehicleTerminalTest extends Specification {
|
||||
"Air_Vehicle_Terminal" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal)
|
||||
|
|
@ -18,8 +23,8 @@ class AirVehicleTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a reaver ('lightgunship')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.air_vehicle_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "lightgunship", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
|
||||
|
|
@ -35,7 +40,6 @@ class AirVehicleTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can not buy a fake vehicle ('reaver')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "reaver", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types._
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class CertTerminalTest extends Specification {
|
||||
"Cert_Terminal" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
|
|
@ -18,27 +23,23 @@ class CertTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can learn a certification ('medium_assault')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "medium_assault", 0, PlanetSideGUID(0))
|
||||
terminal.Request(player, msg) mustEqual Terminal.LearnCertification(CertificationType.MediumAssault, 2)
|
||||
}
|
||||
|
||||
"player can not learn a fake certification ('juggling')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "juggling", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
}
|
||||
|
||||
"player can forget a certification ('medium_assault')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "medium_assault", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.SellCertification(CertificationType.MediumAssault, 2)
|
||||
}
|
||||
|
||||
"player can not forget a fake certification ('juggling')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "juggling", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class DropshipVehicleTerminalTest extends Specification {
|
||||
"Dropship_Vehicle_Terminal" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal)
|
||||
|
|
@ -18,8 +23,8 @@ class DropshipVehicleTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a galaxy ('dropship')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "dropship", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
|
||||
|
|
@ -41,7 +46,6 @@ class DropshipVehicleTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can not buy a fake vehicle ('galaxy')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.dropship_vehicle_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "galaxy", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class GroundVehicleTerminalTest extends Specification {
|
||||
"Ground_Vehicle_Terminal" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
|
|
@ -18,8 +23,8 @@ class GroundVehicleTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a harasser ('two_man_assault_buggy')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
|
||||
|
|
@ -35,7 +40,6 @@ class GroundVehicleTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can not buy a fake vehicle ('harasser')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class ImplantTerminalInterfaceTest extends Specification {
|
||||
"Implant_Terminal_Interface" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
|
||||
|
|
@ -18,8 +23,8 @@ class ImplantTerminalInterfaceTest extends Specification {
|
|||
}
|
||||
|
||||
"player can learn an implant ('darklight_vision')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "darklight_vision", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.LearnImplant] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.LearnImplant]
|
||||
|
|
@ -27,15 +32,14 @@ class ImplantTerminalInterfaceTest extends Specification {
|
|||
}
|
||||
|
||||
"player can not learn a fake implant ('aimbot')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "aimbot", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
}
|
||||
|
||||
"player can surrender an implant ('darklight_vision')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.implant_terminal_interface)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "darklight_vision", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.SellImplant] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.SellImplant]
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects.terminal
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import net.psforever.objects.definition.SeatDefinition
|
||||
import net.psforever.objects.mount.Mountable
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.implantmech.{ImplantTerminalMech, ImplantTerminalMechControl}
|
||||
import net.psforever.objects.vehicles.Seat
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3}
|
||||
import objects.ActorTest
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
|
|
@ -68,43 +68,101 @@ class ImplantTerminalMechControl1Test extends ActorTest() {
|
|||
class ImplantTerminalMechControl2Test extends ActorTest() {
|
||||
"ImplantTerminalMechControl" should {
|
||||
"let a player mount" in {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
|
||||
obj.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], obj), "mech")
|
||||
val (player, mech) = ImplantTerminalMechTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val msg = Mountable.TryMount(player, 0)
|
||||
|
||||
obj.Actor ! msg
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
mech.Actor ! msg
|
||||
val reply = receiveOne(Duration.create(200, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
val reply2 = reply.asInstanceOf[Mountable.MountMessages]
|
||||
assert(reply2.player == player)
|
||||
assert(reply2.response.isInstanceOf[Mountable.CanMount])
|
||||
val reply3 = reply2.response.asInstanceOf[Mountable.CanMount]
|
||||
assert(reply3.obj == obj)
|
||||
assert(reply3.obj == mech)
|
||||
assert(reply3.seat_num == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ImplantTerminalMechControl3Test extends ActorTest() {
|
||||
import net.psforever.types.CharacterGender
|
||||
"ImplantTerminalMechControl" should {
|
||||
"block a player from mounting" in {
|
||||
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player1, mech) = ImplantTerminalMechTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
|
||||
obj.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], obj), "mech")
|
||||
obj.Actor ! Mountable.TryMount(player1, 0)
|
||||
|
||||
mech.Actor ! Mountable.TryMount(player1, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //consume reply
|
||||
|
||||
obj.Actor ! Mountable.TryMount(player2, 0)
|
||||
mech.Actor ! Mountable.TryMount(player2, 0)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
val reply2 = reply.asInstanceOf[Mountable.MountMessages]
|
||||
assert(reply2.player == player2)
|
||||
assert(reply2.response.isInstanceOf[Mountable.CanNotMount])
|
||||
val reply3 = reply2.response.asInstanceOf[Mountable.CanNotMount]
|
||||
assert(reply3.obj == obj)
|
||||
assert(reply3.obj == mech)
|
||||
assert(reply3.seat_num == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ImplantTerminalMechControl4Test extends ActorTest() {
|
||||
"ImplantTerminalMechControl" should {
|
||||
"dismount player after mounting" in {
|
||||
val (player, mech) = ImplantTerminalMechTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
mech.Actor ! Mountable.TryMount(player, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //consume reply
|
||||
assert(mech.Seat(0).get.isOccupied)
|
||||
|
||||
mech.Actor ! Mountable.TryDismount(player, 0)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
val reply2 = reply.asInstanceOf[Mountable.MountMessages]
|
||||
assert(reply2.player == player)
|
||||
assert(reply2.response.isInstanceOf[Mountable.CanDismount])
|
||||
val reply3 = reply2.response.asInstanceOf[Mountable.CanDismount]
|
||||
assert(reply3.obj == mech)
|
||||
assert(reply3.seat_num == 0)
|
||||
assert(!mech.Seat(0).get.isOccupied)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ImplantTerminalMechControl5Test extends ActorTest() {
|
||||
"ImplantTerminalMechControl" should {
|
||||
"block a player from dismounting" in {
|
||||
val (player, mech) = ImplantTerminalMechTest.SetUpAgents(PlanetSideEmpire.TR)
|
||||
mech.Actor ! Mountable.TryMount(player, 0)
|
||||
receiveOne(Duration.create(100, "ms")) //consume reply
|
||||
assert(mech.Seat(0).get.isOccupied)
|
||||
|
||||
mech.Velocity = Vector3(1,0,0) //makes no sense, but it works as the "seat" is not bailable
|
||||
mech.Actor ! Mountable.TryDismount(player, 0)
|
||||
val reply = receiveOne(Duration.create(100, "ms"))
|
||||
assert(reply.isInstanceOf[Mountable.MountMessages])
|
||||
val reply2 = reply.asInstanceOf[Mountable.MountMessages]
|
||||
assert(reply2.player == player)
|
||||
assert(reply2.response.isInstanceOf[Mountable.CanNotDismount])
|
||||
val reply3 = reply2.response.asInstanceOf[Mountable.CanNotDismount]
|
||||
assert(reply3.obj == mech)
|
||||
assert(reply3.seat_num == 0)
|
||||
assert(mech.Seat(0).get.isOccupied)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ImplantTerminalMechTest {
|
||||
def SetUpAgents(faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, ImplantTerminalMech) = {
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
|
||||
val terminal = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
|
||||
terminal.Actor = system.actorOf(Props(classOf[ImplantTerminalMechControl], terminal), "mech")
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = faction
|
||||
terminal.GUID = PlanetSideGUID(1)
|
||||
(Player("test", faction, CharacterGender.Male, 0, 0), terminal)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.{AmmoBox, GlobalDefinitions, Player, Tool}
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types._
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class OrderTerminalTest extends Specification {
|
||||
"Order_Terminal" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
|
|
@ -18,7 +23,6 @@ class OrderTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a box of ammunition ('9mmbullet_AP')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "9mmbullet_AP", 0, PlanetSideGUID(0))
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
|
||||
|
|
@ -29,7 +33,6 @@ class OrderTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a weapon ('suppressor')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "suppressor", 0, PlanetSideGUID(0))
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
|
||||
|
|
@ -39,7 +42,6 @@ class OrderTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a box of vehicle ammunition ('105mmbullet')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 3, "105mmbullet", 0, PlanetSideGUID(0))
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
|
||||
|
|
@ -50,7 +52,6 @@ class OrderTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a support tool ('bank')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 2, "bank", 0, PlanetSideGUID(0))
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyEquipment] mustEqual true
|
||||
|
|
@ -60,14 +61,12 @@ class OrderTerminalTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy different armor ('lite_armor')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.BuyExosuit(ExoSuitType.Agile)
|
||||
}
|
||||
|
||||
"player can not buy fake equipment ('sabot')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "sabot", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
@ -76,7 +75,6 @@ class OrderTerminalTest extends Specification {
|
|||
//TODO loudout tests
|
||||
|
||||
"player can not buy equipment from the wrong page ('9mmbullet_AP', page 1)" in {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminal)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "9mmbullet_AP", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects.terminal
|
||||
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.terminals.{Terminal, TerminalControl}
|
||||
import akka.actor.{ActorSystem, Props}
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.serverobject.terminals.{Terminal, TerminalControl, TerminalDefinition}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types._
|
||||
|
|
@ -21,8 +23,7 @@ class TerminalControl1Test extends ActorTest() {
|
|||
|
||||
class TerminalControl2Test extends ActorTest() {
|
||||
"TerminalControl can not process wrong messages" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term")
|
||||
val (_, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.cert_terminal, PlanetSideEmpire.TR)
|
||||
|
||||
terminal.Actor !"hello"
|
||||
val reply = receiveOne(Duration.create(500, "ms"))
|
||||
|
|
@ -34,9 +35,7 @@ class TerminalControl2Test extends ActorTest() {
|
|||
//test for Cert_Terminal messages (see CertTerminalTest)
|
||||
class CertTerminalControl1Test extends ActorTest() {
|
||||
"TerminalControl can be used to learn a certification ('medium_assault')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.cert_terminal, PlanetSideEmpire.TR)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "medium_assault", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Actor ! Terminal.Request(player, msg)
|
||||
|
|
@ -51,9 +50,7 @@ class CertTerminalControl1Test extends ActorTest() {
|
|||
|
||||
class CertTerminalControl2Test extends ActorTest() {
|
||||
"TerminalControl can be used to warn about not learning a fake certification ('juggling')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.cert_terminal, PlanetSideEmpire.TR)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "juggling", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Actor ! Terminal.Request(player, msg)
|
||||
|
|
@ -68,9 +65,7 @@ class CertTerminalControl2Test extends ActorTest() {
|
|||
|
||||
class CertTerminalControl3Test extends ActorTest() {
|
||||
"TerminalControl can be used to forget a certification ('medium_assault')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.cert_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.cert_terminal, PlanetSideEmpire.TR)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "medium_assault", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Actor ! Terminal.Request(player, msg)
|
||||
|
|
@ -85,9 +80,7 @@ class CertTerminalControl3Test extends ActorTest() {
|
|||
|
||||
class VehicleTerminalControl1Test extends ActorTest() {
|
||||
"TerminalControl can be used to buy a vehicle ('two_man_assault_buggy')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.ground_vehicle_terminal, PlanetSideEmpire.TR)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Actor ! Terminal.Request(player, msg)
|
||||
|
|
@ -112,9 +105,7 @@ class VehicleTerminalControl1Test extends ActorTest() {
|
|||
|
||||
class VehicleTerminalControl2Test extends ActorTest() {
|
||||
"TerminalControl can be used to warn about not buy a vehicle ('harasser')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.ground_vehicle_terminal)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-cert-term")
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val (player, terminal) = TerminalControlTest.SetUpAgents(GlobalDefinitions.ground_vehicle_terminal, PlanetSideEmpire.TR)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Actor ! Terminal.Request(player, msg)
|
||||
|
|
@ -126,3 +117,13 @@ class VehicleTerminalControl2Test extends ActorTest() {
|
|||
assert(reply2.response == Terminal.NoDeal())
|
||||
}
|
||||
}
|
||||
|
||||
object TerminalControlTest {
|
||||
def SetUpAgents(tdef : TerminalDefinition, faction : PlanetSideEmpire.Value)(implicit system : ActorSystem) : (Player, Terminal) = {
|
||||
val terminal = Terminal(tdef)
|
||||
terminal.Actor = system.actorOf(Props(classOf[TerminalControl], terminal), "test-term")
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = faction
|
||||
(Player("test", faction, CharacterGender.Male, 0, 0), terminal)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
package objects.terminal
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.{GlobalDefinitions, Player}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, TransactionType}
|
||||
import org.specs2.mutable.Specification
|
||||
|
|
@ -11,6 +13,9 @@ import org.specs2.mutable.Specification
|
|||
class VehicleTerminalCombinedTest extends Specification {
|
||||
"Ground_Vehicle_Terminal" should {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
|
||||
|
|
@ -18,8 +23,8 @@ class VehicleTerminalCombinedTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a ground vehicle, the harasser ('two_man_assault_buggy')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "two_man_assault_buggy", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
|
||||
|
|
@ -35,8 +40,8 @@ class VehicleTerminalCombinedTest extends Specification {
|
|||
}
|
||||
|
||||
"player can buy a flying vehicle, the reaver ('lightgunship')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "lightgunship", 0, PlanetSideGUID(0))
|
||||
|
||||
val reply = terminal.Request(player, msg)
|
||||
reply.isInstanceOf[Terminal.BuyVehicle] mustEqual true
|
||||
val reply2 = reply.asInstanceOf[Terminal.BuyVehicle]
|
||||
|
|
@ -52,7 +57,6 @@ class VehicleTerminalCombinedTest extends Specification {
|
|||
}
|
||||
|
||||
"player can not buy a fake vehicle ('harasser')" in {
|
||||
val terminal = Terminal(GlobalDefinitions.vehicle_terminal_combined)
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 0, "harasser", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
|||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
import net.psforever.objects.serverobject.mblocker.Locker
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
|
|
@ -103,30 +104,46 @@ object Maps {
|
|||
VehicleSpawnPad.Constructor(Vector3(3508.9844f, 2895.961f, 92.296875f), Vector3(0f, 0f, 270.0f))
|
||||
)) //TODO guid not correct
|
||||
|
||||
LocalBases = 30
|
||||
LocalBuilding(2, FoundationBuilder(Building.Structure))
|
||||
ObjectToBuilding(186, 2)
|
||||
ObjectToBuilding(187, 2)
|
||||
ObjectToBuilding(188, 2)
|
||||
ObjectToBuilding(522, 2)
|
||||
ObjectToBuilding(523, 2)
|
||||
ObjectToBuilding(524, 2)
|
||||
ObjectToBuilding(525, 2)
|
||||
ObjectToBuilding(526, 2)
|
||||
ObjectToBuilding(527, 2)
|
||||
ObjectToBuilding(528, 2)
|
||||
ObjectToBuilding(529, 2)
|
||||
ObjectToBuilding(686, 2)
|
||||
ObjectToBuilding(687, 2)
|
||||
ObjectToBuilding(688, 2)
|
||||
ObjectToBuilding(689, 2)
|
||||
ObjectToBuilding(690, 2)
|
||||
ObjectToBuilding(691, 2)
|
||||
ObjectToBuilding(692, 2)
|
||||
ObjectToBuilding(693, 2)
|
||||
ObjectToBuilding(842, 2)
|
||||
ObjectToBuilding(843, 2)
|
||||
ObjectToBuilding(844, 2)
|
||||
ObjectToBuilding(845, 2)
|
||||
ObjectToBuilding(853, 2) //TODO check building_id
|
||||
ObjectToBuilding(855, 2) //TODO check building_id
|
||||
ObjectToBuilding(860, 2) //TODO check building_id
|
||||
ObjectToBuilding(1063, 2) //TODO unowned courtyard terminal?
|
||||
ObjectToBuilding(500, 2) //TODO unowned courtyard spawnpad?
|
||||
ObjectToBuilding(304, 2) //TODO unowned courtyard terminal?
|
||||
ObjectToBuilding(501, 2) //TODO unowned courtyard spawnpad?
|
||||
|
||||
ObjectToBase(330, 29)
|
||||
ObjectToBase(331, 29)
|
||||
ObjectToBase(332, 29)
|
||||
ObjectToBase(333, 29)
|
||||
//ObjectToBase(520, 29)
|
||||
ObjectToBase(522, 2)
|
||||
ObjectToBase(523, 2)
|
||||
ObjectToBase(524, 2)
|
||||
ObjectToBase(525, 2)
|
||||
ObjectToBase(526, 2)
|
||||
ObjectToBase(527, 2)
|
||||
ObjectToBase(528, 2)
|
||||
ObjectToBase(529, 2)
|
||||
ObjectToBase(556, 29)
|
||||
ObjectToBase(557, 29)
|
||||
ObjectToBase(558, 29)
|
||||
ObjectToBase(559, 29)
|
||||
ObjectToBase(1081, 2)
|
||||
ObjectToBase(1063, 2) //TODO unowned courtyard terminal?
|
||||
ObjectToBase(500, 2) //TODO unowned courtyard spawnpad?
|
||||
ObjectToBase(304, 2) //TODO unowned courtyard terminal?
|
||||
ObjectToBase(501, 2) //TODO unowned courtyard spawnpad?
|
||||
LocalBuilding(29, FoundationBuilder(Building.Structure))
|
||||
ObjectToBuilding(330, 29)
|
||||
ObjectToBuilding(332, 29)
|
||||
ObjectToBuilding(556, 29)
|
||||
ObjectToBuilding(558, 29)
|
||||
|
||||
//ObjectToBuilding(1081, ?)
|
||||
//ObjectToBuilding(520, ?)
|
||||
|
||||
DoorToLock(330, 558)
|
||||
DoorToLock(331, 559)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ import net.psforever.objects._
|
|||
import net.psforever.objects.equipment._
|
||||
import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver}
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
|
||||
import net.psforever.objects.mount.Mountable
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
||||
|
|
@ -424,7 +425,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
val obj_guid : PlanetSideGUID = obj.GUID
|
||||
log.info(s"MountVehicleMsg: $player_guid mounts $obj @ $seat_num")
|
||||
tplayer.VehicleSeated = Some(obj_guid)
|
||||
//tplayer.VehicleSeated = Some(obj_guid)
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(obj_guid, 0, 1000L))) //health of mech
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, ObjectAttachMessage(obj_guid, player_guid, seat_num)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seat_num))
|
||||
|
|
@ -434,7 +435,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
log.info(s"MountVehicleMsg: $player_guid mounts $obj_guid @ $seat_num")
|
||||
vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(obj_guid) //clear all deconstruction timers
|
||||
tplayer.VehicleSeated = Some(obj_guid)
|
||||
//tplayer.VehicleSeated = Some(obj_guid)
|
||||
if(seat_num == 0) { //simplistic vehicle ownership management
|
||||
obj.Owner match {
|
||||
case Some(owner_guid) =>
|
||||
|
|
@ -466,8 +467,37 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case Mountable.CanMount(obj : Mountable, _) =>
|
||||
log.warn(s"MountVehicleMsg: $obj is some generic mountable object and nothing will happen")
|
||||
|
||||
case Mountable.CanDismount(obj : ImplantTerminalMech, seat_num) =>
|
||||
val obj_guid : PlanetSideGUID = obj.GUID
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
log.info(s"DismountVehicleMsg: $player_guid dismounts $obj @ $seat_num")
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(player_guid, seat_num, false)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, seat_num, false))
|
||||
|
||||
case Mountable.CanDismount(obj : Vehicle, seat_num) =>
|
||||
val player_guid : PlanetSideGUID = tplayer.GUID
|
||||
if(player_guid == player.GUID) {
|
||||
//disembarking self
|
||||
log.info(s"DismountVehicleMsg: $player_guid dismounts $obj @ $seat_num")
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(player_guid, seat_num, false)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, seat_num, false))
|
||||
UnAccessContents(obj)
|
||||
}
|
||||
else {
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, seat_num, true, obj.GUID))
|
||||
}
|
||||
if(obj.Seats.values.count(seat => seat.isOccupied) == 0) {
|
||||
vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m)
|
||||
}
|
||||
|
||||
case Mountable.CanDismount(obj : Mountable, _) =>
|
||||
log.warn(s"DismountVehicleMsg: $obj is some generic mountable object and nothing will happen")
|
||||
|
||||
case Mountable.CanNotMount(obj, seat_num) =>
|
||||
log.warn(s"MountVehicleMsg: $tplayer attempted to mount $obj's seat $seat_num, but was not allowed")
|
||||
|
||||
case Mountable.CanNotDismount(obj, seat_num) =>
|
||||
log.warn(s"DismountVehicleMsg: $tplayer attempted to dismount $obj's seat $seat_num, but was not allowed")
|
||||
}
|
||||
|
||||
case Terminal.TerminalMessage(tplayer, msg, order) =>
|
||||
|
|
@ -961,11 +991,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.info("Load the now-registered player")
|
||||
//load the now-registered player
|
||||
tplayer.Spawn
|
||||
sendResponse(PacketCoding.CreateGamePacket(0,
|
||||
ObjectCreateDetailedMessage(ObjectClass.avatar, tplayer.GUID, tplayer.Definition.Packet.DetailedConstructorData(tplayer).get)
|
||||
))
|
||||
val dcdata = tplayer.Definition.Packet.DetailedConstructorData(tplayer).get
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, ObjectCreateDetailedMessage(ObjectClass.avatar, tplayer.GUID, dcdata)))
|
||||
avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.LoadPlayer(tplayer.GUID, tplayer.Definition.Packet.ConstructorData(tplayer).get))
|
||||
log.debug(s"ObjectCreateDetailedMessage: ${tplayer.Definition.Packet.DetailedConstructorData(tplayer).get}")
|
||||
log.debug(s"ObjectCreateDetailedMessage: $dcdata")
|
||||
|
||||
case SetCurrentAvatar(tplayer) =>
|
||||
val guid = tplayer.GUID
|
||||
|
|
@ -1823,52 +1852,49 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
// TODO: Not all incoming UseItemMessage's respond with another UseItemMessage (i.e. doors only send out GenericObjectStateMsg)
|
||||
continent.GUID(object_guid) match {
|
||||
case Some(door : Door) =>
|
||||
continent.Map.DoorToLock.get(object_guid.guid) match { //check for IFF Lock
|
||||
case Some(lock_guid) =>
|
||||
val lock_hacked = continent.GUID(lock_guid).get.asInstanceOf[IFFLock].HackedBy match {
|
||||
case Some(_) =>
|
||||
true
|
||||
case None =>
|
||||
Vector3.ScalarProjection(door.Outwards, player.Position - door.Position) < 0f
|
||||
}
|
||||
continent.Map.ObjectToBase.get(lock_guid) match { //check for associated base
|
||||
case Some(base_id) =>
|
||||
if(continent.Base(base_id).get.Faction == player.Faction || lock_hacked) { //either base allegiance aligns or locks is hacked
|
||||
door.Actor ! Door.Use(player, msg)
|
||||
}
|
||||
case None =>
|
||||
if(lock_hacked) { //is lock hacked? this may be a weird case
|
||||
door.Actor ! Door.Use(player, msg)
|
||||
}
|
||||
}
|
||||
case None =>
|
||||
door.Actor ! Door.Use(player, msg) //let door open freely
|
||||
if(player.Faction == door.Faction || ((continent.Map.DoorToLock.get(object_guid.guid) match {
|
||||
case Some(lock_guid) => continent.GUID(lock_guid).get.asInstanceOf[IFFLock].HackedBy.isDefined
|
||||
case None => !door.isOpen
|
||||
}) || Vector3.ScalarProjection(door.Outwards, player.Position - door.Position) < 0f)) {
|
||||
door.Actor ! Door.Use(player, msg)
|
||||
}
|
||||
else if(door.isOpen) {
|
||||
//the door is open globally ... except on our screen
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, GenericObjectStateMsg(object_guid, 16)))
|
||||
}
|
||||
|
||||
case Some(panel : IFFLock) =>
|
||||
player.Slot(player.DrawnSlot).Equipment match {
|
||||
case Some(tool : SimpleItem) =>
|
||||
if(tool.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||
//TODO get player hack level (for now, presume 15s in intervals of 4/s)
|
||||
progressBarValue = Some(-2.66f)
|
||||
self ! WorldSessionActor.ItemHacking(player, panel, tool.GUID, 2.66f, FinishHackingDoor(panel, 1114636288L))
|
||||
log.info("Hacking a door~")
|
||||
}
|
||||
case _ => ;
|
||||
if(panel.Faction != player.Faction && panel.HackedBy.isEmpty) {
|
||||
player.Slot(player.DrawnSlot).Equipment match {
|
||||
case Some(tool : SimpleItem) =>
|
||||
if(tool.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||
//TODO get player hack level (for now, presume 15s in intervals of 4/s)
|
||||
progressBarValue = Some(-2.66f)
|
||||
self ! WorldSessionActor.ItemHacking(player, panel, tool.GUID, 2.66f, FinishHackingDoor(panel, 1114636288L))
|
||||
log.info("Hacking a door~")
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
case Some(obj : Locker) =>
|
||||
val container = player.Locker
|
||||
accessedContainer = Some(container)
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, UseItemMessage(avatar_guid, unk1, container.GUID, unk2, unk3, unk4, unk5, unk6, unk7, unk8, 456)))
|
||||
if(player.Faction == obj.Faction) {
|
||||
log.info(s"UseItem: $player accessing a locker")
|
||||
val container = player.Locker
|
||||
accessedContainer = Some(container)
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, UseItemMessage(avatar_guid, unk1, container.GUID, unk2, unk3, unk4, unk5, unk6, unk7, unk8, 456)))
|
||||
}
|
||||
else {
|
||||
log.info(s"UseItem: not $player's locker")
|
||||
}
|
||||
|
||||
case Some(obj : Vehicle) =>
|
||||
if(obj.Faction == player.Faction) {
|
||||
val equipment = player.Slot(player.DrawnSlot).Equipment
|
||||
val equipment = player.Slot(player.DrawnSlot).Equipment
|
||||
if(player.Faction == obj.Faction) {
|
||||
if(equipment match {
|
||||
case Some(tool : Tool) =>
|
||||
tool.Definition match {
|
||||
case GlobalDefinitions.nano_dispenser | GlobalDefinitions.remote_electronics_kit => false
|
||||
case GlobalDefinitions.nano_dispenser => false
|
||||
case _ => true
|
||||
}
|
||||
case _ => true
|
||||
|
|
@ -1889,13 +1915,19 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case GlobalDefinitions.nano_dispenser =>
|
||||
//TODO repairing behavior
|
||||
|
||||
case GlobalDefinitions.remote_electronics_kit =>
|
||||
//TODO hacking behavior
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
}
|
||||
//enemy player interactions
|
||||
else if(equipment.isDefined) {
|
||||
equipment.get.Definition match {
|
||||
case GlobalDefinitions.remote_electronics_kit =>
|
||||
//TODO hacking behavior
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
case Some(obj : PlanetSideGameObject) =>
|
||||
if(itemType != 121) {
|
||||
|
|
@ -1933,7 +1965,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
log.info("ItemTransaction: " + msg)
|
||||
continent.GUID(terminal_guid) match {
|
||||
case Some(term : Terminal) =>
|
||||
term.Actor ! Terminal.Request(player, msg)
|
||||
if(player.Faction == term.Faction) {
|
||||
term.Actor ! Terminal.Request(player, msg)
|
||||
}
|
||||
case Some(obj : PlanetSideGameObject) => ;
|
||||
case None => ;
|
||||
}
|
||||
|
|
@ -2015,36 +2049,19 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
case msg @ DismountVehicleMsg(player_guid, unk1, unk2) =>
|
||||
//TODO optimize this later
|
||||
log.info(s"DismountVehicleMsg: $msg")
|
||||
//common warning for this section
|
||||
def dismountWarning(msg : String) : Unit = {
|
||||
log.warn(s"$msg; some vehicle might not know that a player is no longer sitting in it")
|
||||
}
|
||||
if(player.GUID == player_guid) {
|
||||
//normally disembarking from a seat
|
||||
val previouslySeated = player.VehicleSeated
|
||||
player.VehicleSeated = None
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DismountVehicleMsg(player_guid, unk1, unk2)))
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.DismountVehicle(player_guid, unk1, unk2))
|
||||
//common warning for this section
|
||||
def dismountWarning(msg : String) : Unit = {
|
||||
log.warn(s"$msg; some vehicle might not know that a player is no longer sitting in it")
|
||||
}
|
||||
//find vehicle seat and disembark it
|
||||
previouslySeated match {
|
||||
player.VehicleSeated match {
|
||||
case Some(obj_guid) =>
|
||||
continent.GUID(obj_guid) match {
|
||||
case Some(obj : Mountable) =>
|
||||
val seats = obj.Seats.values
|
||||
seats.find(seat => seat.Occupant.contains(player)) match {
|
||||
case Some(seat) =>
|
||||
if(seat.Bailable || obj.Velocity.isEmpty || Vector3.MagnitudeSquared(obj.Velocity.get).toInt == 0) { //ugh, float comparison
|
||||
seat.Occupant = None
|
||||
//special actions
|
||||
obj match {
|
||||
case (veh : Vehicle) =>
|
||||
if(seats.count(seat => seat.isOccupied) == 0) {
|
||||
vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(veh, continent, 600L) //start vehicle decay (10m)
|
||||
UnAccessContents(veh)
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
obj.PassengerInSeat(player) match {
|
||||
case Some(seat_num : Int) =>
|
||||
obj.Actor ! Mountable.TryDismount(player, seat_num)
|
||||
case None =>
|
||||
dismountWarning(s"DismountVehicleMsg: can not find where player $player_guid is seated in mountable $obj_guid")
|
||||
}
|
||||
|
|
@ -2056,35 +2073,23 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
}
|
||||
else {
|
||||
//kicking someone else out of a seat; need to own that seat
|
||||
//kicking someone else out of a seat; need to own that seat/mountable
|
||||
player.VehicleOwned match {
|
||||
case Some(vehicle_guid) =>
|
||||
continent.GUID(player_guid) match {
|
||||
case Some(tplayer : Player) =>
|
||||
if(tplayer.VehicleSeated.contains(vehicle_guid)) {
|
||||
continent.GUID(vehicle_guid) match {
|
||||
case Some(obj : Vehicle) =>
|
||||
val seats = obj.Seats.values
|
||||
seats.find(seat => seat.Occupant.contains(tplayer)) match {
|
||||
case Some(seat) =>
|
||||
seat.Occupant = None
|
||||
tplayer.VehicleSeated = None
|
||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, unk1, unk2, vehicle_guid))
|
||||
if(seats.count(seat => seat.isOccupied) == 0) {
|
||||
vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m)
|
||||
}
|
||||
case None =>
|
||||
log.warn(s"DismountVehicleMsg: can not find where player $player_guid is seated in vehicle $vehicle_guid")
|
||||
}
|
||||
case _ =>
|
||||
log.warn(s"DismountVehicleMsg: can not find vehicle $vehicle_guid")
|
||||
}
|
||||
case Some(obj_guid) =>
|
||||
(continent.GUID(obj_guid), continent.GUID(player_guid)) match {
|
||||
case (Some(obj : Mountable), Some(tplayer : Player)) =>
|
||||
obj.PassengerInSeat(tplayer) match {
|
||||
case Some(seat_num : Int) =>
|
||||
obj.Actor ! Mountable.TryDismount(tplayer, seat_num)
|
||||
case None =>
|
||||
dismountWarning(s"DismountVehicleMsg: can not find where other player $player_guid is seated in mountable $obj_guid")
|
||||
}
|
||||
else {
|
||||
log.warn(s"DismountVehicleMsg: non-owner player $player trying to kick player $tplayer out of his seat")
|
||||
}
|
||||
case _ =>
|
||||
case (None, _) => ;
|
||||
log.warn(s"DismountVehicleMsg: $player can not find his vehicle")
|
||||
case (_, None) => ;
|
||||
log.warn(s"DismountVehicleMsg: player $player_guid could not be found to kick")
|
||||
case _ =>
|
||||
log.warn(s"DismountVehicleMsg: object is either not a Mountable or not a Player")
|
||||
}
|
||||
case None =>
|
||||
log.warn(s"DismountVehicleMsg: $player does not own a vehicle")
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ object Zones {
|
|||
super.Init(context)
|
||||
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
Base(2).get.Faction = PlanetSideEmpire.VS //HART building C
|
||||
Base(29).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower
|
||||
Building(2).get.Faction = PlanetSideEmpire.VS //HART building C
|
||||
Building(29).get.Faction = PlanetSideEmpire.NC //South Villa Gun Tower
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class DeconstructionActor extends Actor {
|
|||
case DeconstructionActor.RequestDeleteVehicle(vehicle, zone, time) =>
|
||||
vehicles = vehicles :+ DeconstructionActor.VehicleEntry(vehicle, zone, time)
|
||||
vehicle.Actor ! Vehicle.PrepareForDeletion
|
||||
//kick everyone out
|
||||
//kick everyone out; this is a no-blocking manual form of MountableBehavior ! Mountable.TryDismount
|
||||
vehicle.Definition.MountPoints.values.foreach(seat_num => {
|
||||
val zone_id : String = zone.Id
|
||||
val seat : Seat = vehicle.Seat(seat_num).get
|
||||
|
|
|
|||
Loading…
Reference in a new issue