Exclude Equipment from Loadouts (#249)

* routines for eliminating equipment and configurations from loadout availability depending on the terminal type

* fix to FavoritesMessage use of exo-suit type and subtype causing entries to identify incorrectly; standard is the fallback exo-suit type should a player try to load a suit type they no longer have certed

* factored subtype value into exo-suit fallback selection

* when in a vehicle, and accessing a terminal, the item purchased will attempt to be placed in the vehicle's trunk before testing the player's free hand; the item will not go into the player's backpack
This commit is contained in:
Fate-JH 2019-04-21 08:22:14 -04:00 committed by GitHub
parent c91b3caa99
commit 6399963e68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 164 additions and 31 deletions

View file

@ -5803,6 +5803,7 @@ object GlobalDefinitions {
order_terminala.Tab += 2 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.supportAmmunition ++ EquipmentTerminalDefinition.supportWeapons)
order_terminala.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
order_terminala.Tab += 4 -> OrderTerminalDefinition.InfantryLoadoutPage()
order_terminala.Tab(4).asInstanceOf[OrderTerminalDefinition.InfantryLoadoutPage].Exclude = ExoSuitType.MAX
order_terminala.SellEquipmentByDefault = true
order_terminalb.Name = "order_terminalb"
@ -5811,6 +5812,7 @@ object GlobalDefinitions {
order_terminalb.Tab += 2 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.supportAmmunition ++ EquipmentTerminalDefinition.supportWeapons)
order_terminalb.Tab += 3 -> OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
order_terminalb.Tab += 4 -> OrderTerminalDefinition.InfantryLoadoutPage()
order_terminalb.Tab(4).asInstanceOf[OrderTerminalDefinition.InfantryLoadoutPage].Exclude = ExoSuitType.MAX
order_terminalb.SellEquipmentByDefault = true
cert_terminal.Name = "cert_terminal"

View file

@ -94,6 +94,7 @@ class SpecialExoSuitDefinition(private val suitType : ExoSuitType.Value) extends
override def Use : ExoSuitDefinition = {
val obj = new SpecialExoSuitDefinition(SuitType)
obj.Permissions = Permissions
obj.MaxArmor = MaxArmor
obj.InventoryScale = InventoryScale
obj.InventoryOffset = InventoryOffset

View file

@ -1,7 +1,7 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.loadouts
import net.psforever.types.ExoSuitType
import net.psforever.types.{CertificationType, ExoSuitType}
/**
* A blueprint of a player's uniform, their holster items, and their inventory items, saved in a specific state.
@ -99,4 +99,19 @@ object InfantryLoadout {
case ExoSuitType.Infiltration => 7
}
}
/**
* Assuming the exo-suit is a mechanized assault type,
* use the subtype to determine what certifications would be valid for permitted access to that specific exo-suit.
* The "C" does not stand for "certification."
* @see `CertificationType`
* @param subtype the numeric subtype
* @return a `Set` of all certifications that would grant access to the mechanized assault exo-suit subtype
*/
def DetermineSubtypeC(subtype : Int) : Set[CertificationType.Value] = subtype match {
case 1 => Set(CertificationType.AIMAX, CertificationType.UniMAX)
case 2 => Set(CertificationType.AVMAX, CertificationType.UniMAX)
case 3 => Set(CertificationType.AAMAX, CertificationType.UniMAX)
case _ => Set.empty[CertificationType.Value]
}
}

View file

@ -136,7 +136,7 @@ object OrderTerminalDefinition {
Terminal.BuyExosuit(suit, subtype)
case _ =>
items.get(msg.item_name) match {
case Some(item : (()=>Equipment)) =>
case Some(item) =>
Terminal.BuyEquipment(item())
case _ =>
Terminal.NoDeal()
@ -180,7 +180,7 @@ object OrderTerminalDefinition {
final case class EquipmentPage(stock : Map[String, ()=>Equipment]) extends Tab {
override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(item : (()=>Equipment)) =>
case Some(item) =>
Terminal.BuyEquipment(item())
case _ =>
Terminal.NoDeal()
@ -216,23 +216,56 @@ object OrderTerminalDefinition {
}
}
/**
* The base class for "loadout" type tabs.
* Defines logic for enumerating items and entities that should be eliminated from being loaded.
* The method for filtering those excluded items, if applicable,
* and management of the resulting loadout object
* is the responsibility of the specific tab that is instantiated.
*/
abstract class LoadoutTab extends Tab {
private var contraband : Seq[Any] = Nil
def Exclude : Seq[Any] = contraband
def Exclude_=(equipment : Any) : Seq[Any] = {
contraband = Seq(equipment)
Exclude
}
def Exclude_=(equipmentList : Seq[Any]) : Seq[Any] = {
contraband = equipmentList
Exclude
}
}
/**
* The tab used to select which custom loadout the player is using.
* Player loadouts are defined by an exo-suit to be worn by the player
* and equipment in the holsters and the inventory.
* In this case, the reference to the player that is a parameter of the functions maintains information about the loadouts;
* no extra information specific to this page is necessary.
* If an exo-suit type is considered excluded, the whole loadout is blocked.
* If the exclusion is written as a `Tuple` object `(A, B)`,
* `A` will be expected as an exo-suit type, and `B` will be expected as its subtype,
* and the pair must both match to block the whole loadout.
* If any of the player's inventory is considered excluded, only those items will be filtered.
* @see `ExoSuitType`
* @see `Equipment`
* @see `InfantryLoadout`
* @see `Loadout`
*/
final case class InfantryLoadoutPage() extends Tab {
//TODO block equipment by blocking ammunition type
final case class InfantryLoadoutPage() extends LoadoutTab {
override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
player.LoadLoadout(msg.unk1) match {
case Some(loadout : InfantryLoadout) =>
val holsters = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
val inventory = loadout.inventory.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
case Some(loadout : InfantryLoadout) if !Exclude.contains(loadout.exosuit) && !Exclude.contains((loadout.exosuit, loadout.subtype)) =>
val holsters = loadout.visible_slots
.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
.filterNot { entry => Exclude.contains(entry.obj.Definition) }
val inventory = loadout.inventory
.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
.filterNot { entry => Exclude.contains(entry.obj.Definition) }
Terminal.InfantryLoadout(loadout.exosuit, loadout.subtype, holsters, inventory)
case _ =>
Terminal.NoDeal()
@ -246,16 +279,21 @@ object OrderTerminalDefinition {
* and equipment in the trunk.
* In this case, the reference to the player that is a parameter of the functions maintains information about the loadouts;
* no extra information specific to this page is necessary.
* If a vehicle type (by definition) is considered excluded, the whole loadout is blocked.
* If any of the vehicle's inventory is considered excluded, only those items will be filtered.
* @see `Equipment`
* @see `Loadout`
* @see `VehicleLoadout`
*/
final case class VehicleLoadoutPage() extends Tab {
final case class VehicleLoadoutPage() extends LoadoutTab {
override def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
player.LoadLoadout(msg.unk1 + 10) match {
case Some(loadout : VehicleLoadout) =>
val weapons = loadout.visible_slots.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
val inventory = loadout.inventory.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
case Some(loadout : VehicleLoadout) if !Exclude.contains(loadout.vehicle_definition) =>
val weapons = loadout.visible_slots
.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
val inventory = loadout.inventory
.map(entry => { InventoryItem(BuildSimplifiedPattern(entry.item), entry.index) })
.filterNot { entry => Exclude.contains(entry.obj.Definition) }
Terminal.VehicleLoadout(loadout.vehicle_definition, weapons, inventory)
case _ =>
Terminal.NoDeal()