mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-12 15:04:39 +00:00
MAX Capacitors (#297)
* fix isAnchored / isOverdrived faction check * Faction specific MAX definitions * GenericActionMessage documentation * MAX Capacitor functionality and changes to damage resolution for NC MAX shield
This commit is contained in:
parent
d168c40093
commit
28beea4e30
10 changed files with 351 additions and 56 deletions
|
|
@ -26,23 +26,26 @@ import scala.collection.mutable
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
object GlobalDefinitions {
|
object GlobalDefinitions {
|
||||||
/*
|
// Characters
|
||||||
characters
|
|
||||||
*/
|
|
||||||
val avatar = new AvatarDefinition(121)
|
val avatar = new AvatarDefinition(121)
|
||||||
/*
|
/*
|
||||||
exo-suits
|
exo-suits
|
||||||
*/
|
*/
|
||||||
val Standard = ExoSuitDefinition(ExoSuitType.Standard)
|
val Standard = ExoSuitDefinition(ExoSuitType.Standard)
|
||||||
|
|
||||||
val Agile = ExoSuitDefinition(ExoSuitType.Agile)
|
val Agile = ExoSuitDefinition(ExoSuitType.Agile)
|
||||||
|
|
||||||
val Reinforced = ExoSuitDefinition(ExoSuitType.Reinforced)
|
val Reinforced = ExoSuitDefinition(ExoSuitType.Reinforced)
|
||||||
|
|
||||||
val Infiltration = ExoSuitDefinition(ExoSuitType.Infiltration)
|
val Infiltration = ExoSuitDefinition(ExoSuitType.Infiltration)
|
||||||
|
|
||||||
val MAX = SpecialExoSuitDefinition(ExoSuitType.MAX)
|
val VSMAX = SpecialExoSuitDefinition(ExoSuitType.MAX)
|
||||||
|
|
||||||
|
val TRMAX = SpecialExoSuitDefinition(ExoSuitType.MAX)
|
||||||
|
|
||||||
|
val NCMAX = SpecialExoSuitDefinition(ExoSuitType.MAX)
|
||||||
init_exosuit()
|
init_exosuit()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Implants
|
Implants
|
||||||
*/
|
*/
|
||||||
|
|
@ -1527,7 +1530,7 @@ object GlobalDefinitions {
|
||||||
Standard.ResistanceSplash = 15
|
Standard.ResistanceSplash = 15
|
||||||
Standard.ResistanceAggravated = 8
|
Standard.ResistanceAggravated = 8
|
||||||
|
|
||||||
Agile.Name = "lite_armor"
|
Agile.Name = "agile"
|
||||||
Agile.MaxArmor = 100
|
Agile.MaxArmor = 100
|
||||||
Agile.InventoryScale = InventoryTile.Tile99
|
Agile.InventoryScale = InventoryTile.Tile99
|
||||||
Agile.InventoryOffset = 6
|
Agile.InventoryOffset = 6
|
||||||
|
|
@ -1539,7 +1542,7 @@ object GlobalDefinitions {
|
||||||
Agile.ResistanceSplash = 25
|
Agile.ResistanceSplash = 25
|
||||||
Agile.ResistanceAggravated = 10
|
Agile.ResistanceAggravated = 10
|
||||||
|
|
||||||
Reinforced.Name = "med_armor"
|
Reinforced.Name = "reinforced"
|
||||||
Reinforced.Permissions = List(CertificationType.ReinforcedExoSuit)
|
Reinforced.Permissions = List(CertificationType.ReinforcedExoSuit)
|
||||||
Reinforced.MaxArmor = 200
|
Reinforced.MaxArmor = 200
|
||||||
Reinforced.InventoryScale = InventoryTile.Tile1209
|
Reinforced.InventoryScale = InventoryTile.Tile1209
|
||||||
|
|
@ -1561,18 +1564,39 @@ object GlobalDefinitions {
|
||||||
Infiltration.Holster(0, EquipmentSize.Pistol)
|
Infiltration.Holster(0, EquipmentSize.Pistol)
|
||||||
Infiltration.Holster(4, EquipmentSize.Melee)
|
Infiltration.Holster(4, EquipmentSize.Melee)
|
||||||
|
|
||||||
MAX.Permissions = List(CertificationType.AIMAX,CertificationType.AVMAX, CertificationType.AAMAX, CertificationType.UniMAX)
|
def CommonMaxConfig(max : SpecialExoSuitDefinition): Unit = {
|
||||||
MAX.MaxArmor = 650
|
max.Permissions = List(CertificationType.AIMAX,CertificationType.AVMAX, CertificationType.AAMAX, CertificationType.UniMAX)
|
||||||
MAX.InventoryScale = InventoryTile.Tile1612
|
max.MaxArmor = 650
|
||||||
MAX.InventoryOffset = 6
|
max.InventoryScale = InventoryTile.Tile1612
|
||||||
MAX.Holster(0, EquipmentSize.Max)
|
max.InventoryOffset = 6
|
||||||
MAX.Holster(4, EquipmentSize.Melee)
|
max.Holster(0, EquipmentSize.Max)
|
||||||
MAX.Subtract.Damage1 = -2
|
max.Holster(4, EquipmentSize.Melee)
|
||||||
MAX.ResistanceDirectHit = 6
|
max.Subtract.Damage1 = -2
|
||||||
MAX.ResistanceSplash = 35
|
max.ResistanceDirectHit = 6
|
||||||
MAX.ResistanceAggravated = 10
|
max.ResistanceSplash = 35
|
||||||
MAX.Damage = StandardMaxDamage
|
max.ResistanceAggravated = 10
|
||||||
MAX.Model = StandardResolutions.Max
|
max.Damage = StandardMaxDamage
|
||||||
|
max.Model = StandardResolutions.Max
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonMaxConfig(VSMAX)
|
||||||
|
VSMAX.MaxCapacitor = 50
|
||||||
|
VSMAX.CapacitorRechargeDelayMillis = 5000
|
||||||
|
VSMAX.CapacitorRechargePerSecond = 3
|
||||||
|
VSMAX.CapacitorDrainPerSecond = 20
|
||||||
|
|
||||||
|
CommonMaxConfig(TRMAX)
|
||||||
|
TRMAX.MaxCapacitor = 300
|
||||||
|
TRMAX.CapacitorRechargeDelayMillis = 10000
|
||||||
|
TRMAX.CapacitorRechargePerSecond = 10
|
||||||
|
TRMAX.CapacitorDrainPerSecond = 30
|
||||||
|
|
||||||
|
CommonMaxConfig(NCMAX)
|
||||||
|
NCMAX.MaxCapacitor = 400
|
||||||
|
NCMAX.CapacitorRechargeDelayMillis = 10000
|
||||||
|
NCMAX.CapacitorRechargePerSecond = 4
|
||||||
|
NCMAX.CapacitorDrainPerSecond = 4
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Initialize `AmmoBoxDefinition` globals.
|
* Initialize `AmmoBoxDefinition` globals.
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,12 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
|
||||||
private var health : Int = 0
|
private var health : Int = 0
|
||||||
private var stamina : Int = 0
|
private var stamina : Int = 0
|
||||||
private var armor : Int = 0
|
private var armor : Int = 0
|
||||||
|
|
||||||
|
private var capacitor : Float = 0f
|
||||||
|
private var capacitorState : CapacitorStateType.Value = CapacitorStateType.Idle
|
||||||
|
private var capacitorLastUsedMillis : Long = 0
|
||||||
|
private var capacitorLastChargedMillis : Long = 0
|
||||||
|
|
||||||
private var maxHealth : Int = 100 //TODO affected by empire benefits, territory benefits, and bops
|
private var maxHealth : Int = 100 //TODO affected by empire benefits, territory benefits, and bops
|
||||||
private var maxStamina : Int = 100 //does anything affect this?
|
private var maxStamina : Int = 100 //does anything affect this?
|
||||||
|
|
||||||
|
|
@ -87,6 +93,7 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
|
||||||
Health = MaxHealth
|
Health = MaxHealth
|
||||||
Stamina = MaxStamina
|
Stamina = MaxStamina
|
||||||
Armor = MaxArmor
|
Armor = MaxArmor
|
||||||
|
Capacitor = 0
|
||||||
ResetAllImplants()
|
ResetAllImplants()
|
||||||
}
|
}
|
||||||
isAlive
|
isAlive
|
||||||
|
|
@ -151,6 +158,44 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
|
||||||
|
|
||||||
def MaxArmor : Int = exosuit.MaxArmor
|
def MaxArmor : Int = exosuit.MaxArmor
|
||||||
|
|
||||||
|
def Capacitor : Float = capacitor
|
||||||
|
|
||||||
|
def Capacitor_=(value : Float) : Float = {
|
||||||
|
val newValue = math.min(math.max(0, value), ExoSuitDef.MaxCapacitor)
|
||||||
|
|
||||||
|
if(newValue < capacitor) {
|
||||||
|
capacitorLastUsedMillis = System.currentTimeMillis()
|
||||||
|
capacitorLastChargedMillis = 0
|
||||||
|
}
|
||||||
|
else if(newValue > capacitor && newValue < ExoSuitDef.MaxCapacitor) {
|
||||||
|
capacitorLastChargedMillis = System.currentTimeMillis()
|
||||||
|
capacitorLastUsedMillis = 0
|
||||||
|
}
|
||||||
|
else if(newValue > capacitor && newValue == ExoSuitDef.MaxCapacitor) {
|
||||||
|
capacitorLastChargedMillis = 0
|
||||||
|
capacitorLastUsedMillis = 0
|
||||||
|
capacitorState = CapacitorStateType.Idle
|
||||||
|
}
|
||||||
|
|
||||||
|
capacitor = newValue
|
||||||
|
capacitor
|
||||||
|
}
|
||||||
|
|
||||||
|
def CapacitorState : CapacitorStateType.Value = capacitorState
|
||||||
|
def CapacitorState_=(value : CapacitorStateType.Value) : CapacitorStateType.Value = {
|
||||||
|
value match {
|
||||||
|
case CapacitorStateType.Charging => capacitorLastChargedMillis = System.currentTimeMillis()
|
||||||
|
case CapacitorStateType.Discharging => capacitorLastUsedMillis = System.currentTimeMillis()
|
||||||
|
case _ => ;
|
||||||
|
}
|
||||||
|
|
||||||
|
capacitorState = value
|
||||||
|
capacitorState
|
||||||
|
}
|
||||||
|
|
||||||
|
def CapacitorLastUsedMillis = capacitorLastUsedMillis
|
||||||
|
def CapacitorLastChargedMillis = capacitorLastChargedMillis
|
||||||
|
|
||||||
def VisibleSlots : Set[Int] = if(exosuit.SuitType == ExoSuitType.MAX) {
|
def VisibleSlots : Set[Int] = if(exosuit.SuitType == ExoSuitType.MAX) {
|
||||||
Set(0)
|
Set(0)
|
||||||
}
|
}
|
||||||
|
|
@ -290,9 +335,10 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
|
||||||
def LastDrawnSlot : Int = lastDrawnSlot
|
def LastDrawnSlot : Int = lastDrawnSlot
|
||||||
|
|
||||||
def ExoSuit : ExoSuitType.Value = exosuit.SuitType
|
def ExoSuit : ExoSuitType.Value = exosuit.SuitType
|
||||||
|
def ExoSuitDef : ExoSuitDefinition = exosuit
|
||||||
|
|
||||||
def ExoSuit_=(suit : ExoSuitType.Value) : Unit = {
|
def ExoSuit_=(suit : ExoSuitType.Value) : Unit = {
|
||||||
val eSuit = ExoSuitDefinition.Select(suit)
|
val eSuit = ExoSuitDefinition.Select(suit, Faction)
|
||||||
exosuit = eSuit
|
exosuit = eSuit
|
||||||
Player.SuitSetup(this, eSuit)
|
Player.SuitSetup(this, eSuit)
|
||||||
ChangeSpecialAbility()
|
ChangeSpecialAbility()
|
||||||
|
|
@ -509,9 +555,9 @@ class Player(private val core : Avatar) extends PlanetSideGameObject
|
||||||
SpecialExoSuitDefinition.Mode.Normal
|
SpecialExoSuitDefinition.Mode.Normal
|
||||||
}
|
}
|
||||||
|
|
||||||
def isAnchored : Boolean = ExoSuit == ExoSuitType.MAX && Faction == PlanetSideEmpire.NC && UsingSpecial == SpecialExoSuitDefinition.Mode.Anchored
|
def isAnchored : Boolean = ExoSuit == ExoSuitType.MAX && Faction == PlanetSideEmpire.TR && UsingSpecial == SpecialExoSuitDefinition.Mode.Anchored
|
||||||
|
|
||||||
def isOverdrived : Boolean = ExoSuit == ExoSuitType.MAX && Faction == PlanetSideEmpire.NC && UsingSpecial == SpecialExoSuitDefinition.Mode.Overdrive
|
def isOverdrived : Boolean = ExoSuit == ExoSuitType.MAX && Faction == PlanetSideEmpire.TR && UsingSpecial == SpecialExoSuitDefinition.Mode.Overdrive
|
||||||
|
|
||||||
def isShielded : Boolean = ExoSuit == ExoSuitType.MAX && Faction == PlanetSideEmpire.NC && UsingSpecial == SpecialExoSuitDefinition.Mode.Shielded
|
def isShielded : Boolean = ExoSuit == ExoSuitType.MAX && Faction == PlanetSideEmpire.NC && UsingSpecial == SpecialExoSuitDefinition.Mode.Shielded
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import net.psforever.objects.equipment.EquipmentSize
|
||||||
import net.psforever.objects.inventory.InventoryTile
|
import net.psforever.objects.inventory.InventoryTile
|
||||||
import net.psforever.objects.vital._
|
import net.psforever.objects.vital._
|
||||||
import net.psforever.objects.vital.resistance.ResistanceProfileMutators
|
import net.psforever.objects.vital.resistance.ResistanceProfileMutators
|
||||||
import net.psforever.types.{CertificationType, ExoSuitType}
|
import net.psforever.types.{CertificationType, ExoSuitType, PlanetSideEmpire}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A definition for producing the personal armor the player wears.
|
* A definition for producing the personal armor the player wears.
|
||||||
|
|
@ -21,6 +21,10 @@ class ExoSuitDefinition(private val suitType : ExoSuitType.Value) extends BasicD
|
||||||
protected val holsters : Array[EquipmentSize.Value] = Array.fill[EquipmentSize.Value](5)(EquipmentSize.Blocked)
|
protected val holsters : Array[EquipmentSize.Value] = Array.fill[EquipmentSize.Value](5)(EquipmentSize.Blocked)
|
||||||
protected var inventoryScale : InventoryTile = InventoryTile.Tile11 //override with custom InventoryTile
|
protected var inventoryScale : InventoryTile = InventoryTile.Tile11 //override with custom InventoryTile
|
||||||
protected var inventoryOffset : Int = 0
|
protected var inventoryOffset : Int = 0
|
||||||
|
protected var maxCapacitor : Int = 0
|
||||||
|
protected var capacitorRechargeDelayMillis : Int = 0
|
||||||
|
protected var capacitorRechargePerSecond : Int = 0
|
||||||
|
protected var capacitorDrainPerSecond : Int = 0
|
||||||
Name = "exo-suit"
|
Name = "exo-suit"
|
||||||
Damage = StandardInfantryDamage
|
Damage = StandardInfantryDamage
|
||||||
Resistance = StandardInfantryResistance
|
Resistance = StandardInfantryResistance
|
||||||
|
|
@ -35,6 +39,34 @@ class ExoSuitDefinition(private val suitType : ExoSuitType.Value) extends BasicD
|
||||||
MaxArmor
|
MaxArmor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def MaxCapacitor : Int = maxCapacitor
|
||||||
|
|
||||||
|
def MaxCapacitor_=(value : Int) : Int = {
|
||||||
|
maxCapacitor = value
|
||||||
|
maxCapacitor
|
||||||
|
}
|
||||||
|
|
||||||
|
def CapacitorRechargeDelayMillis : Int = capacitorRechargeDelayMillis
|
||||||
|
|
||||||
|
def CapacitorRechargeDelayMillis_=(value : Int) : Int = {
|
||||||
|
capacitorRechargeDelayMillis = value
|
||||||
|
capacitorRechargeDelayMillis
|
||||||
|
}
|
||||||
|
|
||||||
|
def CapacitorRechargePerSecond : Int = capacitorRechargePerSecond
|
||||||
|
|
||||||
|
def CapacitorRechargePerSecond_=(value : Int) : Int = {
|
||||||
|
capacitorRechargePerSecond = value
|
||||||
|
capacitorRechargePerSecond
|
||||||
|
}
|
||||||
|
|
||||||
|
def CapacitorDrainPerSecond : Int = capacitorDrainPerSecond
|
||||||
|
|
||||||
|
def CapacitorDrainPerSecond_=(value : Int) : Int = {
|
||||||
|
capacitorDrainPerSecond = value
|
||||||
|
capacitorDrainPerSecond
|
||||||
|
}
|
||||||
|
|
||||||
def InventoryScale : InventoryTile = inventoryScale
|
def InventoryScale : InventoryTile = inventoryScale
|
||||||
|
|
||||||
def InventoryScale_=(scale : InventoryTile) : InventoryTile = {
|
def InventoryScale_=(scale : InventoryTile) : InventoryTile = {
|
||||||
|
|
@ -96,6 +128,10 @@ class SpecialExoSuitDefinition(private val suitType : ExoSuitType.Value) extends
|
||||||
val obj = new SpecialExoSuitDefinition(SuitType)
|
val obj = new SpecialExoSuitDefinition(SuitType)
|
||||||
obj.Permissions = Permissions
|
obj.Permissions = Permissions
|
||||||
obj.MaxArmor = MaxArmor
|
obj.MaxArmor = MaxArmor
|
||||||
|
obj.MaxCapacitor = MaxCapacitor
|
||||||
|
obj.CapacitorRechargePerSecond = CapacitorRechargePerSecond
|
||||||
|
obj.CapacitorDrainPerSecond = CapacitorDrainPerSecond
|
||||||
|
obj.CapacitorRechargeDelayMillis = CapacitorRechargeDelayMillis
|
||||||
obj.InventoryScale = InventoryScale
|
obj.InventoryScale = InventoryScale
|
||||||
obj.InventoryOffset = InventoryOffset
|
obj.InventoryOffset = InventoryOffset
|
||||||
obj.Subtract.Damage0 = Subtract.Damage0
|
obj.Subtract.Damage0 = Subtract.Damage0
|
||||||
|
|
@ -138,14 +174,19 @@ object ExoSuitDefinition {
|
||||||
/**
|
/**
|
||||||
* A function to retrieve the correct defintion of an exo-suit from the type of exo-suit.
|
* A function to retrieve the correct defintion of an exo-suit from the type of exo-suit.
|
||||||
* @param suit the `Enumeration` corresponding to this exo-suit
|
* @param suit the `Enumeration` corresponding to this exo-suit
|
||||||
|
* @param faction the faction the player belongs to for this exosuit
|
||||||
* @return the exo-suit definition
|
* @return the exo-suit definition
|
||||||
*/
|
*/
|
||||||
def Select(suit : ExoSuitType.Value) : ExoSuitDefinition = {
|
def Select(suit : ExoSuitType.Value, faction : PlanetSideEmpire.Value) : ExoSuitDefinition = {
|
||||||
suit match {
|
suit match {
|
||||||
case ExoSuitType.Agile => GlobalDefinitions.Agile.Use
|
|
||||||
case ExoSuitType.Infiltration => GlobalDefinitions.Infiltration.Use
|
case ExoSuitType.Infiltration => GlobalDefinitions.Infiltration.Use
|
||||||
case ExoSuitType.MAX => GlobalDefinitions.MAX.Use
|
case ExoSuitType.Agile => GlobalDefinitions.Agile.Use
|
||||||
case ExoSuitType.Reinforced => GlobalDefinitions.Reinforced.Use
|
case ExoSuitType.Reinforced => GlobalDefinitions.Reinforced.Use
|
||||||
|
case ExoSuitType.MAX => faction match {
|
||||||
|
case PlanetSideEmpire.TR => GlobalDefinitions.TRMAX.Use
|
||||||
|
case PlanetSideEmpire.NC => GlobalDefinitions.NCMAX.Use
|
||||||
|
case PlanetSideEmpire.VS => GlobalDefinitions.VSMAX.Use
|
||||||
|
}
|
||||||
case _ => GlobalDefinitions.Standard.Use
|
case _ => GlobalDefinitions.Standard.Use
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,13 +106,13 @@ object ResistanceCalculations {
|
||||||
//extractors
|
//extractors
|
||||||
def NoResistExtractor(target : SourceEntry) : Int = 0
|
def NoResistExtractor(target : SourceEntry) : Int = 0
|
||||||
|
|
||||||
def ExoSuitDirectExtractor(target : PlayerSource) : Int = ExoSuitDefinition.Select(target.ExoSuit).ResistanceDirectHit
|
def ExoSuitDirectExtractor(target : PlayerSource) : Int = ExoSuitDefinition.Select(target.ExoSuit, target.Faction).ResistanceDirectHit
|
||||||
|
|
||||||
def ExoSuitSplashExtractor(target : PlayerSource) : Int = ExoSuitDefinition.Select(target.ExoSuit).ResistanceSplash
|
def ExoSuitSplashExtractor(target : PlayerSource) : Int = ExoSuitDefinition.Select(target.ExoSuit, target.Faction).ResistanceSplash
|
||||||
|
|
||||||
def ExoSuitAggravatedExtractor(target : PlayerSource) : Int = ExoSuitDefinition.Select(target.ExoSuit).ResistanceAggravated
|
def ExoSuitAggravatedExtractor(target : PlayerSource) : Int = ExoSuitDefinition.Select(target.ExoSuit, target.Faction).ResistanceAggravated
|
||||||
|
|
||||||
def ExoSuitRadiationExtractor(target : PlayerSource) : Float = ExoSuitDefinition.Select(target.ExoSuit).RadiationShielding
|
def ExoSuitRadiationExtractor(target : PlayerSource) : Float = ExoSuitDefinition.Select(target.ExoSuit, target.Faction).RadiationShielding
|
||||||
|
|
||||||
def VehicleDirectExtractor(target : VehicleSource) : Int = target.Definition.ResistanceDirectHit
|
def VehicleDirectExtractor(target : VehicleSource) : Int = target.Definition.ResistanceDirectHit
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,27 +109,53 @@ object ResolutionCalculations {
|
||||||
|
|
||||||
def NoApplication(damageValue : Int, data : ResolvedProjectile)(target : Any) : Unit = { }
|
def NoApplication(damageValue : Int, data : ResolvedProjectile)(target : Any) : Unit = { }
|
||||||
|
|
||||||
|
def SubtractWithRemainder(current : Int, damage : Int) : (Int, Int) = {
|
||||||
|
val a = Math.max(0, current - damage)
|
||||||
|
val remainingDamage = Math.abs(current - damage - a)
|
||||||
|
|
||||||
|
(a, remainingDamage)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expanded `(Any)=>Unit` function for infantry.
|
* The expanded `(Any)=>Unit` function for infantry.
|
||||||
* Apply the damage values to the health field and personal armor field for an infantry target.
|
* Apply the damage values to the capacitor (if shielded NC max), health field and personal armor field for an infantry target.
|
||||||
* @param damageValues a tuple containing damage values for: health, personal armor
|
* @param damageValues a tuple containing damage values for: health, personal armor
|
||||||
* @param data the historical `ResolvedProjectile` information
|
* @param data the historical `ResolvedProjectile` information
|
||||||
* @param target the `Player` object to be affected by these damage values (at some point)
|
* @param target the `Player` object to be affected by these damage values (at some point)
|
||||||
*/
|
*/
|
||||||
def InfantryApplication(damageValues : (Int, Int), data : ResolvedProjectile)(target : Any) : Unit = target match {
|
def InfantryApplication(damageValues : (Int, Int), data : ResolvedProjectile)(target : Any) : Unit = target match {
|
||||||
case player : Player =>
|
case player : Player =>
|
||||||
val (a, b) = damageValues
|
var (a, b) = damageValues
|
||||||
|
var result = (0, 0)
|
||||||
//TODO Personal Shield implant test should go here and modify the values a and b
|
//TODO Personal Shield implant test should go here and modify the values a and b
|
||||||
if(player.isAlive && !(a == 0 && b == 0)) {
|
if(player.isAlive && !(a == 0 && b == 0)) {
|
||||||
player.History(data)
|
player.History(data)
|
||||||
if(player.Armor - b < 0) {
|
if(player.Capacitor.toInt > 0 && player.isShielded) {
|
||||||
player.Health = player.Health - a - (b - player.Armor)
|
// Subtract armour damage from capacitor
|
||||||
player.Armor = 0
|
result = SubtractWithRemainder(player.Capacitor.toInt, b)
|
||||||
}
|
player.Capacitor = result._1
|
||||||
else {
|
b = result._2
|
||||||
player.Armor = player.Armor - b
|
|
||||||
player.Health = player.Health - a
|
// Then follow up with health damage if any capacitor is left
|
||||||
|
result = SubtractWithRemainder(player.Capacitor.toInt, a)
|
||||||
|
player.Capacitor = result._1
|
||||||
|
a = result._2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subtract any remaining armour damage from armour
|
||||||
|
result = SubtractWithRemainder(player.Armor, b)
|
||||||
|
player.Armor = result._1
|
||||||
|
b = result._2
|
||||||
|
|
||||||
|
// Then bleed through to health if armour ran out
|
||||||
|
result = SubtractWithRemainder(player.Health, b)
|
||||||
|
player.Health = result._1
|
||||||
|
b = result._2
|
||||||
|
|
||||||
|
// Finally, apply health damage to health
|
||||||
|
result = SubtractWithRemainder(player.Health, a)
|
||||||
|
player.Health = result._1
|
||||||
|
a = result._2
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,15 @@ import scodec.codecs._
|
||||||
* 45 - ?<br>
|
* 45 - ?<br>
|
||||||
* <br>
|
* <br>
|
||||||
* Actions (when sent from client):<br>
|
* Actions (when sent from client):<br>
|
||||||
|
* 15 - Max anchor
|
||||||
|
* 16 - Max unanchor
|
||||||
|
* 20 - Client requests MAX special effect (NC shield and TR overdrive. VS jump jets are handled by the jump_thrust boolean on PlayerStateMessageUpstream)
|
||||||
|
* 21 - Disable MAX special effect (NC shield)
|
||||||
* 29 - AFK<br>
|
* 29 - AFK<br>
|
||||||
* 30 - back in game<br>
|
* 30 - back in game<br>
|
||||||
* 36 - turn on "Looking for Squad"<br>
|
* 36 - turn on "Looking for Squad"<br>
|
||||||
* 37 - turn off "Looking for Squad"
|
* 37 - turn off "Looking for Squad"
|
||||||
|
*
|
||||||
* @param action what this packet does
|
* @param action what this packet does
|
||||||
*/
|
*/
|
||||||
final case class GenericActionMessage(action : Int)
|
final case class GenericActionMessage(action : Int)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package net.psforever.types
|
||||||
|
|
||||||
|
object CapacitorStateType extends Enumeration {
|
||||||
|
type Type = Value
|
||||||
|
|
||||||
|
val Idle = Value(0)
|
||||||
|
val Charging = Value(1)
|
||||||
|
val ChargeDelay = Value(2)
|
||||||
|
val Discharging = Value(3)
|
||||||
|
}
|
||||||
|
|
@ -223,7 +223,7 @@ class ResolutionCalculationsTests extends Specification {
|
||||||
InfantryDamageAfterResist(100,100)(50, 10) mustEqual (40,10)
|
InfantryDamageAfterResist(100,100)(50, 10) mustEqual (40,10)
|
||||||
}
|
}
|
||||||
|
|
||||||
"calculate health and armor damage, with bonus damage, for infantry target" in {
|
"calculate health and armor damage, with bleed through damage, for infantry target" in {
|
||||||
//health = 100, armor = 5 -> resist 10 but only have 5, so rollover extra -> damages (40+5, 5)
|
//health = 100, armor = 5 -> resist 10 but only have 5, so rollover extra -> damages (40+5, 5)
|
||||||
InfantryDamageAfterResist(100,5)(50, 10) mustEqual (45,5)
|
InfantryDamageAfterResist(100,5)(50, 10) mustEqual (45,5)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package objects
|
package objects
|
||||||
|
|
||||||
|
import net.psforever.objects.GlobalDefinitions
|
||||||
import net.psforever.objects.definition.{ExoSuitDefinition, SpecialExoSuitDefinition}
|
import net.psforever.objects.definition.{ExoSuitDefinition, SpecialExoSuitDefinition}
|
||||||
import net.psforever.objects.equipment._
|
import net.psforever.objects.equipment._
|
||||||
import net.psforever.objects.inventory.InventoryTile
|
import net.psforever.objects.inventory.InventoryTile
|
||||||
import net.psforever.types.ExoSuitType
|
import net.psforever.types.{ExoSuitType, PlanetSideEmpire}
|
||||||
import org.specs2.mutable._
|
import org.specs2.mutable._
|
||||||
|
|
||||||
class ExoSuitTest extends Specification {
|
class ExoSuitTest extends Specification {
|
||||||
|
|
@ -127,15 +128,47 @@ class ExoSuitTest extends Specification {
|
||||||
|
|
||||||
"ExoSuitDefinition.Select" should {
|
"ExoSuitDefinition.Select" should {
|
||||||
"produce common, shared instances of exo suits" in {
|
"produce common, shared instances of exo suits" in {
|
||||||
ExoSuitDefinition.Select(ExoSuitType.Standard) eq ExoSuitDefinition.Select(ExoSuitType.Standard)
|
ExoSuitDefinition.Select(ExoSuitType.Standard, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Standard, PlanetSideEmpire.VS)
|
||||||
ExoSuitDefinition.Select(ExoSuitType.Agile) eq ExoSuitDefinition.Select(ExoSuitType.Agile)
|
ExoSuitDefinition.Select(ExoSuitType.Agile, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Agile, PlanetSideEmpire.VS)
|
||||||
ExoSuitDefinition.Select(ExoSuitType.Reinforced) eq ExoSuitDefinition.Select(ExoSuitType.Reinforced)
|
ExoSuitDefinition.Select(ExoSuitType.Reinforced, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Reinforced, PlanetSideEmpire.VS)
|
||||||
ExoSuitDefinition.Select(ExoSuitType.Infiltration) eq ExoSuitDefinition.Select(ExoSuitType.Infiltration)
|
ExoSuitDefinition.Select(ExoSuitType.Infiltration, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Infiltration, PlanetSideEmpire.VS)
|
||||||
|
}
|
||||||
|
|
||||||
|
"produce common, shared instances of exo suits across factions" in {
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Standard, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Standard, PlanetSideEmpire.TR)
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Standard, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Standard, PlanetSideEmpire.NC)
|
||||||
|
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Agile, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Agile, PlanetSideEmpire.TR)
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Agile, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Agile, PlanetSideEmpire.NC)
|
||||||
|
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Reinforced, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Reinforced, PlanetSideEmpire.TR)
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Reinforced, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Reinforced, PlanetSideEmpire.NC)
|
||||||
|
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Infiltration, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Infiltration, PlanetSideEmpire.TR)
|
||||||
|
ExoSuitDefinition.Select(ExoSuitType.Infiltration, PlanetSideEmpire.VS) eq ExoSuitDefinition.Select(ExoSuitType.Infiltration, PlanetSideEmpire.NC)
|
||||||
|
}
|
||||||
|
|
||||||
|
"can select max for TR" in {
|
||||||
|
val obj = ExoSuitDefinition.Select(ExoSuitType.MAX, PlanetSideEmpire.TR)
|
||||||
|
obj.isInstanceOf[SpecialExoSuitDefinition] mustEqual true
|
||||||
|
obj.MaxCapacitor mustEqual 300
|
||||||
|
}
|
||||||
|
|
||||||
|
"can select max for VS" in {
|
||||||
|
val obj = ExoSuitDefinition.Select(ExoSuitType.MAX, PlanetSideEmpire.VS)
|
||||||
|
obj.isInstanceOf[SpecialExoSuitDefinition] mustEqual true
|
||||||
|
obj.MaxCapacitor mustEqual 50
|
||||||
|
}
|
||||||
|
|
||||||
|
"can select max for NC" in {
|
||||||
|
val obj = ExoSuitDefinition.Select(ExoSuitType.MAX, PlanetSideEmpire.NC)
|
||||||
|
obj.isInstanceOf[SpecialExoSuitDefinition] mustEqual true
|
||||||
|
obj.MaxCapacitor mustEqual 400
|
||||||
}
|
}
|
||||||
|
|
||||||
"produces unique instances of the mechanized assault exo suit" in {
|
"produces unique instances of the mechanized assault exo suit" in {
|
||||||
val obj = ExoSuitDefinition.Select(ExoSuitType.MAX)
|
val obj = ExoSuitDefinition.Select(ExoSuitType.MAX, PlanetSideEmpire.VS)
|
||||||
obj ne ExoSuitDefinition.Select(ExoSuitType.MAX)
|
obj ne ExoSuitDefinition.Select(ExoSuitType.MAX, PlanetSideEmpire.VS)
|
||||||
obj.isInstanceOf[SpecialExoSuitDefinition] mustEqual true
|
obj.isInstanceOf[SpecialExoSuitDefinition] mustEqual true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1269,14 +1269,30 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
if(player.isAlive) {
|
if(player.isAlive) {
|
||||||
val originalHealth = player.Health
|
val originalHealth = player.Health
|
||||||
val originalArmor = player.Armor
|
val originalArmor = player.Armor
|
||||||
|
val originalCapacitor = player.Capacitor.toInt
|
||||||
resolution_function(target)
|
resolution_function(target)
|
||||||
val health = player.Health
|
val health = player.Health
|
||||||
val armor = player.Armor
|
val armor = player.Armor
|
||||||
|
val capacitor = player.Capacitor.toInt
|
||||||
val damageToHealth = originalHealth - health
|
val damageToHealth = originalHealth - health
|
||||||
val damageToArmor = originalArmor - armor
|
val damageToArmor = originalArmor - armor
|
||||||
damageLog.info(s"${player.Name}-infantry: BEFORE=$originalHealth/$originalArmor, AFTER=$health/$armor, CHANGE=$damageToHealth/$damageToArmor")
|
val damageToCapacitor = originalCapacitor - capacitor
|
||||||
if(damageToHealth != 0 || damageToArmor != 0) {
|
damageLog.info(s"${player.Name}-infantry: BEFORE=$originalHealth/$originalArmor/$originalCapacitor, AFTER=$health/$armor/$capacitor, CHANGE=$damageToHealth/$damageToArmor/$damageToCapacitor")
|
||||||
|
if(damageToHealth != 0 || damageToArmor != 0 || damageToCapacitor != 0) {
|
||||||
val playerGUID = player.GUID
|
val playerGUID = player.GUID
|
||||||
|
if(damageToHealth > 0) {
|
||||||
|
sendResponse(PlanetsideAttributeMessage(playerGUID, 0, health))
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(playerGUID, 0, health))
|
||||||
|
}
|
||||||
|
|
||||||
|
if(damageToArmor > 0) {
|
||||||
|
sendResponse(PlanetsideAttributeMessage(playerGUID, 4, armor))
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(playerGUID, 4, armor))
|
||||||
|
}
|
||||||
|
|
||||||
|
if(damageToCapacitor > 0) {
|
||||||
|
sendResponse(PlanetsideAttributeMessage(playerGUID, 7, capacitor))
|
||||||
|
}
|
||||||
sendResponse(PlanetsideAttributeMessage(playerGUID, 0, health))
|
sendResponse(PlanetsideAttributeMessage(playerGUID, 0, health))
|
||||||
sendResponse(PlanetsideAttributeMessage(playerGUID, 4, armor))
|
sendResponse(PlanetsideAttributeMessage(playerGUID, 4, armor))
|
||||||
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(playerGUID, 0, health))
|
continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(playerGUID, 0, health))
|
||||||
|
|
@ -2067,7 +2083,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
val fallbackSubtype = 0
|
val fallbackSubtype = 0
|
||||||
//a loadout with a prohibited exo-suit type will result in a fallback exo-suit type
|
//a loadout with a prohibited exo-suit type will result in a fallback exo-suit type
|
||||||
val (nextSuit : ExoSuitType.Value, nextSubtype : Int) =
|
val (nextSuit : ExoSuitType.Value, nextSubtype : Int) =
|
||||||
if(ExoSuitDefinition.Select(exosuit).Permissions match {
|
if(ExoSuitDefinition.Select(exosuit, player.Faction).Permissions match {
|
||||||
case Nil =>
|
case Nil =>
|
||||||
true
|
true
|
||||||
case permissions if subtype != 0 =>
|
case permissions if subtype != 0 =>
|
||||||
|
|
@ -2122,7 +2138,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val newSuitDef = ExoSuitDefinition.Select(nextSuit)
|
val newSuitDef = ExoSuitDefinition.Select(nextSuit, player.Faction)
|
||||||
val (afterInventory, extra) = GridInventory.recoverInventory(
|
val (afterInventory, extra) = GridInventory.recoverInventory(
|
||||||
inventory.filterNot(dropPred),
|
inventory.filterNot(dropPred),
|
||||||
tplayer.Inventory
|
tplayer.Inventory
|
||||||
|
|
@ -3911,6 +3927,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
else {
|
else {
|
||||||
player.Stamina > 0
|
player.Stamina > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CapacitorTick(jump_thrust)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
timeDL = 0
|
timeDL = 0
|
||||||
|
|
@ -5347,7 +5365,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
tool.ToFireMode = convertFireModeIndex
|
tool.ToFireMode = convertFireModeIndex
|
||||||
sendResponse(ChangeFireModeMessage(tool.GUID, convertFireModeIndex))
|
sendResponse(ChangeFireModeMessage(tool.GUID, convertFireModeIndex))
|
||||||
case _ =>
|
case _ =>
|
||||||
log.info(s"GenericObject: $player is MAX with an unexpected weapon - ${definition.Name}")
|
log.warn(s"GenericObject: $player is MAX with an unexpected weapon - ${definition.Name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(action == 16) { //max deployment
|
else if(action == 16) { //max deployment
|
||||||
|
|
@ -5365,7 +5383,25 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
tool.ToFireMode = convertFireModeIndex
|
tool.ToFireMode = convertFireModeIndex
|
||||||
sendResponse(ChangeFireModeMessage(tool.GUID, convertFireModeIndex))
|
sendResponse(ChangeFireModeMessage(tool.GUID, convertFireModeIndex))
|
||||||
case _ =>
|
case _ =>
|
||||||
log.info(s"GenericObject: $player is MAX with an unexpected weapon - ${definition.Name}")
|
log.warn(s"GenericObject: $player is MAX with an unexpected weapon - ${definition.Name}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action == 20) {
|
||||||
|
if(player.ExoSuit == ExoSuitType.MAX) {
|
||||||
|
ToggleMaxSpecialState(enable = true)
|
||||||
|
} else {
|
||||||
|
log.warn("Got GenericActionMessage 20 but can't handle it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action == 21) {
|
||||||
|
if(player.ExoSuit == ExoSuitType.MAX) {
|
||||||
|
player.Faction match {
|
||||||
|
case PlanetSideEmpire.NC =>
|
||||||
|
ToggleMaxSpecialState(enable = false)
|
||||||
|
case _ => log.warn(s"Player ${player.Name} tried to cancel an uncancellable MAX special ability")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Got GenericActionMessage 21 but can't handle it")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(action == 36) { //Looking For Squad ON
|
else if(action == 36) { //Looking For Squad ON
|
||||||
|
|
@ -5462,6 +5498,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
case msg @ WeaponFireMessage(seq_time, weapon_guid, projectile_guid, shot_origin, unk1, unk2, unk3, unk4, unk5, unk6, unk7) =>
|
case msg @ WeaponFireMessage(seq_time, weapon_guid, projectile_guid, shot_origin, unk1, unk2, unk3, unk4, unk5, unk6, unk7) =>
|
||||||
log.info(s"WeaponFire: $msg")
|
log.info(s"WeaponFire: $msg")
|
||||||
|
if(player.isShielded) {
|
||||||
|
// Cancel NC MAX shield if it's active
|
||||||
|
ToggleMaxSpecialState(enable = false)
|
||||||
|
}
|
||||||
FindContainedWeapon match {
|
FindContainedWeapon match {
|
||||||
case (Some(obj), Some(tool : Tool)) =>
|
case (Some(obj), Some(tool : Tool)) =>
|
||||||
if(tool.Magazine <= 0) { //safety: enforce ammunition depletion
|
if(tool.Magazine <= 0) { //safety: enforce ammunition depletion
|
||||||
|
|
@ -7807,6 +7847,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
val player_guid = tplayer.GUID
|
val player_guid = tplayer.GUID
|
||||||
val pos = tplayer.Position
|
val pos = tplayer.Position
|
||||||
val respawnTimer = 300000 //milliseconds
|
val respawnTimer = 300000 //milliseconds
|
||||||
|
ToggleMaxSpecialState(enable = false)
|
||||||
tplayer.Die
|
tplayer.Die
|
||||||
deadState = DeadState.Dead
|
deadState = DeadState.Dead
|
||||||
timeDL = 0
|
timeDL = 0
|
||||||
|
|
@ -10102,6 +10143,75 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
squadUpdateCounter = (squadUpdateCounter + 1) % queuedSquadActions.length
|
squadUpdateCounter = (squadUpdateCounter + 1) % queuedSquadActions.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def CapacitorTick(jump_thrust : Boolean): Unit = {
|
||||||
|
if(player.ExoSuit == ExoSuitType.MAX) {
|
||||||
|
//Discharge
|
||||||
|
if(jump_thrust || player.isOverdrived || player.isShielded) {
|
||||||
|
if(player.CapacitorState == CapacitorStateType.Discharging) {
|
||||||
|
// Previous tick was already discharging, calculate how much energy to drain from time between the two ticks
|
||||||
|
val timeDiff = (System.currentTimeMillis() - player.CapacitorLastUsedMillis).toFloat / 1000
|
||||||
|
val drainAmount = player.ExoSuitDef.CapacitorDrainPerSecond.toFloat * timeDiff
|
||||||
|
player.Capacitor -= drainAmount
|
||||||
|
sendResponse(PlanetsideAttributeMessage(player.GUID, 7, player.Capacitor.toInt))
|
||||||
|
} else {
|
||||||
|
// Start discharging
|
||||||
|
player.CapacitorState = CapacitorStateType.Discharging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Charge
|
||||||
|
else if(player.Capacitor < player.ExoSuitDef.MaxCapacitor
|
||||||
|
&& (player.CapacitorState == CapacitorStateType.Idle || player.CapacitorState == CapacitorStateType.Charging || (player.CapacitorState == CapacitorStateType.ChargeDelay && System.currentTimeMillis() - player.CapacitorLastUsedMillis > player.ExoSuitDef.CapacitorRechargeDelayMillis)))
|
||||||
|
{
|
||||||
|
if(player.CapacitorState == CapacitorStateType.Charging) {
|
||||||
|
val timeDiff = (System.currentTimeMillis() - player.CapacitorLastChargedMillis).toFloat / 1000
|
||||||
|
val chargeAmount = player.ExoSuitDef.CapacitorRechargePerSecond * timeDiff
|
||||||
|
player.Capacitor += chargeAmount
|
||||||
|
sendResponse(PlanetsideAttributeMessage(player.GUID, 7, player.Capacitor.toInt))
|
||||||
|
} else {
|
||||||
|
player.CapacitorState = CapacitorStateType.Charging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(player.Faction == PlanetSideEmpire.VS) {
|
||||||
|
// Start charge delay for VS when not boosting
|
||||||
|
if(!jump_thrust && player.CapacitorState == CapacitorStateType.Discharging ) {
|
||||||
|
player.CapacitorState = CapacitorStateType.ChargeDelay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Start charge delay for other factions if capacitor is empty or special ability is off
|
||||||
|
if(player.CapacitorState == CapacitorStateType.Discharging && (player.Capacitor == 0 || (!player.isOverdrived && !player.isShielded))) {
|
||||||
|
player.CapacitorState = CapacitorStateType.ChargeDelay
|
||||||
|
ToggleMaxSpecialState(enable = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(player.CapacitorState != CapacitorStateType.Idle) {
|
||||||
|
player.CapacitorState = CapacitorStateType.Idle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def ToggleMaxSpecialState(enable : Boolean): Unit = {
|
||||||
|
if(player.ExoSuit == ExoSuitType.MAX) {
|
||||||
|
if(enable) {
|
||||||
|
player.Faction match {
|
||||||
|
case PlanetSideEmpire.TR => if(player.Capacitor == player.ExoSuitDef.MaxCapacitor) player.UsingSpecial = SpecialExoSuitDefinition.Mode.Overdrive
|
||||||
|
case PlanetSideEmpire.NC => if(player.Capacitor > 0) player.UsingSpecial = SpecialExoSuitDefinition.Mode.Shielded
|
||||||
|
case _ => log.warn(s"Player ${player.Name} tried to use a MAX special ability but their faction doesn't have one")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(player.UsingSpecial == SpecialExoSuitDefinition.Mode.Overdrive || player.UsingSpecial == SpecialExoSuitDefinition.Mode.Shielded) {
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttributeToAll(player.GUID, 8, 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttributeToAll(player.GUID, 8, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main purpose of this method is to determine which targets will receive "locked on" warnings from remote projectiles.
|
* The main purpose of this method is to determine which targets will receive "locked on" warnings from remote projectiles.
|
||||||
* For a given series of globally unique identifiers, indicating targets,
|
* For a given series of globally unique identifiers, indicating targets,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue