mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
make a better guess on the wonership of a facility during a capture/resecure; during a neutral capture, an 'owning side' will be decalred based on effort; changed the calculation of kill experience to simplify the modifiers and reduce the potential to have 0 bep
This commit is contained in:
parent
7f61206ddd
commit
cc2089b513
|
|
@ -14,7 +14,7 @@ class CaptureFlagConverter extends ObjectCreateConverter[CaptureFlag]() {
|
|||
override def ConstructorData(obj : CaptureFlag) : Try[CaptureFlagData] = {
|
||||
val hackInfo = obj.Owner.asInstanceOf[Building].CaptureTerminal.get.HackedBy match {
|
||||
case Some(hackInfo) => hackInfo
|
||||
case _ => Hackable.HackInfo(PlayerSource("", PlanetSideEmpire.NEUTRAL, Vector3.Zero), PlanetSideGUID(0), 0L, 0L)
|
||||
case _ => Hackable.HackInfo(PlayerSource("", PlanetSideEmpire.NEUTRAL, Vector3.Zero), PlanetSideGUID(0), 0L, 0L, obj.Faction)
|
||||
}
|
||||
|
||||
val millisecondsRemaining = math.max(0, hackInfo.hackStartTime + hackInfo.hackDuration - System.currentTimeMillis())
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ trait Hackable {
|
|||
def HackedBy_=(agent: Option[Player]): Option[HackInfo] = {
|
||||
(hackedBy, agent) match {
|
||||
case (None, Some(actor)) =>
|
||||
hackedBy = Some(HackInfo(PlayerSource(actor), actor.GUID, System.currentTimeMillis(), 0L))
|
||||
hackedBy = Some(HackInfo(PlayerSource(actor), actor.GUID, System.currentTimeMillis(), 0L, Faction))
|
||||
case (Some(info), Some(actor)) =>
|
||||
if (actor.Faction == this.Faction) {
|
||||
//hack cleared
|
||||
hackedBy = None
|
||||
} else if (actor.Faction != info.hackerFaction) {
|
||||
//override the hack state with a new hack state if the new user has different faction affiliation
|
||||
hackedBy = Some(HackInfo(PlayerSource(actor), actor.GUID, System.currentTimeMillis(), 0L))
|
||||
hackedBy = Some(HackInfo(PlayerSource(actor), actor.GUID, System.currentTimeMillis(), 0L, Faction))
|
||||
}
|
||||
case (_, None) =>
|
||||
hackedBy = None
|
||||
|
|
@ -73,14 +73,15 @@ trait Hackable {
|
|||
object Hackable {
|
||||
final case class HackInfo(
|
||||
player: PlayerSource,
|
||||
hackerGUID: PlanetSideGUID,
|
||||
hackStartTime: Long,
|
||||
hackDuration: Long
|
||||
hackerGUID: PlanetSideGUID,
|
||||
hackStartTime: Long,
|
||||
hackDuration: Long,
|
||||
originalFaction: PlanetSideEmpire.Value
|
||||
) {
|
||||
def hackerName: String = player.Name
|
||||
def hackerFaction: PlanetSideEmpire.Value = player.Faction
|
||||
def hackerPos: Vector3 = player.Position
|
||||
|
||||
def Duration(time: Long): HackInfo = HackInfo(player, hackerGUID, hackStartTime, time)
|
||||
def Duration(time: Long): HackInfo = HackInfo(player, hackerGUID, hackStartTime, time, originalFaction)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ class Building(
|
|||
val (hacking, hackingFaction, hackTime): (Boolean, PlanetSideEmpire.Value, Long) = CaptureTerminal match {
|
||||
case Some(obj: CaptureTerminal with Hackable) =>
|
||||
obj.HackedBy match {
|
||||
case Some(Hackable.HackInfo(p, _, start, length)) =>
|
||||
case Some(Hackable.HackInfo(p, _, start, length, _)) =>
|
||||
val hack_time_remaining_ms = math.max(0, start + length - System.currentTimeMillis())
|
||||
(true, p.Faction, hack_time_remaining_ms)
|
||||
case _ =>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ trait FacilityHackParticipation extends ParticipationLogic {
|
|||
protected var playerContribution: mutable.LongMap[(Player, Int, Long)] = mutable.LongMap[(Player, Int, Long)]()
|
||||
protected var playerPopulationOverTime: Seq[Map[PlanetSideEmpire.Value, Int]] = Seq[Map[PlanetSideEmpire.Value, Int]]()
|
||||
|
||||
def PlayerContributionRaw: Map[Long, (Player, Int, Long)] = playerContribution.toMap
|
||||
|
||||
def PlayerContribution(timeDelay: Long): Map[Long, Float] = {
|
||||
playerContribution
|
||||
.collect {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2023 PSForever
|
||||
package net.psforever.objects.serverobject.structures.participation
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.sourcing.PlayerSource
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
|
@ -16,5 +17,7 @@ case object NoParticipation extends ParticipationLogic {
|
|||
completionTime: Long,
|
||||
isResecured: Boolean
|
||||
): Unit = { /* nothing here */ }
|
||||
override def PlayerContributionRaw: Map[Long, (Player, Int, Long)] = Map.empty[Long, (Player, Int, Long)]
|
||||
|
||||
override def PlayerContribution(timeDelay: Long): Map[Long, Float] = Map.empty[Long, Float]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2023 PSForever
|
||||
package net.psforever.objects.serverobject.structures.participation
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.sourcing.PlayerSource
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
|
@ -31,5 +32,7 @@ trait ParticipationLogic {
|
|||
isResecured: Boolean
|
||||
): Unit
|
||||
|
||||
def PlayerContributionRaw: Map[Long, (Player, Int, Long)]
|
||||
|
||||
def PlayerContribution(timeDelay: Long = 600): Map[Long, Float]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class CaptureTerminal(private val idef: CaptureTerminalDefinition) extends Ameni
|
|||
|
||||
override def toString: String = {
|
||||
val guid = if (HasGUID) {
|
||||
s" ${Continent}-${GUID.guid}"
|
||||
s" $Continent-${GUID.guid}"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,33 +320,25 @@ object KillAssists {
|
|||
0L
|
||||
} else if (base > 1) {
|
||||
//include battle rank disparity modifier
|
||||
val battleRankDisparity = {
|
||||
val battleRankDisparity: Long = {
|
||||
import net.psforever.objects.avatar.BattleRank
|
||||
val killerLevel = BattleRank.withExperience(killer.bep).value
|
||||
val victimLevel = BattleRank.withExperience(victim.bep).value
|
||||
if (victimLevel > killerLevel || killerLevel - victimLevel < 6) {
|
||||
if (killerLevel < 7) {
|
||||
6 * victimLevel + 10
|
||||
} else if (killerLevel < 12) {
|
||||
(12 - killerLevel) * victimLevel + 10
|
||||
} else if (killerLevel < 25) {
|
||||
25 + victimLevel - killerLevel
|
||||
} else {
|
||||
25
|
||||
}
|
||||
val victimMinusKiller = victimLevel - killerLevel
|
||||
if (victimMinusKiller > -1) {
|
||||
victimMinusKiller * 10 + victimLevel
|
||||
} else {
|
||||
math.floor(-0.15f * base - killerLevel + victimLevel).toLong
|
||||
val bothLevels = killerLevel + victimLevel
|
||||
val pointFive = (base.toFloat * 0.25f).toInt
|
||||
-1 * (if (bothLevels >= base) {
|
||||
pointFive
|
||||
} else {
|
||||
math.min(bothLevels, pointFive)
|
||||
})
|
||||
}
|
||||
}
|
||||
val baseWithDisparity: Long = base + battleRankDisparity
|
||||
val killCount: Long = victim.progress.kills.size
|
||||
if (battleRankDisparity > 0) {
|
||||
//include menace modifier
|
||||
val pureMenace = calculateMenace(victim)
|
||||
baseWithDisparity + (killCount * (1f + pureMenace.toFloat / 10f)).toLong
|
||||
} else {
|
||||
math.max(baseWithDisparity, killCount)
|
||||
}
|
||||
}.toLong
|
||||
//include menace modifier
|
||||
base + battleRankDisparity + (victim.progress.kills.size.toFloat * (1f + calculateMenace(victim).toFloat / 10f)).toLong
|
||||
} else {
|
||||
base
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,14 @@ class HackCaptureActor extends Actor {
|
|||
// Timed hack finished (or neutral LLU base with no neighbour as timed hack), capture the base
|
||||
val hackTime = terminal.Definition.FacilityHackTime.toMillis
|
||||
HackCompleted(terminal, hackedByFaction)
|
||||
building.Participation.RewardFacilityCapture(terminal.Faction, hackedByFaction, hacker, hackTime, hackTime, isResecured = false)
|
||||
building.Participation.RewardFacilityCapture(
|
||||
HackCaptureActor.GetDefendingFaction(terminal, building, hackedByFaction),
|
||||
hackedByFaction,
|
||||
hacker,
|
||||
hackTime,
|
||||
hackTime,
|
||||
isResecured = false
|
||||
)
|
||||
}
|
||||
}
|
||||
// If there's hacked objects left in the list restart the timer with the shortest hack time left
|
||||
|
|
@ -95,7 +102,14 @@ class HackCaptureActor extends Actor {
|
|||
case flag: CaptureFlag => target.Zone.LocalEvents ! CaptureFlagManager.Lost(flag, CaptureFlagLostReasonEnum.Resecured)
|
||||
}
|
||||
NotifyHackStateChange(target, isResecured = true)
|
||||
building.Participation.RewardFacilityCapture(target.Faction, faction, hacker, target.Definition.FacilityHackTime.toMillis, System.currentTimeMillis() - results.head.hack_timestamp, isResecured = true)
|
||||
building.Participation.RewardFacilityCapture(
|
||||
target.Faction,
|
||||
faction,
|
||||
hacker,
|
||||
target.Definition.FacilityHackTime.toMillis,
|
||||
System.currentTimeMillis() - results.head.hack_timestamp,
|
||||
isResecured = true
|
||||
)
|
||||
// Restart the timer in case the object we just removed was the next one scheduled
|
||||
RestartTimer()
|
||||
|
||||
|
|
@ -111,7 +125,14 @@ class HackCaptureActor extends Actor {
|
|||
val hackedByFaction = hackInfo.hackerFaction
|
||||
hackedObjects = hackedObjects.filterNot(x => x == entry)
|
||||
HackCompleted(terminal, hackedByFaction)
|
||||
building.Participation.RewardFacilityCapture(terminal.Faction, hacker.Faction, hacker, terminal.Definition.FacilityHackTime.toMillis, System.currentTimeMillis() - entry.hack_timestamp, isResecured = false)
|
||||
building.Participation.RewardFacilityCapture(
|
||||
HackCaptureActor.GetDefendingFaction(terminal, building, hackedByFaction),
|
||||
hackedByFaction,
|
||||
hacker,
|
||||
terminal.Definition.FacilityHackTime.toMillis,
|
||||
System.currentTimeMillis() - entry.hack_timestamp,
|
||||
isResecured = false
|
||||
)
|
||||
entry.target.Actor ! CommonMessages.ClearHack()
|
||||
flag.Zone.LocalEvents ! CaptureFlagManager.Captured(flag)
|
||||
// If there's hacked objects left in the list restart the timer with the shortest hack time left
|
||||
|
|
@ -247,6 +268,44 @@ object HackCaptureActor {
|
|||
hack_timestamp: Long
|
||||
)
|
||||
|
||||
def GetDefendingFaction(
|
||||
terminal: CaptureTerminal,
|
||||
building: Building,
|
||||
excludeThisFaction: PlanetSideEmpire.Value
|
||||
): PlanetSideEmpire.Value = {
|
||||
terminal.HackedBy
|
||||
.map { _.originalFaction }
|
||||
.orElse { Some(terminal.Faction) }
|
||||
.collect {
|
||||
case PlanetSideEmpire.NEUTRAL =>
|
||||
val factionEfforts = building.Participation
|
||||
.PlayerContributionRaw
|
||||
.values
|
||||
.foldLeft(Array.fill(4)(0L))({ case (a, b) =>
|
||||
val (player, duration, _) = b
|
||||
val index = player.Faction.id
|
||||
a.update(index, a(index) + duration.toLong)
|
||||
a
|
||||
})
|
||||
factionEfforts.update(excludeThisFaction.id, Long.MinValue)
|
||||
factionEfforts
|
||||
.indices
|
||||
.maxByOption(factionEfforts)
|
||||
.map { index => PlanetSideEmpire(index) }
|
||||
.getOrElse {
|
||||
val test = PlanetSideEmpire(0)
|
||||
if (excludeThisFaction == test) {
|
||||
PlanetSideEmpire(1)
|
||||
} else {
|
||||
test
|
||||
}
|
||||
}
|
||||
case faction =>
|
||||
faction
|
||||
}
|
||||
.get
|
||||
}
|
||||
|
||||
def GetHackingFaction(terminal: CaptureTerminal): Option[PlanetSideEmpire.Value] = {
|
||||
terminal.HackedBy.map { a => a.player.Faction }
|
||||
}
|
||||
|
|
@ -255,7 +314,7 @@ object HackCaptureActor {
|
|||
terminal.HackedBy match {
|
||||
case _ if isResecured =>
|
||||
17039360L
|
||||
case Some(Hackable.HackInfo(p, _, start, length)) =>
|
||||
case Some(Hackable.HackInfo(p, _, start, length, _)) =>
|
||||
// See PlanetSideAttributeMessage #20 documentation for an explanation of how the timer is calculated
|
||||
val hackTimeRemainingMS = math.max(0, start + length - System.currentTimeMillis())
|
||||
val startNum = p.Faction match {
|
||||
|
|
|
|||
Loading…
Reference in a new issue