Files
Andrew6810 39c0ed874e init
2022-10-21 06:50:13 -07:00

388 lines
11 KiB
Lua

-- Arathi mod v3.0
-- rewrite by Tandanu
--
-- thanks to DiabloH
local Arathi = DBM:NewMod("ArathiBasin", "DBM-PvP", 2)
local L = Arathi:GetLocalizedStrings()
Arathi:SetZone(DBM_DISABLE_ZONE_DETECTION)
Arathi:RemoveOption("HealthFrame")
Arathi:RegisterEvents(
"ZONE_CHANGED_NEW_AREA",
"CHAT_MSG_BG_SYSTEM_HORDE",
"CHAT_MSG_BG_SYSTEM_ALLIANCE",
"CHAT_MSG_BG_SYSTEM_NEUTRAL",
"UPDATE_WORLD_STATES"
)
local bgzone = false
local ResPerSec = {
[0] = 0,
[1] = 10/12,
[2] = 10/9,
[3] = 10/6,
[4] = 10/3,
[5] = 30,
}
local allyColor = {
r = 0,
g = 0,
b = 1,
}
local hordeColor = {
r = 1,
g = 0,
b = 0,
}
local objectives = {
Farm = 0,
GoldMine = 0,
LumberMill = 0,
Stables = 0,
Blacksmith = 0,
}
local function get_objective(id)
if id >=16 and id <=20 then return "GoldMine"
elseif id >= 21 and id <= 25 then return "LumberMill"
elseif id >= 26 and id <= 30 then return "Blacksmith"
elseif id >= 31 and id <= 35 then return "Farm"
elseif id >= 36 and id <= 40 then return "Stables"
else return false
end
end
local function get_basecount()
local alliance = 0
local horde = 0
for k,v in pairs(objectives) do
if v == 18 or v == 23 or v == 28 or v == 33 or v == 38 then
alliance = alliance + 1
elseif v == 20 or v == 25 or v == 30 or v == 35 or v == 40 then
horde = horde + 1
end
end
return alliance, horde
end
local function get_score()
if not bgzone then return 0,0 end
local AllyScore = tonumber(string.match((select(3, GetWorldStateUIInfo(1)) or ""), L.ScoreExpr)) or 0
local HordeScore = tonumber(string.match((select(3, GetWorldStateUIInfo(2)) or ""), L.ScoreExpr)) or 0
return AllyScore, HordeScore
end
local get_gametime
local update_gametime
do
local gametime = 0
function update_gametime()
gametime = time()
end
function get_gametime()
local systime = GetBattlefieldInstanceRunTime()
if systime > 0 then
return systime / 1000
else
return time() - gametime
end
end
end
do
local function AB_Initialize()
if select(2, IsInInstance()) == "pvp" and GetRealZoneText() == L.ZoneName then
bgzone = true
update_gametime()
for i=1, GetNumMapLandmarks(), 1 do
local name, _, textureIndex = GetMapLandmarkInfo(i)
if name and textureIndex then
local typ = get_objective(textureIndex)
if typ then
objectives[typ] = textureIndex
end
end
end
if Arathi.Options.ShowAbEstimatedPoints then
Arathi:ShowEstimatedPoints()
end
if Arathi.Options.ShowAbBasesToWin then
Arathi:ShowBasesToWin()
end
elseif bgzone then
bgzone = false
if Arathi.Options.ShowAbEstimatedPoints then
Arathi:HideEstimatedPoints()
end
if Arathi.Options.ShowAbBasesToWin then
Arathi:HideBasesToWin()
end
end
end
Arathi.OnInitialize = AB_Initialize
Arathi.ZONE_CHANGED_NEW_AREA = AB_Initialize
end
Arathi:AddBoolOption("ShowAbEstimatedPoints", true, nil, function()
if Arathi.Options.ShowAbEstimatedPoints and bgzone then
Arathi:ShowEstimatedPoints()
else
Arathi:HideEstimatedPoints()
end
end)
Arathi:AddBoolOption("ShowAbBasesToWin", false, nil, function()
if Arathi.Options.ShowAbBasesToWin and bgzone then
Arathi:ShowBasesToWin()
else
Arathi:HideBasesToWin()
end
end)
local startTimer = Arathi:NewTimer(62, "TimerStart")
local winTimer = Arathi:NewTimer(30, "TimerWin")
local capTimer = Arathi:NewTimer(63, "TimerCap")
local function obj_state(id)
if id == 18 or id == 23 or id == 28 or id == 33 or id == 38 then
return 1 -- if obj_state(id) > 2 then .. conflict state ... ( 1 == alliance, 2 == horde )
elseif id == 20 or id == 25 or id == 30 or id == 35 or id == 40 then
return 2
elseif id == 17 or id == 22 or id == 27 or id == 32 or id == 37 then
return 3 -- if obj_state(id) == 3 then --- alliance trys to capture from horde
elseif id == 19 or id == 24 or id == 29 or id == 34 or id == 39 then
return 4 -- if obj_state(id) == 3 then --- horde trys to capture from alliance
else return 0
end
end
do
local function check_for_updates()
if not bgzone then return end
for i=1, GetNumMapLandmarks(), 1 do
local name, _, textureIndex = GetMapLandmarkInfo(i)
if name and textureIndex then
local typ = get_objective(textureIndex)
if typ then
if obj_state(objectives[typ]) <= 2 and obj_state(textureIndex) > 2 then
capTimer:Start(nil, name)
if obj_state(textureIndex) == 3 then
capTimer:SetColor(allyColor, name)
capTimer:UpdateIcon("Interface\\Icons\\INV_BannerPVP_02.blp", name)
else
capTimer:SetColor(hordeColor, name)
capTimer:UpdateIcon("Interface\\Icons\\INV_BannerPVP_01.blp", name)
end
elseif obj_state(textureIndex) <= 2 then
capTimer:Stop(name)
end
objectives[typ] = textureIndex
end
end
end
end
local function schedule_check(self)
self:Schedule(1, check_for_updates)
end
Arathi.CHAT_MSG_BG_SYSTEM_ALLIANCE = schedule_check
Arathi.CHAT_MSG_BG_SYSTEM_HORDE = schedule_check
function Arathi:CHAT_MSG_BG_SYSTEM_NEUTRAL(arg1)
if not bgzone then return end
if arg1 == L.BgStart60 then
startTimer:Start()
elseif arg1 == L.BgStart30 then
startTimer:Update(31, 62)
end
schedule_check(self)
end
end
do
local winner_is = 0 -- 0 = nobody 1 = alliance 2 = horde
local last_horde_score = 0
local last_alliance_score = 0
function Arathi:UPDATE_WORLD_STATES()
if not bgzone then return end
local AllyBases, HordeBases = get_basecount()
local AllyScore, HordeScore = get_score()
local callupdate = false
if AllyScore ~= last_alliance_score then
last_alliance_score = AllyScore
if winner_is == 1 then
callupdate = true
end
elseif HordeScore ~= last_horde_score then
last_horde_score = HordeScore
if winner_is == 2 then
callupdate = true
end
end
if callupdate or winner_is == 0 then
self:UpdateWinTimer()
end
end
function Arathi:UpdateWinTimer()
local last_alliance_bases, last_horde_bases = get_basecount()
-- calculate new times
local AllyTime = (1600 - last_alliance_score) / ResPerSec[last_alliance_bases]
local HordeTime = (1600 - last_horde_score) / ResPerSec[last_horde_bases]
if AllyTime > 5000 then AllyTime = 5000 end
if HordeTime > 5000 then HordeTime = 5000 end
if AllyTime == HordeTime then
winner_is = 0
winTimer:Stop()
if self.ScoreFrame1Text then
self.ScoreFrame1Text:SetText("")
self.ScoreFrame2Text:SetText("")
end
elseif AllyTime > HordeTime then -- Horde wins
if self.ScoreFrame1Text and self.ScoreFrame2Text then
local AllyPoints = math.floor(math.floor(((HordeTime * ResPerSec[last_alliance_bases]) + last_alliance_score) / 10) * 10)
self.ScoreFrame1Text:SetText("("..AllyPoints..")")
self.ScoreFrame2Text:SetText("(1600)")
end
winner_is = 2
winTimer:Update(get_gametime(), get_gametime()+HordeTime)
winTimer:DisableEnlarge()
winTimer:UpdateName(L.WinBarText:format(L.Horde))
winTimer:SetColor(hordeColor)
winTimer:UpdateIcon("Interface\\Icons\\INV_BannerPVP_01.blp")
elseif HordeTime > AllyTime then -- Alliance wins
if self.ScoreFrame1Text and self.ScoreFrame2Text then
local HordePoints = math.floor(math.floor(((AllyTime * ResPerSec[last_horde_bases]) + last_horde_score) / 10) * 10)
self.ScoreFrame2Text:SetText("("..HordePoints..")")
self.ScoreFrame1Text:SetText("(1600)")
end
winner_is = 1
winTimer:Update(get_gametime(), get_gametime()+AllyTime)
winTimer:DisableEnlarge()
winTimer:UpdateName(L.WinBarText:format(L.Alliance))
winTimer:SetColor(allyColor)
winTimer:UpdateIcon("Interface\\Icons\\INV_BannerPVP_02.blp")
end
if self.Options.ShowAbBasesToWin then
local FriendlyLast, EnemyLast, FriendlyBases, EnemyBases, baseLowest
if( UnitFactionGroup("player") == "Alliance" ) then
FriendlyLast = last_alliance_score
EnemyLast = last_horde_score
FriendlyBases = last_alliance_bases
EnemyBases = last_horde_bases
else
FriendlyLast = last_horde_score
EnemyLast = last_alliance_score
FriendlyBases = last_horde_bases
EnemyBases = last_alliance_bases
end
if ((1600 - FriendlyLast) / ResPerSec[FriendlyBases]) > ((1600 - EnemyLast) / ResPerSec[EnemyBases]) then
for i=1, 5 do
local EnemyTime = (1600 - EnemyLast) / ResPerSec[ 5 - i ]
local FriendlyTime = (1600 - FriendlyLast) / ResPerSec[ i ]
if( FriendlyTime < EnemyTime ) then
baseLowest = FriendlyTime
else
baseLowest = EnemyTime
end
local EnemyFinal = math.floor( ( EnemyLast + math.floor( baseLowest * ResPerSec[ 5 - i ] + 0.5 ) ) / 10 ) * 10
local FriendlyFinal = math.floor( ( FriendlyLast + math.floor( baseLowest * ResPerSec[ i ] + 0.5 ) ) / 10 ) * 10
if( FriendlyFinal >= 1600 and EnemyFinal < 1600 ) then
self.ScoreFrameToWinText:SetText(L.BasesToWin:format(i))
break
end
end
else
self.ScoreFrameToWinText:SetText("")
end
end
end
end
function Arathi:ShowEstimatedPoints()
if AlwaysUpFrame1Text and AlwaysUpFrame2Text then
if not self.ScoreFrame1 then
self.ScoreFrame1 = CreateFrame("Frame", nil, AlwaysUpFrame1)
self.ScoreFrame1:SetHeight(10)
self.ScoreFrame1:SetWidth(100)
self.ScoreFrame1:SetPoint("LEFT", "AlwaysUpFrame1Text", "RIGHT", 4, 0)
self.ScoreFrame1Text = self.ScoreFrame1:CreateFontString(nil, nil, "GameFontNormalSmall")
self.ScoreFrame1Text:SetAllPoints(self.ScoreFrame1)
self.ScoreFrame1Text:SetJustifyH("LEFT")
end
if not self.ScoreFrame2 then
self.ScoreFrame2 = CreateFrame("Frame", nil, AlwaysUpFrame2)
self.ScoreFrame2:SetHeight(10)
self.ScoreFrame2:SetWidth(100)
self.ScoreFrame2:SetPoint("LEFT", "AlwaysUpFrame2Text", "RIGHT", 4, 0)
self.ScoreFrame2Text= self.ScoreFrame2:CreateFontString(nil, nil, "GameFontNormalSmall")
self.ScoreFrame2Text:SetAllPoints(self.ScoreFrame2)
self.ScoreFrame2Text:SetJustifyH("LEFT")
end
self.ScoreFrame1Text:SetText("")
self.ScoreFrame1:Show()
self.ScoreFrame2Text:SetText("")
self.ScoreFrame2:Show()
end
end
function Arathi:ShowBasesToWin()
if AlwaysUpFrame1Text and AlwaysUpFrame2Text then
if not self.ScoreFrameToWin then
self.ScoreFrameToWin = CreateFrame("Frame", nil, AlwaysUpFrame2)
self.ScoreFrameToWin:SetHeight(10)
self.ScoreFrameToWin:SetWidth(200)
self.ScoreFrameToWin:SetPoint("TOPLEFT", "AlwaysUpFrame2", "BOTTOMLEFT", 22, 2)
self.ScoreFrameToWinText= self.ScoreFrameToWin:CreateFontString(nil, nil, "GameFontNormalSmall")
self.ScoreFrameToWinText:SetAllPoints(self.ScoreFrameToWin)
self.ScoreFrameToWinText:SetJustifyH("LEFT")
end
self.ScoreFrameToWinText:SetText("")
self.ScoreFrameToWin:Show()
end
end
function Arathi:HideEstimatedPoints()
if self.ScoreFrame1 and self.ScoreFrame2 then
self.ScoreFrame1:Hide()
self.ScoreFrame1Text:SetText("")
self.ScoreFrame2:Hide()
self.ScoreFrame2Text:SetText("")
end
end
function Arathi:HideBasesToWin()
if self.ScoreFrameToWin then
self.ScoreFrameToWin:Hide()
self.ScoreFrameToWinText:SetText("")
end
end