From 91be11b2807f3ada369c169fc9f7775b2cd8632d Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Sep 2024 21:44:22 +0200 Subject: Core/GameObjects: Implement ControlZone::UncontestedTime field (#30152) (cherry picked from commit 314e155a0c4b9f904d6b36898941cc1966d8a719) --- src/server/game/Entities/GameObject/GameObject.cpp | 54 ++++++++++++++-------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 10b5933a0f6..445c007c588 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -698,38 +698,56 @@ public: HandleUnitEnterExit(targetList); } - float CalculatePointsPerSecond(std::vector const& targetList) + float CalculatePointsPerSecond(std::vector const& targetList) const { - int32 delta = 0; + int32 hordePlayers = 0; + int32 alliancePlayers = 0; - for (Player* player : targetList) + for (Player const* player : targetList) { if (!player->IsOutdoorPvPActive()) continue; if (player->GetTeamId() == TEAM_HORDE) - delta--; + hordePlayers++; else - delta++; + alliancePlayers++; } - uint32 minTime = _owner.GetGOInfo()->controlZone.minTime; - uint32 maxTime = _owner.GetGOInfo()->controlZone.maxTime; - uint32 minSuperiority = _owner.GetGOInfo()->controlZone.minSuperiority; - uint32 maxSuperiority = _owner.GetGOInfo()->controlZone.maxSuperiority; + int8 factionCoefficient = 0; // alliance superiority = 1; horde superiority = -1 + + if (alliancePlayers > hordePlayers) + factionCoefficient = 1; + else if (hordePlayers > alliancePlayers) + factionCoefficient = -1; - if (static_cast(std::abs(delta)) < minSuperiority) - return 0; + float const timeNeeded = CalculateTimeNeeded(hordePlayers, alliancePlayers); + if (timeNeeded == 0.0f) + return 0.0f; + + return 100.0f / timeNeeded * static_cast(factionCoefficient); + } + + float CalculateTimeNeeded(int32 hordePlayers, int32 alliancePlayers) const + { + uint32 const uncontestedTime = _owner.GetGOInfo()->controlZone.UncontestedTime; + uint32 const delta = std::abs(alliancePlayers - hordePlayers); + uint32 const minSuperiority = _owner.GetGOInfo()->controlZone.minSuperiority; + + if (delta < minSuperiority) + return 0.0f; - float slope = (static_cast(minTime) - maxTime) / std::max((maxSuperiority - minSuperiority), 1); - float intercept = maxTime - slope * minSuperiority; - float timeNeeded = slope * std::abs(delta) + intercept; - float percentageIncrease = 100.0f / timeNeeded; + // return the uncontested time if controlzone is not contested + if (uncontestedTime && (hordePlayers == 0 || alliancePlayers == 0)) + return static_cast(uncontestedTime); - if (delta < 0) - percentageIncrease *= -1; + uint32 const minTime = _owner.GetGOInfo()->controlZone.minTime; + uint32 const maxTime = _owner.GetGOInfo()->controlZone.maxTime; + uint32 const maxSuperiority = _owner.GetGOInfo()->controlZone.maxSuperiority; - return percentageIncrease; + float const slope = static_cast(minTime - maxTime) / static_cast(std::max(maxSuperiority - minSuperiority, 1)); + float const intercept = static_cast(maxTime) - slope * static_cast(minSuperiority); + return slope * static_cast(delta) + intercept; } void HandleUnitEnterExit(std::vector const& newTargetList) -- cgit v1.2.3