The former Player class (former-former PlaterAvatar class) has been split into a persisting Avatar class and a transitory Player class.

This commit is contained in:
FateJH 2018-03-19 20:13:39 -04:00
parent 3e9e3df0fa
commit 8a21df429b
27 changed files with 533 additions and 480 deletions

View file

@ -0,0 +1,203 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
import net.psforever.objects.definition.{AvatarDefinition, ImplantDefinition}
import net.psforever.objects.equipment.EquipmentSize
import net.psforever.types.{CertificationType, CharacterGender, ImplantType, PlanetSideEmpire}
import scala.annotation.tailrec
import scala.collection.mutable
class Avatar(val name : String, val faction : PlanetSideEmpire.Value, val sex : CharacterGender.Value, val head : Int, val voice : Int) {
/** Battle Experience Points */
private var bep : Long = 0
/** Command Experience Points */
private var cep : Long = 0
/** Certifications */
private val certs : mutable.Set[CertificationType.Value] = mutable.Set[CertificationType.Value]()
/** Implants */
private val implants : Array[ImplantSlot] = Array.fill[ImplantSlot](3)(new ImplantSlot)
/** Loadouts */
private val loadouts : Array[Option[Loadout]] = Array.fill[Option[Loadout]](10)(None)
/** Locker (fifth inventory slot) */
private val locker : EquipmentSlot = new OffhandEquipmentSlot(EquipmentSize.Inventory) {
Equipment = new LockerContainer
}
def BEP : Long = bep
def BEP_=(battleExperiencePoints : Long) : Long = {
bep = math.max(0L, math.min(battleExperiencePoints, 4294967295L))
BEP
}
def Certifications : mutable.Set[CertificationType.Value] = certs
def CEP : Long = cep
def CEP_=(commandExperiencePoints : Long) : Long = {
cep = math.max(0L, math.min(commandExperiencePoints, 4294967295L))
CEP
}
/**
* Retrieve the three implant slots for this player.
* @return an `Array` of `ImplantSlot` objects
*/
def Implants : Array[ImplantSlot] = implants
/**
* What kind of implant is installed into the given slot number?
* @see `ImplantType`
* @param slot the slot number
* @return the tye of implant
*/
def Implant(slot : Int) : ImplantType.Value = {
if(-1 < slot && slot < implants.length) { implants(slot).Implant } else { ImplantType.None }
}
/**
* Given a new implant, assign it into a vacant implant slot on this player.<br>
* <br>
* The implant must be unique in terms of which implants have already been assigned to this player.
* Multiple of a type of implant being assigned at once is not supported.
* Additionally, the implant is inserted into the earliest yet-unknown but vacant slot.
* Implant slots are vacant by just being unlocked or by having their previous implant uninstalled.
* @param implant the implant being installed
* @return the index of the `ImplantSlot` where the implant was installed
*/
def InstallImplant(implant : ImplantDefinition) : Option[Int] = {
implants.find({p => p.Installed.contains(implant)}) match { //try to find the installed implant
case None =>
recursiveFindImplantInSlot(implants.iterator, ImplantType.None) match { //install in a free slot
case Some(slot) =>
implants(slot).Implant = implant
Some(slot)
case None =>
None
}
case Some(_) =>
None
}
}
/**
* Remove a specific implant from a player's allocated installed implants.<br>
* <br>
* Due to the exclusiveness of installed implants,
* any implant slot with a matching `Definition` can be uninstalled safely.
* (There will never be any doubles.)
* This operation can lead to an irregular pattern of installed and uninstalled `ImplantSlot` objects.
* Despite that breach of pattern, the logic here is consistent as demonstrated by the client and by packets.
* The client also assigns and removes implants based on slot numbers that only express availability of a "slot."
* @see `AvatarImplantMessage.implantSlot`
* @param implantType the type of implant being uninstalled
* @return the index of the `ImplantSlot` where the implant was found and uninstalled
*/
def UninstallImplant(implantType : ImplantType.Value) : Option[Int] = {
recursiveFindImplantInSlot(implants.iterator, implantType) match {
case Some(slot) =>
implants(slot).Implant = None
Some(slot)
case None =>
None
}
}
/**
* Locate the index of the encountered implant type.
* Functional implants may be exclusive in as far as the input `Iterator`'s source is concerned,
* but any number of `ImplantType.None` values are alway allowed in the source in any order.
* @param iter an `Iterator` of `ImplantSlot` objects
* @param implantType the target implant being sought
* @param index a defaulted index value representing the structure underlying the `Iterator` param
* @return the index where the target implant is installed
*/
@tailrec private def recursiveFindImplantInSlot(iter : Iterator[ImplantSlot], implantType : ImplantType.Value, index : Int = 0) : Option[Int] = {
if(!iter.hasNext) {
None
}
else {
val slot = iter.next
if(slot.Unlocked && slot.Implant == implantType) {
Some(index)
}
else {
recursiveFindImplantInSlot(iter, implantType, index + 1)
}
}
}
def ResetAllImplants() : Unit = {
implants.foreach(slot => {
slot.Installed match {
case Some(_) =>
slot.Initialized = false
case None => ;
}
})
}
/**
* Unlike other objects, the maximum number of `ImplantSlots` are built into the `Player`.
* Additionally, "implants" do not have tightly-coupled "`Definition` objects" that explain a formal implant object.
* The `ImplantDefinition` objects themselves are moved around as if they were the implants.
* The term internally used for this process is "installed" and "uninstalled."
* @see `ImplantSlot`
* @see `DetailedCharacterData.implants`
* @see `AvatarConverter.MakeImplantEntries`
*/
def SaveLoadout(owner : Player, label : String, line : Int) : Unit = {
loadouts(line) = Some(Loadout.Create(owner, label))
}
def LoadLoadout(line : Int) : Option[Loadout] = loadouts(line)
def DeleteLoadout(line : Int) : Unit = {
loadouts(line) = None
}
def Locker : LockerContainer = locker.Equipment.get.asInstanceOf[LockerContainer]
def FifthSlot : EquipmentSlot = locker
def Definition : AvatarDefinition = Avatar.definition
/*
Merit Commendations and Ribbons
*/
// private var tosRibbon : MeritCommendation.Value = MeritCommendation.None
// private var upperRibbon : MeritCommendation.Value = MeritCommendation.None
// private var middleRibbon : MeritCommendation.Value = MeritCommendation.None
// private var lowerRibbon : MeritCommendation.Value = MeritCommendation.None
def canEqual(other: Any): Boolean = other.isInstanceOf[Avatar]
override def equals(other : Any) : Boolean = other match {
case that: Avatar =>
(that canEqual this) &&
name == that.name &&
faction == that.faction &&
sex == that.sex &&
head == that.head &&
voice == that.voice
case _ =>
false
}
override def hashCode() : Int = {
val state = Seq(name, faction, sex, head, voice)
state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
}
override def toString: String = s"$faction $name"
}
object Avatar {
final private val definition : AvatarDefinition = new AvatarDefinition(121)
def apply(name : String, faction : PlanetSideEmpire.Value, sex : CharacterGender.Value, head : Int, voice : Int) : Avatar = {
new Avatar(name, faction, sex, head, voice)
}
}

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects
import net.psforever.objects.definition.{AvatarDefinition, ImplantDefinition}
import net.psforever.objects.definition.AvatarDefinition
import net.psforever.objects.equipment.{Equipment, EquipmentSize}
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
import net.psforever.objects.serverobject.affinity.FactionAffinity
@ -9,15 +9,9 @@ import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types._
import scala.annotation.tailrec
import scala.collection.mutable
import scala.util.{Success, Try}
class Player(private val name : String,
private val faction : PlanetSideEmpire.Value,
private val sex : CharacterGender.Value,
private val head : Int,
private val voice : Int
) extends PlanetSideGameObject with FactionAffinity with Container {
class Player(private val core : Avatar) extends PlanetSideGameObject with FactionAffinity with Container {
private var alive : Boolean = false
private var backpack : Boolean = false
private var health : Int = 0
@ -29,45 +23,20 @@ class Player(private val name : String,
private var exosuit : ExoSuitType.Value = ExoSuitType.Standard
private val freeHand : EquipmentSlot = new OffhandEquipmentSlot(EquipmentSize.Inventory)
private val holsters : Array[EquipmentSlot] = Array.fill[EquipmentSlot](5)(new EquipmentSlot)
private val fifthSlot : EquipmentSlot = new OffhandEquipmentSlot(EquipmentSize.Inventory)
private val inventory : GridInventory = GridInventory()
private var drawnSlot : Int = Player.HandsDownSlot
private var lastDrawnSlot : Int = Player.HandsDownSlot
private val loadouts : Array[Option[Loadout]] = Array.fill[Option[Loadout]](10)(None)
private var bep : Long = 0
private var cep : Long = 0
private val certifications : mutable.Set[CertificationType.Value] = mutable.Set[CertificationType.Value]()
/**
* Unlike other objects, the maximum number of `ImplantSlots` are built into the `Player`.
* Additionally, "implants" do not have tightly-coupled "`Definition` objects" that explain a formal implant object.
* The `ImplantDefinition` objects themselves are moved around as if they were the implants.
* The term internally used for this process is "installed" and "uninstalled."
* @see `ImplantSlot`
* @see `DetailedCharacterData.implants`
* @see `AvatarConverter.MakeImplantEntries`
*/
private val implants : Array[ImplantSlot] = Array.fill[ImplantSlot](3)(new ImplantSlot)
// private var tosRibbon : MeritCommendation.Value = MeritCommendation.None
// private var upperRibbon : MeritCommendation.Value = MeritCommendation.None
// private var middleRibbon : MeritCommendation.Value = MeritCommendation.None
// private var lowerRibbon : MeritCommendation.Value = MeritCommendation.None
private var facingYawUpper : Float = 0f
private var crouching : Boolean = false
private var jumping : Boolean = false
private var cloaked : Boolean = false
private var backpackAccess : Option[PlanetSideGUID] = None
private var admin : Boolean = false
private var vehicleSeated : Option[PlanetSideGUID] = None
private var vehicleOwned : Option[PlanetSideGUID] = None
private var continent : String = "home2" //the zone id
private val playerDef : AvatarDefinition = Player.definition //TODO could be a var
//SouNourS things
/** Last medkituse. */
@ -75,23 +44,20 @@ class Player(private val name : String,
var death_by : Int = 0
var lastSeenStreamMessage : Array[Long] = Array.fill[Long](65535)(0L)
var lastShotSeq_time : Int = -1
/** The player is shooting. */
var shooting : Boolean = false
/** From PlanetsideAttributeMessage */
var PlanetsideAttribute : Array[Long] = Array.ofDim(120)
Player.SuitSetup(this, ExoSuit)
fifthSlot.Equipment = new LockerContainer //the fifth slot is the player's "locker"
def Name : String = name
def Name : String = core.name
def Faction : PlanetSideEmpire.Value = faction
def Faction : PlanetSideEmpire.Value = core.faction
def Sex : CharacterGender.Value = sex
def Sex : CharacterGender.Value = core.sex
def Voice : Int = voice
def Head : Int = core.head
def Head : Int = head
def Voice : Int = core.voice
def isAlive : Boolean = alive
@ -172,9 +138,7 @@ class Player(private val name : String,
holsters(slot)
}
else if(slot == 5) {
new OffhandEquipmentSlot(EquipmentSize.Inventory) {
Equipment = fifthSlot.Equipment
}
core.FifthSlot
}
else if(slot == Player.FreeHandSlot) {
freeHand
@ -188,7 +152,7 @@ class Player(private val name : String,
def Inventory : GridInventory = inventory
def Locker : LockerContainer = fifthSlot.Equipment.get.asInstanceOf[LockerContainer]
def Locker : LockerContainer = core.Locker
def Fit(obj : Equipment) : Option[Int] = {
recursiveHolsterFit(holsters.iterator, obj.Size) match {
@ -219,20 +183,6 @@ class Player(private val name : String,
}
}
def Equip(slot : Int, obj : Equipment) : Boolean = {
if(-1 < slot && slot < 5) {
holsters(slot).Equipment = obj
true
}
else if(slot == Player.FreeHandSlot) {
freeHand.Equipment = obj
true
}
else {
inventory += slot -> obj
}
}
def FreeHand = freeHand
def FreeHand_=(item : Option[Equipment]) : Option[Equipment] = {
@ -242,33 +192,19 @@ class Player(private val name : String,
FreeHand.Equipment
}
def SaveLoadout(label : String, line : Int) : Unit = {
loadouts(line) = Some(Loadout.Create(this, label))
}
def LoadLoadout(line : Int) : Option[Loadout] = loadouts(line)
def DeleteLoadout(line : Int) : Unit = {
loadouts(line) = None
}
def Find(obj : Equipment) : Option[Int] = Find(obj.GUID)
def Find(guid : PlanetSideGUID) : Option[Int] = {
findInHolsters(holsters.iterator, guid) match {
findInHolsters(holsters.iterator, guid)
.orElse(findInInventory(inventory.Items.values.iterator, guid)) match {
case Some(index) =>
Some(index)
case None =>
findInInventory(inventory.Items.values.iterator, guid) match {
case Some(index) =>
Some(index)
case None =>
if(freeHand.Equipment.isDefined && freeHand.Equipment.get.GUID == guid) {
Some(Player.FreeHandSlot)
}
else {
None
}
if(freeHand.Equipment.isDefined && freeHand.Equipment.get.GUID == guid) {
Some(Player.FreeHandSlot)
}
else {
None
}
}
}
@ -348,27 +284,13 @@ class Player(private val name : String,
exosuit = suit
}
def BEP : Long = bep
def LoadLoadout(line : Int) : Option[Loadout] = core.LoadLoadout(line)
def BEP_=(battleExperiencePoints : Long) : Long = {
bep = math.max(0L, math.min(battleExperiencePoints, 4294967295L))
BEP
}
def BEP : Long = core.BEP
def CEP : Long = cep
def CEP : Long = core.CEP
def CEP_=(commandExperiencePoints : Long) : Long = {
cep = math.max(0L, math.min(commandExperiencePoints, 4294967295L))
CEP
}
def Certifications : mutable.Set[CertificationType.Value] = certifications
/**
* Retrieve the three implant slots for this player.
* @return an `Array` of `ImplantSlot` objects
*/
def Implants : Array[ImplantSlot] = implants
def Certifications : Set[CertificationType.Value] = core.Certifications.toSet
/**
* What kind of implant is installed into the given slot number?
@ -376,91 +298,17 @@ class Player(private val name : String,
* @param slot the slot number
* @return the tye of implant
*/
def Implant(slot : Int) : ImplantType.Value = {
if(-1 < slot && slot < implants.length) { implants(slot).Implant } else { ImplantType.None }
}
def Implant(slot : Int) : ImplantType.Value = core.Implant(slot)
/**
* Given a new implant, assign it into a vacant implant slot on this player.<br>
* <br>
* The implant must be unique in terms of which implants have already been assigned to this player.
* Multiple of a type of implant being assigned at once is not supported.
* Additionally, the implant is inserted into the earliest yet-unknown but vacant slot.
* Implant slots are vacant by just being unlocked or by having their previous implant uninstalled.
* @param implant the implant being installed
* @return the index of the `ImplantSlot` where the implant was installed
* A read-only `Array` of tuples representing important information about all unlocked implant slots.
* @return a maximum of three implant types, initialization times, and active flags
*/
def InstallImplant(implant : ImplantDefinition) : Option[Int] = {
implants.find({p => p.Installed.contains(implant)}) match { //try to find the installed implant
case None =>
recursiveFindImplantInSlot(implants.iterator, ImplantType.None) match { //install in a free slot
case Some(slot) =>
implants(slot).Implant = implant
Some(slot)
case None =>
None
}
case Some(_) =>
None
}
def Implants : Array[(ImplantType.Value, Long, Boolean)] = {
core.Implants.takeWhile(_.Unlocked).map( implant => { (implant.Implant, implant.MaxTimer, implant.Active) })
}
/**
* Remove a specific implant from a player's allocated installed implants.<br>
* <br>
* Due to the exclusiveness of installed implants,
* any implant slot with a matching `Definition` can be uninstalled safely.
* (There will never be any doubles.)
* This operation can lead to an irregular pattern of installed and uninstalled `ImplantSlot` objects.
* Despite that breach of pattern, the logic here is consistent as demonstrated by the client and by packets.
* The client also assigns and removes implants based on slot numbers that only express availability of a "slot."
* @see `AvatarImplantMessage.implantSlot`
* @param implantType the type of implant being uninstalled
* @return the index of the `ImplantSlot` where the implant was found and uninstalled
*/
def UninstallImplant(implantType : ImplantType.Value) : Option[Int] = {
recursiveFindImplantInSlot(implants.iterator, implantType) match {
case Some(slot) =>
implants(slot).Implant = None
Some(slot)
case None =>
None
}
}
/**
* Locate the index of the encountered implant type.
* Functional implants may be exclusive in as far as the input `Iterator`'s source is concerned,
* but any number of `ImplantType.None` values are alway allowed in the source in any order.
* @param iter an `Iterator` of `ImplantSlot` objects
* @param implantType the target implant being sought
* @param index a defaulted index value representing the structure underlying the `Iterator` param
* @return the index where the target implant is installed
*/
@tailrec private def recursiveFindImplantInSlot(iter : Iterator[ImplantSlot], implantType : ImplantType.Value, index : Int = 0) : Option[Int] = {
if(!iter.hasNext) {
None
}
else {
val slot = iter.next
if(slot.Unlocked && slot.Implant == implantType) {
Some(index)
}
else {
recursiveFindImplantInSlot(iter, implantType, index + 1)
}
}
}
def ResetAllImplants() : Unit = {
implants.foreach(slot => {
slot.Installed match {
case Some(_) =>
slot.Initialized = false
case None => ;
}
})
}
def ResetAllImplants() : Unit = core.ResetAllImplants()
def FacingYawUpper : Float = facingYawUpper
@ -523,8 +371,6 @@ class Player(private val name : String,
isBackpack && (backpackAccess.isEmpty || backpackAccess.contains(player.GUID))
}
def Admin : Boolean = admin
def VehicleSeated : Option[PlanetSideGUID] = vehicleSeated
def VehicleSeated_=(guid : PlanetSideGUID) : Option[PlanetSideGUID] = VehicleSeated_=(Some(guid))
@ -550,52 +396,33 @@ class Player(private val name : String,
Continent
}
def Definition : AvatarDefinition = playerDef
override def toString : String = {
Player.toString(this)
}
def Definition : AvatarDefinition = core.Definition
def canEqual(other: Any): Boolean = other.isInstanceOf[Player]
override def equals(other : Any) : Boolean = other match {
case that: Player =>
(that canEqual this) &&
name == that.name &&
faction == that.faction &&
sex == that.sex &&
voice == that.voice &&
head == that.head
core == that.core
case _ =>
false
}
override def hashCode() : Int = {
val state = Seq(name, faction, sex, voice, head)
state.map(_.hashCode()).foldLeft(0)((a, b) => 31 * a + b)
core.hashCode()
}
override def toString : String = Player.toString(this)
}
object Player {
final private val definition : AvatarDefinition = new AvatarDefinition(121)
final val FreeHandSlot : Int = 250
final val HandsDownSlot : Int = 255
def apply(name : String, faction : PlanetSideEmpire.Value, sex : CharacterGender.Value, head : Int, voice : Int) : Player = {
new Player(name, faction, sex, head, voice)
def apply(core : Avatar) : Player = {
new Player(core)
}
// /**
// * Change the type of `AvatarDefinition` is used to define the player.
// * @param player the player
// * @param avatarDef the player's new definition entry
// * @return the changed player
// */
// def apply(player : Player, avatarDef : AvatarDefinition) : Player = {
// player.playerDef = avatarDef
// player
// }
def SuitSetup(player : Player, eSuit : ExoSuitType.Value) : Unit = {
val esuitDef : ExoSuitDefinition = ExoSuitDefinition.Select(eSuit)
//exosuit
@ -608,32 +435,11 @@ object Player {
(0 until 5).foreach(index => { player.Slot(index).Size = esuitDef.Holster(index) })
}
def Administrate(player : Player, isAdmin : Boolean) : Player = {
player.admin = isAdmin
player
}
def Release(player : Player) : Player = {
def Respawn(player : Player) : Player = {
if(player.Release) {
val obj = new Player(player.Name, player.Faction, player.Sex, player.Head, player.Voice)
val obj = new Player(player.core)
obj.VehicleOwned = player.VehicleOwned
obj.Continent = player.Continent
//hand over loadouts
(0 until 10).foreach(index => {
obj.loadouts(index) = player.loadouts(index)
})
//hand over implants
(0 until 3).foreach(index => {
if(obj.Implants(index).Unlocked = player.Implants(index).Unlocked) {
obj.Implants(index).Implant = player.Implants(index).Installed
}
})
//hand over knife
// obj.Slot(4).Equipment = player.Slot(4).Equipment
// player.Slot(4).Equipment = None
//hand over locker contents
// obj.fifthSlot.Equipment = player.fifthSlot.Equipment
// player.fifthSlot.Equipment = None
obj
}
else {
@ -641,8 +447,5 @@ object Player {
}
}
def toString(obj : Player) : String = {
val name : String = if(obj.VehicleSeated.isDefined) { s"[${obj.name}, ${obj.VehicleSeated.get.guid}]" } else { obj.Name }
s"[player $name, ${obj.Faction} (${obj.Health}/${obj.MaxHealth})(${obj.Armor}/${obj.MaxArmor})]"
}
def toString(obj : Player) : String = s"${obj.core} ${obj.Health}/${obj.MaxHealth} ${obj.Armor}/${obj.MaxArmor}"
}

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.definition.converter
import net.psforever.objects.{EquipmentSlot, ImplantSlot, Player}
import net.psforever.objects.{EquipmentSlot, Player}
import net.psforever.objects.equipment.Equipment
import net.psforever.packet.game.objectcreate.{BasicCharacterData, CharacterAppearanceData, CharacterData, Cosmetics, DetailedCharacterData, DrawnSlot, ImplantEffects, ImplantEntry, InternalSlot, InventoryData, PlacementData, RibbonBars, UniformStyle}
import net.psforever.types.{GrenadeState, ImplantType}
@ -136,18 +136,12 @@ class AvatarConverter extends ObjectCreateConverter[Player]() {
private def MakeImplantEntries(obj : Player) : List[ImplantEntry] = {
val numImplants : Int = DetailedCharacterData.numberOfImplantSlots(obj.BEP)
val implants = obj.Implants
(0 until numImplants).map(index => {
val slot = implants(index)
slot.Installed match {
case Some(implant) =>
if(slot.Initialized) {
ImplantEntry(slot.Implant, None)
}
else {
ImplantEntry(slot.Implant, Some(implant.Initialization.toInt))
}
case None =>
ImplantEntry(ImplantType.None, None)
obj.Implants.map({ case(implant, initialization, active) =>
if(initialization == 0) {
ImplantEntry(implant, None)
}
else {
ImplantEntry(implant, Some(math.max(0,initialization).toInt))
}
}).toList
}
@ -157,14 +151,14 @@ class AvatarConverter extends ObjectCreateConverter[Player]() {
* @param iter an `Iterator` of `ImplantSlot` objects
* @return the effect of an active implant
*/
@tailrec private def recursiveMakeImplantEffects(iter : Iterator[ImplantSlot]) : Option[ImplantEffects.Value] = {
@tailrec private def recursiveMakeImplantEffects(iter : Iterator[(ImplantType.Value, Long, Boolean)]) : Option[ImplantEffects.Value] = {
if(!iter.hasNext) {
None
}
else {
val slot = iter.next
if(slot.Active) {
slot.Implant match {
val(implant, _, active) = iter.next
if(active) {
implant match {
case ImplantType.AdvancedRegen =>
Some(ImplantEffects.RegenEffects)
case ImplantType.DarklightVision =>

View file

@ -2,7 +2,6 @@
package net.psforever.objects.zones
import akka.actor.{Actor, Props}
import net.psforever.objects.Player
import scala.annotation.tailrec

View file

@ -151,6 +151,7 @@ class ConverterTest extends Specification {
}
"Player" should {
val avatar = Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj : Player = {
/*
Create an AmmoBoxDefinition with which to build two AmmoBoxes
@ -171,7 +172,7 @@ class ConverterTest extends Specification {
val tool = Tool(tdef)
tool.GUID = PlanetSideGUID(92)
tool.AmmoSlot.Box.GUID = PlanetSideGUID(90)
val obj = Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = Player(avatar)
obj.GUID = PlanetSideGUID(93)
obj.Slot(2).Equipment = tool
obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(94)
@ -182,7 +183,7 @@ class ConverterTest extends Specification {
val converter = new CharacterSelectConverter
"convert to packet (BR < 24)" in {
obj.BEP = 0
avatar.BEP = 0
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(_) =>
ok
@ -198,7 +199,7 @@ class ConverterTest extends Specification {
}
"convert to packet (BR >= 24)" in {
obj.BEP = 10000000
avatar.BEP = 10000000
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(_) =>
ok
@ -214,7 +215,7 @@ class ConverterTest extends Specification {
}
"convert to simple packet (BR < 24)" in {
obj.BEP = 0
avatar.BEP = 0
converter.DetailedConstructorData(obj) match {
case Success(_) =>
ok
@ -226,7 +227,7 @@ class ConverterTest extends Specification {
}
"convert to simple packet (BR >= 24)" in {
obj.BEP = 10000000
avatar.BEP = 10000000
converter.DetailedConstructorData(obj) match {
case Success(_) =>
ok

View file

@ -2,7 +2,7 @@
package objects
import akka.actor.{ActorRef, ActorSystem, Props}
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.doors.{Door, DoorControl}
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.zones.Zone
@ -13,7 +13,7 @@ import org.specs2.mutable.Specification
import scala.concurrent.duration.Duration
class DoorTest extends Specification {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
"Door" should {
"construct" in {
@ -123,6 +123,6 @@ object DoorControlTest {
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)
(Player(Avatar("test", faction, CharacterGender.Male, 0, 0)), door)
}
}

View file

@ -3,10 +3,9 @@ package objects
import akka.actor.{ActorRef, ActorSystem, Props}
import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.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}
@ -70,6 +69,6 @@ object IFFLockControlTest {
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)
(Player(Avatar("test", faction, CharacterGender.Male, 0, 0)), lock)
}
}

View file

@ -4,13 +4,15 @@ package objects
import net.psforever.objects._
import net.psforever.types.{CharacterGender, ExoSuitType, PlanetSideEmpire}
import net.psforever.objects.GlobalDefinitions._
import net.psforever.objects.equipment.{Equipment, EquipmentSize}
import org.specs2.mutable._
class LoadoutTest extends Specification {
def CreatePlayer() : Player = {
val avatar = Avatar("TestCharacter", PlanetSideEmpire.VS, CharacterGender.Female, 41, 1)
def CreatePlayer() : (Player, Avatar) = {
val avatar = Avatar("TestCharacter", PlanetSideEmpire.VS, CharacterGender.Female, 41, 1)
val
player = Player("TestCharacter", PlanetSideEmpire.VS, CharacterGender.Female, 41, 1)
player = Player(avatar)
player.Slot(0).Equipment = Tool(beamer)
player.Slot(2).Equipment = Tool(suppressor)
player.Slot(4).Equipment = Tool(forceblade)
@ -20,12 +22,12 @@ class LoadoutTest extends Specification {
player.Slot(33).Equipment = AmmoBox(bullet_9mm_AP)
player.Slot(36).Equipment = AmmoBox(energy_cell)
player.Slot(39).Equipment = SimpleItem(remote_electronics_kit)
player
(player, avatar)
}
"Player Loadout" should {
"test sample player" in {
val obj : Player = CreatePlayer()
val (obj, _) = CreatePlayer()
obj.Holsters()(0).Equipment.get.Definition mustEqual beamer
obj.Holsters()(2).Equipment.get.Definition mustEqual suppressor
obj.Holsters()(4).Equipment.get.Definition mustEqual forceblade
@ -38,23 +40,23 @@ class LoadoutTest extends Specification {
}
"do not load, if never saved" in {
CreatePlayer().LoadLoadout(0) mustEqual None
CreatePlayer()._2.LoadLoadout(0) mustEqual None
}
"save but incorrect load" in {
val obj : Player = CreatePlayer()
obj.SaveLoadout("test", 0)
val (obj, avatar) = CreatePlayer()
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(1) mustEqual None
avatar.LoadLoadout(1) mustEqual None
}
"save and load" in {
val obj : Player = CreatePlayer()
val (obj, avatar) = CreatePlayer()
obj.Slot(0).Equipment.get.asInstanceOf[Tool].Magazine = 1 //non-standard but legal
obj.Slot(2).Equipment.get.asInstanceOf[Tool].AmmoSlot.Magazine = 100 //non-standard (and out of range, real=25)
obj.SaveLoadout("test", 0)
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(0) match {
avatar.LoadLoadout(0) match {
case Some(items) =>
items.Label mustEqual "test"
items.ExoSuit mustEqual obj.ExoSuit
@ -91,11 +93,11 @@ class LoadoutTest extends Specification {
}
"save without inventory contents" in {
val obj : Player = CreatePlayer()
val (obj, avatar) = CreatePlayer()
obj.Inventory.Clear()
obj.SaveLoadout("test", 0)
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(0) match {
avatar.LoadLoadout(0) match {
case Some(items) =>
items.Label mustEqual "test"
items.ExoSuit mustEqual obj.ExoSuit
@ -108,13 +110,13 @@ class LoadoutTest extends Specification {
}
"save without visible slot contents" in {
val obj : Player = CreatePlayer()
val (obj, avatar) = CreatePlayer()
obj.Slot(0).Equipment = None
obj.Slot(2).Equipment = None
obj.Slot(4).Equipment = None
obj.SaveLoadout("test", 0)
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(0) match {
avatar.LoadLoadout(0) match {
case Some(items) =>
items.Label mustEqual "test"
items.ExoSuit mustEqual obj.ExoSuit
@ -127,12 +129,12 @@ class LoadoutTest extends Specification {
}
"save (a construction item) and load" in {
val obj : Player = CreatePlayer()
val (obj, avatar) = CreatePlayer()
obj.Inventory.Clear()
obj.Slot(6).Equipment = ConstructionItem(advanced_ace)
obj.SaveLoadout("test", 0)
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(0) match {
avatar.LoadLoadout(0) match {
case Some(items) =>
items.Inventory.length mustEqual 1
items.Inventory.head.index mustEqual 6
@ -143,12 +145,12 @@ class LoadoutTest extends Specification {
}
"save (a kit) and load" in {
val obj : Player = CreatePlayer()
val (obj, avatar) = CreatePlayer()
obj.Inventory.Clear()
obj.Slot(6).Equipment = Kit(medkit)
obj.SaveLoadout("test", 0)
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(0) match {
avatar.LoadLoadout(0) match {
case Some(items) =>
items.Inventory.length mustEqual 1
items.Inventory.head.index mustEqual 6
@ -159,38 +161,38 @@ class LoadoutTest extends Specification {
}
"save, load, delete" in {
val obj : Player = CreatePlayer()
obj.SaveLoadout("test", 0)
val (obj, avatar) = CreatePlayer()
avatar.SaveLoadout(obj, "test", 0)
obj.LoadLoadout(0) match {
avatar.LoadLoadout(0) match {
case None =>
ko
case Some(_) => ; //good; keep going
}
obj.DeleteLoadout(0)
obj.LoadLoadout(0) mustEqual None
avatar.DeleteLoadout(0)
avatar.LoadLoadout(0) mustEqual None
}
"distinguish MAX subtype information" in {
val obj : Player = CreatePlayer()
val (obj, avatar) = CreatePlayer()
val slot = obj.Slot(0)
slot.Equipment = None //only an unequipped slot can have its Equipment Size changed (Rifle -> Max)
Player.SuitSetup(obj, ExoSuitType.MAX)
obj.SaveLoadout("generic", 0) //weaponless
avatar.SaveLoadout(obj, "generic", 0) //weaponless
slot.Equipment = None
slot.Equipment = Tool(trhev_dualcycler)
obj.SaveLoadout("cycler", 1)
avatar.SaveLoadout(obj, "cycler", 1)
slot.Equipment = None
slot.Equipment = Tool(trhev_pounder)
obj.SaveLoadout("pounder", 2)
avatar.SaveLoadout(obj, "pounder", 2)
slot.Equipment = None
slot.Equipment = Tool(trhev_burster)
obj.SaveLoadout("burster", 3)
avatar.SaveLoadout(obj, "burster", 3)
obj.LoadLoadout(0).get.Subtype mustEqual 0
obj.LoadLoadout(1).get.Subtype mustEqual 1
obj.LoadLoadout(2).get.Subtype mustEqual 2
obj.LoadLoadout(3).get.Subtype mustEqual 3
avatar.LoadLoadout(0).get.Subtype mustEqual 0
avatar.LoadLoadout(1).get.Subtype mustEqual 1
avatar.LoadLoadout(2).get.Subtype mustEqual 2
avatar.LoadLoadout(3).get.Subtype mustEqual 3
}
}
}

View file

@ -2,7 +2,7 @@
package objects
import akka.actor.{Actor, ActorRef, Props}
import net.psforever.objects.Player
import net.psforever.objects.{Avatar, Player}
import net.psforever.objects.definition.{ObjectDefinition, SeatDefinition}
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
import net.psforever.objects.serverobject.PlanetSideServerObject
@ -25,7 +25,7 @@ class MountableControl1Test extends ActorTest() {
class MountableControl2Test extends ActorTest() {
"MountableControl" should {
"let a player mount" in {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val obj = new MountableTest.MountableTestObject
obj.Actor = system.actorOf(Props(classOf[MountableTest.MountableTestControl], obj), "mountable")
val msg = Mountable.TryMount(player, 0)
@ -46,8 +46,8 @@ class MountableControl2Test extends ActorTest() {
class MountableControl3Test extends ActorTest() {
"MountableControl" should {
"block a player from mounting" in {
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(Avatar("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val player2 = Player(Avatar("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val obj = new MountableTest.MountableTestObject
obj.Actor = system.actorOf(Props(classOf[MountableTest.MountableTestControl], obj), "mountable")
obj.Actor ! Mountable.TryMount(player1, 0)

View file

@ -2,35 +2,35 @@
package objects
import net.psforever.objects._
import net.psforever.objects.definition.{ImplantDefinition, SimpleItemDefinition}
import net.psforever.objects.definition.SimpleItemDefinition
import net.psforever.objects.equipment.EquipmentSize
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{CharacterGender, ExoSuitType, ImplantType, PlanetSideEmpire}
import net.psforever.types.{CharacterGender, ExoSuitType, PlanetSideEmpire}
import org.specs2.mutable._
class PlayerTest extends Specification {
"construct" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.isAlive mustEqual false
}
"different players" in {
(Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)) mustEqual true
(Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)) mustEqual false
(Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
Player("Chord", PlanetSideEmpire.NC, CharacterGender.Male, 0, 5)) mustEqual false
(Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Female, 0, 5)) mustEqual false
(Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 1, 5)) mustEqual false
(Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 6)) mustEqual false
(PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)) mustEqual true
(PlayerTest.Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
PlayerTest.Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)) mustEqual false
(PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
PlayerTest.Player("Chord", PlanetSideEmpire.NC, CharacterGender.Male, 0, 5)) mustEqual false
(PlayerTest.Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
PlayerTest.Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Female, 0, 5)) mustEqual false
(PlayerTest.Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
PlayerTest.Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 1, 5)) mustEqual false
(PlayerTest.Player("Chord1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) ==
PlayerTest.Player("Chord2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 6)) mustEqual false
}
"become a backpack" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.isAlive mustEqual false
obj.isBackpack mustEqual false
obj.Release
@ -39,7 +39,7 @@ class PlayerTest extends Specification {
}
"(re)spawn" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.isAlive mustEqual false
obj.Health mustEqual 0
obj.Stamina mustEqual 0
@ -55,7 +55,7 @@ class PlayerTest extends Specification {
}
"set new maximum values (health, stamina)" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.MaxHealth mustEqual 100
obj.MaxStamina mustEqual 100
obj.MaxHealth = 123
@ -66,7 +66,7 @@ class PlayerTest extends Specification {
}
"init (Standard Exo-Suit)" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.ExoSuit mustEqual ExoSuitType.Standard
obj.Slot(0).Size mustEqual EquipmentSize.Pistol
obj.Slot(1).Size mustEqual EquipmentSize.Blocked
@ -79,7 +79,7 @@ class PlayerTest extends Specification {
}
"die" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Spawn
obj.Armor = 35 //50 -> 35
obj.isAlive mustEqual true
@ -95,7 +95,7 @@ class PlayerTest extends Specification {
"draw equipped holsters only" in {
val wep = SimpleItem(SimpleItemDefinition(149))
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Slot(1).Size = EquipmentSize.Pistol
obj.Slot(1).Equipment = wep
obj.DrawnSlot mustEqual Player.HandsDownSlot
@ -108,7 +108,7 @@ class PlayerTest extends Specification {
"remember the last drawn holster" in {
val wep1 = SimpleItem(SimpleItemDefinition(149))
val wep2 = SimpleItem(SimpleItemDefinition(149))
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Slot(0).Size = EquipmentSize.Pistol
obj.Slot(0).Equipment = wep1
obj.Slot(1).Size = EquipmentSize.Pistol
@ -147,7 +147,7 @@ class PlayerTest extends Specification {
"hold something in their free hand" in {
val wep = SimpleItem(SimpleItemDefinition(149))
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Slot(Player.FreeHandSlot).Equipment = wep
obj.Slot(Player.FreeHandSlot).Equipment.get.Definition.ObjectId mustEqual 149
@ -155,14 +155,14 @@ class PlayerTest extends Specification {
"provide an invalid hand that can not hold anything" in {
val wep = SimpleItem(SimpleItemDefinition(149))
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Slot(-1).Equipment = wep
obj.Slot(-1).Equipment mustEqual None
}
"search for the smallest available slot in which to satore equipment" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
"search for the smallest available slot in which to store equipment" in {
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Inventory.Resize(3,3)
obj.Fit(Tool(GlobalDefinitions.beamer)) mustEqual Some(0)
@ -171,7 +171,7 @@ class PlayerTest extends Specification {
val ammo = AmmoBox(GlobalDefinitions.bullet_9mm)
val ammo2 = AmmoBox(GlobalDefinitions.bullet_9mm)
val ammo3 = AmmoBox(GlobalDefinitions.bullet_9mm)
//val ammo3 = AmmoBox(GlobalDefinitions.bullet_9mm)
obj.Fit(ammo) mustEqual Some(6)
obj.Slot(6).Equipment = ammo
obj.Fit(ammo2) mustEqual Some(Player.FreeHandSlot)
@ -179,43 +179,44 @@ class PlayerTest extends Specification {
obj.Fit(ammo2) mustEqual None
}
"install an implant" in {
val testplant : ImplantDefinition = ImplantDefinition(1)
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Implants(0).Unlocked = true
obj.InstallImplant(testplant) mustEqual Some(0)
obj.Implants.find({p => p.Implant == ImplantType(1)}) match { //find the installed implant
case Some(slot) =>
slot.Installed mustEqual Some(testplant)
case _ =>
ko
}
ok
}
"can not install the same type of implant twice" in {
val testplant1 : ImplantDefinition = ImplantDefinition(1)
val testplant2 : ImplantDefinition = ImplantDefinition(1)
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Implants(0).Unlocked = true
obj.Implants(1).Unlocked = true
obj.InstallImplant(testplant1) mustEqual Some(0)
obj.InstallImplant(testplant2) mustEqual Some(1)
}
"uninstall implants" in {
val testplant : ImplantDefinition = ImplantDefinition(1)
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Implants(0).Unlocked = true
obj.InstallImplant(testplant) mustEqual Some(0)
obj.Implants(0).Installed mustEqual Some(testplant)
obj.UninstallImplant(testplant.Type)
obj.Implants(0).Installed mustEqual None
}
//TODO move to Avatar tests
// "install an implant" in {
// val testplant : ImplantDefinition = ImplantDefinition(1)
// val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
// obj.Implants(0).Unlocked = true
// obj.InstallImplant(testplant) mustEqual Some(0)
// obj.Implants.find({p => p.Implant == ImplantType(1)}) match { //find the installed implant
// case Some(slot) =>
// slot.Installed mustEqual Some(testplant)
// case _ =>
// ko
// }
// ok
// }
//
// "can not install the same type of implant twice" in {
// val testplant1 : ImplantDefinition = ImplantDefinition(1)
// val testplant2 : ImplantDefinition = ImplantDefinition(1)
// val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
// obj.Implants(0).Unlocked = true
// obj.Implants(1).Unlocked = true
// obj.InstallImplant(testplant1) mustEqual Some(0)
// obj.InstallImplant(testplant2) mustEqual Some(1)
// }
//
// "uninstall implants" in {
// val testplant : ImplantDefinition = ImplantDefinition(1)
// val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
// obj.Implants(0).Unlocked = true
// obj.InstallImplant(testplant) mustEqual Some(0)
// obj.Implants(0).Installed mustEqual Some(testplant)
//
// obj.UninstallImplant(testplant.Type)
// obj.Implants(0).Installed mustEqual None
// }
"seat in a vehicle" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.VehicleSeated mustEqual None
obj.VehicleSeated = PlanetSideGUID(65)
obj.VehicleSeated mustEqual Some(PlanetSideGUID(65))
@ -224,7 +225,7 @@ class PlayerTest extends Specification {
}
"own in a vehicle" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.VehicleOwned mustEqual None
obj.VehicleOwned = PlanetSideGUID(65)
obj.VehicleOwned mustEqual Some(PlanetSideGUID(65))
@ -233,18 +234,15 @@ class PlayerTest extends Specification {
}
"remember what zone he is in" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
val obj = PlayerTest.Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Continent mustEqual "home2"
obj.Continent = "ugd01"
obj.Continent mustEqual "ugd01"
}
}
"administrate" in {
val obj = new Player("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Admin mustEqual false
Player.Administrate(obj, true)
obj.Admin mustEqual true
Player.Administrate(obj, false)
obj.Admin mustEqual false
object PlayerTest {
def Player(name : String, faction : PlanetSideEmpire.Value, sex : CharacterGender.Value, head : Int, voice : Int) : Player = {
new Player(Avatar(name, faction, sex, head, voice))
}
}

View file

@ -6,7 +6,7 @@ import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawn
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.objects.{Avatar, GlobalDefinitions, Player, Vehicle}
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3}
import org.specs2.mutable.Specification
@ -111,6 +111,6 @@ object VehicleSpawnPadControl {
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)
(Player(Avatar("test", faction, CharacterGender.Male, 0, 0)), pad)
}
}

View file

@ -2,17 +2,18 @@
package objects
import akka.actor.Props
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
import net.psforever.objects._
import net.psforever.objects.definition.{SeatDefinition, VehicleDefinition}
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 net.psforever.types.ExoSuitType
import org.specs2.mutable._
import scala.concurrent.duration.Duration
class VehicleTest extends Specification {
import VehicleTest._
"SeatDefinition" should {
val seat = new SeatDefinition
@ -73,7 +74,7 @@ class VehicleTest extends Specification {
val seat = new Seat(seat_def)
seat.Occupant.isDefined mustEqual false
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(avatar1)
player1.ExoSuit = ExoSuitType.MAX
seat.Occupant = player1
seat.Occupant.isDefined mustEqual true
@ -84,13 +85,13 @@ class VehicleTest extends Specification {
val seat = new Seat(seat_def)
seat.Occupant.isDefined mustEqual false
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(avatar1)
player1.ExoSuit = ExoSuitType.MAX
seat.Occupant = player1
seat.Occupant.isDefined mustEqual true
seat.Occupant.contains(player1) mustEqual true
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(avatar1)
player2.ExoSuit = ExoSuitType.MAX
seat.Occupant = player2
seat.Occupant.isDefined mustEqual true
@ -101,13 +102,13 @@ class VehicleTest extends Specification {
val seat = new Seat(seat_def)
seat.Occupant.isDefined mustEqual false
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(avatar1)
player1.ExoSuit = ExoSuitType.MAX
seat.Occupant = player1
seat.Occupant.isDefined mustEqual true
seat.Occupant.contains(player1) mustEqual true
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(avatar2)
player2.ExoSuit = ExoSuitType.MAX
seat.Occupant = player2
seat.Occupant.isDefined mustEqual true
@ -160,7 +161,7 @@ class VehicleTest extends Specification {
val fury_vehicle = Vehicle(GlobalDefinitions.fury)
fury_vehicle.Owner.isDefined mustEqual false
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(avatar1)
player1.GUID = PlanetSideGUID(1)
fury_vehicle.Owner = player1
fury_vehicle.Owner.isDefined mustEqual true
@ -171,13 +172,13 @@ class VehicleTest extends Specification {
val fury_vehicle = Vehicle(GlobalDefinitions.fury)
fury_vehicle.Owner.isDefined mustEqual false
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(avatar1)
player1.GUID = PlanetSideGUID(1)
fury_vehicle.Owner = player1
fury_vehicle.Owner.isDefined mustEqual true
fury_vehicle.Owner.contains(PlanetSideGUID(1)) mustEqual true
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(avatar2)
player2.GUID = PlanetSideGUID(2)
fury_vehicle.Owner = player2
fury_vehicle.Owner.isDefined mustEqual true
@ -234,9 +235,9 @@ class VehicleTest extends Specification {
"can find a passenger in a seat" in {
val harasser_vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(avatar1)
player1.GUID = PlanetSideGUID(1)
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(avatar2)
player2.GUID = PlanetSideGUID(2)
harasser_vehicle.Seat(0).get.Occupant = player1 //don't worry about ownership for now
harasser_vehicle.Seat(1).get.Occupant = player2
@ -282,9 +283,9 @@ 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)
val player1 = Player(VehicleTest.avatar1)
player1.GUID = PlanetSideGUID(1)
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(VehicleTest.avatar2)
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
vehicle.GUID = PlanetSideGUID(3)
vehicle.Actor = system.actorOf(Props(classOf[VehicleControl], vehicle), "vehicle-test")
@ -303,9 +304,9 @@ class VehicleControl1Test extends ActorTest {
class VehicleControl2Test extends ActorTest {
"Vehicle Control" should {
"reactivate and resume handling mount messages" in {
val player1 = Player("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player1 = Player(VehicleTest.avatar1)
player1.GUID = PlanetSideGUID(1)
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(VehicleTest.avatar2)
player2.GUID = PlanetSideGUID(2)
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
vehicle.GUID = PlanetSideGUID(3)
@ -324,3 +325,10 @@ class VehicleControl2Test extends ActorTest {
}
}
}
object VehicleTest {
import net.psforever.objects.Avatar
import net.psforever.types.{CharacterGender, PlanetSideEmpire}
val avatar1 = Avatar("test1", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val avatar2 = Avatar("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
}

View file

@ -10,7 +10,7 @@ import objects.ActorTest
class GUIDTaskRegister5Test extends ActorTest() {
"RegisterAvatar" in {
val (_, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup
val obj = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val obj = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val obj_wep = Tool(GlobalDefinitions.beamer)
obj.Slot(0).Equipment = obj_wep
val obj_wep_ammo = AmmoBox(GlobalDefinitions.energy_cell)

View file

@ -9,7 +9,7 @@ import objects.ActorTest
class GUIDTaskUnregister5Test extends ActorTest() {
"UnregisterAvatar" in {
val (guid, uns, taskResolver, probe) = GUIDTaskTest.CommonTestSetup
val obj = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val obj = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val obj_wep = Tool(GlobalDefinitions.beamer)
obj.Slot(0).Equipment = obj_wep
val obj_wep_ammo = AmmoBox(GlobalDefinitions.energy_cell)

View file

@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
@ -12,7 +12,7 @@ import org.specs2.mutable.Specification
class AirVehicleTerminalTest extends Specification {
"Air_Vehicle_Terminal" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -5,14 +5,14 @@ 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.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable.Specification
class CertTerminalTest extends Specification {
"Cert_Terminal" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
@ -12,7 +12,7 @@ import org.specs2.mutable.Specification
class DropshipVehicleTerminalTest extends Specification {
"Dropship_Vehicle_Terminal" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
@ -12,7 +12,7 @@ import org.specs2.mutable.Specification
class GroundVehicleTerminalTest extends Specification {
"Ground_Vehicle_Terminal" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
@ -12,7 +12,7 @@ import org.specs2.mutable.Specification
class ImplantTerminalInterfaceTest extends Specification {
"Implant_Terminal_Interface" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -6,7 +6,7 @@ import net.psforever.objects.definition.SeatDefinition
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.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3}
import objects.ActorTest
import org.specs2.mutable.Specification
@ -44,7 +44,7 @@ class ImplantTerminalMechTest extends Specification {
}
"get passenger in a seat" in {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val obj = ImplantTerminalMech(GlobalDefinitions.implant_terminal_mech)
obj.PassengerInSeat(player) mustEqual None
obj.Seats(0).Occupant = player
@ -89,7 +89,7 @@ class ImplantTerminalMechControl3Test extends ActorTest() {
"ImplantTerminalMechControl" should {
"block a player from mounting" in {
val (player1, mech) = ImplantTerminalMechTest.SetUpAgents(PlanetSideEmpire.TR)
val player2 = Player("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player2 = Player(Avatar("test2", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
mech.Actor ! Mountable.TryMount(player1, 0)
receiveOne(Duration.create(100, "ms")) //consume reply
@ -163,6 +163,6 @@ object ImplantTerminalMechTest {
terminal.Owner = new Building(0, Zone.Nowhere)
terminal.Owner.Faction = faction
terminal.GUID = PlanetSideGUID(1)
(Player("test", faction, CharacterGender.Male, 0, 0), terminal)
(Player(Avatar("test", faction, CharacterGender.Male, 0, 0)), terminal)
}
}

View file

@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.terminals.{MatrixTerminalDefinition, Terminal}
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player, Vehicle}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable.Specification
@ -54,7 +54,7 @@ class MatrixTerminalTest extends Specification {
}
"player can not buy (anything)" in {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
terminal.Request(player, msg) mustEqual Terminal.NoDeal()

View file

@ -5,7 +5,7 @@ import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.serverobject.terminals.{OrderTerminalABDefinition, Terminal}
import net.psforever.objects.zones.Zone
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable.Specification
@ -47,14 +47,14 @@ class OrderTerminalABTest extends Specification {
}
"player can buy different armor ('lite_armor')" in {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "lite_armor", 0, PlanetSideGUID(0))
terminal.Request(player, msg) mustEqual Terminal.BuyExosuit(ExoSuitType.Agile)
}
"player can buy max armor ('trhev_antiaircraft')" in {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0))
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "trhev_antiaircraft", 0, PlanetSideGUID(0))
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
@ -62,10 +62,11 @@ class OrderTerminalABTest extends Specification {
//TODO loudout tests
"player can not load max loadout" in {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
player.SaveLoadout("test1", 0)
val avatar = Avatar("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(avatar)
avatar.SaveLoadout(player, "test1", 0)
player.ExoSuit = ExoSuitType.MAX
player.SaveLoadout("test2", 1)
avatar.SaveLoadout(player, "test2", 1)
val msg1 = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.InfantryLoadout, 4, "", 0, PlanetSideGUID(0))
terminal.Request(player, msg1) mustEqual Terminal.InfantryLoadout(ExoSuitType.Standard, 0, Nil, Nil)

View file

@ -5,14 +5,14 @@ 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.objects.{AmmoBox, Avatar, GlobalDefinitions, Player, Tool}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types._
import org.specs2.mutable.Specification
class OrderTerminalTest extends Specification {
"Order_Terminal" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -5,7 +5,7 @@ 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.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
import net.psforever.types._
import objects.ActorTest
@ -124,6 +124,6 @@ object TerminalControlTest {
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)
(Player(Avatar("test", faction, CharacterGender.Male, 0, 0)), terminal)
}
}

View file

@ -3,7 +3,7 @@ package objects.terminal
import akka.actor.ActorRef
import net.psforever.objects.serverobject.structures.Building
import net.psforever.objects.{GlobalDefinitions, Player}
import net.psforever.objects.{Avatar, GlobalDefinitions, Player}
import net.psforever.objects.serverobject.terminals.Terminal
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{ItemTransactionMessage, PlanetSideGUID}
@ -12,7 +12,7 @@ import org.specs2.mutable.Specification
class VehicleTerminalCombinedTest extends Specification {
"Ground_Vehicle_Terminal" should {
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
val player = Player(Avatar("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

View file

@ -9,6 +9,7 @@ import scodec.Attempt.{Failure, Successful}
import scodec.bits._
import org.log4s.MDC
import MDCContextAware.Implicits._
import net.psforever.objects.GlobalDefinitions._
import services.ServiceManager.Lookup
import net.psforever.objects._
import net.psforever.objects.equipment._
@ -60,6 +61,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
var flying : Boolean = false
var speed : Float = 1.0f
var spectator : Boolean = false
var admin : Boolean = false
var clientKeepAlive : Cancellable = DefaultCancellable.obj
var progressBarUpdate : Cancellable = DefaultCancellable.obj
@ -763,9 +765,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ItemTransactionResultMessage (msg.terminal_guid, TransactionType.InfantryLoadout, true))
case Terminal.LearnCertification(cert, cost) =>
if(!player.Certifications.contains(cert)) {
if(!tplayer.Certifications.contains(cert)) {
log.info(s"$tplayer is learning the $cert certification for $cost points")
tplayer.Certifications += cert
avatar.Certifications += cert
sendResponse(PlanetsideAttributeMessage(tplayer.GUID, 24, cert.id.toLong))
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, true))
}
@ -775,9 +777,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
case Terminal.SellCertification(cert, cost) =>
if(player.Certifications.contains(cert)) {
if(tplayer.Certifications.contains(cert)) {
log.info(s"$tplayer is forgetting the $cert certification for $cost points")
tplayer.Certifications -= cert
avatar.Certifications -= cert
sendResponse(PlanetsideAttributeMessage(tplayer.GUID, 25, cert.id.toLong))
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Sell, true))
}
@ -794,8 +796,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(mech_guid) =>
(
continent.Map.TerminalToInterface.get(mech_guid.guid),
if(!tplayer.Implants.exists({slot => slot.Implant == implant_type})) { //no duplicates
tplayer.InstallImplant(implant)
if(!avatar.Implants.exists({slot => slot.Implant == implant_type})) { //no duplicates
avatar.InstallImplant(implant)
}
else {
None
@ -834,7 +836,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(mech_guid) =>
(
continent.Map.TerminalToInterface.get(mech_guid.guid),
tplayer.UninstallImplant(implant_type)
avatar.UninstallImplant(implant_type)
)
case None =>
(None, None)
@ -1004,12 +1006,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
case NewPlayerLoaded(tplayer) =>
log.info(s"Player $tplayer has been loaded")
player = tplayer
//LoadMapMessage will cause the client to send back a BeginZoningMessage packet (see below)
sendResponse(LoadMapMessage(continent.Map.Name, continent.Id, 40100,25,true,3770441820L))
AvatarCreate()
case PlayerLoaded(tplayer) =>
log.info(s"Player $tplayer has been loaded")
player = tplayer
AvatarCreate()
self ! SetCurrentAvatar(tplayer)
@ -1020,6 +1024,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
case SetCurrentAvatar(tplayer) =>
player = tplayer
val guid = tplayer.GUID
LivePlayerList.Assign(continent.Number, sessionId, guid)
sendResponse(SetCurrentAvatarMessage(guid,0,0))
@ -1178,6 +1183,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
}
var player : Player = null
var avatar : Avatar = null
var spawnZones : Map[Int, Building] = null
def handleGamePkt(pkt : PlanetSideGamePacket) = pkt match {
@ -1187,39 +1193,40 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO begin temp player character auto-loading; remove later
import net.psforever.objects.GlobalDefinitions._
import net.psforever.types.CertificationType._
player = Player("TestCharacter"+sessionId.toString, PlanetSideEmpire.VS, CharacterGender.Female, 41, 1)
avatar = Avatar("TestCharacter"+sessionId.toString, PlanetSideEmpire.VS, CharacterGender.Female, 41, 1)
avatar.Certifications += StandardAssault
avatar.Certifications += MediumAssault
avatar.Certifications += StandardExoSuit
avatar.Certifications += AgileExoSuit
avatar.Certifications += ReinforcedExoSuit
avatar.Certifications += ATV
avatar.Certifications += Harasser
//
avatar.Certifications += InfiltrationSuit
avatar.Certifications += Sniping
avatar.Certifications += AntiVehicular
avatar.Certifications += HeavyAssault
avatar.Certifications += SpecialAssault
avatar.Certifications += EliteAssault
avatar.Certifications += GroundSupport
avatar.Certifications += GroundTransport
avatar.Certifications += Flail
avatar.Certifications += Switchblade
avatar.Certifications += AssaultBuggy
avatar.Certifications += ArmoredAssault1
avatar.Certifications += ArmoredAssault2
avatar.Certifications += AirCavalryScout
avatar.Certifications += AirCavalryAssault
avatar.Certifications += AirCavalryInterceptor
avatar.Certifications += AirSupport
avatar.Certifications += GalaxyGunship
avatar.Certifications += Phantasm
avatar.Certifications += UniMAX
AwardBattleExperiencePoints(avatar, 1000000L)
player = new Player(avatar)
//player.Position = Vector3(3561.0f, 2854.0f, 90.859375f) //home3, HART C
player.Position = Vector3(3881.9688f, 4432.008f, 267.0f) //z6, Anguta / n.tower
player.Orientation = Vector3(0f, 0f, 90f)
player.Certifications += StandardAssault
player.Certifications += MediumAssault
player.Certifications += StandardExoSuit
player.Certifications += AgileExoSuit
player.Certifications += ReinforcedExoSuit
player.Certifications += ATV
player.Certifications += Harasser
//
player.Certifications += InfiltrationSuit
player.Certifications += Sniping
player.Certifications += AntiVehicular
player.Certifications += HeavyAssault
player.Certifications += SpecialAssault
player.Certifications += EliteAssault
player.Certifications += GroundSupport
player.Certifications += GroundTransport
player.Certifications += Flail
player.Certifications += Switchblade
player.Certifications += AssaultBuggy
player.Certifications += ArmoredAssault1
player.Certifications += ArmoredAssault2
player.Certifications += AirCavalryScout
player.Certifications += AirCavalryAssault
player.Certifications += AirCavalryInterceptor
player.Certifications += AirSupport
player.Certifications += GalaxyGunship
player.Certifications += Phantasm
player.Certifications += UniMAX
AwardBattleExperiencePoints(player, 1000000L)
// player.ExoSuit = ExoSuitType.MAX //TODO strange issue; divide number above by 10 when uncommenting
player.Slot(0).Equipment = SimpleItem(remote_electronics_kit) //Tool(GlobalDefinitions.StandardPistol(player.Faction))
player.Slot(2).Equipment = Tool(punisher) //suppressor
@ -1355,14 +1362,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
self ! SetCurrentAvatar(player)
case msg @ PlayerStateMessageUpstream(avatar_guid, pos, vel, yaw, pitch, yaw_upper, seq_time, unk3, is_crouching, is_jumping, unk4, is_cloaking, unk5, unk6) =>
if(player.isAlive && player.GUID == avatar_guid) {
if(!player.isAlive) {
player.Position = pos
player.Velocity = vel
player.Orientation = Vector3(player.Orientation.x, pitch, yaw)
player.FacingYawUpper = yaw_upper
player.Crouching = is_crouching
player.Jumping = is_jumping
val wepInHand : Boolean = player.Slot(player.DrawnSlot).Equipment match {
case Some(item) => item.Definition == GlobalDefinitions.bolt_driver
case None => false
@ -1429,9 +1435,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
case msg @ ReleaseAvatarRequestMessage() =>
log.info(s"ReleaseAvatarRequest: ${player.GUID} on ${continent.Id} has released")
player.Release
val knife = player.Slot(4).Equipment.get
taskResolver ! RemoveEquipmentFromSlot(player, knife, 4)
sendResponse(PlanetsideAttributeMessage(player.GUID, 6, 1))
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, 2, true))
player = Player.Release(player) //swap new player
case msg @ SpawnRequestMessage(u1, u2, u3, u4, u5) =>
log.info(s"SpawnRequestMessage: $msg")
@ -1439,20 +1446,19 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(building) =>
scala.util.Random.shuffle(building.Amenities.filter(_.isInstanceOf[SpawnTube])).headOption match { //TODO temporary shuffle
case Some(tube) =>
log.info(s"SpawnRequestMessage: new player was at position ${player.Position}")
player.Position = tube.Position
player.Orientation = tube.Orientation
player.FacingYawUpper = 0
log.info(s"SpawnRequestMessage: new player moved to position ${player.Position}")
val tplayer = SpawnRequest(player) //new player
tplayer.Position = tube.Position
tplayer.Orientation = tube.Orientation
log.info(s"SpawnRequestMessage: new player will spawn in ${building.Id} @ tube ${tube.GUID.guid}")
sendResponse(AvatarDeadStateMessage(DeadState.RespawnTime, 10000, 10000, Vector3.Zero, 2, true))
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
context.system.scheduler.scheduleOnce(10 seconds, taskResolver, RegisterAvatar(player))
context.system.scheduler.scheduleOnce(10 seconds, taskResolver, RegisterAvatar(tplayer))
case None =>
log.warn(s"SpawnRequestMessage: can not find a spawn point in this spawn group - $u2")
}
case None =>
log.warn(s"SpawnRequestMessage: can not find somewhere to spawn in ${continent.Id}")
log.warn(s"SpawnRequestMessage: can not find somewhere to spawn on ${continent.Id}")
}
case msg @ SetChatFilterMessage(send_channel, origin, whitelist) =>
@ -2120,10 +2126,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
action match {
case FavoritesAction.Unknown => ;
case FavoritesAction.Save =>
player.SaveLoadout(name, line)
avatar.SaveLoadout(player, name, line)
sendResponse(FavoritesMessage(0, player_guid, line, name))
case FavoritesAction.Delete =>
player.DeleteLoadout(line)
avatar.DeleteLoadout(line)
sendResponse(FavoritesMessage(0, player_guid, line, ""))
}
}
@ -2540,10 +2546,32 @@ class WorldSessionActor extends Actor with MDCContextAware {
override def onFailure(ex : Throwable) : Unit = {
localAnnounce ! PlayerFailedToLoad(localPlayer) //alerts WSA
}
}, List(GUIDTask.RegisterAvatar(tplayer)(continent.GUID))
}, List(RegisterLightweightAvatar(tplayer)(continent.GUID))
)
}
//TODO temporary function for registering avatar without locker contents
def RegisterLightweightAvatar(tplayer : Player)(implicit guid : ActorRef) : TaskResolver.GiveTask = {
import net.psforever.objects.LockerContainer
import net.psforever.objects.inventory.InventoryItem
val holsterTasks = tplayer.Holsters().filter(_.Equipment.isDefined).map(slot =>{
GUIDTask.RegisterEquipment(slot.Equipment.get)(guid)
}).toList
val inventoryTasks = tplayer.Inventory.Items.map({ case((_ : Int, entry : InventoryItem)) => GUIDTask.RegisterEquipment(entry.obj)(guid)})
TaskResolver.GiveTask(GUIDTask.RegisterObjectTask(tplayer)(guid).task, holsterTasks ++ inventoryTasks)
}
//TODO temporary function for unregistering avatar without locker contents
def UnregisterLightweightAvatar(tplayer : Player)(implicit guid : ActorRef) : TaskResolver.GiveTask = {
import net.psforever.objects.LockerContainer
import net.psforever.objects.inventory.InventoryItem
val holsterTasks = tplayer.Holsters().filter(_.Equipment.isDefined).map(slot =>{
GUIDTask.UnregisterEquipment(slot.Equipment.get)(guid)
}).toList
val inventoryTasks = tplayer.Inventory.Items.map({ case((_ : Int, entry : InventoryItem)) => GUIDTask.UnregisterEquipment(entry.obj)(guid)})
TaskResolver.GiveTask(GUIDTask.UnregisterObjectTask(tplayer)(guid).task, holsterTasks ++ inventoryTasks)
}
/**
* Construct tasking that adds a completed and registered vehicle into the scene.
* Use this function to renew the globally unique identifiers on a vehicle that has already been added to the scene once.
@ -2807,21 +2835,21 @@ class WorldSessionActor extends Actor with MDCContextAware {
* @param bep the change in experience points, positive by assertion
* @return the player's current battle experience points
*/
def AwardBattleExperiencePoints(tplayer : Player, bep : Long) : Long = {
val oldBep = tplayer.BEP
def AwardBattleExperiencePoints(avatar : Avatar, bep : Long) : Long = {
val oldBep = avatar.BEP
if(bep <= 0) {
log.error(s"trying to set $bep battle experience points on $tplayer; value can not be negative")
log.error(s"trying to set $bep battle experience points on $avatar; value can not be negative")
oldBep
}
else {
val oldSlots = DetailedCharacterData.numberOfImplantSlots(oldBep)
val newBep = oldBep + bep
val newSlots = DetailedCharacterData.numberOfImplantSlots(newBep)
tplayer.BEP = newBep
avatar.BEP = newBep
if(newSlots > oldSlots) {
(oldSlots until newSlots).foreach(slotNumber => {
tplayer.Implants(slotNumber).Unlocked = true
log.info(s"unlocking implant slot $slotNumber for $tplayer")
avatar.Implants(slotNumber).Unlocked = true
log.info(s"unlocking implant slot $slotNumber for $avatar")
})
}
newBep
@ -3290,6 +3318,23 @@ class WorldSessionActor extends Actor with MDCContextAware {
log.debug(s"ObjectCreateDetailedMessage: $dcdata")
}
def SpawnRequest(tplayer : Player) : Player = {
val faction = tplayer.Faction
val obj = Player.Respawn(tplayer)
//obj.VehicleOwned = tplayer.VehicleOwned
//obj.Continent = tplayer.Continent
obj.Slot(0).Equipment = Tool(StandardPistol(faction))
obj.Slot(2).Equipment = Tool(suppressor)
obj.Slot(4).Equipment = Tool(StandardMelee(faction))
obj.Slot(6).Equipment = AmmoBox(bullet_9mm)
obj.Slot(9).Equipment = AmmoBox(bullet_9mm)
obj.Slot(12).Equipment = AmmoBox(bullet_9mm)
obj.Slot(33).Equipment = AmmoBox(bullet_9mm_AP)
obj.Slot(36).Equipment = AmmoBox(StandardPistolAmmo(faction))
obj.Slot(39).Equipment = SimpleItem(remote_electronics_kit)
obj
}
def failWithError(error : String) = {
log.error(error)
sendResponse(ConnectionClose())

View file

@ -110,7 +110,7 @@ class EquipmentOnGroundTest extends ActorTest {
}
class LoadPlayerTest extends ActorTest {
val obj = Player("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, 1)
val obj = Player(Avatar("TestCharacter1", PlanetSideEmpire.VS, CharacterGender.Female, 1, 1))
obj.GUID = PlanetSideGUID(10)
obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(11)
val pdata = obj.Definition.Packet.DetailedConstructorData(obj).get