Lodestar Terminals (#240)

* added three objects to serve as the terminals for Lodestars; only the multivehicle_rearm_terminal is operational, for now

* giving the new terminal type a setup function for being constructed as an amenity
This commit is contained in:
Fate-JH 2018-12-05 01:17:02 -05:00 committed by GitHub
parent 4eca226b5b
commit c4c8609238
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 226 additions and 3 deletions

View file

@ -938,6 +938,22 @@ object GlobalDefinitions {
val secondary_capture = new CaptureTerminalDefinition(751) // Tower CC
val lodestar_repair_terminal = new OrderTerminalDefinition { //TODO wrong object class
override def ObjectId : Int = 461
}
val multivehicle_rearm_terminal = new _OrderTerminalDefinition(576) {
Name = "multivehicle_rearm_terminal"
Page += 3 -> _OrderTerminalDefinition.EquipmentPage(EquipmentTerminalDefinition.vehicleAmmunition)
Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
}
val bfr_rearm_terminal = new _OrderTerminalDefinition(142) {
Name = "bfr_rearm_terminal"
Page += 3 -> _OrderTerminalDefinition.EquipmentPage(Map.empty[String, ()=>Equipment]) //TODO add stock to page
Page += 4 -> _OrderTerminalDefinition.VehicleLoadoutPage()
}
val manned_turret = new TurretDefinition(480) {
Name = "manned_turret"
MaxHealth = 3600
@ -5394,6 +5410,12 @@ object GlobalDefinitions {
lodestar.MountPoints += 1 -> 0
lodestar.MountPoints += 2 -> 1
lodestar.Cargo += 1 -> new CargoDefinition()
lodestar.Utilities += 2 -> UtilityType.lodestar_repair_terminal
lodestar.Utilities += 3 -> UtilityType.lodestar_repair_terminal
lodestar.Utilities += 4 -> UtilityType.multivehicle_rearm_terminal
lodestar.Utilities += 5 -> UtilityType.multivehicle_rearm_terminal
lodestar.Utilities += 6 -> UtilityType.bfr_rearm_terminal
lodestar.Utilities += 7 -> UtilityType.bfr_rearm_terminal
lodestar.TrunkSize = InventoryTile.Tile1612
lodestar.TrunkOffset = 30
lodestar.AutoPilotSpeeds = (0, 4)

View file

@ -1,11 +1,18 @@
// Copyright (c) 2017 PSForever
package net.psforever.objects.serverobject.terminals
import net.psforever.objects.Player
import net.psforever.objects.loadouts.InfantryLoadout
import akka.actor.ActorContext
import net.psforever.objects.definition.ImplantDefinition
import net.psforever.objects.{Player, Vehicle}
import net.psforever.objects.equipment.Equipment
import net.psforever.objects.loadouts.{InfantryLoadout, VehicleLoadout}
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.{CertificationType, ExoSuitType}
import scala.collection.mutable
/**
* The definition for any `Terminal` that is of a type "order_terminal".
@ -51,3 +58,182 @@ class OrderTerminalDefinition extends EquipmentTerminalDefinition(612) {
}
}
}
class _OrderTerminalDefinition(objId : Int) extends TerminalDefinition(objId) {
private val pages : mutable.HashMap[Int, _OrderTerminalDefinition.PageDefinition] =
new mutable.HashMap[Int, _OrderTerminalDefinition.PageDefinition]()
private var sellEquipmentDefault : Boolean = true
def Page : mutable.HashMap[Int, _OrderTerminalDefinition.PageDefinition] = pages
def SellEquipmentByDefault : Boolean = sellEquipmentDefault
def SellEquipmentByDefault_=(sell : Boolean) : Boolean = {
sellEquipmentDefault = sell
SellEquipmentByDefault
}
override def Buy(player: Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
pages.get(msg.item_page) match {
case Some(page) =>
page.Buy(player, msg)
case _ =>
Terminal.NoDeal()
}
}
override def Loadout(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Buy(player, msg)
override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
if(sellEquipmentDefault) {
Terminal.SellEquipment()
}
else {
pages.get(msg.item_page) match {
case Some(page) =>
page.Sell(player, msg)
case _ =>
Terminal.NoDeal()
}
}
}
}
object _OrderTerminalDefinition {
abstract class PageDefinition(stock : Map[String, Any]) {
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange
}
final case class ArmorPage(stock : Map[String, (ExoSuitType.Value, Int)]) extends PageDefinition(stock) {
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some((suit : ExoSuitType.Value, subtype : Int)) =>
Terminal.BuyExosuit(suit, subtype)
case _ =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
final case class CertificationPage(stock : Map[String, CertificationType.Value]) extends PageDefinition(stock) {
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(cert : CertificationType.Value) =>
Terminal.LearnCertification(cert)
case _ =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(cert : CertificationType.Value) =>
Terminal.SellCertification(cert)
case None =>
Terminal.NoDeal()
}
}
}
final case class EquipmentPage(stock : Map[String, ()=>Equipment]) extends PageDefinition(stock) {
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(item : (()=>Equipment)) =>
Terminal.BuyEquipment(item())
case _ =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.SellEquipment()
}
final case class ImplantPage(stock : Map[String, ImplantDefinition]) extends PageDefinition(stock) {
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(implant : ImplantDefinition) =>
Terminal.LearnImplant(implant)
case None =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(implant : ImplantDefinition) =>
Terminal.SellImplant(implant)
case None =>
Terminal.NoDeal()
}
}
}
final case class InfantryLoadoutPage() extends PageDefinition(Map.empty) {
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) })
Terminal.InfantryLoadout(loadout.exosuit, loadout.subtype, holsters, inventory)
case _ =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
final case class VehicleLoadoutPage() extends PageDefinition(Map.empty) {
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) })
Terminal.VehicleLoadout(loadout.vehicle_definition, weapons, inventory)
case _ =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
import net.psforever.objects.loadouts.{Loadout => Contents} //distinguish from Terminal.Loadout message
final case class VehiclePage(stock : Map[String, ()=>Vehicle], trunk : Map[String, Contents]) extends PageDefinition(stock) {
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
stock.get(msg.item_name) match {
case Some(vehicle) =>
val (weapons, inventory) = trunk.get(msg.item_name) match {
case Some(loadout : VehicleLoadout) =>
(
loadout.visible_slots.map(entry => { InventoryItem(EquipmentTerminalDefinition.BuildSimplifiedPattern(entry.item), entry.index) }),
loadout.inventory.map(entry => { InventoryItem(EquipmentTerminalDefinition.BuildSimplifiedPattern(entry.item), entry.index) })
)
case _ =>
(List.empty, List.empty)
}
Terminal.BuyVehicle(vehicle(), weapons, inventory)
case None =>
Terminal.NoDeal()
}
}
def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = Terminal.NoDeal()
}
/**
* 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}")
}
}
}

View file

@ -22,7 +22,10 @@ object UtilityType extends Enumeration {
type Type = Value
val
ams_respawn_tube,
bfr_rearm_terminal,
lodestar_repair_terminal,
matrix_terminalc,
multivehicle_rearm_terminal,
order_terminala,
order_terminalb,
teleportpad_terminal,
@ -93,8 +96,14 @@ object Utility {
private def BuildUtilityFunc(util : UtilityType.Value) : Amenity = util match {
case UtilityType.ams_respawn_tube =>
new SpawnTubeUtility(GlobalDefinitions.ams_respawn_tube)
case UtilityType.bfr_rearm_terminal =>
new TerminalUtility(GlobalDefinitions.bfr_rearm_terminal)
case UtilityType.lodestar_repair_terminal =>
new TerminalUtility(GlobalDefinitions.lodestar_repair_terminal)
case UtilityType.matrix_terminalc =>
new TerminalUtility(GlobalDefinitions.matrix_terminalc)
case UtilityType.multivehicle_rearm_terminal =>
new TerminalUtility(GlobalDefinitions.multivehicle_rearm_terminal)
case UtilityType.order_terminala =>
new TerminalUtility(GlobalDefinitions.order_terminala)
case UtilityType.order_terminalb =>
@ -180,8 +189,14 @@ object Utility {
private def SelectUtilitySetupFunc(util : UtilityType.Value) : UtilLogic = util match {
case UtilityType.ams_respawn_tube =>
SpawnTubeDefinition.Setup
case UtilityType.bfr_rearm_terminal =>
_OrderTerminalDefinition.Setup
case UtilityType.lodestar_repair_terminal =>
OrderTerminalABDefinition.Setup //TODO wrong
case UtilityType.matrix_terminalc =>
MatrixTerminalDefinition.Setup
case UtilityType.multivehicle_rearm_terminal =>
_OrderTerminalDefinition.Setup
case UtilityType.order_terminala =>
OrderTerminalABDefinition.Setup
case UtilityType.order_terminalb =>

View file

@ -3764,7 +3764,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
//TODO matrix spawn point; for now, just blindly bind to show work (and hope nothing breaks)
sendResponse(BindPlayerMessage(BindStatus.Bind, "", true, true, SpawnGroup.Sanctuary, 0, 0, terminal.Position))
}
else if(tdef.isInstanceOf[RepairRearmSiloDefinition]) {
else if(tdef.isInstanceOf[RepairRearmSiloDefinition] || tdef == GlobalDefinitions.multivehicle_rearm_terminal) {
FindLocalVehicle match {
case Some(vehicle) =>
sendResponse(UseItemMessage(avatar_guid, item_used_guid, object_guid, unk2, unk3, unk4, unk5, unk6, unk7, unk8, itemType))