mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-01-20 02:54:46 +00:00
added an Enumeration of certifications
This commit is contained in:
parent
db8d3fc7ca
commit
69af5124ba
|
|
@ -28,6 +28,7 @@ class AvatarConverter extends ObjectCreateConverter[Player]() {
|
|||
}
|
||||
|
||||
override def DetailedConstructorData(obj : Player) : Try[DetailedCharacterData] = {
|
||||
import net.psforever.types.CertificationType._
|
||||
Success(
|
||||
DetailedCharacterData(
|
||||
MakeAppearanceData(obj),
|
||||
|
|
@ -36,10 +37,9 @@ class AvatarConverter extends ObjectCreateConverter[Player]() {
|
|||
obj.MaxHealth,
|
||||
obj.Health,
|
||||
obj.Armor,
|
||||
1, 7, 7,
|
||||
obj.MaxStamina,
|
||||
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.empty[String], //TODO fte 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.packet.{Marshallable, PacketHelpers}
|
||||
import net.psforever.types.ImplantType
|
||||
import net.psforever.types.{CertificationType, ImplantType}
|
||||
import scodec.{Attempt, Codec}
|
||||
import scodec.codecs._
|
||||
import shapeless.{::, HNil}
|
||||
|
|
@ -12,9 +12,9 @@ import scala.annotation.tailrec
|
|||
|
||||
/**
|
||||
* 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 activation na
|
||||
* @param activation the activation timer
|
||||
* @see `ImplantType`
|
||||
*/
|
||||
final case class ImplantEntry(implant : ImplantType.Value,
|
||||
|
|
@ -87,7 +87,7 @@ final case class DetailedCharacterData(appearance : CharacterAppearanceData,
|
|||
unk3 : Int, //7
|
||||
staminaMax : Int,
|
||||
stamina : Int,
|
||||
certs : List[Int],
|
||||
certs : List[CertificationType.Value],
|
||||
implants : List[ImplantEntry],
|
||||
firstTimeEvents : List[String],
|
||||
tutorials : List[String],
|
||||
|
|
@ -98,13 +98,12 @@ final case class DetailedCharacterData(appearance : CharacterAppearanceData,
|
|||
override def bitsize : Long = {
|
||||
//factor guard bool values into the base size, not corresponding optional fields, unless contained or enumerated
|
||||
val appearanceSize = appearance.bitsize
|
||||
val varBit : Option[Int] = CharacterAppearanceData.altModelBit(appearance)
|
||||
val certSize = (certs.length + 1) * 8 //cert list
|
||||
var implantSize : Long = 0L //implant list
|
||||
for(entry <- implants) {
|
||||
implantSize += entry.bitsize
|
||||
}
|
||||
val implantPadding = DetailedCharacterData.implantFieldPadding(implants, varBit)
|
||||
val implantPadding = DetailedCharacterData.implantFieldPadding(implants, CharacterAppearanceData.altModelBit(appearance))
|
||||
val fteLen = firstTimeEvents.size //fte list
|
||||
var eventListSize : Long = 32L + DetailedCharacterData.ftePadding(fteLen, implantPadding)
|
||||
for(str <- firstTimeEvents) {
|
||||
|
|
@ -127,28 +126,28 @@ final case class DetailedCharacterData(appearance : CharacterAppearanceData,
|
|||
|
||||
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 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 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 unk1 na
|
||||
* @param unk2 na
|
||||
* @param unk3 na
|
||||
* @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 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 tutorials the list of tutorials completed by this avatar
|
||||
* @param inventory the avatar's inventory
|
||||
* @param drawn_slot the holster that is initially drawn
|
||||
* @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 =
|
||||
new DetailedCharacterData(appearance, bep, cep, healthMax, health, armor, unk1, unk2, unk3, staminaMax, stamina, certs, implants, firstTimeEvents, tutorials, Some(inventory), drawn_slot)
|
||||
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, 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] = (
|
||||
("implant" | ImplantType.codec) ::
|
||||
|
|
@ -285,7 +284,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
|||
("staminaMax" | uint16L) ::
|
||||
("stamina" | uint16L) ::
|
||||
ignore(147) ::
|
||||
("certs" | listOfN(uint8L, uint8L)) ::
|
||||
("certs" | listOfN(uint8L, CertificationType.codec)) ::
|
||||
optional(bool, uint32L) :: //ask about sample CCRIDER
|
||||
ignore(4) ::
|
||||
(("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.lower mustEqual MeritCommendation.None
|
||||
char.appearance.ribbons.tos mustEqual MeritCommendation.None
|
||||
char.bep mustEqual 0
|
||||
char.cep mustEqual 0
|
||||
char.healthMax mustEqual 100
|
||||
char.health mustEqual 100
|
||||
char.armor mustEqual 50 //standard exosuit value
|
||||
|
|
@ -214,7 +216,15 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
char.unk3 mustEqual 7
|
||||
char.staminaMax 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.head mustEqual "xpe_sanctuary_help"
|
||||
char.firstTimeEvents(1) mustEqual "xpe_th_firemodes"
|
||||
|
|
@ -406,11 +416,19 @@ class ObjectCreateDetailedMessageTest extends Specification {
|
|||
50,
|
||||
1, 7, 7,
|
||||
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(),
|
||||
"xpe_sanctuary_help" :: "xpe_th_firemodes" :: "used_beamer" :: "map13" :: Nil,
|
||||
List.empty,
|
||||
InventoryData(inv),
|
||||
Some(InventoryData(inv)),
|
||||
DrawnSlot.Pistol1
|
||||
)
|
||||
val msg = ObjectCreateDetailedMessage(0x79, PlanetSideGUID(75), obj)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue