mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
Utility:
A container class for vehicle-installed Amenity objects that are owned by the vehicle. It not only constructs the internalized Amenity but harbors logic that is required to setup the object at a more appropriate time (at start of VehicleControl). OrderTerminalABDefinition: Terminals built into the sides of the advanced mobile spawn, accessible when it deploys. OCM packet converters, GUID registrtaion, and setup code allows the code to wire into the vehicle.
This commit is contained in:
parent
fb1c365bc2
commit
860edf9a97
|
|
@ -12,7 +12,7 @@ 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.objects.vehicles.{SeatArmorRestriction, UtilityType}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
object GlobalDefinitions {
|
||||
|
|
@ -486,6 +486,10 @@ object GlobalDefinitions {
|
|||
*/
|
||||
val order_terminal = new OrderTerminalDefinition
|
||||
|
||||
val order_terminala = new OrderTerminalABDefinition(613)
|
||||
|
||||
val order_terminalb = new OrderTerminalABDefinition(614)
|
||||
|
||||
val cert_terminal = new CertTerminalDefinition
|
||||
|
||||
val implant_terminal_mech = new ImplantTerminalMechDefinition
|
||||
|
|
@ -2343,6 +2347,8 @@ object GlobalDefinitions {
|
|||
ams.Seats(0).ArmorRestriction = SeatArmorRestriction.NoReinforcedOrMax
|
||||
ams.MountPoints += 1 -> 0
|
||||
ams.MountPoints += 2 -> 0
|
||||
ams.Utilities += 3 -> UtilityType.order_terminala
|
||||
ams.Utilities += 4 -> UtilityType.order_terminalb
|
||||
ams.Packet = utilityConverter
|
||||
|
||||
val variantConverter = new VariantVehicleConverter
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import net.psforever.packet.game.objectcreate.DriveState
|
|||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* The server-side support object that represents a vehicle.<br>
|
||||
|
|
@ -49,7 +48,7 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
private val groupPermissions : Array[VehicleLockState.Value] = Array(VehicleLockState.Locked, VehicleLockState.Empire, VehicleLockState.Empire, VehicleLockState.Locked)
|
||||
private var seats : Map[Int, Seat] = Map.empty
|
||||
private var weapons : Map[Int, EquipmentSlot] = Map.empty
|
||||
private val utilities : mutable.ArrayBuffer[Utility] = mutable.ArrayBuffer()
|
||||
private var utilities : Map[Int, Utility] = Map()
|
||||
private val trunk : GridInventory = GridInventory()
|
||||
|
||||
//init
|
||||
|
|
@ -325,16 +324,21 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
}
|
||||
}
|
||||
|
||||
def Utilities : mutable.ArrayBuffer[Utility] = utilities
|
||||
def Utilities : Map[Int, Utility] = utilities
|
||||
|
||||
/**
|
||||
* Get a referenece ot a certain `Utility` attached to this `Vehicle`.
|
||||
* @param utilNumber the attachment number of the `Utility`
|
||||
* @return the `Utility` or `None` (if invalid)
|
||||
*/
|
||||
def Utility(utilNumber : Int) : Option[Utility] = {
|
||||
def Utility(utilNumber : Int) : Option[PlanetSideServerObject] = {
|
||||
if(utilNumber >= 0 && utilNumber < this.utilities.size) {
|
||||
Some(this.utilities(utilNumber))
|
||||
this.utilities.get(utilNumber) match {
|
||||
case Some(util) =>
|
||||
Some(util())
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
}
|
||||
else {
|
||||
None
|
||||
|
|
@ -506,10 +510,8 @@ object Vehicle {
|
|||
}).toMap
|
||||
//create seats
|
||||
vehicle.seats = vdef.Seats.map({ case(num, definition) => num -> Seat(definition)}).toMap
|
||||
for(i <- vdef.Utilities) {
|
||||
//TODO utilies must be loaded and wired on a case-by-case basis?
|
||||
vehicle.Utilities += Utility.Select(i, vehicle)
|
||||
}
|
||||
//create utilities
|
||||
vehicle.utilities = vdef.Utilities.map({ case(num, util) => num -> Utility(util, vehicle) }).toMap
|
||||
//trunk
|
||||
vdef.TrunkSize match {
|
||||
case InventoryTile.None => ;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.definition
|
|||
|
||||
import net.psforever.objects.definition.converter.VehicleConverter
|
||||
import net.psforever.objects.inventory.InventoryTile
|
||||
import net.psforever.objects.vehicles.UtilityType
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) {
|
|||
/* key - seat index (where this weapon attaches during object construction), value - the weapon on an EquipmentSlot */
|
||||
private val weapons : mutable.HashMap[Int, ToolDefinition] = mutable.HashMap[Int, ToolDefinition]()
|
||||
private var deployment : Boolean = false
|
||||
private val utilities : mutable.ArrayBuffer[Int] = mutable.ArrayBuffer[Int]()
|
||||
private val utilities : mutable.HashMap[Int, UtilityType.Value] = mutable.HashMap()
|
||||
private var trunkSize : InventoryTile = InventoryTile.None
|
||||
private var trunkOffset : Int = 0
|
||||
private var canCloak : Boolean = false
|
||||
|
|
@ -69,7 +70,7 @@ class VehicleDefinition(objectId : Int) extends ObjectDefinition(objectId) {
|
|||
Deployment
|
||||
}
|
||||
|
||||
def Utilities : mutable.ArrayBuffer[Int] = utilities
|
||||
def Utilities : mutable.HashMap[Int, UtilityType.Value] = utilities
|
||||
|
||||
def TrunkSize : InventoryTile = trunkSize
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.definition.converter
|
||||
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.packet.game.objectcreate.CommonTerminalData
|
||||
|
||||
import scala.util.{Success, Try}
|
||||
|
||||
class TerminalConverter extends ObjectCreateConverter[Terminal]() {
|
||||
override def ConstructorData(obj : Terminal) : Try[CommonTerminalData] = { Success(CommonTerminalData(obj.Faction)) }
|
||||
}
|
||||
|
|
@ -29,55 +29,28 @@ class VehicleConverter extends ObjectCreateConverter[Vehicle]() {
|
|||
false,
|
||||
obj.Cloaked,
|
||||
SpecificFormatData(obj),
|
||||
Some(InventoryData(MakeMountings(obj).sortBy(_.parentSlot)))
|
||||
Some(InventoryData((MakeUtilities(obj) ++ MakeMountings(obj)).sortBy(_.parentSlot)))
|
||||
)(SpecificFormatModifier)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param obj the `Player` game object
|
||||
* @return a list of all tools that were in the mounted weapon slots in decoded packet form
|
||||
*/
|
||||
|
||||
private def MakeMountings(obj : Vehicle) : List[InventoryItemData.InventoryItem] = {
|
||||
obj.Weapons.map({
|
||||
case((index, slot)) =>
|
||||
val equip : Equipment = slot.Equipment.get
|
||||
InventoryItemData(equip.Definition.ObjectId, equip.GUID, index, equip.Definition.Packet.ConstructorData(equip).get)
|
||||
val equipDef = equip.Definition
|
||||
InventoryItemData(equipDef.ObjectId, equip.GUID, index, equipDef.Packet.ConstructorData(equip).get)
|
||||
}).toList
|
||||
}
|
||||
|
||||
// /**
|
||||
// * na
|
||||
// * @param obj the `Player` game object
|
||||
// * @return a list of all items that were in the inventory in decoded packet form
|
||||
// */
|
||||
// private def MakeTrunk(obj : Vehicle) : List[InternalSlot] = {
|
||||
// obj.Trunk.Items.map({
|
||||
// case(_, item) =>
|
||||
// val equip : Equipment = item.obj
|
||||
// InventoryItemData(equip.Definition.ObjectId, equip.GUID, item.start, equip.Definition.Packet.ConstructorData(equip).get)
|
||||
// }).toList
|
||||
// }
|
||||
|
||||
// @tailrec private def recursiveMakeSeats(iter : Iterator[(Int, Seat)], list : List[InventoryItemData.InventoryItem] = Nil) : List[InventoryItemData.InventoryItem] = {
|
||||
// if(!iter.hasNext) {
|
||||
// list
|
||||
// }
|
||||
// else {
|
||||
// val (index, seat) = iter.next
|
||||
// seat.Occupant match {
|
||||
// case Some(avatar) =>
|
||||
// val definition = avatar.Definition
|
||||
// recursiveMakeSeats(
|
||||
// iter,
|
||||
// list :+ InventoryItemData(definition.ObjectId, avatar.GUID, index, definition.Packet.ConstructorData(avatar).get)
|
||||
// )
|
||||
// case None =>
|
||||
// recursiveMakeSeats(iter, list)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
protected def MakeUtilities(obj : Vehicle) : List[InventoryItemData.InventoryItem] = {
|
||||
obj.Utilities.map({
|
||||
case(index, utilContainer) =>
|
||||
val util = utilContainer()
|
||||
val utilDef = util.Definition
|
||||
InventoryItemData(utilDef.ObjectId, util.GUID, index, utilDef.Packet.ConstructorData(util).get)
|
||||
}).toList
|
||||
}
|
||||
|
||||
protected def SpecificFormatModifier : VehicleFormat.Value = VehicleFormat.Normal
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.guid
|
||||
|
||||
import net.psforever.objects.vehicles.Utility
|
||||
|
||||
/**
|
||||
* The basic compiled tasks for assigning (registering) and revoking (unregistering) globally unique identifiers.<br>
|
||||
* <br>
|
||||
|
|
@ -149,8 +151,9 @@ object GUIDTask {
|
|||
def RegisterVehicle(vehicle : Vehicle)(implicit guid : ActorRef) : TaskResolver.GiveTask = {
|
||||
import net.psforever.objects.inventory.InventoryItem
|
||||
val weaponTasks = vehicle.Weapons.map({ case(_ : Int, entry : EquipmentSlot) => RegisterEquipment(entry.Equipment.get)}).toList
|
||||
val utilTasks = vehicle.Utilities.map({case (_ : Int, util : Utility) => RegisterObjectTask(util())}).toList
|
||||
val inventoryTasks = vehicle.Trunk.Items.map({ case((_ : Int, entry : InventoryItem)) => RegisterEquipment(entry.obj)})
|
||||
TaskResolver.GiveTask(RegisterObjectTask(vehicle).task, weaponTasks ++ inventoryTasks)
|
||||
TaskResolver.GiveTask(RegisterObjectTask(vehicle).task, weaponTasks ++ utilTasks ++ inventoryTasks)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -252,8 +255,9 @@ object GUIDTask {
|
|||
def UnregisterVehicle(vehicle : Vehicle)(implicit guid : ActorRef) : TaskResolver.GiveTask = {
|
||||
import net.psforever.objects.inventory.InventoryItem
|
||||
val weaponTasks = vehicle.Weapons.map({ case(_ : Int, entry : EquipmentSlot) => UnregisterTool(entry.Equipment.get.asInstanceOf[Tool]) }).toList
|
||||
val utilTasks = vehicle.Utilities.map({case (_ : Int, util : Utility) => UnregisterObjectTask(util())}).toList
|
||||
val inventoryTasks = vehicle.Trunk.Items.map({ case((_ : Int, entry : InventoryItem)) => UnregisterEquipment(entry.obj)})
|
||||
TaskResolver.GiveTask(UnregisterObjectTask(vehicle).task, weaponTasks ++ inventoryTasks)
|
||||
TaskResolver.GiveTask(UnregisterObjectTask(vehicle).task, weaponTasks ++ utilTasks ++ inventoryTasks)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,10 +4,27 @@ package net.psforever.objects.serverobject.terminals
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.definition._
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.packet.game.ItemTransactionMessage
|
||||
import net.psforever.types.ExoSuitType
|
||||
|
||||
import scala.annotation.switch
|
||||
|
||||
abstract class EquipmentTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
|
||||
Name = "equipment_terminal"
|
||||
|
||||
/**
|
||||
* Process a `TransactionType.Sell` action by the user.
|
||||
* There is no specific tab associated with this action.
|
||||
* It is a common button on the terminal interface window.
|
||||
* Additionally, the equipment to be sold ia almost always in the player's `FreeHand` slot.
|
||||
* Selling `Equipment` is always permitted.
|
||||
* @param player the player
|
||||
* @param msg the original packet carrying the request
|
||||
* @return an actionable message that explains how to process the request
|
||||
*/
|
||||
override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
|
||||
Terminal.SellEquipment()
|
||||
}
|
||||
}
|
||||
|
||||
object EquipmentTerminalDefinition {
|
||||
|
|
@ -22,7 +39,15 @@ object EquipmentTerminalDefinition {
|
|||
"standard_issue_armor" -> (ExoSuitType.Standard, 0),
|
||||
"lite_armor" -> (ExoSuitType.Agile, 0),
|
||||
"med_armor" -> (ExoSuitType.Reinforced, 0),
|
||||
"stealth_armor" -> (ExoSuitType.Infiltration, 0),
|
||||
"stealth_armor" -> (ExoSuitType.Infiltration, 0)
|
||||
)
|
||||
|
||||
/**
|
||||
* A `Map` of information for changing mechanized assault exo-suits.
|
||||
* key - an identification string sent by the client
|
||||
* value - a `Tuple` containing exo-suit specifications
|
||||
*/
|
||||
val maxSuits : Map[String, (ExoSuitType.Value, Int)] = Map(
|
||||
"trhev_antiaircraft" -> (ExoSuitType.MAX, 3),
|
||||
"trhev_antipersonnel" -> (ExoSuitType.MAX, 1),
|
||||
"trhev_antivehicular" -> (ExoSuitType.MAX, 2),
|
||||
|
|
@ -337,4 +362,57 @@ object EquipmentTerminalDefinition {
|
|||
MakeKit(obj.kdef)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a `TransactionType.Buy` action by the user.
|
||||
* Either attempt to purchase equipment or attempt to switch directly to a different exo-suit.
|
||||
* @param page0Stock the `Equipment` items and `AmmoBox` items available on the first tab
|
||||
* @param page2Stock the `Equipment` items and `AmmoBox` items available on the third tab
|
||||
* @param exosuits the exo-suit types (and subtypes) available on the second tab
|
||||
* @param player the player
|
||||
* @param msg the original packet carrying the request
|
||||
* @return an actionable message that explains how to process the request
|
||||
*/
|
||||
def Buy(page0Stock : Map[String, ()=>Equipment],
|
||||
page2Stock : Map[String, ()=>Equipment],
|
||||
exosuits : Map[String, (ExoSuitType.Value, Int)])
|
||||
(player : Player, msg : ItemTransactionMessage): Terminal.Exchange = {
|
||||
(msg.item_page : @switch) match {
|
||||
case 0 => //Weapon tab
|
||||
page0Stock.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case 2 => //Support tab
|
||||
page2Stock.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case 3 => //Vehicle tab
|
||||
vehicleAmmunition.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case 1 => //Armor tab
|
||||
exosuits.get(msg.item_name) match {
|
||||
case Some((suit, subtype)) =>
|
||||
Terminal.BuyExosuit(suit, subtype)
|
||||
case None =>
|
||||
maxAmmo.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.inventory.InventoryItem
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.packet.game.ItemTransactionMessage
|
||||
import net.psforever.objects.serverobject.terminals.EquipmentTerminalDefinition._
|
||||
import net.psforever.types.ExoSuitType
|
||||
|
||||
/**
|
||||
* The definition for any `Terminal` that is of a type "ams_order_terminal".
|
||||
* As the name indicates, paired on the flanks of an advanced mobile spawn vehicle.<br>
|
||||
* <br>
|
||||
* `Buy` and `Sell` `Equipment` items and `AmmoBox` items.
|
||||
* Change `ExoSuitType` and retrieve `Loadout` entries.
|
||||
* Changing into mechanized assault exo-suits (MAXes) is not permitted.
|
||||
*/
|
||||
class OrderTerminalABDefinition(object_id : Int) extends EquipmentTerminalDefinition(object_id) {
|
||||
if(object_id == 613) {
|
||||
Name = "order_terminala"
|
||||
}
|
||||
else if(object_id == 614) {
|
||||
Name = "order_terminalb"
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("terminal must be either object id 613 or object id 614")
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Equipment` available from this `Terminal` on specific pages.
|
||||
*/
|
||||
private val buyFunc : (Player, ItemTransactionMessage)=>Terminal.Exchange =
|
||||
EquipmentTerminalDefinition.Buy(
|
||||
infantryAmmunition ++ infantryWeapons,
|
||||
supportAmmunition ++ supportWeapons,
|
||||
suits
|
||||
)
|
||||
|
||||
override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = buyFunc(player, msg)
|
||||
|
||||
/**
|
||||
* Process a `TransactionType.InfantryLoadout` action by the user.
|
||||
* `Loadout` objects are blueprints composed of exo-suit specifications and simplified `Equipment`-to-slot mappings.
|
||||
* If a valid loadout is found, its data is transformed back into actual `Equipment` for return to the user.
|
||||
* Loadouts that would suit the player into a mechanized assault exo-suit are not permitted.
|
||||
* @param player the player
|
||||
* @param msg the original packet carrying the request
|
||||
* @return an actionable message that explains how to process the request
|
||||
*/
|
||||
override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
|
||||
if(msg.item_page == 4) { //Favorites tab
|
||||
player.LoadLoadout(msg.unk1) match {
|
||||
case Some(loadout) =>
|
||||
if(loadout.ExoSuit != ExoSuitType.MAX) {
|
||||
val holsters = loadout.VisibleSlots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
|
||||
val inventory = loadout.Inventory.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
|
||||
Terminal.InfantryLoadout(loadout.ExoSuit, loadout.Subtype, holsters, inventory)
|
||||
}
|
||||
else {
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
else {
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object OrderTerminalABDefinition {
|
||||
/**
|
||||
* Assemble some logic for a provided object.
|
||||
* @param obj an `Amenity` object;
|
||||
* anticipating a `Terminal` object using this same definition
|
||||
* @param context hook to the local `Actor` system
|
||||
*/
|
||||
def Setup(obj : Amenity, context : ActorContext) : Unit = {
|
||||
import akka.actor.{ActorRef, Props}
|
||||
if(obj.Actor == ActorRef.noSender) {
|
||||
obj.Actor = context.actorOf(Props(classOf[TerminalControl], obj), s"${obj.Definition.Name}_${obj.GUID.guid}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,14 @@
|
|||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.InventoryItem
|
||||
import net.psforever.packet.game.ItemTransactionMessage
|
||||
import net.psforever.objects.serverobject.terminals.EquipmentTerminalDefinition._
|
||||
|
||||
import scala.annotation.switch
|
||||
|
||||
/**
|
||||
* The definition for any `Terminal` that is of a type "order_terminal".
|
||||
* This kind of "order_terminal" is applicable to facilities.<br>
|
||||
* <br>
|
||||
* `Buy` and `Sell` `Equipment` items and `AmmoBox` items.
|
||||
* Change `ExoSuitType` and retrieve `Loadout` entries.
|
||||
*/
|
||||
|
|
@ -20,68 +19,12 @@ class OrderTerminalDefinition extends EquipmentTerminalDefinition(612) {
|
|||
/**
|
||||
* The `Equipment` available from this `Terminal` on specific pages.
|
||||
*/
|
||||
private val page0Stock : Map[String, ()=>Equipment] = infantryAmmunition ++ infantryWeapons
|
||||
private val page2Stock : Map[String, ()=>Equipment] = supportAmmunition ++ supportWeapons
|
||||
private val buyFunc : (Player, ItemTransactionMessage)=>Terminal.Exchange = EquipmentTerminalDefinition.Buy(
|
||||
infantryAmmunition ++ infantryWeapons,
|
||||
supportAmmunition ++ supportWeapons,
|
||||
suits ++ maxSuits)
|
||||
|
||||
/**
|
||||
* Process a `TransactionType.Buy` action by the user.
|
||||
* Either attempt to purchase equipment or attempt to switch directly to a different exo-suit.
|
||||
* @param player the player
|
||||
* @param msg the original packet carrying the request
|
||||
* @return an actionable message that explains how to process the request
|
||||
*/
|
||||
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
|
||||
(msg.item_page : @switch) match {
|
||||
case 0 => //Weapon tab
|
||||
page0Stock.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case 2 => //Support tab
|
||||
page2Stock.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case 3 => //Vehicle tab
|
||||
vehicleAmmunition.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
case 1 => //Armor tab
|
||||
suits.get(msg.item_name) match {
|
||||
case Some((suit, subtype)) =>
|
||||
Terminal.BuyExosuit(suit, subtype)
|
||||
case None =>
|
||||
maxAmmo.get(msg.item_name) match {
|
||||
case Some(item) =>
|
||||
Terminal.BuyEquipment(item())
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a `TransactionType.Sell` action by the user.
|
||||
* There is no specific `order_terminal` tab associated with this action.
|
||||
* Additionally, the equipment to be sold ia almost always in the player's `FreeHand` slot.
|
||||
* Selling `Equipment` is always permitted.
|
||||
* @param player the player
|
||||
* @param msg the original packet carrying the request
|
||||
* @return an actionable message that explains how to process the request
|
||||
*/
|
||||
override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
|
||||
Terminal.SellEquipment()
|
||||
}
|
||||
override def Buy(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = buyFunc(player, msg)
|
||||
|
||||
/**
|
||||
* Process a `TransactionType.InfantryLoadout` action by the user.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.objects.serverobject.terminals
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.definition.converter.TerminalConverter
|
||||
import net.psforever.packet.game.ItemTransactionMessage
|
||||
|
||||
/**
|
||||
|
|
@ -10,6 +11,7 @@ import net.psforever.packet.game.ItemTransactionMessage
|
|||
*/
|
||||
abstract class TerminalDefinition(objectId : Int) extends net.psforever.objects.definition.ObjectDefinition(objectId) {
|
||||
Name = "terminal"
|
||||
Packet = new TerminalConverter
|
||||
|
||||
/**
|
||||
* The unimplemented functionality for this `Terminal`'s `TransactionType.Buy` and `TransactionType.Learn` activity.
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.vehicles
|
||||
|
||||
import net.psforever.objects.Vehicle
|
||||
|
||||
/**
|
||||
* A `Utility` designed to simulate the NTU-distributive functions of an ANT.
|
||||
* @param objectId the object id that is associated with this sort of `Utility`
|
||||
* @param vehicle the `Vehicle` to which this `Utility` is attached
|
||||
*/
|
||||
class ANTResourceUtility(objectId : Int, vehicle : Vehicle) extends Utility(objectId, vehicle) {
|
||||
private var currentNTU : Int = 0
|
||||
|
||||
def NTU : Int = currentNTU
|
||||
|
||||
def NTU_=(ntu : Int) : Int = {
|
||||
currentNTU = ntu
|
||||
currentNTU = math.max(math.min(currentNTU, MaxNTU), 0)
|
||||
NTU
|
||||
}
|
||||
|
||||
def MaxNTU : Int = ANTResourceUtility.MaxNTU
|
||||
}
|
||||
|
||||
object ANTResourceUtility {
|
||||
private val MaxNTU : Int = 300 //TODO what should this value be?
|
||||
|
||||
def apply(objectId : Int, vehicle : Vehicle) : ANTResourceUtility = {
|
||||
new ANTResourceUtility(objectId, vehicle)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,104 +1,97 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.vehicles
|
||||
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
import scala.annotation.switch
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.serverobject.terminals.{OrderTerminalABDefinition, Terminal}
|
||||
|
||||
/**
|
||||
* A `Utility` represents an unknown but functional entity that is attached to a `Vehicle` and is not a weapon or a seat.
|
||||
* This is a placeholder solution until a better system is established.
|
||||
* @param objectId the object id that is associated with this sort of `Utility`
|
||||
* @param vehicle the `Vehicle` to which this `Utility` is attached
|
||||
* An `Enumeration` of the available vehicular utilities.<br>
|
||||
* <br>
|
||||
* These values are used to connect `Amenity` objects and their extra logic encapsulated in this class
|
||||
* with information in the `VehicleDefinition` object for that kind of vehicle.
|
||||
* @see `Vehicle.LoadDefinition`
|
||||
* @see `VehicleDefinition.Utilities`
|
||||
*/
|
||||
class Utility(val objectId : Int, vehicle : Vehicle) extends IdentifiableEntity {
|
||||
private var active : Boolean = false
|
||||
object UtilityType extends Enumeration {
|
||||
type Type = Value
|
||||
val
|
||||
order_terminala,
|
||||
order_terminalb
|
||||
= Value
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a specific functional extension that is a component of a certain `Vehicle` object.<br>
|
||||
* <br>
|
||||
* A `Utility` object is a variation of an `Amenity` object that might be found in a `Building` object.
|
||||
* The object itself is stored inside the `Utility` as if it were a container.
|
||||
* `Amenity` objects are required because they are to be owned by the `vehicle` for purposes of faction affinity.
|
||||
* Only specific kinds of objects count for being `Utility` contents/objects.
|
||||
* Additional "setup" logic can be supplied that will be called when the owner vehicle's control `Actor` is created.
|
||||
* Ostensibly, the purpose of the additional logic, when it is called,
|
||||
* is to initialize a control `Actor` for the contained object.
|
||||
* This `Actor` is expected by other logic.
|
||||
* @see `Vehicle.LoadDefinition`
|
||||
* @see `VehicleDefinition.Utilities`
|
||||
* @param util the type of the `Amenity` object to be created
|
||||
* @param vehicle the owner of this object
|
||||
* @see `Amenity.Owner`
|
||||
*/
|
||||
class Utility(util : UtilityType.Value, vehicle : Vehicle) {
|
||||
private val obj : Amenity = Utility.BuildUtilityFunc(util)
|
||||
obj.Owner = vehicle
|
||||
private val setupFunc : Utility.UtilLogic = Utility.SelectUtilitySetupFunc(util)
|
||||
|
||||
/**
|
||||
* The faction association of this `Utility` is tied directly to the connected `Vehicle`.
|
||||
* @return the faction association
|
||||
* Access the contained object in this `Utility`.
|
||||
* @return the contained `Amenity` object
|
||||
*/
|
||||
def Faction : PlanetSideEmpire.Value = {
|
||||
vehicle.Faction
|
||||
}
|
||||
def apply() : Amenity = obj
|
||||
|
||||
/**
|
||||
* An "active" `Utility` can be used by players; an "inactive" one can not be used in its current state.
|
||||
* @return whether this `Utility` is active.
|
||||
* Run the setup code that was provided in the object constructor parameters.
|
||||
* While it is expected to construct an `Actor`, that is not required.
|
||||
* @param context an `ActorContext` potentially useful for the function
|
||||
*/
|
||||
def ActiveState : Boolean = {
|
||||
this.active
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the "active" state of this `Utility`.
|
||||
* @param state the new active state
|
||||
* @return the current active state after being changed
|
||||
*/
|
||||
def ActiveState_=(state : Boolean) : Boolean = {
|
||||
this.active = state
|
||||
state
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the string representation to provide additional information.
|
||||
* @return the string output
|
||||
*/
|
||||
override def toString : String = {
|
||||
Utility.toString(this)
|
||||
}
|
||||
def Setup(implicit context : ActorContext) : Unit = setupFunc(obj, context)
|
||||
}
|
||||
|
||||
object Utility {
|
||||
type UtilLogic = (Amenity, ActorContext)=>Unit
|
||||
|
||||
/**
|
||||
* An overloaded constructor.
|
||||
* @param objectId the object id the is associated with this sort of `Utility`
|
||||
* @param vehicle the `Vehicle` to which this `Utility` is attached
|
||||
* Overloaded constructor.
|
||||
* @param util the type of the `Amenity` object to be created
|
||||
* @param vehicle the owner of this object
|
||||
* @return a `Utility` object
|
||||
*/
|
||||
def apply(objectId : Int, vehicle : Vehicle) : Utility = {
|
||||
new Utility(objectId, vehicle)
|
||||
def apply(util : UtilityType.Value, vehicle : Vehicle) : Utility = {
|
||||
new Utility(util, vehicle)
|
||||
}
|
||||
|
||||
/**
|
||||
* An overloaded constructor.
|
||||
* @param objectId the object id the is associated with this sort of `Utility`
|
||||
* @param vehicle the `Vehicle` to which this `Utility` is attached
|
||||
* @return a `Utility` object
|
||||
* Create the called-out object.
|
||||
* @param util the type of the `Amenity` object
|
||||
* @return the `Amenity` object
|
||||
*/
|
||||
def apply(guid : PlanetSideGUID, objectId : Int, vehicle : Vehicle) : Utility = {
|
||||
val obj = new Utility(objectId, vehicle)
|
||||
obj.GUID = guid
|
||||
obj
|
||||
private def BuildUtilityFunc(util : UtilityType.Value) : Amenity = util match {
|
||||
case UtilityType.order_terminala =>
|
||||
Terminal(GlobalDefinitions.order_terminala)
|
||||
case UtilityType.order_terminalb =>
|
||||
Terminal(GlobalDefinitions.order_terminalb)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create one of a specific type of utilities.
|
||||
* @param objectId the object id that is associated with this sort of `Utility`
|
||||
* @param vehicle the `Vehicle` to which this `Utility` is attached
|
||||
* @return a permitted `Utility` object
|
||||
* Provide the called-out object's logic.
|
||||
* @param util the type of the `Amenity` object
|
||||
* @return the `Amenity` object
|
||||
*/
|
||||
def Select(objectId : Int, vehicle : Vehicle) : Utility = {
|
||||
(objectId : @switch) match {
|
||||
case 60 => //this is the object id of an ANT
|
||||
ANTResourceUtility(objectId, vehicle)
|
||||
|
||||
case 49 | 519 | 613 | 614 => //ams parts
|
||||
Utility(objectId, vehicle)
|
||||
|
||||
case _ =>
|
||||
throw new IllegalArgumentException(s"the requested objectID #$objectId is not accepted as a valid Utility")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a fixed string representation.
|
||||
* @return the string output
|
||||
*/
|
||||
def toString(obj : Utility) : String = {
|
||||
s"{utility-${obj.objectId}}"
|
||||
private def SelectUtilitySetupFunc(util : UtilityType.Value) : UtilLogic = util match {
|
||||
case UtilityType.order_terminala =>
|
||||
OrderTerminalABDefinition.Setup
|
||||
case UtilityType.order_terminalb =>
|
||||
OrderTerminalABDefinition.Setup
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package net.psforever.objects.vehicles
|
|||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
import net.psforever.objects.serverobject.mount.MountableBehavior
|
||||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
|
||||
/**
|
||||
|
|
@ -13,10 +13,13 @@ import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffi
|
|||
* 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
|
||||
class VehicleControl(vehicle : Vehicle) extends Actor
|
||||
with FactionAffinityBehavior.Check
|
||||
with MountableBehavior.Mount
|
||||
with MountableBehavior.Dismount {
|
||||
//make control actors belonging to utilities when making control actor belonging to vehicle
|
||||
vehicle.Utilities.foreach({case (_, util) => util.Setup })
|
||||
|
||||
def MountableObject = vehicle //do not add type!
|
||||
|
||||
def FactionObject : FactionAffinity = vehicle
|
||||
|
|
@ -27,6 +30,13 @@ class VehicleControl(private val vehicle : Vehicle) extends Actor
|
|||
.orElse(mountBehavior)
|
||||
.orElse(dismountBehavior)
|
||||
.orElse {
|
||||
case FactionAffinity.ConvertFactionAffinity(faction) =>
|
||||
val originalAffinity = vehicle.Faction
|
||||
if(originalAffinity != (vehicle.Faction = faction)) {
|
||||
vehicle.Utilities.foreach({ case(_ : Int, util : Utility) => util().Actor forward FactionAffinity.ConfirmFactionAffinity() })
|
||||
}
|
||||
sender ! FactionAffinity.AssertFactionAffinity(vehicle, faction)
|
||||
|
||||
case Vehicle.PrepareForDeletion =>
|
||||
context.become(Disabled)
|
||||
|
||||
|
|
|
|||
|
|
@ -365,6 +365,7 @@ object ObjectClass {
|
|||
final val vulture = 986
|
||||
final val wasp = 997
|
||||
//other
|
||||
final val ams_order_terminal = 48
|
||||
final val ams_respawn_tube = 49
|
||||
final val avatar = 121
|
||||
final val bfr_rearm_terminal = 142
|
||||
|
|
@ -950,6 +951,7 @@ object ObjectClass {
|
|||
//vehicles?
|
||||
case ObjectClass.orbital_shuttle => ConstructorData.genericCodec(OrbitalShuttleData.codec, "HART")
|
||||
//other
|
||||
case ObjectClass.ams_order_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
|
||||
case ObjectClass.ams_respawn_tube => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
|
||||
case ObjectClass.bfr_rearm_terminal => ConstructorData.genericCodec(CommonTerminalData.codec, "terminal")
|
||||
case ObjectClass.implant_terminal_interface => ConstructorData.genericCodec(CommonTerminalData.codec, "implant terminal")
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import net.psforever.objects.GlobalDefinitions.remote_electronics_kit
|
||||
import net.psforever.objects.definition.converter.{ACEConverter, CharacterSelectConverter, REKConverter}
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.definition._
|
||||
import net.psforever.objects.equipment.CItem.{DeployedItem, Unit}
|
||||
import net.psforever.objects.equipment._
|
||||
import net.psforever.objects.inventory.InventoryTile
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.types.{CharacterGender, PlanetSideEmpire, Vector3}
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
import scala.util.Success
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
class ConverterTest extends Specification {
|
||||
"AmmoBox" should {
|
||||
|
|
@ -275,6 +277,26 @@ class ConverterTest extends Specification {
|
|||
}
|
||||
}
|
||||
|
||||
"Terminal" should {
|
||||
"convert to packet" in {
|
||||
val obj = Terminal(GlobalDefinitions.order_terminala)
|
||||
|
||||
obj.Definition.Packet.DetailedConstructorData(obj) match {
|
||||
case Failure(err) =>
|
||||
err.isInstanceOf[NoSuchMethodException] mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
|
||||
obj.Definition.Packet.ConstructorData(obj) match {
|
||||
case Success(pkt) =>
|
||||
pkt mustEqual CommonTerminalData(PlanetSideEmpire.NEUTRAL, 0)
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"Vehicle" should {
|
||||
"convert to packet" in {
|
||||
val hellfire_ammo = AmmoBoxDefinition(Ammo.hellfire_ammo.id)
|
||||
|
|
|
|||
69
common/src/test/scala/objects/UtilityTest.scala
Normal file
69
common/src/test/scala/objects/UtilityTest.scala
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{Actor, ActorRef, Props}
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import org.specs2.mutable._
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class UtilityTest extends Specification {
|
||||
"Utility" should {
|
||||
"create an order_terminala object" in {
|
||||
val obj = Utility(UtilityType.order_terminala, UtilityTest.vehicle)
|
||||
obj().isInstanceOf[Terminal] mustEqual true
|
||||
obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 613
|
||||
obj().asInstanceOf[Terminal].Actor == ActorRef.noSender
|
||||
}
|
||||
|
||||
"create an order_terminalb object" in {
|
||||
val obj = Utility(UtilityType.order_terminalb, UtilityTest.vehicle)
|
||||
obj().isInstanceOf[Terminal] mustEqual true
|
||||
obj().asInstanceOf[Terminal].Definition.ObjectId mustEqual 614
|
||||
obj().asInstanceOf[Terminal].Actor == ActorRef.noSender
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Utility1Test extends ActorTest() {
|
||||
"Utility" should {
|
||||
"wire an order_terminala Actor" in {
|
||||
val obj = Utility(UtilityType.order_terminala, UtilityTest.vehicle)
|
||||
obj().GUID = PlanetSideGUID(1)
|
||||
assert(obj().Actor == ActorRef.noSender)
|
||||
|
||||
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
|
||||
receiveOne(Duration.create(100, "ms")) //consume and discard
|
||||
assert(obj().Actor != ActorRef.noSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Utility2Test extends ActorTest() {
|
||||
"Utility" should {
|
||||
"wire an order_terminalb Actor" in {
|
||||
val obj = Utility(UtilityType.order_terminalb, UtilityTest.vehicle)
|
||||
obj().GUID = PlanetSideGUID(1)
|
||||
assert(obj().Actor == ActorRef.noSender)
|
||||
|
||||
system.actorOf(Props(classOf[UtilityTest.SetupControl], obj), "test") ! ""
|
||||
receiveOne(Duration.create(100, "ms")) //consume and discard
|
||||
assert(obj().Actor != ActorRef.noSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object UtilityTest {
|
||||
val vehicle = Vehicle(GlobalDefinitions.quadstealth)
|
||||
|
||||
class SetupControl(obj : Utility) extends Actor {
|
||||
def receive : Receive = {
|
||||
case _ =>
|
||||
obj.Setup(context)
|
||||
sender ! ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects.terminal
|
||||
|
||||
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.packet.game.{ItemTransactionMessage, PlanetSideGUID}
|
||||
import net.psforever.types._
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
class OrderTerminalABTest extends Specification {
|
||||
"OrderTerminalAB" should {
|
||||
"define (a)" in {
|
||||
val a = new OrderTerminalABDefinition(613)
|
||||
a.ObjectId mustEqual 613
|
||||
a.Name mustEqual "order_terminala"
|
||||
}
|
||||
|
||||
"define (b)" in {
|
||||
val b = new OrderTerminalABDefinition(614)
|
||||
b.ObjectId mustEqual 614
|
||||
b.Name mustEqual "order_terminalb"
|
||||
}
|
||||
|
||||
"define (invalid)" in {
|
||||
var id : Int = (math.random * Int.MaxValue).toInt
|
||||
if(id == 613) {
|
||||
id += 2
|
||||
}
|
||||
else if(id == 614) {
|
||||
id += 1
|
||||
}
|
||||
|
||||
new OrderTerminalABDefinition(id) must throwA[IllegalArgumentException]
|
||||
}
|
||||
}
|
||||
|
||||
"Order_Terminal" should {
|
||||
val terminal = Terminal(GlobalDefinitions.order_terminala)
|
||||
terminal.Owner = new Building(0, Zone.Nowhere)
|
||||
terminal.Owner.Faction = PlanetSideEmpire.TR
|
||||
|
||||
"construct" in {
|
||||
terminal.Actor mustEqual ActorRef.noSender
|
||||
}
|
||||
|
||||
"player can buy different armor ('lite_armor')" in {
|
||||
val player = Player("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 msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Buy, 1, "trhev_antiaircraft", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.NoDeal()
|
||||
}
|
||||
//TODO loudout tests
|
||||
|
||||
"player can not load max loadout" in {
|
||||
val player = Player("test", PlanetSideEmpire.TR, CharacterGender.Male, 0, 0)
|
||||
player.SaveLoadout("test1", 0)
|
||||
player.ExoSuit = ExoSuitType.MAX
|
||||
player.SaveLoadout("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)
|
||||
|
||||
val msg2 = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.InfantryLoadout, 4, "", 1, PlanetSideGUID(0))
|
||||
terminal.Request(player, msg2) mustEqual Terminal.NoDeal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2097,8 +2097,24 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
case msg @ DeployRequestMessage(player_guid, entity, unk1, unk2, unk3, pos) =>
|
||||
//if you try to deploy, can not undeploy
|
||||
log.info("DeployRequest: " + msg)
|
||||
//LOCAL FUNCTIONALITY ONLY FOR THIS BRANCH
|
||||
val player_guid = player.GUID
|
||||
if(unk1 == 2) { // deploy AMS
|
||||
//sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity,49,1))) // TODO : ANT ? With increment when loading NTU ?
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, unk1, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
Thread.sleep(1000) // 2 seconds
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, 3, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 10, 1)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 11, 1)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 12, 1)))
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, PlanetsideAttributeMessage(entity, 13, 1)))
|
||||
}
|
||||
else if(unk1 == 1) { // undeploy AMS
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, unk1, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
Thread.sleep(1000) // 2 seconds
|
||||
sendResponse(PacketCoding.CreateGamePacket(0, DeployRequestMessage(player_guid, entity, 0, unk2, unk3, Vector3(0f, 0f, 0f))))
|
||||
}
|
||||
|
||||
case msg @ AvatarGrenadeStateMessage(player_guid, state) =>
|
||||
log.info("AvatarGrenadeStateMessage: " + msg)
|
||||
|
|
|
|||
Loading…
Reference in a new issue