mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-04-28 07:15:21 +00:00
enhancing the three primary character codecs thanks to new analysis
This commit is contained in:
parent
a1ce8ac1f3
commit
bf72d553e1
9 changed files with 59 additions and 121 deletions
|
|
@ -66,7 +66,6 @@ object AvatarConverter {
|
||||||
def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
|
def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
|
||||||
CharacterAppearanceData(
|
CharacterAppearanceData(
|
||||||
BasicCharacterData(obj.Name, obj.Faction, obj.Sex, obj.Head, obj.Voice),
|
BasicCharacterData(obj.Name, obj.Faction, obj.Sex, obj.Head, obj.Voice),
|
||||||
voice2 = 0,
|
|
||||||
black_ops = false,
|
black_ops = false,
|
||||||
jammered = false,
|
jammered = false,
|
||||||
obj.ExoSuit,
|
obj.ExoSuit,
|
||||||
|
|
@ -96,7 +95,7 @@ object AvatarConverter {
|
||||||
}, //TODO not precise
|
}, //TODO not precise
|
||||||
DressBattleRank(obj),
|
DressBattleRank(obj),
|
||||||
DressCommandRank(obj),
|
DressCommandRank(obj),
|
||||||
recursiveMakeImplantEffects(obj.Implants.iterator),
|
MakeImplantEffectList(obj.Implants),
|
||||||
MakeCosmetics(obj.BEP)
|
MakeCosmetics(obj.BEP)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -196,34 +195,24 @@ object AvatarConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an active implant whose effect will be displayed on this player.
|
* Find and encode implants whose effect will be displayed on this player.
|
||||||
* @param iter an `Iterator` of `ImplantSlot` objects
|
* @param implants a `Sequence` of `ImplantSlot` objects
|
||||||
* @return the effect of an active implant
|
* @return the effect of an active implant
|
||||||
*/
|
*/
|
||||||
@tailrec private def recursiveMakeImplantEffects(iter : Iterator[(ImplantType.Value, Long, Boolean)]) : Option[ImplantEffects.Value] = {
|
private def MakeImplantEffectList(implants : Seq[(ImplantType.Value, Long, Boolean)]) : List[ImplantEffects.Value] = {
|
||||||
if(!iter.hasNext) {
|
implants.collect {
|
||||||
None
|
case ((implant,_,true)) =>
|
||||||
}
|
|
||||||
else {
|
|
||||||
val(implant, _, active) = iter.next
|
|
||||||
if(active) {
|
|
||||||
implant match {
|
implant match {
|
||||||
case ImplantType.AdvancedRegen =>
|
case ImplantType.AdvancedRegen =>
|
||||||
Some(ImplantEffects.RegenEffects)
|
ImplantEffects.RegenEffects
|
||||||
case ImplantType.DarklightVision =>
|
case ImplantType.DarklightVision =>
|
||||||
Some(ImplantEffects.DarklightEffects)
|
ImplantEffects.DarklightEffects
|
||||||
case ImplantType.PersonalShield =>
|
case ImplantType.PersonalShield =>
|
||||||
Some(ImplantEffects.PersonalShieldEffects)
|
ImplantEffects.PersonalShieldEffects
|
||||||
case ImplantType.Surge =>
|
case ImplantType.Surge =>
|
||||||
Some(ImplantEffects.SurgeEffects)
|
ImplantEffects.SurgeEffects
|
||||||
case _ =>
|
|
||||||
recursiveMakeImplantEffects(iter)
|
|
||||||
}
|
}
|
||||||
}
|
}.toList
|
||||||
else {
|
|
||||||
recursiveMakeImplantEffects(iter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ class CharacterSelectConverter extends AvatarConverter {
|
||||||
private def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
|
private def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
|
||||||
CharacterAppearanceData(
|
CharacterAppearanceData(
|
||||||
BasicCharacterData(obj.Name, obj.Faction, obj.Sex, obj.Head, CharacterVoice.Mute),
|
BasicCharacterData(obj.Name, obj.Faction, obj.Sex, obj.Head, CharacterVoice.Mute),
|
||||||
voice2 = 0,
|
|
||||||
black_ops = false,
|
black_ops = false,
|
||||||
jammered = false,
|
jammered = false,
|
||||||
obj.ExoSuit,
|
obj.ExoSuit,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ class CorpseConverter extends AvatarConverter {
|
||||||
private def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
|
private def MakeAppearanceData(obj : Player) : (Int)=>CharacterAppearanceData = {
|
||||||
CharacterAppearanceData(
|
CharacterAppearanceData(
|
||||||
BasicCharacterData(obj.Name, obj.Faction, CharacterGender.Male, 0, CharacterVoice.Mute),
|
BasicCharacterData(obj.Name, obj.Faction, CharacterGender.Male, 0, CharacterVoice.Mute),
|
||||||
voice2 = 0,
|
|
||||||
black_ops = false,
|
black_ops = false,
|
||||||
jammered = false,
|
jammered = false,
|
||||||
obj.ExoSuit,
|
obj.ExoSuit,
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@ import shapeless.{::, HNil}
|
||||||
* `RibbonBars`
|
* `RibbonBars`
|
||||||
* @see `http://www.planetside-universe.com/p-outfit-decals-31.htm`
|
* @see `http://www.planetside-universe.com/p-outfit-decals-31.htm`
|
||||||
* @param app the player's cardinal appearance settings
|
* @param app the player's cardinal appearance settings
|
||||||
* @param voice2 na;
|
// * @param voice2 na;
|
||||||
* affects the frequency by which the character's voice is heard (somehow);
|
// * affects the frequency by which the character's voice is heard (somehow);
|
||||||
* commonly 3 for best results
|
// * commonly 3 for best results
|
||||||
* @param black_ops whether or not this avatar is enrolled in Black OPs
|
* @param black_ops whether or not this avatar is enrolled in Black OPs
|
||||||
* @param jammered the player has been caught in an EMP blast recently;
|
* @param jammered the player has been caught in an EMP blast recently;
|
||||||
* creates a jammered sound effect that follows the player around and can be heard by others
|
* creates a jammered sound effect that follows the player around and can be heard by others
|
||||||
|
|
@ -61,7 +61,6 @@ import shapeless.{::, HNil}
|
||||||
* @param ribbons the four merit commendation ribbon medals
|
* @param ribbons the four merit commendation ribbon medals
|
||||||
*/
|
*/
|
||||||
final case class CharacterAppearanceData(app : BasicCharacterData,
|
final case class CharacterAppearanceData(app : BasicCharacterData,
|
||||||
voice2 : Int,
|
|
||||||
black_ops : Boolean,
|
black_ops : Boolean,
|
||||||
jammered : Boolean,
|
jammered : Boolean,
|
||||||
exosuit : ExoSuitType.Value,
|
exosuit : ExoSuitType.Value,
|
||||||
|
|
@ -140,13 +139,16 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
|
||||||
("sex" | CharacterGender.codec) ::
|
("sex" | CharacterGender.codec) ::
|
||||||
("head" | uint8L) ::
|
("head" | uint8L) ::
|
||||||
("voice" | CharacterVoice.codec) ::
|
("voice" | CharacterVoice.codec) ::
|
||||||
("voice2" | uint2L) ::
|
uint32L ::
|
||||||
ignore(78) :: //unknown
|
uint16L ::
|
||||||
|
uint16L ::
|
||||||
|
uint16L ::
|
||||||
uint16L :: //usually either 0 or 65535
|
uint16L :: //usually either 0 or 65535
|
||||||
uint32L :: //for outfit_name (below) to be visible in-game, this value should be non-zero
|
uint32L :: //for outfit_name (below) to be visible in-game, this value should be non-zero
|
||||||
("outfit_name" | PacketHelpers.encodedWideStringAligned( outfitNamePadding )) ::
|
("outfit_name" | PacketHelpers.encodedWideStringAligned( outfitNamePadding )) ::
|
||||||
("outfit_logo" | uint8L) ::
|
("outfit_logo" | uint8L) ::
|
||||||
ignore(1) :: //unknown
|
ignore(1) :: //unknown
|
||||||
|
//TODO bool :: //ps.c 1069587
|
||||||
("backpack" | bool) :: //requires alt_model flag (does NOT require health == 0)
|
("backpack" | bool) :: //requires alt_model flag (does NOT require health == 0)
|
||||||
bool :: //stream misalignment when set
|
bool :: //stream misalignment when set
|
||||||
("facingPitch" | Angular.codec_pitch) ::
|
("facingPitch" | Angular.codec_pitch) ::
|
||||||
|
|
@ -166,32 +168,34 @@ object CharacterAppearanceData extends Marshallable[CharacterAppearanceData] {
|
||||||
})
|
})
|
||||||
).exmap[CharacterAppearanceData] (
|
).exmap[CharacterAppearanceData] (
|
||||||
{
|
{
|
||||||
case _ :: _ :: false :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: true :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: HNil |
|
case _ :: _ :: false :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: true :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: HNil |
|
||||||
_ :: _ :: false :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: true :: _ :: HNil =>
|
_ :: _ :: false :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: _ :: true :: _ :: HNil =>
|
||||||
Attempt.Failure(Err("invalid character appearance data; can not encode alternate model without required bit set"))
|
Attempt.Failure(Err("invalid character appearance data; can not encode alternate model without required bit set"))
|
||||||
|
|
||||||
case faction :: bops :: _ :: _ :: jamd :: false :: 0 :: name :: suit :: _ :: sex :: head :: v1 :: v2 :: _ :: _ :: _/*has_outfit_name*/ :: outfit :: logo :: _ :: bpack :: false :: facingPitch :: facingYawUpper :: _ :: _ :: _ :: lfs :: gstate :: cloaking :: _ :: false :: charging :: _ :: zipline :: ribbons :: HNil =>
|
case faction :: bops :: _ :: _ :: jamd :: false :: 0 :: name :: suit :: _ :: sex :: head :: v1 :: _ :: _ :: _ :: _ :: _ :: _/*has_outfit_name*/ :: outfit :: logo :: _ :: bpack :: false :: facingPitch :: facingYawUpper :: _ :: _ :: _ :: lfs :: gstate :: cloaking :: _ :: false :: charging :: _ :: zipline :: ribbons :: HNil =>
|
||||||
Attempt.successful(
|
Attempt.successful(
|
||||||
CharacterAppearanceData(BasicCharacterData(name, faction, sex, head, v1), v2, bops, jamd, suit, outfit, logo, bpack, facingPitch, facingYawUpper, lfs, gstate, cloaking, charging, zipline, ribbons)(name_padding)
|
CharacterAppearanceData(BasicCharacterData(name, faction, sex, head, v1), bops, jamd, suit, outfit, logo, bpack, facingPitch, facingYawUpper, lfs, gstate, cloaking, charging, zipline, ribbons)(name_padding)
|
||||||
)
|
)
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
Attempt.Failure(Err("invalid character appearance data; can not encode"))
|
Attempt.Failure(Err("invalid character appearance data; can not encode"))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case CharacterAppearanceData(BasicCharacterData(name, PlanetSideEmpire.NEUTRAL, _, _, _), _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
|
case CharacterAppearanceData(BasicCharacterData(name, PlanetSideEmpire.NEUTRAL, _, _, _), _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
|
||||||
Attempt.failure(Err(s"character $name's faction can not declare as neutral"))
|
Attempt.failure(Err(s"character $name's faction can not declare as neutral"))
|
||||||
|
|
||||||
case CharacterAppearanceData(BasicCharacterData(name, faction, sex, head, v1), v2, bops, jamd, suit, outfit, logo, bpack, facingPitch, facingYawUpper, lfs, gstate, cloaking, charging, zipline, ribbons) =>
|
case CharacterAppearanceData(BasicCharacterData(name, faction, sex, head, voice), bops, jamd, suit, outfit, logo, bpack, facingPitch, facingYawUpper, lfs, gstate, cloaking, charging, zipline, ribbons) =>
|
||||||
val has_outfit_name : Long = outfit.length.toLong //TODO this is a kludge
|
val has_outfit_name : Long = outfit.length.toLong //TODO this is a kludge
|
||||||
var alt_model : Boolean = false
|
var alt_model : Boolean = false
|
||||||
var alt_model_extrabit : Option[Boolean] = None
|
var alt_model_extrabit : Option[Boolean] = None
|
||||||
|
var volume : Long = 192L
|
||||||
if(zipline || bpack) {
|
if(zipline || bpack) {
|
||||||
alt_model = true
|
alt_model = true
|
||||||
alt_model_extrabit = Some(false)
|
alt_model_extrabit = Some(false)
|
||||||
|
volume = 0L
|
||||||
}
|
}
|
||||||
Attempt.successful(
|
Attempt.successful(
|
||||||
faction :: bops :: alt_model :: () :: jamd :: false :: 0 :: name :: suit :: () :: sex :: head :: v1 :: v2 :: () :: 0 :: has_outfit_name :: outfit :: logo :: () :: bpack :: false :: facingPitch :: facingYawUpper :: () :: alt_model_extrabit :: () :: lfs :: gstate :: cloaking :: () :: false :: charging :: () :: zipline :: ribbons :: HNil
|
faction :: bops :: alt_model :: () :: jamd :: false :: 0 :: name :: suit :: () :: sex :: head :: voice :: volume :: 0 :: 0 :: 0 :: 0 :: has_outfit_name :: outfit :: logo :: () :: bpack :: false :: facingPitch :: facingYawUpper :: () :: alt_model_extrabit :: () :: lfs :: gstate :: cloaking :: () :: false :: charging :: () :: zipline :: ribbons :: HNil
|
||||||
)
|
)
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@ import shapeless.{::, HNil}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Values for the implant effects on a character model.
|
* Values for the implant effects on a character model.
|
||||||
* The effects can not be activated simultaneously.
|
* The effects are not additive and this value is not a bitmask.<br>
|
||||||
* In at least one case, attempting to activate multiple effects will cause the PlanetSide client to crash.<br>
|
|
||||||
* <br>
|
* <br>
|
||||||
* `RegenEffects` is a reverse-flagged item - inactive when the corresponding bit is set.
|
* `RegenEffects` is a reverse-flagged item - inactive when the corresponding bit is set.
|
||||||
* For that reason, every other effect is `n`+1, while `NoEffects` is 1 and `RegenEffects` is 0.
|
* For that reason, every other effect is `n`+1, while `NoEffects` is 1 and `RegenEffects` is 0.
|
||||||
|
|
@ -65,7 +64,8 @@ object UniformStyle extends Enumeration {
|
||||||
* @param command_rank the player's command rank as a number from 0 to 5;
|
* @param command_rank the player's command rank as a number from 0 to 5;
|
||||||
* cosmetic armor associated with the command rank will be applied automatically
|
* cosmetic armor associated with the command rank will be applied automatically
|
||||||
* @param implant_effects the effects of implants that can be seen on a player's character;
|
* @param implant_effects the effects of implants that can be seen on a player's character;
|
||||||
* though many implants can be used simultaneously, only one implant effect can be applied here
|
* the number of entries equates to the number of effects applied;
|
||||||
|
* the maximu number of effects is three
|
||||||
* @param cosmetics optional decorative features that are added to the player's head model by console/chat commands;
|
* @param cosmetics optional decorative features that are added to the player's head model by console/chat commands;
|
||||||
* they become available at battle rank 24, but here they require the third uniform upgrade (rank 25);
|
* they become available at battle rank 24, but here they require the third uniform upgrade (rank 25);
|
||||||
* these flags do not exist if they are not applicable
|
* these flags do not exist if they are not applicable
|
||||||
|
|
@ -82,7 +82,7 @@ final case class CharacterData(health : Int,
|
||||||
uniform_upgrade : UniformStyle.Value,
|
uniform_upgrade : UniformStyle.Value,
|
||||||
unk : Int,
|
unk : Int,
|
||||||
command_rank : Int,
|
command_rank : Int,
|
||||||
implant_effects : Option[ImplantEffects.Value],
|
implant_effects : List[ImplantEffects.Value],
|
||||||
cosmetics : Option[Cosmetics])
|
cosmetics : Option[Cosmetics])
|
||||||
(is_backpack : Boolean,
|
(is_backpack : Boolean,
|
||||||
is_seated : Boolean) extends ConstructorData {
|
is_seated : Boolean) extends ConstructorData {
|
||||||
|
|
@ -90,7 +90,7 @@ final case class CharacterData(health : Int,
|
||||||
override def bitsize : Long = {
|
override def bitsize : Long = {
|
||||||
//factor guard bool values into the base size, not its corresponding optional field
|
//factor guard bool values into the base size, not its corresponding optional field
|
||||||
val seatedSize = if(is_seated) { 0 } else { 16 }
|
val seatedSize = if(is_seated) { 0 } else { 16 }
|
||||||
val effectsSize : Long = if(implant_effects.isDefined) { 4L } else { 0L }
|
val effectsSize : Long = implant_effects.length * 4L
|
||||||
val cosmeticsSize : Long = if(cosmetics.isDefined) { cosmetics.get.bitsize } else { 0L }
|
val cosmeticsSize : Long = if(cosmetics.isDefined) { cosmetics.get.bitsize } else { 0L }
|
||||||
11L + seatedSize + effectsSize + cosmeticsSize
|
11L + seatedSize + effectsSize + cosmeticsSize
|
||||||
}
|
}
|
||||||
|
|
@ -107,22 +107,21 @@ object CharacterData extends Marshallable[CharacterData] {
|
||||||
* @param cosmetics optional decorative features that are added to the player's head model by console/chat commands
|
* @param cosmetics optional decorative features that are added to the player's head model by console/chat commands
|
||||||
* @return a `CharacterData` object
|
* @return a `CharacterData` object
|
||||||
*/
|
*/
|
||||||
def apply(health : Int, armor : Int, uniform : UniformStyle.Value, cr : Int, implant_effects : Option[ImplantEffects.Value], cosmetics : Option[Cosmetics]) : (Boolean,Boolean)=>CharacterData =
|
def apply(health : Int, armor : Int, uniform : UniformStyle.Value, cr : Int, implant_effects : List[ImplantEffects.Value], cosmetics : Option[Cosmetics]) : (Boolean,Boolean)=>CharacterData =
|
||||||
CharacterData(health, armor, uniform, 0, cr, implant_effects, cosmetics)
|
CharacterData(health, armor, uniform, 0, cr, implant_effects, cosmetics)
|
||||||
|
|
||||||
def codec(is_backpack : Boolean) : Codec[CharacterData] = (
|
def codec(is_backpack : Boolean) : Codec[CharacterData] = (
|
||||||
("health" | uint8L) :: //dead state when health == 0
|
("health" | uint8L) :: //dead state when health == 0
|
||||||
("armor" | uint8L) ::
|
("armor" | uint8L) ::
|
||||||
(("uniform_upgrade" | UniformStyle.codec) >>:~ { style =>
|
(("uniform_upgrade" | UniformStyle.codec) >>:~ { style =>
|
||||||
ignore(3) :: //unknown
|
ignore(3) :: //uniform_upgrade is actually interpreted as a 6u field, but the lower 3u seems to be discarded
|
||||||
("command_rank" | uintL(3)) ::
|
("command_rank" | uintL(3)) ::
|
||||||
bool :: //misalignment when == 1
|
listOfN(uint2, "implant_effects" | ImplantEffects.codec) ::
|
||||||
optional(bool, "implant_effects" | ImplantEffects.codec) ::
|
|
||||||
conditional(style == UniformStyle.ThirdUpgrade, "cosmetics" | Cosmetics.codec)
|
conditional(style == UniformStyle.ThirdUpgrade, "cosmetics" | Cosmetics.codec)
|
||||||
})
|
})
|
||||||
).exmap[CharacterData] (
|
).exmap[CharacterData] (
|
||||||
{
|
{
|
||||||
case health :: armor :: uniform :: _ :: cr :: false :: implant_effects :: cosmetics :: HNil =>
|
case health :: armor :: uniform :: _ :: cr :: implant_effects :: cosmetics :: HNil =>
|
||||||
val newHealth = if(is_backpack) { 0 } else { health }
|
val newHealth = if(is_backpack) { 0 } else { health }
|
||||||
Attempt.Successful(CharacterData(newHealth, armor, uniform, 0, cr, implant_effects, cosmetics)(is_backpack, false))
|
Attempt.Successful(CharacterData(newHealth, armor, uniform, 0, cr, implant_effects, cosmetics)(is_backpack, false))
|
||||||
|
|
||||||
|
|
@ -132,7 +131,7 @@ object CharacterData extends Marshallable[CharacterData] {
|
||||||
{
|
{
|
||||||
case CharacterData(health, armor, uniform, _, cr, implant_effects, cosmetics) =>
|
case CharacterData(health, armor, uniform, _, cr, implant_effects, cosmetics) =>
|
||||||
val newHealth = if(is_backpack) { 0 } else { health }
|
val newHealth = if(is_backpack) { 0 } else { health }
|
||||||
Attempt.Successful(newHealth :: armor :: uniform :: () :: cr :: false :: implant_effects :: cosmetics :: HNil)
|
Attempt.Successful(newHealth :: armor :: uniform :: () :: cr :: implant_effects :: cosmetics :: HNil)
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
Attempt.Failure(Err("invalid character data; can not decode"))
|
Attempt.Failure(Err("invalid character data; can not decode"))
|
||||||
|
|
@ -141,23 +140,22 @@ object CharacterData extends Marshallable[CharacterData] {
|
||||||
|
|
||||||
def codec_seated(is_backpack : Boolean) : Codec[CharacterData] = (
|
def codec_seated(is_backpack : Boolean) : Codec[CharacterData] = (
|
||||||
("uniform_upgrade" | UniformStyle.codec) >>:~ { style =>
|
("uniform_upgrade" | UniformStyle.codec) >>:~ { style =>
|
||||||
ignore(3) :: //unknown
|
ignore(3) :: //uniform_upgrade is actually interpreted as a 6u field, but the lower 3u seems to be discarded
|
||||||
("command_rank" | uintL(3)) ::
|
("command_rank" | uintL(3)) ::
|
||||||
bool :: //stream misalignment when != 1
|
listOfN(uint2, "implant_effects" | ImplantEffects.codec) ::
|
||||||
optional(bool, "implant_effects" | ImplantEffects.codec) ::
|
|
||||||
conditional(style == UniformStyle.ThirdUpgrade, "cosmetics" | Cosmetics.codec)
|
conditional(style == UniformStyle.ThirdUpgrade, "cosmetics" | Cosmetics.codec)
|
||||||
}
|
}
|
||||||
).exmap[CharacterData] (
|
).exmap[CharacterData] (
|
||||||
{
|
{
|
||||||
case uniform :: _ :: cr :: false :: implant_effects :: cosmetics :: HNil =>
|
case uniform :: _ :: cr :: implant_effects :: cosmetics :: HNil =>
|
||||||
Attempt.Successful(new CharacterData(100, 0, uniform, 0, cr, implant_effects, cosmetics)(is_backpack, true))
|
Attempt.Successful(new CharacterData(100, 0, uniform, 0, cr, implant_effects, cosmetics)(is_backpack, true))
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
Attempt.Failure(Err("invalid character data; can not encode"))
|
Attempt.Failure(Err("invalid character data; can not encode"))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case obj @ CharacterData(_, _, uniform, _, cr, implant_effects, cosmetics) =>
|
case CharacterData(_, _, uniform, _, cr, implant_effects, cosmetics) =>
|
||||||
Attempt.Successful(uniform :: () :: cr :: false :: implant_effects :: cosmetics :: HNil)
|
Attempt.Successful(uniform :: () :: cr :: implant_effects :: cosmetics :: HNil)
|
||||||
|
|
||||||
case _ =>
|
case _ =>
|
||||||
Attempt.Failure(Err("invalid character data; can not decode"))
|
Attempt.Failure(Err("invalid character data; can not decode"))
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,6 @@ final case class ImplantEntry(implant : ImplantType.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;
|
||||||
* range is 0-65535;
|
* range is 0-65535;
|
||||||
* the avatar's `y` armor points is tied to their exo-suit type
|
* the avatar's `y` armor points is tied to their exo-suit type
|
||||||
* @param unk1 na;
|
|
||||||
* defaults to 1
|
|
||||||
* @param unk2 na;
|
|
||||||
* defaults to 7
|
|
||||||
* @param unk3 na;
|
|
||||||
* defaults to 7
|
|
||||||
* @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;
|
||||||
* range is 0-65535
|
* range is 0-65535
|
||||||
* @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;
|
||||||
|
|
@ -73,9 +67,6 @@ final case class DetailedCharacterData(bep : Long,
|
||||||
healthMax : Int,
|
healthMax : Int,
|
||||||
health : Int,
|
health : Int,
|
||||||
armor : Int,
|
armor : Int,
|
||||||
unk1 : Int, //1
|
|
||||||
unk2 : Int, //7
|
|
||||||
unk3 : Int, //7
|
|
||||||
staminaMax : Int,
|
staminaMax : Int,
|
||||||
stamina : Int,
|
stamina : Int,
|
||||||
certs : List[CertificationType.Value],
|
certs : List[CertificationType.Value],
|
||||||
|
|
@ -111,24 +102,6 @@ final case class DetailedCharacterData(bep : Long,
|
||||||
}
|
}
|
||||||
|
|
||||||
object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
||||||
/**
|
|
||||||
* Overloaded constructor for `DetailedCharacterData` that requires an inventory and drops unknown values.
|
|
||||||
* @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 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 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
|
|
||||||
* @return a `DetailedCharacterData` object
|
|
||||||
*/
|
|
||||||
def apply(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], cosmetics : Option[Cosmetics]) : (Option[Int])=>DetailedCharacterData =
|
|
||||||
DetailedCharacterData(bep, cep, healthMax, health, armor, 1, 7, 7, staminaMax, stamina, certs, implants, firstTimeEvents, tutorials, cosmetics)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `Codec` for entries in the `List` of implants.
|
* `Codec` for entries in the `List` of implants.
|
||||||
*/
|
*/
|
||||||
|
|
@ -255,16 +228,14 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
||||||
def codec(pad_length : Option[Int]) : Codec[DetailedCharacterData] = (
|
def codec(pad_length : Option[Int]) : Codec[DetailedCharacterData] = (
|
||||||
("bep" | uint32L) >>:~ { bep =>
|
("bep" | uint32L) >>:~ { bep =>
|
||||||
("cep" | uint32L) ::
|
("cep" | uint32L) ::
|
||||||
ignore(96) ::
|
uint32L ::
|
||||||
|
uint32L ::
|
||||||
|
uint32L ::
|
||||||
("healthMax" | uint16L) ::
|
("healthMax" | uint16L) ::
|
||||||
("health" | uint16L) ::
|
("health" | uint16L) ::
|
||||||
ignore(1) ::
|
ignore(1) ::
|
||||||
("armor" | uint16L) ::
|
("armor" | uint16L) ::
|
||||||
ignore(9) ::
|
uint32 :: //TODO switch endianness
|
||||||
("unk1" | uint8L) ::
|
|
||||||
ignore(8) ::
|
|
||||||
("unk2" | uint4L) ::
|
|
||||||
("unk3" | uintL(3)) ::
|
|
||||||
("staminaMax" | uint16L) ::
|
("staminaMax" | uint16L) ::
|
||||||
("stamina" | uint16L) ::
|
("stamina" | uint16L) ::
|
||||||
ignore(147) ::
|
ignore(147) ::
|
||||||
|
|
@ -290,14 +261,14 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
||||||
}
|
}
|
||||||
).exmap[DetailedCharacterData] (
|
).exmap[DetailedCharacterData] (
|
||||||
{
|
{
|
||||||
case bep :: cep :: _ :: hpmax :: hp :: _ :: armor :: _ :: u1 :: _ :: u2 :: u3 :: stamax :: stam :: _ :: certs :: _ :: _ :: implants :: _ :: _ :: fte0 :: fte1 :: _ :: tut0 :: tut1 :: _ :: _ :: _ :: cosmetics :: HNil =>
|
case bep :: cep :: 0 :: 0 :: 0 :: hpmax :: hp :: _ :: armor :: 32831L :: stamax :: stam :: _ :: certs :: _ :: _ :: implants :: _ :: _ :: fte0 :: fte1 :: _ :: tut0 :: tut1 :: _ :: _ :: _ :: cosmetics :: HNil =>
|
||||||
//prepend the displaced first elements to their lists
|
//prepend the displaced first elements to their lists
|
||||||
val fteList : List[String] = if(fte0.isDefined) { fte0.get +: fte1 } else { fte1 }
|
val fteList : List[String] = if(fte0.isDefined) { fte0.get +: fte1 } else { fte1 }
|
||||||
val tutList : List[String] = if(tut0.isDefined) { tut0.get +: tut1 } else { tut1 }
|
val tutList : List[String] = if(tut0.isDefined) { tut0.get +: tut1 } else { tut1 }
|
||||||
Attempt.successful(DetailedCharacterData(bep, cep, hpmax, hp, armor, u1, u2, u3, stamax, stam, certs, implants, fteList, tutList, cosmetics)(pad_length))
|
Attempt.successful(new DetailedCharacterData(bep, cep, hpmax, hp, armor, stamax, stam, certs, implants, fteList, tutList, cosmetics)(pad_length))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
case DetailedCharacterData(bep, cep, hpmax, hp, armor, u1, u2, u3, stamax, stam, certs, implants, fteList, tutList, cos) =>
|
case DetailedCharacterData(bep, cep, hpmax, hp, armor, stamax, stam, certs, implants, fteList, tutList, cos) =>
|
||||||
val implantCapacity : Int = numberOfImplantSlots(bep)
|
val implantCapacity : Int = numberOfImplantSlots(bep)
|
||||||
val implantList = if(implants.length > implantCapacity) {
|
val implantList = if(implants.length > implantCapacity) {
|
||||||
implants.slice(0, implantCapacity)
|
implants.slice(0, implantCapacity)
|
||||||
|
|
@ -318,7 +289,7 @@ object DetailedCharacterData extends Marshallable[DetailedCharacterData] {
|
||||||
}
|
}
|
||||||
val br24 : Boolean = isBR24(bep)
|
val br24 : Boolean = isBR24(bep)
|
||||||
val cosmetics : Option[Cosmetics] = if(br24) { cos } else { None }
|
val cosmetics : Option[Cosmetics] = if(br24) { cos } else { None }
|
||||||
Attempt.successful(bep :: cep :: () :: hpmax :: hp :: () :: armor :: () :: u1 :: () :: u2 :: u3 :: stamax :: stam :: () :: certs :: None :: () :: implantList :: () :: fteList.size.toLong :: firstEvent :: fteListCopy :: tutList.size.toLong :: firstTutorial :: tutListCopy :: () :: br24 :: () :: cosmetics :: HNil)
|
Attempt.successful(bep :: cep :: 0L :: 0L :: 0L :: hpmax :: hp :: () :: armor :: 32831L :: stamax :: stam :: () :: certs :: None :: () :: implantList :: () :: fteList.size.toLong :: firstEvent :: fteListCopy :: tutList.size.toLong :: firstTutorial :: tutListCopy :: () :: br24 :: () :: cosmetics :: HNil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ class CharacterDataTest extends Specification {
|
||||||
basic.app.sex mustEqual CharacterGender.Male
|
basic.app.sex mustEqual CharacterGender.Male
|
||||||
basic.app.head mustEqual 5
|
basic.app.head mustEqual 5
|
||||||
basic.app.voice mustEqual CharacterVoice.Voice5
|
basic.app.voice mustEqual CharacterVoice.Voice5
|
||||||
basic.voice2 mustEqual 3
|
|
||||||
basic.black_ops mustEqual false
|
basic.black_ops mustEqual false
|
||||||
basic.jammered mustEqual false
|
basic.jammered mustEqual false
|
||||||
basic.exosuit mustEqual ExoSuitType.Reinforced
|
basic.exosuit mustEqual ExoSuitType.Reinforced
|
||||||
|
|
@ -60,8 +59,8 @@ class CharacterDataTest extends Specification {
|
||||||
char.armor mustEqual 253
|
char.armor mustEqual 253
|
||||||
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
||||||
char.command_rank mustEqual 5
|
char.command_rank mustEqual 5
|
||||||
char.implant_effects.isDefined mustEqual true
|
char.implant_effects.length mustEqual 1
|
||||||
char.implant_effects.get mustEqual ImplantEffects.NoEffects
|
char.implant_effects.head mustEqual ImplantEffects.NoEffects
|
||||||
char.cosmetics.isDefined mustEqual true
|
char.cosmetics.isDefined mustEqual true
|
||||||
char.cosmetics.get.no_helmet mustEqual true
|
char.cosmetics.get.no_helmet mustEqual true
|
||||||
char.cosmetics.get.beret mustEqual true
|
char.cosmetics.get.beret mustEqual true
|
||||||
|
|
@ -131,7 +130,6 @@ class CharacterDataTest extends Specification {
|
||||||
basic.app.sex mustEqual CharacterGender.Male
|
basic.app.sex mustEqual CharacterGender.Male
|
||||||
basic.app.head mustEqual 5
|
basic.app.head mustEqual 5
|
||||||
basic.app.voice mustEqual CharacterVoice.Voice5
|
basic.app.voice mustEqual CharacterVoice.Voice5
|
||||||
basic.voice2 mustEqual 3
|
|
||||||
basic.black_ops mustEqual false
|
basic.black_ops mustEqual false
|
||||||
basic.jammered mustEqual false
|
basic.jammered mustEqual false
|
||||||
basic.exosuit mustEqual ExoSuitType.Reinforced
|
basic.exosuit mustEqual ExoSuitType.Reinforced
|
||||||
|
|
@ -175,7 +173,6 @@ class CharacterDataTest extends Specification {
|
||||||
basic.app.sex mustEqual CharacterGender.Male
|
basic.app.sex mustEqual CharacterGender.Male
|
||||||
basic.app.head mustEqual 10
|
basic.app.head mustEqual 10
|
||||||
basic.app.voice mustEqual CharacterVoice.Voice2
|
basic.app.voice mustEqual CharacterVoice.Voice2
|
||||||
basic.voice2 mustEqual 0
|
|
||||||
basic.black_ops mustEqual false
|
basic.black_ops mustEqual false
|
||||||
basic.jammered mustEqual false
|
basic.jammered mustEqual false
|
||||||
basic.exosuit mustEqual ExoSuitType.MAX
|
basic.exosuit mustEqual ExoSuitType.MAX
|
||||||
|
|
@ -197,7 +194,7 @@ class CharacterDataTest extends Specification {
|
||||||
char.armor mustEqual 0
|
char.armor mustEqual 0
|
||||||
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
||||||
char.command_rank mustEqual 2
|
char.command_rank mustEqual 2
|
||||||
char.implant_effects.isDefined mustEqual false
|
char.implant_effects.isEmpty mustEqual true
|
||||||
char.cosmetics.isDefined mustEqual true
|
char.cosmetics.isDefined mustEqual true
|
||||||
char.cosmetics.get.no_helmet mustEqual true
|
char.cosmetics.get.no_helmet mustEqual true
|
||||||
char.cosmetics.get.beret mustEqual true
|
char.cosmetics.get.beret mustEqual true
|
||||||
|
|
@ -228,7 +225,6 @@ class CharacterDataTest extends Specification {
|
||||||
5,
|
5,
|
||||||
CharacterVoice.Voice5
|
CharacterVoice.Voice5
|
||||||
),
|
),
|
||||||
3,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
ExoSuitType.Reinforced,
|
ExoSuitType.Reinforced,
|
||||||
|
|
@ -250,7 +246,7 @@ class CharacterDataTest extends Specification {
|
||||||
255, 253,
|
255, 253,
|
||||||
UniformStyle.ThirdUpgrade,
|
UniformStyle.ThirdUpgrade,
|
||||||
5,
|
5,
|
||||||
Some(ImplantEffects.NoEffects),
|
List(ImplantEffects.NoEffects),
|
||||||
Some(Cosmetics(true, true, true, true, false))
|
Some(Cosmetics(true, true, true, true, false))
|
||||||
)
|
)
|
||||||
val inv = InventoryData(
|
val inv = InventoryData(
|
||||||
|
|
@ -284,7 +280,6 @@ class CharacterDataTest extends Specification {
|
||||||
5,
|
5,
|
||||||
CharacterVoice.Voice5
|
CharacterVoice.Voice5
|
||||||
),
|
),
|
||||||
3,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
ExoSuitType.Reinforced,
|
ExoSuitType.Reinforced,
|
||||||
|
|
@ -306,7 +301,7 @@ class CharacterDataTest extends Specification {
|
||||||
255, 253,
|
255, 253,
|
||||||
UniformStyle.ThirdUpgrade,
|
UniformStyle.ThirdUpgrade,
|
||||||
5,
|
5,
|
||||||
Some(ImplantEffects.NoEffects),
|
List(ImplantEffects.NoEffects),
|
||||||
Some(Cosmetics(true, true, true, true, false))
|
Some(Cosmetics(true, true, true, true, false))
|
||||||
)
|
)
|
||||||
val inv = InventoryData(
|
val inv = InventoryData(
|
||||||
|
|
@ -337,7 +332,6 @@ class CharacterDataTest extends Specification {
|
||||||
10,
|
10,
|
||||||
CharacterVoice.Voice2
|
CharacterVoice.Voice2
|
||||||
),
|
),
|
||||||
0,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
ExoSuitType.MAX,
|
ExoSuitType.MAX,
|
||||||
|
|
@ -359,7 +353,7 @@ class CharacterDataTest extends Specification {
|
||||||
0, 0,
|
0, 0,
|
||||||
UniformStyle.ThirdUpgrade,
|
UniformStyle.ThirdUpgrade,
|
||||||
2,
|
2,
|
||||||
None,
|
List(),
|
||||||
Some(Cosmetics(true, true, true, true, false))
|
Some(Cosmetics(true, true, true, true, false))
|
||||||
)
|
)
|
||||||
val obj = PlayerData(pos, app, char, DrawnSlot.Pistol1)
|
val obj = PlayerData(pos, app, char, DrawnSlot.Pistol1)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
basic.app.sex mustEqual CharacterGender.Female
|
basic.app.sex mustEqual CharacterGender.Female
|
||||||
basic.app.head mustEqual 41
|
basic.app.head mustEqual 41
|
||||||
basic.app.voice mustEqual CharacterVoice.Voice1
|
basic.app.voice mustEqual CharacterVoice.Voice1
|
||||||
basic.voice2 mustEqual 3
|
|
||||||
basic.black_ops mustEqual false
|
basic.black_ops mustEqual false
|
||||||
basic.jammered mustEqual false
|
basic.jammered mustEqual false
|
||||||
basic.exosuit mustEqual ExoSuitType.Standard
|
basic.exosuit mustEqual ExoSuitType.Standard
|
||||||
|
|
@ -63,9 +62,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
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
|
||||||
char.unk1 mustEqual 1
|
|
||||||
char.unk2 mustEqual 7
|
|
||||||
char.unk3 mustEqual 7
|
|
||||||
char.staminaMax mustEqual 100
|
char.staminaMax mustEqual 100
|
||||||
char.stamina mustEqual 100
|
char.stamina mustEqual 100
|
||||||
char.certs.length mustEqual 7
|
char.certs.length mustEqual 7
|
||||||
|
|
@ -175,7 +171,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
basic.app.sex mustEqual CharacterGender.Female
|
basic.app.sex mustEqual CharacterGender.Female
|
||||||
basic.app.head mustEqual 41
|
basic.app.head mustEqual 41
|
||||||
basic.app.voice mustEqual CharacterVoice.Voice1
|
basic.app.voice mustEqual CharacterVoice.Voice1
|
||||||
basic.voice2 mustEqual 3
|
|
||||||
basic.black_ops mustEqual false
|
basic.black_ops mustEqual false
|
||||||
basic.jammered mustEqual false
|
basic.jammered mustEqual false
|
||||||
basic.exosuit mustEqual ExoSuitType.Standard
|
basic.exosuit mustEqual ExoSuitType.Standard
|
||||||
|
|
@ -199,9 +194,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
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
|
||||||
char.unk1 mustEqual 1
|
|
||||||
char.unk2 mustEqual 7
|
|
||||||
char.unk3 mustEqual 7
|
|
||||||
char.staminaMax mustEqual 100
|
char.staminaMax mustEqual 100
|
||||||
char.stamina mustEqual 100
|
char.stamina mustEqual 100
|
||||||
char.certs.length mustEqual 7
|
char.certs.length mustEqual 7
|
||||||
|
|
@ -382,7 +374,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
41,
|
41,
|
||||||
CharacterVoice.Voice1
|
CharacterVoice.Voice1
|
||||||
),
|
),
|
||||||
3,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
ExoSuitType.Standard,
|
ExoSuitType.Standard,
|
||||||
|
|
@ -402,7 +393,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
0,
|
0,
|
||||||
100, 100,
|
100, 100,
|
||||||
50,
|
50,
|
||||||
1, 7, 7,
|
|
||||||
100, 100,
|
100, 100,
|
||||||
List(
|
List(
|
||||||
CertificationType.StandardAssault,
|
CertificationType.StandardAssault,
|
||||||
|
|
@ -453,7 +443,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
41,
|
41,
|
||||||
CharacterVoice.Voice1
|
CharacterVoice.Voice1
|
||||||
),
|
),
|
||||||
3,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
ExoSuitType.Standard,
|
ExoSuitType.Standard,
|
||||||
|
|
@ -473,7 +462,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
0,
|
0,
|
||||||
100, 100,
|
100, 100,
|
||||||
50,
|
50,
|
||||||
1, 7, 7,
|
|
||||||
100, 100,
|
100, 100,
|
||||||
List(
|
List(
|
||||||
CertificationType.StandardAssault,
|
CertificationType.StandardAssault,
|
||||||
|
|
@ -520,7 +508,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
)
|
)
|
||||||
val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
|
val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
|
||||||
BasicCharacterData("KiCkJr", PlanetSideEmpire.NC, CharacterGender.Male, 24, CharacterVoice.Voice4),
|
BasicCharacterData("KiCkJr", PlanetSideEmpire.NC, CharacterGender.Male, 24, CharacterVoice.Voice4),
|
||||||
3,
|
|
||||||
false, false,
|
false, false,
|
||||||
ExoSuitType.Agile,
|
ExoSuitType.Agile,
|
||||||
"",
|
"",
|
||||||
|
|
@ -541,7 +528,6 @@ class DetailedCharacterDataTest extends Specification {
|
||||||
6366766,
|
6366766,
|
||||||
694787,
|
694787,
|
||||||
100, 100, 100,
|
100, 100, 100,
|
||||||
1, 7, 7,
|
|
||||||
100, 46,
|
100, 46,
|
||||||
List(
|
List(
|
||||||
CertificationType.StandardAssault,
|
CertificationType.StandardAssault,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ class MountedVehiclesTest extends Specification {
|
||||||
app.app.sex mustEqual CharacterGender.Male
|
app.app.sex mustEqual CharacterGender.Male
|
||||||
app.app.head mustEqual 5
|
app.app.head mustEqual 5
|
||||||
app.app.voice mustEqual CharacterVoice.Voice5
|
app.app.voice mustEqual CharacterVoice.Voice5
|
||||||
app.voice2 mustEqual 3
|
|
||||||
app.black_ops mustEqual false
|
app.black_ops mustEqual false
|
||||||
app.lfs mustEqual false
|
app.lfs mustEqual false
|
||||||
app.outfit_name mustEqual "Black Beret Armoured Corps"
|
app.outfit_name mustEqual "Black Beret Armoured Corps"
|
||||||
|
|
@ -76,7 +75,7 @@ class MountedVehiclesTest extends Specification {
|
||||||
char.armor mustEqual 0
|
char.armor mustEqual 0
|
||||||
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
char.uniform_upgrade mustEqual UniformStyle.ThirdUpgrade
|
||||||
char.command_rank mustEqual 5
|
char.command_rank mustEqual 5
|
||||||
char.implant_effects mustEqual None
|
char.implant_effects.isEmpty mustEqual true
|
||||||
char.cosmetics mustEqual Some(Cosmetics(true, true, true, true, false))
|
char.cosmetics mustEqual Some(Cosmetics(true, true, true, true, false))
|
||||||
inv.size mustEqual 4
|
inv.size mustEqual 4
|
||||||
inv.head.objectClass mustEqual ObjectClass.medicalapplicator
|
inv.head.objectClass mustEqual ObjectClass.medicalapplicator
|
||||||
|
|
@ -107,7 +106,6 @@ class MountedVehiclesTest extends Specification {
|
||||||
"encode (Scrawny Ronnie's mosquito)" in {
|
"encode (Scrawny Ronnie's mosquito)" in {
|
||||||
val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
|
val app : (Int)=>CharacterAppearanceData = CharacterAppearanceData(
|
||||||
BasicCharacterData("ScrawnyRonnie", PlanetSideEmpire.TR, CharacterGender.Male, 5, CharacterVoice.Voice5),
|
BasicCharacterData("ScrawnyRonnie", PlanetSideEmpire.TR, CharacterGender.Male, 5, CharacterVoice.Voice5),
|
||||||
3,
|
|
||||||
false, false,
|
false, false,
|
||||||
ExoSuitType.Agile,
|
ExoSuitType.Agile,
|
||||||
"Black Beret Armoured Corps",
|
"Black Beret Armoured Corps",
|
||||||
|
|
@ -128,7 +126,7 @@ class MountedVehiclesTest extends Specification {
|
||||||
UniformStyle.ThirdUpgrade,
|
UniformStyle.ThirdUpgrade,
|
||||||
0,
|
0,
|
||||||
5,
|
5,
|
||||||
None,
|
Nil,
|
||||||
Some(Cosmetics(true, true, true, true, false))
|
Some(Cosmetics(true, true, true, true, false))
|
||||||
)
|
)
|
||||||
val inv : InventoryData = InventoryData(
|
val inv : InventoryData = InventoryData(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue