--[[ Author 1: Znadul (Kor'gall) Author 2: Corvian (Warsong) Date: 21/06/2006 Version: 0.8 Description: Special thnx: AeneasKuM and mrpel (ui.worldofwar.net) - 1.12 fix ]]-- --------------------------------------------------------------------------------- -- VARIABLES --------------------------------------------------------------------------------- local lOriginalWorldStateAlwaysUpFrame_Update; ABHEFS_VERSION = "0.8"; local ABHEFS_FlagsData = { [0] = { time = 999999, rate = 999999 }, [1] = { time = 11, rate = 1.1 }, [2] = { time = 10, rate = 1 }, [3] = { time = 6, rate = 0.6 }, [4] = { time = 3, rate = 0.3 }, [5] = { time = 1, rate = 0.03333 } }; local ABHEFS_POIsData = { -- ids: 1-Mine, 2-Lumber, 3-BS, 4-Farm, 5-Stables (not used) [16] = { id = 1, faction = "Neutral", conflict = false }, [17] = { id = 1, faction = "Aliance", conflict = true }, [18] = { id = 1, faction = "Aliance", conflict = false }, [19] = { id = 1, faction = "Horde", conflict = true }, [20] = { id = 1, faction = "Horde", conflict = false }, [21] = { id = 2, faction = "Neutral", conflict = false }, [22] = { id = 2, faction = "Aliance", conflict = true }, [23] = { id = 2, faction = "Aliance", conflict = false }, [24] = { id = 2, faction = "Horde", conflict = true }, [25] = { id = 2, faction = "Horde", conflict = false }, [26] = { id = 3, faction = "Neutral", conflict = false }, [27] = { id = 3, faction = "Aliance", conflict = true }, [28] = { id = 3, faction = "Aliance", conflict = false }, [29] = { id = 3, faction = "Horde", conflict = true }, [30] = { id = 3, faction = "Horde", conflict = false }, [31] = { id = 4, faction = "Neutral", conflict = false }, [32] = { id = 4, faction = "Aliance", conflict = true }, [33] = { id = 4, faction = "Aliance", conflict = false }, [34] = { id = 4, faction = "Horde", conflict = true }, [35] = { id = 4, faction = "Horde", conflict = false }, [36] = { id = 5, faction = "Neutral", conflict = false }, [37] = { id = 5, faction = "Aliance", conflict = true }, [38] = { id = 5, faction = "Aliance", conflict = false }, [39] = { id = 5, faction = "Horde", conflict = true }, [40] = { id = 5, faction = "Horde", conflict = false } }; local ABHEFS_FlagsStatus = { [ABHEFS_GOLDMINE] = { id = 1, status = -1, timeLeft = 0 }, [ABHEFS_LUMBERMILL] = { id = 2, status = -1, timeLeft = 0 }, [ABHEFS_BLACKSMITH] = { id = 3, status = -1, timeLeft = 0 }, [ABHEFS_FARM] = { id = 4, status = -1, timeLeft = 0 }, [ABHEFS_STABLES] = { id = 5, status = -1, timeLeft = 0 } }; local ABHEFS_ScoreStatus = { ["Aliance"] = { score = 0, lastUpdate = 0, flags = 0, updated = false}, ["Horde"] = { score = 0, lastUpdate = 0, flags = 0, updated = false } }; local ABHEFS_DebugData = { }; local ABHEFS_PlayerFaction = nil; local ABHEFS_TimeLeft = 0; local ABHEFS_FlagAssaultTime = 64; local ABHEFS_ShowTime = false; local ABHEFS_LastLeftTimerUpdate; local ABHEFS_LastTimersUpdate; local ABHEFS_isWinning = { faction = 0, score = 0}; -- faction: 1-alliance 2-horde --------------------------------------------------------------------------------- -- LOCAL FUNCTIONS --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- -- GLOBAL FUNCTIONS --------------------------------------------------------------------------------- function ABHEFSPrint(msg) --* if (DEFAULT_CHAT_FRAME) then DEFAULT_CHAT_FRAME:AddMessage(msg, 1.0, 0.5, 1.0); end end function ABHEFS_ResetStatus() --* for i, value in ABHEFS_FlagsStatus do value.status = -1; value.timeLeft = 0; end for i, value in ABHEFS_ScoreStatus do value.score = 0; value.lastUpdate = 0; value.flags = 0; value.updated = false; end end function ABHEFS_TimeToStr(time) --* if ( time >= 60 ) then secs = mod(time, 60); mins = (time - secs) / 60; else mins = 0; secs = time; end if ( mins < 10 ) then mins = "0" .. mins; end if ( secs < 10 ) then secs = "0" .. secs; end timeText = mins .. ":" .. secs; return timeText; end function ABHEFS_SlashHandler(command) --* local i,j, cmd, param = string.find(command, "^([^ ]+) (.+)$"); -- nil prevention if (not cmd) then cmd = command; end if (not cmd) then cmd = ""; end if (not param) then param = ""; end if (cmd == "on") then -- hook WorldStateAlwaysUpFrame_Update = ABHEFS_WorldStateAlwaysUpFrame_Update; ABHEFSPrint("ABHEFS enabled"); WorldStateAlwaysUpFrame_Update(); end if (cmd == "off") then -- unhook WorldStateAlwaysUpFrame_Update = lOriginalWorldStateAlwaysUpFrame_Update; ABHEFSPrint("ABHEFS disabled"); getglobal("ABHEFS_Frame"):Hide(); -- WorldStateAlwaysUpFrame_Update(); end if (cmd == "resetpos") then getglobal("ABHEFS_Frame"):ClearAllPoints(); getglobal("ABHEFS_Frame"):SetPoint("TOPLEFT", "AlwaysUpFrame2", "BOTTOMLEFT", 0, 0); end if ((cmd == "") or (cmd == "help")) then ABHEFSPrint("Usage:"); ABHEFSPrint(" /ABHEFS (on/off) | Enable / Disable"); ABHEFSPrint(" /ABHEFS resetpos | Reset the frame position"); end end function ABHEFS_TimeTo(faction, endScore) --* -- check for endScore reached if (ABHEFS_ScoreStatus[faction].score >= endScore) then return 0; end timePerTick = ABHEFS_FlagsData[ABHEFS_ScoreStatus[faction].flags].time; timeToNextTick = timePerTick - (time() - ABHEFS_ScoreStatus[faction].lastUpdate); -- check for reached at next tick if (endScore == ABHEFS_ScoreStatus[faction].score + 10) then return timeToNextTick; end timeTo = (((endScore - (ABHEFS_ScoreStatus[faction].score + 10)) / 10) * timePerTick) + timeToNextTick; return timeTo; end function ABHEFS_scoreAfter(faction, seconds) --* timePerTick = ABHEFS_FlagsData[ABHEFS_ScoreStatus[faction].flags].time; timeToNextTick = timePerTick - (time() - ABHEFS_ScoreStatus[faction].lastUpdate); -- check for no changes until second if (timeToNextTick > seconds) then return ABHEFS_ScoreStatus[faction].score; end scoreAfter = ABHEFS_ScoreStatus[faction].score + 10 + (floor((seconds - timeToNextTick) / timePerTick) * 10); return scoreAfter; end function ABHEFS_GetData() --* local winner, stat1, stat2; local scoreWinner; local estimatedTime; local min, secs; _, stat1 = GetWorldStateUIInfo(1); _, stat2 = GetWorldStateUIInfo(2); _, _, strAllyBases, strAllyScore = string.find(stat1, ABHEFS_WORLDSTATESTRING); _, _, strHordeBases, strHordeScore = string.find(stat2, ABHEFS_WORLDSTATESTRING); allyBases = tonumber(strAllyBases); hordeBases = tonumber(strHordeBases); allyScore = tonumber(strAllyScore); hordeScore = tonumber(strHordeScore); needed = ABHEFS_GetNeeded(allyScore, hordeScore); -- check for data and victory if (not allyScore) or (not hordeScore) or (allyScore == 2000) or (hordeScore == 2000) then getglobal("ABHEFS_Frame"):Hide(); ABHEFS_ResetStatus(); ABHEFS_TimeLeft = 0; return; else getglobal("ABHEFS_Frame"):Show(); end -- bases are always updated ABHEFS_ScoreStatus["Aliance"].flags = allyBases; ABHEFS_ScoreStatus["Horde"].flags = hordeBases; -- check for first update if (ABHEFS_ScoreStatus["Horde"].lastUpdate == 0) then ABHEFS_ScoreStatus["Horde"].score = hordeScore; ABHEFS_ScoreStatus["Horde"].lastUpdate = time(); end if (ABHEFS_ScoreStatus["Aliance"].lastUpdate == 0) then ABHEFS_ScoreStatus["Aliance"].score = allyScore; ABHEFS_ScoreStatus["Aliance"].lastUpdate = time(); end -- check for 5-0 if (allyBases == 5) then return 2000, hordeScore; elseif (hordeBases == 5) then return allyScore, 2000, nil, needed; end if (allyBases == 0) and (hordeBases == 0) then estimatedAlly = "ind."; estimatedHorde = "ind."; return estimatedAlly, estimatedHorde, nil, needed; end -- if some1 is 0 then updated is true anyway if (allyBases == 0) then ABHEFS_ScoreStatus["Aliance"].updated = true; end if (hordeBases == 0) then ABHEFS_ScoreStatus["Horde"].updated = true; end if (hordeScore ~= ABHEFS_ScoreStatus["Horde"].score) then ABHEFS_ScoreStatus["Horde"].score = hordeScore; ABHEFS_ScoreStatus["Horde"].lastUpdate = time(); ABHEFS_ScoreStatus["Horde"].updated = true; elseif (allyScore ~= ABHEFS_ScoreStatus["Aliance"].score) then ABHEFS_ScoreStatus["Aliance"].score = allyScore; ABHEFS_ScoreStatus["Aliance"].lastUpdate = time(); ABHEFS_ScoreStatus["Aliance"].updated = true; end -- TODO: check for only flags change -- only show when both factions updateds if not ABHEFS_ScoreStatus["Aliance"].updated or not ABHEFS_ScoreStatus["Horde"].updated then estimatedAlly = "ind."; estimatedHorde = "ind."; return estimatedAlly, estimatedHorde, nil, needed; end estiHordeTime = ABHEFS_TimeTo("Horde", 2000); estiAlianceTime = ABHEFS_TimeTo("Aliance", 2000); if (estiHordeTime > estiAlianceTime) or (hordeBases == 0) then -- aliance victory estimatedAlly = 2000; estimatedHorde = ABHEFS_scoreAfter("Horde", estiAlianceTime); winner = 1; scoreWinner = allyScore; estimatedTime = estiAlianceTime; else estimatedHorde = 2000; estimatedAlly = ABHEFS_scoreAfter("Aliance", estiHordeTime); winner = 2; scoreWinner = hordeScore; estimatedTime = estiHordeTime; end if estimatedTime then -- only return estimatedTime for resources changes on winner if (winner ~= ABHEFS_isWinning.faction) or (scoreWinner ~= ABHEFS_isWinning.score) then ABHEFS_TimeLeft = estimatedTime; ABHEFS_LastLeftTimerUpdate = time(); ABHEFS_isWinning.faction = winner; ABHEFS_isWinning.score = scoreWinner; return estimatedAlly, estimatedHorde, ABHEFS_TimeToStr(estimatedTime), needed; else return estimatedAlly, estimatedHorde, ABHEFS_TimeToStr(ABHEFS_TimeLeft),needed; end else return estimatedAlly, estimatedHorde, nil, needed; end end function ABHEFS_GetNeeded(aScore, hScore) if (aScore and hScore) then aScore = tonumber(aScore); hScore = tonumber(hScore); if (((2000 - aScore) * ABHEFS_FlagsData[1].rate) < ((2000 - hScore) * ABHEFS_FlagsData[4].rate)) then return 1; elseif (((2000 - aScore) * ABHEFS_FlagsData[2].rate) < ((2000 - hScore) * ABHEFS_FlagsData[3].rate)) then return 2; elseif (((2000 - aScore) * ABHEFS_FlagsData[3].rate) < ((2000 - hScore) * ABHEFS_FlagsData[2].rate)) then return 3; elseif (((2000 - aScore) * ABHEFS_FlagsData[4].rate) < ((2000 - hScore) * ABHEFS_FlagsData[1].rate)) then return 4; else return 5; end else return; end end function ABHEFS_UpdateFlags() --* local name, status, lastStatus; local timeLeft; local ownerFaction, oppositeFaction; local x1, x2, y1, y2; SetMapToCurrentZone(); -- read data local numLMs = GetNumMapLandmarks(); for i = 1, numLMs, 1 do name, _, status = GetMapLandmarkInfo(i); -- check for change status (only trackeable status, with entry in ABHEFS_POIsData) if ABHEFS_FlagsStatus[name] and (ABHEFS_FlagsStatus[name].status ~= status) and ABHEFS_POIsData[status] then lastStatus = ABHEFS_FlagsStatus[name].status; ABHEFS_FlagsStatus[name].status = status; if (lastStatus ~= -1) and ABHEFS_POIsData[status].conflict then -- just assaulted -- if lastStatus == -1 the new status is the first known status ABHEFS_FlagsStatus[name].timeLeft = ABHEFS_FlagAssaultTime; else ABHEFS_FlagsStatus[name].timeLeft = 0; end end end -- write flags for index, value in ABHEFS_FlagsStatus do status = value.status; timeLeft = value.timeLeft; i = value.id; if ABHEFS_POIsData[status] and (ABHEFS_POIsData[status].faction ~= "Neutral") then ownerFaction = ABHEFS_POIsData[status].faction; if (ownerFaction == "Aliance") then oppositeFaction = "Horde"; else oppositeFaction = "Aliance"; end flagFrameShow = getglobal("ABHEFS_"..ownerFaction.."Flag"..i); flagFrameTextShow = getglobal("ABHEFS_"..ownerFaction.."Flag"..i.."TimeText"); flagFrameTextureShow = getglobal("ABHEFS_"..ownerFaction.."Flag"..i.."Texture"); flagFrameHide = getglobal("ABHEFS_"..oppositeFaction.."Flag"..i); x1, x2, y1, y2 = WorldMap_GetPOITextureCoords(status); flagFrameTextureShow:SetTexCoord(x1, x2, y1, y2); if (timeLeft > 0) then flagFrameTextShow:SetText(ABHEFS_TimeToStr(timeLeft)); else flagFrameTextShow:SetText(""); end flagFrameShow:Show(); flagFrameHide:Hide(); else getglobal("ABHEFS_AlianceFlag"..i):Hide(); getglobal("ABHEFS_HordeFlag"..i):Hide(); end end end --------------------------------------------------------------------------------- -- EVENT FUNCTIONS --------------------------------------------------------------------------------- function ABHEFS_OnLoad() -- events this:RegisterEvent("UPDATE_WORLD_STATES"); this:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE"); this:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE"); -- drag this:RegisterForDrag("LeftButton"); -- hook lOriginalWorldStateAlwaysUpFrame_Update = WorldStateAlwaysUpFrame_Update; -- enabled on load WorldStateAlwaysUpFrame_Update = ABHEFS_WorldStateAlwaysUpFrame_Update; ABHEFS_LastTimersUpdate = time(); ABHEFSPrint("ABHEFS redux v."..ABHEFS_VERSION.."has loaded!"); SLASH_ABHEFS1 = "/ABHEFS"; SlashCmdList["ABHEFS"] = ABHEFS_SlashHandler; end function ABHEFS_OnEvent() if (event == "UPDATE_WORLD_STATES") then -- void atm end if (event == "CHAT_MSG_BG_SYSTEM_ALLIANCE" or event == "CHAT_MSG_BG_SYSTEM_HORDE") then ABHEFS_UpdateFlags(); end end function ABHEFS_OnUpdate() -- check for Arathi Basin local inArathi = false; for i=1, MAX_BATTLEFIELD_QUEUES do local status, mapName = GetBattlefieldStatus(i); if (status == "active") and (mapName == ABHEFS_MAPNAME) then inArathi = true; end end if not inArathi then getglobal("ABHEFS_Frame"):Hide(); ABHEFS_ResetStatus(); return; end -- execute code every second if (ABHEFS_LastTimersUpdate ~= time()) then ABHEFS_LastTimersUpdate = time(); -- flags time for i, value in ABHEFS_FlagsStatus do timeLeft = value.timeLeft; if (timeLeft > 0) then value.timeLeft = timeLeft - 1; end end ABHEFS_UpdateFlags(false); -- Estimated End time if (ABHEFS_TimeLeft == 0) or not ABHEFS_ShowTime then return; end if (ABHEFS_LastLeftTimerUpdate ~= time()) then -- get time elapsed elapsed = time() - ABHEFS_LastLeftTimerUpdate; ABHEFS_TimeLeft = ABHEFS_TimeLeft - elapsed; getglobal("ABHEFS_FrameTimeText"):SetText(ABHEFS_TIMELEFT .. ABHEFS_TimeToStr(ABHEFS_TimeLeft)); ABHEFS_LastLeftTimerUpdate = time(); end end end function ABHEFS_OnDragStart() ABHEFS_Frame:StartMoving(); end function ABHEFS_OnDragStop() ABHEFS_Frame:StopMovingOrSizing(); end --------------------------------------------------------------------------------- -- HOOK --------------------------------------------------------------------------------- function ABHEFS_WorldStateAlwaysUpFrame_Update() local inArathi = false; lOriginalWorldStateAlwaysUpFrame_Update(); -- check for Arathi Basin for i=1, MAX_BATTLEFIELD_QUEUES do local status, mapName = GetBattlefieldStatus(i); if (status == "active") and (mapName == ABHEFS_MAPNAME) then inArathi = true; end end if not inArathi then getglobal("ABHEFS_Frame"):Hide(); ABHEFS_ResetStatus(); return; end if (ABHEFS_PlayerFaction == nil) then ABHEFS_PlayerFaction = UnitFactionGroup("player"); end ABHEFS_UpdateFlags(); -- update scores frameTextAlly = getglobal("ABHEFS_FrameText1"); frameTextHorde = getglobal("ABHEFS_FrameText2"); frameTimeLeft = getglobal("ABHEFS_FrameTimeText"); frameBasesNeeded = getglobal("ABHEFS_FrameNeededText"); estimatedAlly, estimatedHorde, estimatedTime, needed = ABHEFS_GetData(); if estimatedAlly then frameTextAlly:SetText(estimatedAlly); end if estimatedHorde then frameTextHorde:SetText(estimatedHorde); end if needed then if (ABHEFS_PlayerFaction == "Horde") then needed = 6 - needed; end frameBasesNeeded:SetText(ABHEFS_BASESNEEDED..needed); end if estimatedTime then ABHEFS_ShowTime = true; frameTimeLeft:SetText(ABHEFS_TIMELEFT..estimatedTime); else ABHEFS_ShowTime = false; frameTimeLeft:SetText(""); end; end