mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-15 16:34:39 +00:00
added an Enumeration of certifications
This commit is contained in:
parent
db8d3fc7ca
commit
69af5124ba
5 changed files with 166 additions and 64 deletions
|
|
@ -28,6 +28,7 @@ class AvatarConverter extends ObjectCreateConverter[Player]() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override def DetailedConstructorData(obj : Player) : Try[DetailedCharacterData] = {
|
override def DetailedConstructorData(obj : Player) : Try[DetailedCharacterData] = {
|
||||||
|
import net.psforever.types.CertificationType._
|
||||||
Success(
|
Success(
|
||||||
DetailedCharacterData(
|
DetailedCharacterData(
|
||||||
MakeAppearanceData(obj),
|
MakeAppearanceData(obj),
|
||||||
|
|
@ -36,10 +37,9 @@ class AvatarConverter extends ObjectCreateConverter[Player]() {
|
||||||
obj.MaxHealth,
|
obj.MaxHealth,
|
||||||
obj.Health,
|
obj.Health,
|
||||||
obj.Armor,
|
obj.Armor,
|
||||||
1, 7, 7,
|
|
||||||
obj.MaxStamina,
|
obj.MaxStamina,
|
||||||
obj.Stamina,
|
obj.Stamina,
|
||||||
List(0, 1, 11, 21, 26, 27, 28), //TODO certification list
|
List(StandardAssault, MediumAssault, ATV, Harasser, StandardExoSuit, AgileExoSuit, ReinforcedExoSuit), //TODO certification list
|
||||||
List(), //TODO implant list
|
List(), //TODO implant list
|
||||||
List.empty[String], //TODO fte list
|
List.empty[String], //TODO fte list
|
||||||
List.empty[String], //TODO tutorial list
|
List.empty[String], //TODO tutorial list
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package net.psforever.packet.game.objectcreate
|
||||||
|
|
||||||
import net.psforever.newcodecs.newcodecs
|
import net.psforever.newcodecs.newcodecs
|
||||||
import net.psforever.packet.{Marshallable, PacketHelpers}
|
import net.psforever.packet.{Marshallable, PacketHelpers}
|
||||||
import net.psforever.types.ImplantType
|
import net.psforever.types.{CertificationType, ImplantType}
|
||||||
import scodec.{Attempt, Codec}
|
import scodec.{Attempt, Codec}
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
import shapeless.{::, HNil}
|
import shapeless.{::, HNil}
|
||||||
|
|
@ -12,9 +12,9 @@ import scala.annotation.tailrec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An entry in the `List` of valid implant slots in `DetailedCharacterData`.
|
* An entry in the `List` of valid implant slots in `DetailedCharacterData`.
|
||||||
* "`activation`" is not necessarily the best word for it ...
|
* `activation`, if defined, indicates the time remaining (in seconds?) before an implant can be activated.
|
||||||
* @param implant the type of implant
|
* @param implant the type of implant
|
||||||
* @param activation na
|
* @param activation the activation timer
|
||||||
* @see `ImplantType`
|
* @see `ImplantType`
|
||||||
*/
|
*/
|
||||||
final case class ImplantEntry(implant : ImplantType.Value,
|
final case class ImplantEntry(implant : ImplantType.Value,
|
||||||
|
|
@ -87,7 +87,7 @@ final case class DetailedCharacterData(appearance : CharacterAppearanceData,
|
||||||
unk3 : Int, //7
|
unk3 : Int, //7
|
||||||
staminaMax : Int,
|
staminaMax : Int,
|
||||||
stamina : Int,
|
stamina : Int,
|
||||||
certs : List[Int],
|
certs : List[CertificationType.Value],
|
||||||
implants : List[ImplantEntry],
|
implants : List[ImplantEntry],
|
||||||
firstTimeEvents : List[String],
|
firstTimeEvents : List[String],
|
||||||
tutorials : List[String],
|
tutorials : List[String],
|
||||||
|
|
@ -98,13 +98,12 @@ final case class DetailedCharacterData(appearance : CharacterAppearanceData,
|
||||||
override def bitsize : Long = {
|
override def bitsize : Long = {
|
||||||
//factor guard bool values into the base size, not corresponding optional fields, unless contained or enumerated
|
//factor guard bool values into the base size, not corresponding optional fields, unless contained or enumerated
|
||||||
val appearanceSize = appearance.bitsize
|
val appearanceSize = appearance.bitsize
|
||||||
val varBit : Option[Int] = CharacterAppearanceData.altModelBit(appearance)
|
|
||||||
val certSize = (certs.length + 1) * 8 //cert list
|
val certSize = (certs.length + 1) * 8 //cert list
|
||||||
var implantSize : Long = 0L //implant list
|
var implantSize : Long = 0L //implant list
|
||||||
for(entry <- implants) {
|
for(entry <- implants) {
|
||||||
implantSize += entry.bitsize
|
implantSize += entry.bitsize
|
||||||
}
|
}
|
||||||
val implantPadding = DetailedCharacterData.implantFieldPadding(implants, varBit)
|
val implantPadding = DetailedCharacterData.implantFieldPadding(implants, CharacterAppearanceData.altModelBit(appearance))
|
||||||
val fteLen = firstTimeEvents.size //fte list
|
val fteLen = firstTimeEvents.size //fte list
|
||||||
var eventListSize : Long = 32L + DetailedCharacterData.ftePadding(fteLen, implantPadding)
|
var eventListSize : Long = 32L + DetailedCharacterData.ftePadding(fteLen, implantPadding)
|
||||||
for(str <- firstTimeEvents) {
|
for(str <- firstTimeEvents) {
|
||||||
|
|
@ -127,28 +126,28 @@ final case class DetailedCharacterData(appearance : CharacterAppearanceData,
|
||||||
|
|
||||||
object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
||||||
/**
|
/**
|
||||||
* Overloaded constructor for `DetailedCharacterData` that allows for a not-optional inventory.
|
* Overloaded constructor for `DetailedCharacterData` that requires an inventory and drops unknown values.
|
||||||
* @param appearance data about the avatar's basic aesthetics
|
* @param appearance data about the avatar's basic aesthetics
|
||||||
|
* @param bep the avatar's battle experience points, which determines his Battle Rank
|
||||||
|
* @param cep the avatar's command experience points, which determines his Command Rank
|
||||||
* @param healthMax for `x / y` of hitpoints, this is the avatar's `y` value
|
* @param healthMax for `x / y` of hitpoints, this is the avatar's `y` value
|
||||||
* @param health for `x / y` of hitpoints, this is the avatar's `x` value
|
* @param health for `x / y` of hitpoints, this is the avatar's `x` value
|
||||||
* @param armor for `x / y` of armor points, this is the avatar's `x` value
|
* @param armor for `x / y` of armor points, this is the avatar's `x` value
|
||||||
* @param unk1 na
|
|
||||||
* @param unk2 na
|
|
||||||
* @param unk3 na
|
|
||||||
* @param staminaMax for `x / y` of stamina points, this is the avatar's `y` value
|
* @param staminaMax for `x / y` of stamina points, this is the avatar's `y` value
|
||||||
* @param stamina for `x / y` of stamina points, this is the avatar's `x` value
|
* @param stamina for `x / y` of stamina points, this is the avatar's `x` value
|
||||||
* @param certs na
|
* @param certs the `List` of active certifications
|
||||||
|
* @param implants the `List` of implant slots currently possessed by this avatar
|
||||||
* @param firstTimeEvents the list of first time events performed by this avatar
|
* @param firstTimeEvents the list of first time events performed by this avatar
|
||||||
* @param tutorials the list of tutorials completed by this avatar
|
* @param tutorials the list of tutorials completed by this avatar
|
||||||
* @param inventory the avatar's inventory
|
* @param inventory the avatar's inventory
|
||||||
* @param drawn_slot the holster that is initially drawn
|
* @param drawn_slot the holster that is initially drawn
|
||||||
* @return a `DetailedCharacterData` object
|
* @return a `DetailedCharacterData` object
|
||||||
*/
|
*/
|
||||||
def apply(appearance : CharacterAppearanceData, bep : Long, cep : Long, healthMax : Int, health : Int, armor : Int, unk1 : Int, unk2 : Int, unk3 : Int, staminaMax : Int, stamina : Int, certs : List[Int], implants : List[ImplantEntry], firstTimeEvents : List[String], tutorials : List[String], inventory : InventoryData, drawn_slot : DrawnSlot.Value) : DetailedCharacterData =
|
def apply(appearance : CharacterAppearanceData, bep : Long, cep : Long, healthMax : Int, health : Int, armor : Int, staminaMax : Int, stamina : Int, certs : List[CertificationType.Value], implants : List[ImplantEntry], firstTimeEvents : List[String], tutorials : List[String], inventory : InventoryData, drawn_slot : DrawnSlot.Value) : DetailedCharacterData =
|
||||||
new DetailedCharacterData(appearance, bep, cep, healthMax, health, armor, unk1, unk2, unk3, staminaMax, stamina, certs, implants, firstTimeEvents, tutorials, Some(inventory), drawn_slot)
|
new DetailedCharacterData(appearance, bep, cep, healthMax, health, armor, 1, 7, 7, staminaMax, stamina, certs, implants, firstTimeEvents, tutorials, Some(inventory), drawn_slot)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `Codec` for entires in the list of implants.
|
* `Codec` for entries in the `List` of implants.
|
||||||
*/
|
*/
|
||||||
private val implant_entry_codec : Codec[ImplantEntry] = (
|
private val implant_entry_codec : Codec[ImplantEntry] = (
|
||||||
("implant" | ImplantType.codec) ::
|
("implant" | ImplantType.codec) ::
|
||||||
|
|
@ -285,7 +284,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
||||||
("staminaMax" | uint16L) ::
|
("staminaMax" | uint16L) ::
|
||||||
("stamina" | uint16L) ::
|
("stamina" | uint16L) ::
|
||||||
ignore(147) ::
|
ignore(147) ::
|
||||||
("certs" | listOfN(uint8L, uint8L)) ::
|
("certs" | listOfN(uint8L, CertificationType.codec)) ::
|
||||||
optional(bool, uint32L) :: //ask about sample CCRIDER
|
optional(bool, uint32L) :: //ask about sample CCRIDER
|
||||||
ignore(4) ::
|
ignore(4) ::
|
||||||
(("implants" | PacketHelpers.listOfNSized(numberOfImplantSlots(bep), implant_entry_codec)) >>:~ { implants =>
|
(("implants" | PacketHelpers.listOfNSized(numberOfImplantSlots(bep), implant_entry_codec)) >>:~ { implants =>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright (c) 2017 PSForever
|
||||||
|
package net.psforever.types
|
||||||
|
|
||||||
|
import net.psforever.packet.PacketHelpers
|
||||||
|
import scodec.codecs._
|
||||||
|
/**
|
||||||
|
* An `Enumeration` of the available certifications.<br>
|
||||||
|
* <br>
|
||||||
|
* As indicated, the following certifications are always enqueued on an avatar's permissions:
|
||||||
|
* `StandardAssault`, `StandardExoSuit`, `AgileExoSuit`.
|
||||||
|
* They must still be included in any formal lists of permitted equipment for a user.
|
||||||
|
* The other noted certifications require all prerequisite certifications listed or they themselves will not be listed:
|
||||||
|
* `ElectronicsExpert` and `AdvancedEngineering`.
|
||||||
|
* No other certification requires its prerequisites explicitly listed to be listed itself.
|
||||||
|
* Any certification that contains multiple other certifications overrides those individual certifications in the list.
|
||||||
|
* There is no certification for the Advanced Nanite Transport.<br>
|
||||||
|
* <br>
|
||||||
|
* In terms of pricing, `StandardAssault`, `StandardExoSuit`, and `AgileExoSuit` are costless.
|
||||||
|
* A certification that contains multiple other certifications acts as the overriding cost.
|
||||||
|
* (Taking `UniMAX` while owning `AAMAX` will refund the `AAMAX` cost and replace it with the `UniMAX` cost.)
|
||||||
|
*/
|
||||||
|
object CertificationType extends Enumeration {
|
||||||
|
type Type = Value
|
||||||
|
val
|
||||||
|
//0
|
||||||
|
StandardAssault, //always listed
|
||||||
|
MediumAssault,
|
||||||
|
HeavyAssault,
|
||||||
|
SpecialAssault,
|
||||||
|
AntiVehicular,
|
||||||
|
Sniping,
|
||||||
|
EliteAssault,
|
||||||
|
AirCalvaryScout,
|
||||||
|
AirCalvaryInterceptor,
|
||||||
|
AirCalvaryAssault,
|
||||||
|
//10
|
||||||
|
AirSupport,
|
||||||
|
ATV,
|
||||||
|
LightScout,
|
||||||
|
AssaultBuggy,
|
||||||
|
ArmoredAssault1,
|
||||||
|
ArmoredAssault2,
|
||||||
|
GroundTransport,
|
||||||
|
GroundSupport,
|
||||||
|
BattleFrameRobotics,
|
||||||
|
Flail,
|
||||||
|
//20
|
||||||
|
Switchblade,
|
||||||
|
Harasser,
|
||||||
|
Phantasm,
|
||||||
|
GalaxyGunship,
|
||||||
|
BFRAntiAircraft,
|
||||||
|
BFRAntiInfantry,
|
||||||
|
StandardExoSuit, //always listed
|
||||||
|
AgileExoSuit, //always listed
|
||||||
|
ReinforcedExoSuit,
|
||||||
|
InfiltrationSuit,
|
||||||
|
//30
|
||||||
|
AAMAX,
|
||||||
|
AIMAX,
|
||||||
|
AVMAX,
|
||||||
|
UniMAX,
|
||||||
|
Medical,
|
||||||
|
AdvancedMedical,
|
||||||
|
Hacking,
|
||||||
|
AdvancedHacking,
|
||||||
|
ExpertHacking,
|
||||||
|
DataCorruption,
|
||||||
|
//40
|
||||||
|
ElectronicsExpert, //requires Hacking and AdvancedHacking
|
||||||
|
Engineering,
|
||||||
|
CombatEngineering,
|
||||||
|
FortificationEngineering,
|
||||||
|
AssaultEngineering,
|
||||||
|
AdvancedEngineering //requires Engineering and CombatEngineering
|
||||||
|
= Value
|
||||||
|
|
||||||
|
implicit val codec = PacketHelpers.createEnumerationCodec(this, uint8L)
|
||||||
|
}
|
||||||
|
|
@ -206,6 +206,8 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
||||||
char.appearance.ribbons.middle mustEqual MeritCommendation.None
|
char.appearance.ribbons.middle mustEqual MeritCommendation.None
|
||||||
char.appearance.ribbons.lower mustEqual MeritCommendation.None
|
char.appearance.ribbons.lower mustEqual MeritCommendation.None
|
||||||
char.appearance.ribbons.tos mustEqual MeritCommendation.None
|
char.appearance.ribbons.tos mustEqual MeritCommendation.None
|
||||||
|
char.bep mustEqual 0
|
||||||
|
char.cep mustEqual 0
|
||||||
char.healthMax mustEqual 100
|
char.healthMax mustEqual 100
|
||||||
char.health mustEqual 100
|
char.health mustEqual 100
|
||||||
char.armor mustEqual 50 //standard exosuit value
|
char.armor mustEqual 50 //standard exosuit value
|
||||||
|
|
@ -214,7 +216,15 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
||||||
char.unk3 mustEqual 7
|
char.unk3 mustEqual 7
|
||||||
char.staminaMax mustEqual 100
|
char.staminaMax mustEqual 100
|
||||||
char.stamina mustEqual 100
|
char.stamina mustEqual 100
|
||||||
char.certs mustEqual List(0, 1, 11, 21, 26, 27, 28)
|
char.certs.length mustEqual 7
|
||||||
|
char.certs.head mustEqual CertificationType.StandardAssault
|
||||||
|
char.certs(1) mustEqual CertificationType.MediumAssault
|
||||||
|
char.certs(2) mustEqual CertificationType.ATV
|
||||||
|
char.certs(3) mustEqual CertificationType.Harasser
|
||||||
|
char.certs(4) mustEqual CertificationType.StandardExoSuit
|
||||||
|
char.certs(5) mustEqual CertificationType.AgileExoSuit
|
||||||
|
char.certs(6) mustEqual CertificationType.ReinforcedExoSuit
|
||||||
|
char.implants.length mustEqual 0
|
||||||
char.firstTimeEvents.size mustEqual 4
|
char.firstTimeEvents.size mustEqual 4
|
||||||
char.firstTimeEvents.head mustEqual "xpe_sanctuary_help"
|
char.firstTimeEvents.head mustEqual "xpe_sanctuary_help"
|
||||||
char.firstTimeEvents(1) mustEqual "xpe_th_firemodes"
|
char.firstTimeEvents(1) mustEqual "xpe_th_firemodes"
|
||||||
|
|
@ -406,11 +416,19 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
||||||
50,
|
50,
|
||||||
1, 7, 7,
|
1, 7, 7,
|
||||||
100, 100,
|
100, 100,
|
||||||
List(0, 1, 11, 21, 26, 27, 28),
|
List(
|
||||||
|
CertificationType.StandardAssault,
|
||||||
|
CertificationType.MediumAssault,
|
||||||
|
CertificationType.ATV,
|
||||||
|
CertificationType.Harasser,
|
||||||
|
CertificationType.StandardExoSuit,
|
||||||
|
CertificationType.AgileExoSuit,
|
||||||
|
CertificationType.ReinforcedExoSuit
|
||||||
|
),
|
||||||
List(),
|
List(),
|
||||||
"xpe_sanctuary_help" :: "xpe_th_firemodes" :: "used_beamer" :: "map13" :: Nil,
|
"xpe_sanctuary_help" :: "xpe_th_firemodes" :: "used_beamer" :: "map13" :: Nil,
|
||||||
List.empty,
|
List.empty,
|
||||||
InventoryData(inv),
|
Some(InventoryData(inv)),
|
||||||
DrawnSlot.Pistol1
|
DrawnSlot.Pistol1
|
||||||
)
|
)
|
||||||
val msg = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), obj)
|
val msg = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), obj)
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue