mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-01 11:33:41 +00:00
accounted for collapsing cert trees, exclusive certifications, and a method of keeping track of certification costs (#227)
This commit is contained in:
parent
2f0629d83a
commit
8b5073dcbc
7 changed files with 449 additions and 61 deletions
|
|
@ -0,0 +1,233 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.avatar
|
||||
|
||||
import net.psforever.types.CertificationType
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object Certification {
|
||||
object Dependencies {
|
||||
/**
|
||||
* Find the certifications that are immediately dependent on the target certification.
|
||||
* (For `A`, find all `B` that are `B ⇒ A`.)
|
||||
* @param certification the target certification
|
||||
* @return all connected certifications
|
||||
*/
|
||||
def From(certification : CertificationType.Value) : Set[CertificationType.Value] = dependencies(certification).toSet
|
||||
|
||||
/**
|
||||
* Find all certifications that are dependent on the target certification.
|
||||
* (For `A`, find all `B...C` where `C ⇒ B` and `B ⇒ A`.)
|
||||
* @param certification the target certification
|
||||
* @return all connected certifications
|
||||
*/
|
||||
def FromAll(certification : CertificationType.Value) : Set[CertificationType.Value] = {
|
||||
var available : List[CertificationType.Value] = List(certification)
|
||||
var allocated : mutable.ListBuffer[CertificationType.Value] = mutable.ListBuffer.empty[CertificationType.Value]
|
||||
do {
|
||||
available = available.flatMap(cert => dependencies(cert))
|
||||
allocated ++= available
|
||||
}
|
||||
while(available.nonEmpty)
|
||||
allocated.toSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the certifications that are immediate dependencies of the target certification.
|
||||
* (For `A`, find all `B` where `A ⇒ B`.)
|
||||
* @param certification the target certification
|
||||
* @return all connected certifications
|
||||
*/
|
||||
def For(certification : CertificationType.Value) : Set[CertificationType.Value] = {
|
||||
(for {
|
||||
(cert, certs) <- dependencies
|
||||
if certs contains certification
|
||||
} yield cert).toSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all certifications that are dependencies of the target certification.
|
||||
* (For `A`, find all `B...C` where `A ⇒ B` and `B ⇒ C`.)
|
||||
* @param certification the target certification
|
||||
* @return all connected certifications
|
||||
*/
|
||||
def ForAll(certification : CertificationType.Value) : Set[CertificationType.Value] = {
|
||||
var available : List[CertificationType.Value] = List(certification)
|
||||
var allocated : mutable.ListBuffer[CertificationType.Value] = mutable.ListBuffer.empty[CertificationType.Value]
|
||||
do {
|
||||
available = available.flatMap {
|
||||
For
|
||||
}
|
||||
allocated ++= available
|
||||
}
|
||||
while(available.nonEmpty)
|
||||
allocated.toSet
|
||||
}
|
||||
|
||||
import CertificationType._
|
||||
|
||||
/**
|
||||
* Find all certifications that are related but mutually exclusive with the target certification.
|
||||
* (For `A`, find all `B` that `B ⊃ A` but `A XOR B`.)
|
||||
* @param certification the target certification
|
||||
* @return all connected certifications
|
||||
*/
|
||||
def Like(certification : CertificationType.Value) : Set[CertificationType.Value] = certification match {
|
||||
case AssaultBuggy =>
|
||||
Set(Harasser)
|
||||
case LightScout =>
|
||||
Set(AirCavalryScout, AssaultBuggy, Harasser)
|
||||
case UniMAX =>
|
||||
Set(AAMAX, AIMAX, AVMAX)
|
||||
case AdvancedEngineering =>
|
||||
Set(AssaultEngineering, FortificationEngineering)
|
||||
case ElectronicsExpert =>
|
||||
Set(DataCorruption, ExpertHacking)
|
||||
case _ =>
|
||||
Set.empty[CertificationType.Value]
|
||||
}
|
||||
|
||||
private val dependencies : Map[CertificationType.Value, List[CertificationType.Value]] = Map(
|
||||
StandardAssault -> List(),
|
||||
AgileExoSuit -> List(),
|
||||
ReinforcedExoSuit -> List(),
|
||||
InfiltrationSuit -> List(Phantasm),
|
||||
AIMAX -> List(),
|
||||
AVMAX -> List(),
|
||||
AAMAX -> List(),
|
||||
UniMAX -> List(),
|
||||
|
||||
StandardAssault -> List(),
|
||||
MediumAssault -> List(AntiVehicular, HeavyAssault, Sniping, SpecialAssault),
|
||||
AntiVehicular -> List(),
|
||||
HeavyAssault -> List(),
|
||||
Sniping -> List(),
|
||||
SpecialAssault -> List(EliteAssault),
|
||||
EliteAssault -> List(),
|
||||
|
||||
ATV -> List(Switchblade),
|
||||
Switchblade -> List(),
|
||||
Harasser -> List(),
|
||||
AssaultBuggy -> List(),
|
||||
LightScout -> List(AirCavalryAssault),
|
||||
GroundSupport -> List(),
|
||||
GroundTransport -> List(),
|
||||
ArmoredAssault1 -> List(ArmoredAssault2),
|
||||
ArmoredAssault2 -> List(BattleFrameRobotics, Flail),
|
||||
Flail -> List(),
|
||||
|
||||
AirCavalryScout -> List(AirCavalryAssault),
|
||||
AirCavalryAssault -> List(AirCavalryInterceptor),
|
||||
AirCavalryInterceptor -> List(),
|
||||
AirSupport -> List(GalaxyGunship),
|
||||
GalaxyGunship -> List(),
|
||||
Phantasm -> List(),
|
||||
|
||||
BattleFrameRobotics -> List(BFRAntiInfantry, BFRAntiAircraft),
|
||||
BFRAntiInfantry -> List(),
|
||||
BFRAntiAircraft -> List(),
|
||||
|
||||
Medical -> List(AdvancedMedical),
|
||||
AdvancedMedical -> List(),
|
||||
Engineering -> List(CombatEngineering),
|
||||
CombatEngineering -> List(AdvancedEngineering, AssaultEngineering, FortificationEngineering),
|
||||
AdvancedEngineering -> List(),
|
||||
AssaultEngineering -> List(),
|
||||
FortificationEngineering -> List(),
|
||||
Hacking -> List(AdvancedHacking),
|
||||
AdvancedHacking -> List(DataCorruption, ElectronicsExpert, ExpertHacking),
|
||||
DataCorruption -> List(),
|
||||
ElectronicsExpert -> List(),
|
||||
ExpertHacking -> List()
|
||||
)
|
||||
}
|
||||
|
||||
object Cost {
|
||||
/**
|
||||
* For a certification, get its point cost.
|
||||
* @param certification the certification
|
||||
* @return the cost
|
||||
*/
|
||||
def Of(certification : CertificationType.Value) : Int = points(certification)
|
||||
|
||||
/**
|
||||
* For a list of certifications, find the point cost of all unique certifications.
|
||||
* @see `Of(Set)`
|
||||
* @param certifications the certification list
|
||||
* @return the total cost
|
||||
*/
|
||||
def Of(certifications : List[CertificationType.Value]) : Int = Of(certifications.toSet)
|
||||
|
||||
/**
|
||||
* For a set of certifications, find the point cost of all certifications.
|
||||
* @see `OfAll(List)`
|
||||
* @param certifications the certification list
|
||||
* @return the total cost
|
||||
*/
|
||||
def Of(certifications : Set[CertificationType.Value]) : Int = OfAll(certifications.toList)
|
||||
|
||||
/**
|
||||
* For a list of certifications, find the point cost of all certifications, counting any duplicates.
|
||||
* @param certifications the certification list
|
||||
* @return the total cost
|
||||
*/
|
||||
def OfAll(certifications : List[CertificationType.Value]) : Int = {
|
||||
certifications map points sum
|
||||
}
|
||||
|
||||
import CertificationType._
|
||||
private val points : Map[CertificationType.Value, Int] = Map(
|
||||
StandardExoSuit -> 0,
|
||||
AgileExoSuit -> 0,
|
||||
ReinforcedExoSuit -> 3,
|
||||
InfiltrationSuit -> 2,
|
||||
AAMAX -> 2,
|
||||
AIMAX -> 3,
|
||||
AVMAX -> 3,
|
||||
UniMAX -> 6,
|
||||
|
||||
StandardAssault -> 0,
|
||||
MediumAssault -> 2,
|
||||
AntiVehicular -> 3,
|
||||
HeavyAssault -> 4,
|
||||
Sniping -> 3,
|
||||
SpecialAssault -> 3,
|
||||
EliteAssault -> 1,
|
||||
|
||||
ATV -> 1,
|
||||
Switchblade -> 1,
|
||||
Harasser -> 1,
|
||||
AssaultBuggy -> 3,
|
||||
LightScout -> 5,
|
||||
GroundSupport -> 2,
|
||||
GroundTransport -> 2,
|
||||
ArmoredAssault1 -> 2,
|
||||
ArmoredAssault2 -> 3,
|
||||
Flail -> 1,
|
||||
|
||||
AirCavalryScout -> 3,
|
||||
AirCavalryAssault -> 2,
|
||||
AirCavalryInterceptor -> 2,
|
||||
AirSupport -> 3,
|
||||
GalaxyGunship -> 2,
|
||||
Phantasm -> 3,
|
||||
|
||||
BattleFrameRobotics -> 4,
|
||||
BFRAntiInfantry -> 1,
|
||||
BFRAntiAircraft -> 1,
|
||||
|
||||
Medical -> 3,
|
||||
AdvancedMedical -> 2,
|
||||
Engineering -> 3,
|
||||
CombatEngineering -> 2,
|
||||
AdvancedEngineering -> 5,
|
||||
AssaultEngineering -> 3,
|
||||
FortificationEngineering -> 3,
|
||||
Hacking -> 3,
|
||||
AdvancedHacking -> 2,
|
||||
DataCorruption -> 3,
|
||||
ElectronicsExpert -> 4,
|
||||
ExpertHacking -> 2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,47 +16,47 @@ class CertTerminalDefinition extends TerminalDefinition(171) {
|
|||
* The certifications available.
|
||||
* All entries are listed on page (tab) number 0.
|
||||
*/
|
||||
private val certificationList : Map[String, (CertificationType.Value, Int)] = Map(
|
||||
"medium_assault" -> (CertificationType.MediumAssault, 2),
|
||||
"reinforced_armor" -> (CertificationType.ReinforcedExoSuit, 3),
|
||||
"quad_all" -> (CertificationType.ATV, 1),
|
||||
"switchblade" -> (CertificationType.Switchblade, 1),
|
||||
"harasser" -> (CertificationType.Harasser, 1),
|
||||
"anti_vehicular" -> (CertificationType.AntiVehicular, 3),
|
||||
"heavy_assault" -> (CertificationType.HeavyAssault, 4),
|
||||
"sniper" -> (CertificationType.Sniping, 3),
|
||||
"special_assault" -> (CertificationType.SpecialAssault, 3),
|
||||
"special_assault_2" -> (CertificationType.EliteAssault, 1),
|
||||
"infiltration_suit" -> (CertificationType.InfiltrationSuit, 2),
|
||||
"max_anti_personnel" -> (CertificationType.AIMAX, 3),
|
||||
"max_anti_vehicular" -> (CertificationType.AVMAX, 3),
|
||||
"max_anti_aircraft" -> (CertificationType.AAMAX, 2),
|
||||
"max_all" -> (CertificationType.UniMAX, 6),
|
||||
"air_cavalry_scout" -> (CertificationType.AirCavalryScout, 3),
|
||||
"air_cavalry_assault" -> (CertificationType.AirCavalryAssault, 2),
|
||||
"air_cavalry_interceptor" -> (CertificationType.AirCavalryInterceptor, 2),
|
||||
"air_support" -> (CertificationType.AirSupport, 3),
|
||||
"gunship" -> (CertificationType.GalaxyGunship, 2),
|
||||
"phantasm" -> (CertificationType.Phantasm, 3),
|
||||
"armored_assault1" -> (CertificationType.ArmoredAssault1, 2),
|
||||
"armored_assault2" -> (CertificationType.ArmoredAssault2, 1),
|
||||
"flail" -> (CertificationType.Flail, 1),
|
||||
"assault_buggy" -> (CertificationType.AssaultBuggy, 3),
|
||||
"ground_support" -> (CertificationType.GroundSupport, 2),
|
||||
"ground_transport" -> (CertificationType.GroundTransport, 2),
|
||||
"light_scout" -> (CertificationType.LightScout, 5),
|
||||
"Repair" -> (CertificationType.Engineering, 3),
|
||||
"combat_engineering" -> (CertificationType.CombatEngineering, 2),
|
||||
"ce_offense" -> (CertificationType.AssaultEngineering, 3),
|
||||
"ce_defense" -> (CertificationType.FortificationEngineering, 3),
|
||||
"ce_advanced" -> (CertificationType.AdvancedEngineering, 5),
|
||||
"Hacking" -> (CertificationType.Hacking, 3),
|
||||
"advanced_hacking" -> (CertificationType.AdvancedHacking, 2),
|
||||
"expert_hacking" -> (CertificationType.ExpertHacking, 2),
|
||||
"virus_hacking" -> (CertificationType.DataCorruption, 3),
|
||||
"electronics_expert" -> (CertificationType.ElectronicsExpert, 4),
|
||||
"Medical" -> (CertificationType.Medical, 3),
|
||||
"advanced_medical" -> (CertificationType.AdvancedMedical, 2)
|
||||
private val certificationList : Map[String, CertificationType.Value] = Map(
|
||||
"medium_assault" -> CertificationType.MediumAssault,
|
||||
"reinforced_armor" -> CertificationType.ReinforcedExoSuit,
|
||||
"quad_all" -> CertificationType.ATV,
|
||||
"switchblade" -> CertificationType.Switchblade,
|
||||
"harasser" -> CertificationType.Harasser,
|
||||
"anti_vehicular" -> CertificationType.AntiVehicular,
|
||||
"heavy_assault" -> CertificationType.HeavyAssault,
|
||||
"sniper" -> CertificationType.Sniping,
|
||||
"special_assault" -> CertificationType.SpecialAssault,
|
||||
"special_assault_2" -> CertificationType.EliteAssault,
|
||||
"infiltration_suit" -> CertificationType.InfiltrationSuit,
|
||||
"max_anti_personnel" -> CertificationType.AIMAX,
|
||||
"max_anti_vehicular" -> CertificationType.AVMAX,
|
||||
"max_anti_aircraft" -> CertificationType.AAMAX,
|
||||
"max_all" -> CertificationType.UniMAX,
|
||||
"air_cavalry_scout" -> CertificationType.AirCavalryScout,
|
||||
"air_cavalry_assault" -> CertificationType.AirCavalryAssault,
|
||||
"air_cavalry_interceptor" -> CertificationType.AirCavalryInterceptor,
|
||||
"air_support" -> CertificationType.AirSupport,
|
||||
"gunship" -> CertificationType.GalaxyGunship,
|
||||
"phantasm" -> CertificationType.Phantasm,
|
||||
"armored_assault1" -> CertificationType.ArmoredAssault1,
|
||||
"armored_assault2" -> CertificationType.ArmoredAssault2,
|
||||
"flail" -> CertificationType.Flail,
|
||||
"assault_buggy" -> CertificationType.AssaultBuggy,
|
||||
"ground_support" -> CertificationType.GroundSupport,
|
||||
"ground_transport" -> CertificationType.GroundTransport,
|
||||
"light_scout" -> CertificationType.LightScout,
|
||||
"Repair" -> CertificationType.Engineering,
|
||||
"combat_engineering" -> CertificationType.CombatEngineering,
|
||||
"ce_offense" -> CertificationType.AssaultEngineering,
|
||||
"ce_defense" -> CertificationType.FortificationEngineering,
|
||||
"ce_advanced" -> CertificationType.AdvancedEngineering,
|
||||
"Hacking" -> CertificationType.Hacking,
|
||||
"advanced_hacking" -> CertificationType.AdvancedHacking,
|
||||
"expert_hacking" -> CertificationType.ExpertHacking,
|
||||
"virus_hacking" -> CertificationType.DataCorruption,
|
||||
"electronics_expert" -> CertificationType.ElectronicsExpert,
|
||||
"Medical" -> CertificationType.Medical,
|
||||
"advanced_medical" -> CertificationType.AdvancedMedical
|
||||
//TODO bfr certification entries
|
||||
)
|
||||
|
||||
|
|
@ -68,8 +68,8 @@ class CertTerminalDefinition extends TerminalDefinition(171) {
|
|||
*/
|
||||
def Buy(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = { //Learn
|
||||
certificationList.get(msg.item_name) match {
|
||||
case Some((cert, cost)) =>
|
||||
Terminal.LearnCertification(cert, cost)
|
||||
case Some(cert) =>
|
||||
Terminal.LearnCertification(cert)
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
|
|
@ -83,8 +83,8 @@ class CertTerminalDefinition extends TerminalDefinition(171) {
|
|||
*/
|
||||
override def Sell(player : Player, msg : ItemTransactionMessage) : Terminal.Exchange = {
|
||||
certificationList.get(msg.item_name) match {
|
||||
case Some((cert, cost)) =>
|
||||
Terminal.SellCertification(cert, cost)
|
||||
case Some(cert) =>
|
||||
Terminal.SellCertification(cert)
|
||||
case None =>
|
||||
Terminal.NoDeal()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,16 +116,14 @@ object Terminal {
|
|||
/**
|
||||
* Provide the certification type unlocked by the player.
|
||||
* @param cert the certification unlocked
|
||||
* @param cost the certification point cost
|
||||
*/
|
||||
final case class LearnCertification(cert : CertificationType.Value, cost : Int) extends Exchange
|
||||
final case class LearnCertification(cert : CertificationType.Value) extends Exchange
|
||||
|
||||
/**
|
||||
* Provide the certification type freed-up by the player.
|
||||
* @param cert the certification returned
|
||||
* @param cost the certification point cost
|
||||
*/
|
||||
final case class SellCertification(cert : CertificationType.Value, cost : Int) extends Exchange
|
||||
final case class SellCertification(cert : CertificationType.Value) extends Exchange
|
||||
|
||||
import net.psforever.objects.definition.ImplantDefinition
|
||||
/**
|
||||
|
|
|
|||
140
common/src/test/scala/objects/CertificationTest.scala
Normal file
140
common/src/test/scala/objects/CertificationTest.scala
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import net.psforever.objects.avatar.Certification
|
||||
import net.psforever.types.CertificationType._
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
class CertificationTest extends Specification {
|
||||
"Dependencies" should {
|
||||
//From
|
||||
"find any certifications immediately dependent on a given certification (nothing)" in {
|
||||
Certification.Dependencies.From(StandardAssault) mustEqual Set()
|
||||
}
|
||||
|
||||
"find any certifications immediately dependent on a given certification (one)" in {
|
||||
Certification.Dependencies.From(Engineering) mustEqual Set(CombatEngineering)
|
||||
}
|
||||
|
||||
"find any certifications immediately dependent on a given certification (multiple)" in {
|
||||
Certification.Dependencies.From(MediumAssault) mustEqual Set(AntiVehicular, HeavyAssault, Sniping, SpecialAssault)
|
||||
}
|
||||
|
||||
"find any certifications immediately dependent on a given certification (intermediate)" in {
|
||||
Certification.Dependencies.From(ArmoredAssault2) mustEqual Set(BattleFrameRobotics, Flail)
|
||||
}
|
||||
//FromAll
|
||||
"find all certifications dependent on a given certification (nothing)" in {
|
||||
Certification.Dependencies.FromAll(StandardAssault) mustEqual Set()
|
||||
}
|
||||
|
||||
"find all certifications dependent on a given certification (one)" in {
|
||||
Certification.Dependencies.FromAll(ATV) mustEqual Set(Switchblade)
|
||||
}
|
||||
|
||||
"find all certifications dependent on a given certification (multiple)" in {
|
||||
Certification.Dependencies.FromAll(MediumAssault) mustEqual Set(AntiVehicular, HeavyAssault, Sniping, SpecialAssault, EliteAssault)
|
||||
}
|
||||
|
||||
"find all certifications dependent on a given certification (intermediate)" in {
|
||||
Certification.Dependencies.FromAll(ArmoredAssault2) mustEqual Set(BattleFrameRobotics, Flail, BFRAntiInfantry, BFRAntiAircraft)
|
||||
}
|
||||
//For
|
||||
"find any certifications that are immediate dependencies for a given certification (nothing)" in {
|
||||
Certification.Dependencies.For(StandardAssault) mustEqual Set()
|
||||
}
|
||||
|
||||
"find any certifications that are immediate dependencies for a given certification (one)" in {
|
||||
Certification.Dependencies.For(CombatEngineering) mustEqual Set(Engineering)
|
||||
}
|
||||
|
||||
"find any certifications that are immediate dependencies for a given certification (multiple)" in {
|
||||
Certification.Dependencies.For(AirCavalryAssault) mustEqual Set(AirCavalryScout, LightScout)
|
||||
}
|
||||
|
||||
"find any certifications that are immediate dependencies for a given certification (intermediate)" in {
|
||||
Certification.Dependencies.For(BattleFrameRobotics) mustEqual Set(ArmoredAssault2)
|
||||
}
|
||||
//ForAll
|
||||
"find all certifications that are dependencies for a given certification (nothing)" in {
|
||||
Certification.Dependencies.ForAll(StandardAssault) mustEqual Set()
|
||||
}
|
||||
|
||||
"find all certifications that are dependencies for a given certification (one)" in {
|
||||
Certification.Dependencies.ForAll(CombatEngineering) mustEqual Set(Engineering)
|
||||
}
|
||||
|
||||
"find all certifications that are dependencies for a given certification (multiple)" in {
|
||||
Certification.Dependencies.ForAll(AirCavalryAssault) mustEqual Set(AirCavalryScout, LightScout)
|
||||
}
|
||||
|
||||
"find all certifications that are dependencies for a given certification (intermediate)" in {
|
||||
Certification.Dependencies.ForAll(BattleFrameRobotics) mustEqual Set(ArmoredAssault1, ArmoredAssault2)
|
||||
}
|
||||
//Like
|
||||
"find related certifications" in {
|
||||
Certification.Dependencies.Like(AssaultBuggy) mustEqual Set(Harasser)
|
||||
Certification.Dependencies.Like(LightScout) mustEqual Set(AirCavalryScout, AssaultBuggy, Harasser)
|
||||
Certification.Dependencies.Like(UniMAX) mustEqual Set(AIMAX, AVMAX, AAMAX)
|
||||
Certification.Dependencies.Like(StandardAssault) mustEqual Set()
|
||||
}
|
||||
}
|
||||
|
||||
"Cost" should {
|
||||
"calculate the point-value of any certification (no value)" in {
|
||||
Certification.Cost.Of(StandardAssault) mustEqual 0
|
||||
}
|
||||
|
||||
"calculate the point-value of any certification (value)" in {
|
||||
Certification.Cost.Of(MediumAssault) mustEqual 2
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all certifications (no value)" in {
|
||||
Certification.Cost.Of(Set(StandardAssault)) mustEqual 0
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all certifications (value)" in {
|
||||
Certification.Cost.Of(Set(MediumAssault)) mustEqual 2
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all certifications (add)" in {
|
||||
Certification.Cost.Of(Set(StandardAssault, MediumAssault)) mustEqual 2
|
||||
Certification.Cost.Of(Set(HeavyAssault, MediumAssault)) mustEqual 6
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all certifications (large collection)" in {
|
||||
Certification.Cost.Of(Set(StandardAssault, MediumAssault, StandardExoSuit, AgileExoSuit, ReinforcedExoSuit, ATV, Harasser)) mustEqual 7
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all unique certifications (no value)" in {
|
||||
Certification.Cost.Of(List(StandardAssault, StandardAssault)) mustEqual 0
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all unique certifications (value)" in {
|
||||
Certification.Cost.Of(List(MediumAssault, MediumAssault)) mustEqual 2
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all unique certifications (add)" in {
|
||||
Certification.Cost.Of(List(StandardAssault, MediumAssault, MediumAssault)) mustEqual 2
|
||||
Certification.Cost.Of(List(HeavyAssault, MediumAssault, HeavyAssault)) mustEqual 6
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all unique certifications (large collection)" in {
|
||||
Certification.Cost.Of(
|
||||
List(
|
||||
StandardAssault, MediumAssault, StandardExoSuit, AgileExoSuit, ReinforcedExoSuit, ATV, Harasser,
|
||||
MediumAssault, StandardExoSuit, ReinforcedExoSuit, ATV
|
||||
)
|
||||
) mustEqual 7
|
||||
}
|
||||
|
||||
"calculate the sum-point-value of all certifications (count duplicates)" in {
|
||||
Certification.Cost.OfAll(
|
||||
List(
|
||||
StandardAssault, MediumAssault, StandardExoSuit, AgileExoSuit, ReinforcedExoSuit, ATV, Harasser,
|
||||
MediumAssault, StandardExoSuit, ReinforcedExoSuit, ATV
|
||||
)
|
||||
) mustEqual 13
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ class CertTerminalTest extends Specification {
|
|||
|
||||
"player can learn a certification ('medium_assault')" in {
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Learn, 0, "medium_assault", 0, PlanetSideGUID(0))
|
||||
terminal.Request(player, msg) mustEqual Terminal.LearnCertification(CertificationType.MediumAssault, 2)
|
||||
terminal.Request(player, msg) mustEqual Terminal.LearnCertification(CertificationType.MediumAssault)
|
||||
}
|
||||
|
||||
"player can not learn a fake certification ('juggling')" in {
|
||||
|
|
@ -36,7 +36,7 @@ class CertTerminalTest extends Specification {
|
|||
"player can forget a certification ('medium_assault')" in {
|
||||
val msg = ItemTransactionMessage(PlanetSideGUID(1), TransactionType.Sell, 0, "medium_assault", 0, PlanetSideGUID(0))
|
||||
|
||||
terminal.Request(player, msg) mustEqual Terminal.SellCertification(CertificationType.MediumAssault, 2)
|
||||
terminal.Request(player, msg) mustEqual Terminal.SellCertification(CertificationType.MediumAssault)
|
||||
}
|
||||
|
||||
"player can not forget a fake certification ('juggling')" in {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class CertTerminalControl1Test extends ActorTest {
|
|||
val reply2 = reply.asInstanceOf[Terminal.TerminalMessage]
|
||||
assert(reply2.player == player)
|
||||
assert(reply2.msg == msg)
|
||||
assert(reply2.response == Terminal.LearnCertification(CertificationType.MediumAssault, 2))
|
||||
assert(reply2.response == Terminal.LearnCertification(CertificationType.MediumAssault))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ class CertTerminalControl3Test extends ActorTest {
|
|||
val reply2 = reply.asInstanceOf[Terminal.TerminalMessage]
|
||||
assert(reply2.player == player)
|
||||
assert(reply2.msg == msg)
|
||||
assert(reply2.response == Terminal.SellCertification(CertificationType.MediumAssault, 2))
|
||||
assert(reply2.response == Terminal.SellCertification(CertificationType.MediumAssault))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import csr.{CSRWarp, CSRZone, Traveler}
|
|||
import net.psforever.objects.GlobalDefinitions._
|
||||
import services.ServiceManager.Lookup
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Certification
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.definition.ToolDefinition
|
||||
import net.psforever.objects.definition.converter.{CorpseConverter, DestroyedVehicleConverter}
|
||||
|
|
@ -1180,27 +1181,43 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
sendResponse(ItemTransactionResultMessage (msg.terminal_guid, TransactionType.Loadout, false))
|
||||
}
|
||||
|
||||
case Terminal.LearnCertification(cert, cost) =>
|
||||
case Terminal.LearnCertification(cert) =>
|
||||
val name = tplayer.Name
|
||||
if(!tplayer.Certifications.contains(cert)) {
|
||||
log.info(s"$tplayer is learning the $cert certification for $cost points")
|
||||
val guid = tplayer.GUID
|
||||
log.info(s"$name is learning the $cert certification for ${Certification.Cost.Of(cert)} points")
|
||||
avatar.Certifications += cert
|
||||
sendResponse(PlanetsideAttributeMessage(tplayer.GUID, 24, cert.id))
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 24, cert.id.toLong))
|
||||
|
||||
tplayer.Certifications.intersect(Certification.Dependencies.Like(cert)).foreach(entry => {
|
||||
log.info(s"$cert replaces the learned certification $entry that cost ${Certification.Cost.Of(entry)} points")
|
||||
avatar.Certifications -= entry
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 25, entry.id.toLong))
|
||||
})
|
||||
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, true))
|
||||
}
|
||||
else {
|
||||
log.warn(s"$tplayer already knows the $cert certification, so he can't learn it")
|
||||
log.warn(s"$name already knows the $cert certification, so he can't learn it")
|
||||
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false))
|
||||
}
|
||||
|
||||
case Terminal.SellCertification(cert, cost) =>
|
||||
case Terminal.SellCertification(cert) =>
|
||||
val name = tplayer.Name
|
||||
if(tplayer.Certifications.contains(cert)) {
|
||||
log.info(s"$tplayer is forgetting the $cert certification for $cost points")
|
||||
val guid = tplayer.GUID
|
||||
log.info(s"$name is forgetting the $cert certification for ${Certification.Cost.Of(cert)} points")
|
||||
avatar.Certifications -= cert
|
||||
sendResponse(PlanetsideAttributeMessage(tplayer.GUID, 25, cert.id))
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 25, cert.id.toLong))
|
||||
|
||||
tplayer.Certifications.intersect(Certification.Dependencies.FromAll(cert)).foreach(entry => {
|
||||
log.info(s"$name is also forgetting the ${Certification.Cost.Of(entry)}-point $entry certification which depends on $cert")
|
||||
avatar.Certifications -= entry
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 25, entry.id.toLong))
|
||||
})
|
||||
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Sell, true))
|
||||
}
|
||||
else {
|
||||
log.warn(s"$tplayer doesn't know what a $cert certification is, so he can't forget it")
|
||||
log.warn(s"$name doesn't know what a $cert certification is, so he can't forget it")
|
||||
sendResponse(ItemTransactionResultMessage(msg.terminal_guid, TransactionType.Learn, false))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue