diff --git a/.gitignore b/.gitignore
index 139597f..0d72554 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
+/format.lua
diff --git a/.pkgmeta b/.pkgmeta
index 8d337a7..fc9a586 100755
--- a/.pkgmeta
+++ b/.pkgmeta
@@ -2,11 +2,8 @@ package-as: GarrisonCommander
enable-nolib-creation: no
externals:
- libs/AlarShared-3.0:
- url: git://git.curseforge.net/wow/alar-art-remover/mainline.git/libs/AlarShared-3.0
- libs/Ace3:
- url: svn://svn.wowace.com/wow/ace3/mainline/trunk
- tag: latest
+ libs/LibInit:
+ url: git://git.curseforge.net/wow/libinit/mainline.git/
manual-changelog:
filename: CHANGELOG.txt
diff --git a/GarrisonCommander.lua b/GarrisonCommander.lua
index 0697754..4c52ce3 100644
--- a/GarrisonCommander.lua
+++ b/GarrisonCommander.lua
@@ -1,17 +1,31 @@
-local __FILE__=tostring(debugstack(1,2,0):match("(.*):1:")) -- MUST BE LINE 1
-print("Loading GarrisonCommander")
-local toc=select(4,GetBuildInfo())
local me, ns = ...
-local pp=print
-if (LibDebug) then LibDebug() end
-local L=LibStub("AceLocale-3.0"):GetLocale(me,true)
-local C=LibStub("AlarCrayon-3.0"):GetColorTable()
-local addon=LibStub("AlarLoader-3.0")(__FILE__,me,ns):CreateAddon(me,true) --#Addon
-local print=ns.print or print
+local addon=LibStub("LibInit"):NewAddon(me,'AceHook-3.0','AceTimer-3.0','AceEvent-3.0') --#Addon
+local C=addon:GetColorTable()
+local L=addon:GetLocale()
+local print=function(...) addon:Print(...) end
+local trace=function(...) addon:_Trace(false,1,...) end
+local xprint=function(dbg,...) if (type(dbg)=="boolean") then if dbg then addon:Print('DBG',...) end end end--else addon:Print(dbg,...) end end
+--xprint=function() end
local debug=ns.debug or print
local dump=ns.dump or print
+local pairs=pairs
+local select=select
+local next=next
+local tinsert=tinsert
+local tremove=tremove
+local setmetatable=setmetatable
+local getmetatable=getmetatable
+local type=type
+local GetAddOnMetadata=GetAddOnMetadata
+local CreateFrame=CreateFrame
+local wipe=wipe
+---TODO:
+-- Colorare i seguaci in base ala disponbilita' (verdi disponibili, rossi in altre missioni. Magary gialli se working?)
+-- Memorizzare la percentuale di successo delle missioni partire, per visualizzarla nel pannello in progress
+-- Rifare il tooltip
+-- Decidere come (se) usare lo spazio che rimane a destra delle icone
+
--@debug@
-ns.debugEnable('on')
local function tcopy(obj, seen)
if type(obj) ~= 'table' then return obj end
if seen and seen[obj] then return seen[obj] end
@@ -63,143 +77,773 @@ local function capitalize(s)
s=tostring(s)
return strupper(s:sub(1,1))..strlower(s:sub(2))
end
-local masterplan
-local followers
-local successes={}
-local requested={}
-local threats={}
-local availableFollowers=0
-local skipBusy
-local wipe=wipe
-local GMF=GarrisonMissionFrame
-local GMFFollowers=GarrisonMissionFrameFollowers
-local GMFMissions=GarrisonMissionFrameMissions
-local GMFMissionPage=GMF.MissionTab
-local GMFRewardPage
-local GMFFollowerPage=GMF.FollowerTab
-local GMFTab1=GarrisonMissionFrameTab1
-local GMFTab2=GarrisonMissionFrameTab2
-local GMFMissionsTab1=GarrisonMissionFrameMissionsTab1
-local GMFMissionsTab2=GarrisonMissionFrameMissionsTab2
-local GarrisonMissionFrameMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
-local GARRISON_FOLLOWER_WORKING=GARRISON_FOLLOWER_WORKING -- "Working
-local GARRISON_FOLLOWER_ON_MISSION=GARRISON_FOLLOWER_ON_MISSION -- "On Mission"
-local GARRISON_FOLLOWER_INACTIVE=GARRISON_FOLLOWER_INACTIVE --"Inactive"
-local GARRISON_FOLLOWER_EXHAUSTED=GARRISON_FOLLOWER_EXHAUSTED -- "Recovering (1 Day)"
-local GARRISON_FOLLOWER_IN_PARTY=GARRISON_FOLLOWER_IN_PARTY
+-- Name is here just for doc, I will be using the localized one
+
+local abilities={
+ {
+ ["name"] = "Wild Aggression",
+ ["icon"] = "Interface\\ICONS\\Spell_Nature_Reincarnation.blp",
+ }, -- [1]
+ {
+ ["name"] = "Massive Strike",
+ ["icon"] = "Interface\\ICONS\\Ability_Warrior_SavageBlow.blp",
+ }, -- [2]
+ {
+ ["name"] = "Group Damage",
+ ["icon"] = "Interface\\ICONS\\Spell_Fire_SelfDestruct.blp",
+ }, -- [3]
+ {
+ ["name"] = "Magic Debuff",
+ ["icon"] = "Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp",
+ }, -- [4]
+ nil, -- [5]
+ {
+ ["name"] = "Danger Zones",
+ ["icon"] = "Interface\\ICONS\\spell_Shaman_Earthquake.blp",
+ }, -- [6]
+ {
+ ["name"] = "Minion Swarms",
+ ["icon"] = "Interface\\ICONS\\Spell_DeathKnight_ArmyOfTheDead.blp",
+ }, -- [7]
+ {
+ ["name"] = "Powerful Spell",
+ ["icon"] = "Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp",
+ }, -- [8]
+ {
+ ["name"] = "Deadly Minions",
+ ["icon"] = "Interface\\ICONS\\Achievement_Boss_TwinOrcBrutes.blp",
+ }, -- [9]
+ {
+ ["name"] = "Timed Battle",
+ ["icon"] = "Interface\\ICONS\\SPELL_HOLY_BORROWEDTIME.BLP",
+ }, -- [10]
+}
+
+local function getAbilityName(texture)
+ for i=1,#abilities do
+ if (abilities[i] and abilities[i].icon==texture) then
+ return abilities[i].name
+ end
+ end
+ return "unknown"
+end
+--- upvalues
+local AVAILABLE=AVAILABLE -- "Available"
+local BUTTON_INFO=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS.. " " .. GARRISON_MISSION_PERCENT_CHANCE
+local ENVIRONMENT_SUBHEADER=ENVIRONMENT_SUBHEADER -- "Environment"
+local G=C_Garrison
local GARRISON_BUILDING_SELECT_FOLLOWER_TITLE=GARRISON_BUILDING_SELECT_FOLLOWER_TITLE -- "Select a Follower";
local GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP=GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP -- "Click here to assign a Follower";
+local GARRISON_FOLLOWERS=GARRISON_FOLLOWERS -- "Followers"
local GARRISON_FOLLOWER_CAN_COUNTER=GARRISON_FOLLOWER_CAN_COUNTER -- "This follower can counter:"
+local GARRISON_FOLLOWER_EXHAUSTED=GARRISON_FOLLOWER_EXHAUSTED -- "Recovering (1 Day)"
+local GARRISON_FOLLOWER_INACTIVE=GARRISON_FOLLOWER_INACTIVE --"Inactive"
+local GARRISON_FOLLOWER_IN_PARTY=GARRISON_FOLLOWER_IN_PARTY
+local GARRISON_FOLLOWER_ON_MISSION=GARRISON_FOLLOWER_ON_MISSION -- "On Mission"
+local GARRISON_FOLLOWER_WORKING=GARRISON_FOLLOWER_WORKING -- "Working
+local GARRISON_MISSION_PERCENT_CHANCE="%d%%"-- GARRISON_MISSION_PERCENT_CHANCE
local GARRISON_MISSION_SUCCESS=GARRISON_MISSION_SUCCESS -- "Success"
local GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS -- "%d Follower mission";
-local UNKNOWN_CHANCE=GARRISON_MISSION_PERCENT_CHANCE:gsub('%%d%%%%',UNKNOWN)
-local GARRISON_MISSION_PERCENT_CHANCE=GARRISON_MISSION_PERCENT_CHANCE .. " (Estimated)"
-local BUTTON_INFO=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS.. " " .. GARRISON_MISSION_PERCENT_CHANCE
-local GARRISON_FOLLOWERS=GARRISON_FOLLOWERS -- "Followers"
local GARRISON_PARTY_NOT_FULL_TOOLTIP=GARRISON_PARTY_NOT_FULL_TOOLTIP -- "You do not have enough followers on this mission."
-local AVAILABLE=AVAILABLE -- "Available"
+local NOT_COLLECTED=NOT_COLLECTED -- not collected
+local GMF=GarrisonMissionFrame
+local GMFFollowerPage=GMF.FollowerTab
+local GMFFollowers=GarrisonMissionFrameFollowers
+local GMFMissionPage=GMF.MissionTab
+local GMFMissionPageFollowers = GMFMissionPage.MissionPage.Followers
+local GMFMissions=GarrisonMissionFrameMissions
+local GMFMissionsTab1=GarrisonMissionFrameMissionsTab1
+local GMFMissionsTab2=GarrisonMissionFrameMissionsTab2
+local GMFMissionsTab3=GarrisonMissionFrameMissionsTab2
+local GMFRewardPage=GMF.MissionComplete
+local GMFRewardSplash=GMFMissions.CompleteDialog
+local GMFMissionsListScrollFrameScrollChild=GarrisonMissionFrameMissionsListScrollFrameScrollChild
+local GMFMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
+local GMFFollowersListScrollFrameScrollChild=GarrisonMissionFrameFollowersListScrollFrameScrollChild
+local GMFFollowersListScrollFrame=GarrisonMissionFrameFollowersListScrollFrame
+local GMFTab1=GarrisonMissionFrameTab1
+local GMFTab2=GarrisonMissionFrameTab2
+local GMFTab3=GarrisonMissionFrameTab3
+local GarrisonMissionFrameMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
+local IGNORE_UNAIVALABLE_FOLLOWERS=IGNORE.. ' ' .. UNAVAILABLE .. ' ' .. GARRISON_FOLLOWERS
+local IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=IGNORE.. ' ' .. GARRISON_FOLLOWER_INACTIVE .. ',' .. GARRISON_FOLLOWER_ON_MISSION ..',' .. GARRISON_FOLLOWER_WORKING.. ','.. GARRISON_FOLLOWER_EXHAUSTED .. ' ' .. GARRISON_FOLLOWERS
local PARTY=PARTY -- "Party"
-local ENVIRONMENT_SUBHEADER=ENVIRONMENT_SUBHEADER -- "Environment"
-local SPELL_TARGET_TYPE4_DESC=capitalize(SPELL_TARGET_TYPE4_DESC) -- party member
local SPELL_TARGET_TYPE1_DESC=capitalize(SPELL_TARGET_TYPE1_DESC) -- any
+local SPELL_TARGET_TYPE4_DESC=capitalize(SPELL_TARGET_TYPE4_DESC) -- party member
local ANYONE='('..SPELL_TARGET_TYPE1_DESC..')'
-local IGNORE_UNAIVALABLE_FOLLOWERS=IGNORE.. ' ' .. UNAVAILABLE .. ' ' .. GARRISON_FOLLOWERS
-local IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=IGNORE.. ' ' .. GARRISON_FOLLOWER_INACTIVE .. ',' .. GARRISON_FOLLOWER_ON_MISSION ..',' .. GARRISON_FOLLOWER_WORKING.. ','.. GARRISON_FOLLOWER_EXHAUSTED .. ' ' .. GARRISON_FOLLOWERS
+local UNKNOWN_CHANCE=GARRISON_MISSION_PERCENT_CHANCE:gsub('%%d%%%%',UNKNOWN)
IGNORE_UNAIVALABLE_FOLLOWERS=capitalize(IGNORE_UNAIVALABLE_FOLLOWERS)
IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=capitalize(IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL)
+local GARRISON_DURATION_HOURS_MINUTES=GARRISON_DURATION_HOURS_MINUTES
+local GARRISON_DURATION_DAYS_HOURS=GARRISON_DURATION_DAYS_HOURS
+local AGE_HOURS="First seen " .. GARRISON_DURATION_HOURS_MINUTES .. " ago"
+local AGE_DAYS="First seen " .. GARRISON_DURATION_DAYS_HOURS .. " ago"
+local UNKNOWN=UNKNOWN
+local TYPE=TYPE
+-- Panel sizes
+local BIGSIZEW=1400
+local BIGSIZEH=662
+local SIZEW=950
+local SIZEH=662
+local SIZEV
+local GCSIZE=800
+local BIGBUTTON=BIGSIZEW-GCSIZE
+local SMALLBUTTON=BIGSIZEW-GCSIZE
+local GCF
+local GCFMissions
+local GCFBusyStatus
local GameTooltip=GameTooltip
-local GetItemQualityColor=GetItemQualityColor
-local hookedListUpdate
-local timers={}
-function addon:AddLine(icon,name,status,quality,...)
- local r2,g2,b2=C.Red()
- local q=ITEM_QUALITY_COLORS[quality or 1] or {}
- if (status==AVAILABLE) then
- r2,g2,b2=C.Green()
- elseif (status==GARRISON_FOLLOWER_WORKING) then
- r2,g2,b2=C.Orange()
- end
- --GameTooltip:AddDoubleLine(name, status or AVAILABLE,r,g,b,r2,g2,b2)
- --GameTooltip:AddTexture(icon)
- GameTooltip:AddDoubleLine(icon and "|T" .. tostring(icon) .. ":0|t " .. name or name, status,q.r,q.g,q.b,r2,g2,b2)
-end
+-- Want to know what I call!!
+local GarrisonMissionButton_OnEnter=GarrisonMissionButton_OnEnter
+local GarrisonFollowerList_UpdateFollowers=GarrisonFollowerList_UpdateFollowers
+local GarrisonMissionList_UpdateMissions=GarrisonMissionList_UpdateMissions
+local GarrisonMissionPage_ClearFollower=GarrisonMissionPage_ClearFollower
+local GarrisonMissionPage_UpdateMissionForParty=GarrisonMissionPage_UpdateMissionForParty
+local GarrisonMissionPage_SetFollower=GarrisonMissionPage_SetFollower
+local GetItemInfo=GetItemInfo
+local type=type
+local ITEM_QUALITY_COLORS=ITEM_QUALITY_COLORS
+local deadly={r=C.Purple.r,g=C.Purple.g,b=C.Purple.b}
function addon:GetDifficultyColor(perc)
- local difficulty='trivial'
if(perc >90) then
- difficulty='standard'
+ return QuestDifficultyColors['standard']
elseif (perc >74) then
- difficulty='difficult'
+ return QuestDifficultyColors['difficult']
elseif(perc>49) then
- difficulty='verydifficult'
+ return QuestDifficultyColors['verydifficult']
elseif(perc >20) then
- difficulty='impossible'
- end
- return QuestDifficultyColors[difficulty]
-end
-function addon:RestoreTooltip()
- local self = GMF.MissionTab.MissionList;
- local scrollFrame = self.listScroll;
- local buttons = scrollFrame.buttons;
- for i =1,#buttons do
- buttons[i]:SetScript("OnEnter",GarrisonMissionButton_OnEnter)
+ return QuestDifficultyColors['impossible']
+ else
+ return QuestDifficultyColors['trivial']
end
end
-local openParty,isInParty,pushFollower,closeParty,roomInParty
+if (LibDebug) then LibDebug() end
+----- Local variables
+--
+local t0={
+ __index=function(t,k) rawset(t,k,{}) return t[k] end
+}
+
+local t1={
+ __index=function(t,k) rawset(t,k,setmetatable({},t0)) return t[k] end
+}
+local t2={
+ __index=function(t,k) rawset(t,k,setmetatable({},t1)) return t[k] end
+}
+local masterplan
+local availableFollowers=0 -- Total numner of non in mission followers
+local followersCache={}
+local followersCacheIndex={}
+local dirty=false
+local cache
+local dbcache
+local timers={}
+local counters=setmetatable({},t0)
+local counterThreatIndex=setmetatable({},t2)
+local counterFollowerIndex=setmetatable({},t2)
+local onMission={}
+
+--- Parties storage
+--
+--
+local parties=setmetatable({},{
+ __index=function(t,k) rawset(t,k,{members={},perc=0,full=false}) return t[k] end
+})
+
+--- Follower Missions Info
+--
+local followerMissions=setmetatable({},{
+ __index=function(t,k) rawset(t,k,{}) return t[k] end
+})
+--- Counters Info per mission
+--
+
+local counters=setmetatable({},{
+ __index=function(t,k) rawset(t,k,{}) return t[k] end
+})
+
+
+-----------------------------------------------------
+-- Coroutines data
+-------------
+local coroutines={
+ Timers={
+ func=false,
+ elapsed=60,
+ interval=10,
+ paused=false
+ },
+ Drawer={
+ func=false,
+ elapsed=0,
+ interval=1,
+ paused=false
+ }
+}
+--
+-- Temporary party management
+local openParty,isInParty,pushFollower,removeFollower,closeParty,roomInParty,storeFollowers
do
- local ID,frames=0,nil
- local members={}
- local max=1
- function openParty(missionID,maxfollowers)
- max=maxfollowers
- local frames={GetFramesRegisteredForEvent('GARRISON_FOLLOWER_LIST_UPDATE')}
+ local ID,frames,members,maxFollowers=0,{},{},1
+ ---@function [parent=#local] openParty
+ function openParty(missionID,followers)
+ if (#frames > 0 or #members > 0) then
+ error(format("Unbalanced openParty/closeParty %d %d",#frames,#members))
+ end
+ maxFollowers=followers
+ frames={GetFramesRegisteredForEvent('GARRISON_FOLLOWER_LIST_UPDATE')}
for i=1,#frames do
frames[i]:UnregisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
end
ID=missionID
end
+ ---@function [parent=#local] isInParty
function isInParty(followerID)
- for i=1,maxfollowers do
+ for i=1,maxFollowers do
if (followerID==members[i]) then return true end
end
end
+ ---@function [parent=#local] roomInParty
function roomInParty()
- return not members[max]
+ return not members[maxFollowers]
end
+ ---@function [parent=#local] pushFollower
function pushFollower(followerID)
+ if (followerID:sub(1,2) ~= '0x') then error(followerID .. "is not an id") end
if (roomInParty()) then
local rc,code=pcall (C_Garrison.AddFollowerToMission,ID,followerID)
if (rc and code) then
tinsert(members,followerID)
return true
+--@debug@
+ else
+ print("Error adding ", followerID,"to",ID,code)
+--@end-debug@
end
end
end
+ ---@function [parent=#local] removeFollowers
+ function removeFollower(followerID)
+ for i=1,maxFollowers do
+ if (followerID==members[i]) then
+ tremove(members,i)
+ local rc,code=pcall(C_Garrison.RemoveFollowerFromMission,ID,followerID)
+--@debug@
+ if (not rc) then xprint("Error removing", members[i],"from",ID,code) end
+--@end-debug@
+ return true end
+ end
+ end
+
+ ---@function [parent=#local] storeFollowers
+ function storeFollowers(table)
+ wipe(table)
+ for i=1,#members do
+ tinsert(table,members[i])
+ end
+ return #table
+ end
+
+ ---@function [parent=#local] closeParty
function closeParty()
+ local perc=select(4,G.GetPartyMissionInfo(ID))
for i=1,3 do
if (members[i]) then
- C_Garrison.RemoveFollowerFromMission(ID,members[i])
+ local rc,code=pcall(C_Garrison.RemoveFollowerFromMission,ID,members[i])
+--@debug@
+ if (not rc) then xprint("Error popping ", members[i]," from ",ID,code) end
+--@end-debug@
+
else
break
end
end
- if (frames) then
- for i=1,#frames do
- frames[i]:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
- end
+ for i=1,#frames do
+ frames[i]:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
end
- frames=nil
+ wipe(frames)
wipe(members)
+ return perc
+ end
+end
+-- ProgressBar
+
+function addon:AddLine(icon,name,status,quality,...)
+ local r2,g2,b2=C.Red()
+ local q=ITEM_QUALITY_COLORS[quality or 1] or {}
+ if (status==AVAILABLE) then
+ r2,g2,b2=C.Green()
+ elseif (status==GARRISON_FOLLOWER_WORKING) then
+ r2,g2,b2=C.Orange()
+ end
+ --GameTooltip:AddDoubleLine(name, status or AVAILABLE,r,g,b,r2,g2,b2)
+ --GameTooltip:AddTexture(icon)
+ GameTooltip:AddDoubleLine(icon and "|T" .. tostring(icon) .. ":0|t " .. name or name, status,q.r,q.g,q.b,r2,g2,b2)
+end
+
+
+function addon:RestoreTooltip()
+ local self = GMF.MissionTab.MissionList;
+ local scrollFrame = self.listScroll;
+ local buttons = scrollFrame.buttons;
+ for i =1,#buttons do
+ buttons[i]:SetScript("OnEnter",GarrisonMissionButton_OnEnter)
+ end
+end
+
+
+
+--[[
+ [12]={
+ description="Iron Horde raiders have descended on nearby draenei villages. Find the raiders' camp and raid it. Turnabout, they say, is fair play.",
+ cost=15,
+ duration="4 hr",
+ slots={
+ ["Minion Swarms"]=1,
+ Type=1,
+ ["Deadly Minions"]=1
+ },
+ durationSeconds=14400,
+ party={
+ party2="<empty>",
+ party1="<empty>"
+ },
+ level=100,
+ type="Combat",
+ counters={
+ ["0x00000000001BE95D"]={
+ [1]={
+ counterIcon="Interface\\ICONS\\Ability_Rogue_FanofKnives.blp",
+ name="Minion Swarms",
+ counterName="Fan of Knives",
+ icon="Interface\\ICONS\\Spell_DeathKnight_ArmyOfTheDead.blp",
+ description="An enemy with many allies. Susceptible to area-of-effect damage."
+ }
+ },
+ ["0x00000000002D61EB"]={
+ [1]={
+ counterIcon="Interface\\ICONS\\Spell_Shaman_Hex.blp",
+ name="Deadly Minions",
+ counterName="Hex",
+ icon="Interface\\ICONS\\Achievement_Boss_TwinOrcBrutes.blp",
+ description="An enemy with powerful allies that should be neutralized."
+ }
+ }
+ },
+ traits={
+ ["0x00000000001BE95D"]={
+ [1]={
+ traitID=236,
+ icon="Interface\\ICONS\\Item_Hearthstone_Card.blp"
+ }
+ }
+ },
+ locPrefix="GarrMissionLocation-Nagrand",
+ rewards={
+ [795]={
+ itemID=120301,
+ quantity=1
+ }
+ },
+ numRewards=1,
+ numFollowers=2,
+ state=-2,
+ iLevel=0,
+ name="Raiding the Raiders",
+ followers={
+ },
+ location="Nagrand",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=380
+ }
+}
+--]]
+-- True manda a davani
+local function cmp(a,b)
+
+ if (a.mechanic and b.trait) then return true end
+ if (a.trait and b.mechanic) then return false end
+ if (a.name==a.name) then
+ if a.bias==b.bias then
+ if (a.rank==b.rank) then
+ return a.quality < b.quality
+ else
+ return a.rank < b.rank
+ end
+ else
+ return a.bias > b.bias
+ end
+ else
+ return a.name < b.name
+ end
+ --if (a.name~=b.name) then return a.name < b.name end
+ --if (a.bias==-1) then return false end
+ --if (b.bias==-1) then return true end
+ --if (a.bias~=b.bias) then return (a.bias>b.bias) end
+ --if (a.rank ~= b.rank) then return (a.rank < b.rank) end
+ return a.quality < b.quality
+end
+
+function addon:FillCounters(missionID,mission)
+ if (not mission) then mission=self:GetMissionData(missionID) end
+ local slots=mission.slots
+ local missioncounters=counters[missionID]
+ wipe(missioncounters)
+ for id,d in pairs(G.GetBuffedFollowersForMission(missionID)) do
+ local rank=self:GetFollowerData(id,'rank')
+ local quality=self:GetFollowerData(id,'quality')
+ local bias= G.GetFollowerBiasForMission(missionID,id);
+ for i,l in pairs(d) do
+ -- i is meaningful
+ -- l.counterIcon
+ -- l.name
+ -- l.counterName
+ -- l.icon
+ -- l.description
+ tinsert(missioncounters,{mechanic=true,name=l.name,followerID=id,bias=bias,rank=rank,quality=quality,icon=l.icon})
+ followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
+ end
+ end
+ for id,d in pairs(G.GetFollowersTraitsForMission(missionID)) do
+ local level=self:GetFollowerData(id,'level')
+ local bias= G.GetFollowerBiasForMission(missionID,id);
+ local rank=self:GetFollowerData(id,'rank')
+ local quality=self:GetFollowerData(id,'quality')
+ for i,l in pairs(d) do
+ --l.traitID
+ --l.icon
+ followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
+ tinsert(missioncounters,{trait=true,name=l.icon,followerID=id,bias=bias,rank=rank,quality=quality,icon=l.icon})
+ end
+ end
+ table.sort(missioncounters,cmp)
+ local cf=counterFollowerIndex[missionID]
+ local ct=counterThreatIndex[missionID]
+ for i=1,#missioncounters do
+ tinsert(cf[missioncounters[i].followerID],i)
+ tinsert(ct[missioncounters[i].icon],i)
+ end
+end
+function addon:Check(missionID)
+
+end
+function addon:ThreatDisplayer()
+ TF="0x00000000000C2C1B"
+ if (not AXE) then
+ local AXE=CreateFrame("Frame","AXE",UIParent,"GarrisonAbilityLargeCounterTemplate")
+ AXI=CreateFrame("Frame","AXI",UIParent,"GarrisonAbilityCounterTemplate")
+ end
+ if (not BUBU) then
+ CreateFrame("CheckButton","BUBU",AXE,"UICheckButtonTemplate")
+ end
+
+ BUBU:SetPoint("CENTER")
+ BUBU:SetChecked(true)
+ BUBU:GetCheckedTexture():SetVertexColor(1,0,0)
+
+ AXE:SetPoint("CENTER",-100.0)
+ AXI:SetPoint("CENTER",100,0)
+ AXE:Show()
+ AXI:Show()
+ local id=154
+ local env=select(5,C_Garrison.GetMissionInfo(id))
+ AXI.Icon:SetTexture(env)
+ AXI.Border:SetVertexColor(1,0,0)
+end
+--[[
+Matchmaker debug for Spell Check
+Slots
+["Danger Zones"]=1,
+Type="Interface\\ICONS\\Achievement_Reputation_Ogre.blp",
+["Interface\\ICONS\\Achievement_Reputation_Ogre.blp"]=1,
+["Powerful Spell"]=1
+[1]={
+ name="Danger Zones",
+ icon="Interface\\ICONS\\spell_Shaman_Earthquake.blp",
+ quality=4,
+ bias=-0.66666668653488,
+ follower="0x00000000002D57C4",
+ rank=96
+},
+[2]={
+ name="Interface\\ICONS\\Achievement_Reputation_Ogre.blp",
+ icon="Interface\\ICONS\\Achievement_Reputation_Ogre.blp",
+ quality=4,
+ bias=0.66666668653488,
+ follower="0x00000000001978B6",
+ rank=600
+},
+[3]={
+ name="Interface\\ICONS\\Achievement_Reputation_Ogre.blp",
+ icon="Interface\\ICONS\\Achievement_Reputation_Ogre.blp",
+ quality=4,
+ bias=-0.66666668653488,
+ follower="0x00000000002D57C4",
+ rank=96
+},
+[4]={
+ name="Interface\\ICONS\\Item_Hearthstone_Card.blp",
+ icon="Interface\\ICONS\\Item_Hearthstone_Card.blp",
+ quality=2,
+ bias=0.66666668653488,
+ follower="0x00000000001BE95D",
+ rank=600
+}
+Preparying party
+Considering Shelly Hamby for Danger Zones
+Considering Qiana Moonshadow for Interface\ICONS\Achievement_Reputation_Ogre.blp
+Considering Shelly Hamby for Interface\ICONS\Achievement_Reputation_Ogre.blp
+Considering Bruma Swiftstone for Interface\ICONS\Item_Hearthstone_Card.blp
+Dopo check per nil
+["Danger Zones"]={
+},
+["Interface\\ICONS\\Achievement_Reputation_Ogre.blp"]={
+},
+["Interface\\ICONS\\Item_Hearthstone_Card.blp"]={
+}
+Party filling
+Party is not full
+Verifying Delvar Ironfist 0 600 3
+Verifying Rangari Chel 0 91 3
+Party filling
+Party is not full
+Verifying Rangari Chel 0 91 3
+Party filling
+Matchmaker end
+
+--]]
+--[[
+Button fields
+LocBG table
+HighlightBR table
+Highlight table
+inProgressFresh boolean
+Party table
+gcPANEL table
+HighlightB table
+HighlightTR table
+Level table
+Expire table
+MissionType table
+Overlay table
+info table
+ItemLevel table
+id number
+HighlightBL table
+Rewards table
+Threats table
+HighlightT table
+0 userdata
+RareText table
+IconBG table
+Title table
+Projections table
+RareOverlay table
+Summary table
+HighlightTL table
+--]]
+local function best(fid1,fid2,counters)
+ if (not fid1) then return fid2 end
+ if (not fid2) then return fid1 end
+ local f1,f2=counters[fid1],counters[fid2]
+ if (isInParty(f1.followerID)) then return fid1 end
+ if (f2.bias<0) then return fid1 end
+ if (f2.bias>f1.bias) then return fid2 end
+ if (f1.bias == f2.bias) then
+ if (f2.quality < f1.quality or f2.rank < f1.rank) then return fid2 end
+ end
+ return fid1
+end
+function addon:MatchMaker(missionID,mission,party,skipbusy)
+ if (not mission) then return end
+ if (GMFRewardSplash:IsShown()) then return end
+ local dbg=missionID==(tonumber(_G.MW) or 0)
+ if (not skipbusy) then
+ skipbusy=self:GetBoolean("IGM")
+ end
+ local ignoreMaxed=self:GetBoolean("IGP")
+ local slots=mission.slots
+ local missionCounters=counters[missionID]
+ local ct=counterThreatIndex[missionID]
+ local skipbusy=addon:GetBoolean("IGM")
+ openParty(missionID,mission.numFollowers)
+ for i=1,#slots do
+ local threat=slots[i].icon
+ local candidates=ct[threat]
+ local choosen
+ for i=1,#candidates do
+ if (addon:GetFollowerStatusForMission(missionCounters[candidates[i]].followerID,skipbusy)) then
+ choosen=best(choosen,candidates[i],missionCounters)
+ end
+ end
+ if (choosen) then
+ if (type(missionCounters[choosen]) ~="table") then
+ error (format("%s %s %d %d",mission.name,threat,missionID,tonumber(choosen) or 0))
+ end
+ pushFollower(missionCounters[choosen].followerID)
+ end
+ if (not roomInParty()) then
+ break
+ end
+ end
+ storeFollowers(party.members)
+ party.full= not roomInParty()
+ party.perc=closeParty()
+end
+function addon:MatchMaker1(missionID,mission,party,skipbusy)
+ if (not mission) then return end
+ if (GMFRewardSplash:IsShown()) then return end
+ local dbg=missionID==(tonumber(_G.MW) or 0)
+ if (not skipbusy) then
+ skipbusy=self:GetBoolean("IGM")
+ end
+ local ignoreMaxed=self:GetBoolean("IGP")
+ local slots=mission.slots
+ if (slots) then
+ wipe(mission.countered)
+ local countered=mission.countered
+ openParty(missionID,mission.numFollowers)
+ for i=1,#counters do
+ local f=counters[i]
+ local menace=f.name
+ if (#countered[menace] == 0) then
+ if (roomInParty() and self:GetFollowerStatusForMission(f.follower,skipbusy) and pushFollower(f.follower)) then
+ tinsert(countered[menace],f.follower)
+ end
+ end
+ end
+ local perc=select(4,G.GetPartyMissionInfo(missionID)) -- If percentage is already 100, I'll try and add the most useless character
+ local candidateMissions=10000
+ local candidateRank=10000
+ local candidateQuality=9999
+ for x=1,3 do
+ if (not roomInParty()) then break end
+ local candidate
+ local candidatePerc=perc
+ for _,data in pairs(followersCache) do
+ local followerID=data.followerID
+ if (not isInParty(followerID) and self:GetFollowerStatusForMission(followerID,skipbusy)) then
+ local missions=#followerMissions[followerID]
+ local rank=data.rank
+ local quality=data.quality
+ xprint(dbg,"Verifying",self:GetFollowerData(followerID,'name'),missions,rank,quality)
+ repeat
+ if (mission.numFollowers==1 and mission.xp and quality>4) then break end -- Pointless using a maxed follower for an xp only mission
+ if (perc<=100) then
+ pushFollower(followerID)
+ local newperc=select(4,G.GetPartyMissionInfo(missionID))
+ removeFollower(followerID)
+ if (newperc > candidatePerc) then
+ candidatePerc=newperc
+ candidate=followerID
+ candidateMissions=missions
+ candidateRank=rank
+ candidateQuality=quality
+ break -- continue
+ elseif (newperc < candidatePerc) then
+ break --continue
+ end
+ end
+ if (missions<candidateMissions) then
+ candidate=followerID
+ candidateMissions=missions
+ candidateRank=rank
+ candidateQuality=quality
+ elseif(missions==candidateMissions and rank<candidateRank) then
+ candidate=followerID
+ candidateMissions=missions
+ candidateRank=rank
+ candidateQuality=quality
+ elseif(missions==candidateMissions and rank==candidateRank and quality<candidateQuality) then
+ candidate=followerID
+ candidateMissions=missions
+ candidateRank=rank
+ candidateQuality=quality
+ end
+ until true -- A poor man continue implementation using break
+ end
+ end
+ if (candidate) then
+ pushFollower(candidate)
+ perc=select(4,G.GetPartyMissionInfo(missionID))
+ end
+
+ end
+ storeFollowers(party.members)
+ party.full= not roomInParty()
+ party.perc=closeParty()
+ end
+end
+function addon:TooltipAdder(missionID)
+ local mission=self:GetMissionData(missionID)
+ local button=GetMouseFocus()
+--@debug@
+ GameTooltip:AddLine("ID:" .. tostring(missionID))
+ if (not mission) then GameTooltip:AddLine("E dove minchia è finita??") return end
+ _G.MISSION=mission
+--@end-debug@
+ local f=GarrisonMissionListTooltipThreatsFrame
+ if (not f.Env) then
+ f.Env=CreateFrame("Frame",nil,f,"GarrisonAbilityCounterTemplate")
+ f.Env:SetWidth(20)
+ f.Env:SetHeight(20)
+ f.Env:SetPoint("LEFT",f)
+ end
+ local t=f.EnvIcon:GetTexture();
+ f.EnvIcon:Hide()
+ --f.Env.Icon:SetTexture("Interface\\ICONS\\Achievement_ZoneSilverpine_01")
+ f.Env.Icon:SetTexture(t)
+ f.Env.Icon:SetWidth(20)
+ f.Env.Icon:SetHeight(20)
+ if (type(mission.counterers[t])=="table") then
+ if (#mission.counterers[t]>0) then
+ f.Env.Border:SetVertexColor(0,1,0)
+ else
+ f.Env.Border:SetVertexColor(1,0,0)
+ end
+ f.Env.Icon:Show()
+ f.Env.Border:Show()
+ f:Raise()
+ f.Env:Show()
+ else
+ f.Env:Hide()
+ end
+--[[
+ if (not f.EnvIcon.Mark) then
+ local ck=CreateFrame("CheckButton",nil,f.EnvIcon,"UICheckButtonTemplate")
+ ck:SetPoint("CENTER")
+ ck:SetChecked(true)
+ ck:GetCheckedTexture():SetVertexColor(0,1,0)
+ f.EnvIcon.Marck=ck
+ ck:Show()
+ end
+--]]
+ GameTooltip:AddDoubleLine(t,"Environment")
+ for i=1,#f.Threats do
+ local t=f.Threats[i]
+ GameTooltip:AddDoubleLine(t.Icon:GetTexture(),getAbilityName(t.Icon:GetTexture()))
+ end
+ GameTooltip:AddLine("Countered")
+ for k,v in pairs(mission.countered) do
+ GameTooltip:AddLine(k,C.Green())
+ for kk,vv in pairs(v) do
+ GameTooltip:AddDoubleLine(kk,vv)
+ end
+ end
+ if (button.fromFollowerPage) then
+ GameTooltip:AddLine(L["Only first 7 missions with over 60% success chance are shown"],C.Orange())
end
end
--- This is a ugly hack while I rewrite this code for 2.0
-function addon:TooltipAdder(missionID,skipTT)
+function addon:_TooltipAdder(missionID,skipTT)
--@debug@
if (not skipTT) then GameTooltip:AddLine("ID:" .. tostring(missionID)) end
--@end-debug@
+ self:MatchMaker(missionID)
+ local perc=select(4,G.GetPartyMissionInfo(missionID))
self:GetRunningMissionData()
- local perc=select(4,C_Garrison.GetPartyMissionInfo(missionID))
local q=self:GetDifficultyColor(perc)
if (not skipTT) then GameTooltip:AddDoubleLine(GARRISON_MISSION_SUCCESS,format(GARRISON_MISSION_PERCENT_CHANCE,perc),nil,nil,nil,q.r,q.g,q.b) end
local buffed=new()
@@ -207,11 +851,12 @@ function addon:TooltipAdder(missionID,skipTT)
local buffs=new()
local traits=new()
local fellas=new()
- local fullname=new()
- for id,d in pairs(C_Garrison.GetBuffedFollowersForMission(missionID)) do
+ availableFollowers=0
+ self:GetRunningMissionData()
+ for id,d in pairs(G.GetBuffedFollowersForMission(missionID)) do
buffed[id]=d
end
- for id,d in pairs(C_Garrison.GetFollowersTraitsForMission(missionID)) do
+ for id,d in pairs(G.GetFollowersTraitsForMission(missionID)) do
for x,y in pairs(d) do
--@debug@
self.db.global.traits[y.traitID]=y.icon
@@ -222,22 +867,22 @@ function addon:TooltipAdder(missionID,skipTT)
end
end
end
- availableFollowers=0
- for index=1,#followers do
+ local followerList=GarrisonMissionFrameFollowers.followersList
+
+ for j=1,#followerList do
+ local index=followerList[j]
local follower=followers[index]
follower.rank=follower.level < 100 and follower.level or follower.iLevel
if (not follower.isCollected) then break end
- follower.status=C_Garrison.GetFollowerStatus(follower.followerID)
- followers[index].status=follower.status
if (not follower.status) then
availableFollowers=availableFollowers+1
end
- if (follower.status and skipBusy) then
+ if (follower.status and self:GetBoolean('IGM')) then
else
local id=follower.followerID
local b=buffed[id]
local t=traited[id]
- local followerBias = C_Garrison.GetFollowerBiasForMission(missionID,id);
+ local followerBias = G.GetFollowerBiasForMission(missionID,id);
follower.bias=followerBias
local formato=C("%3d","White")
if (followerBias==-1) then
@@ -251,72 +896,61 @@ function addon:TooltipAdder(missionID,skipTT)
--@end-debug@
if (b) then
if (not buffs[id]) then
- buffs[id]=index
- fullname[id]=format(formato,follower.rank,follower.name)
+ buffs[id]={rank=follower.rank,simple=follower.name,name=format(formato,follower.rank,follower.name),quality=follower.quality,status=(follower.status or AVAILABLE)}
end
for _,ability in pairs(b) do
- fullname[id]=fullname[id] .. " |T" .. tostring(ability.icon) .. ":0|t"
- if (not follower.status or not skipBusy) then
+ buffs[id].name=buffs[id].name .. " |T" .. tostring(ability.icon) .. ":0|t"
+ if (not follower.status) then
local aname=ability.name
- if (tonumber(fellas[aname])) then
- local previous=followers[tonumber(fellas[aname])]
- if (previous.rank>=follower.rank) then
- break
- end
+ if (not fellas[aname]) then
+ fellas[aname]={}
end
- fellas[aname]=index
+ fellas[aname]={id=follower.followerID,rank=follower.rank,level=follower.level,iLevel=follower.iLevel,name=follower.name}
end
end
end
if (t) then
if (not traits[id]) then
- traits[id]=index
- fullname[id]=format(formato,follower.rank,follower.name)
+ traits[id]={rank=follower.rank,simple=follower.name,name=format(formato,follower.rank,follower.name),quality=follower.quality,status=follower.status or AVAILABLE}
end
for _,ability in pairs(t) do
- fullname[id]=fullname[id] .. " |T" .. tostring(ability.icon) .. ":0|t"
+ traits[id].name=traits[id].name .. " |T" .. tostring(ability.icon) .. ":0|t"
end
end
end
end
- local maxfollowers=C_Garrison.GetMissionMaxFollowers(missionID)
+ local added=new()
+ local maxfollowers=G.GetMissionMaxFollowers(missionID)
requested[missionID]=maxfollowers
local partyshown=false
local perc=0
- local menaces=0
- openParty(missionID,maxfollowers)
if (next(traits) or next(buffs) ) then
if (not skipTT) then GameTooltip:AddLine(GARRISON_FOLLOWER_CAN_COUNTER) end
- for id,i in pairs(buffs) do
- local v=followers[i]
+ for id,v in pairs(buffs) do
local status=(v.status == GARRISON_FOLLOWER_ON_MISSION and (timers[id] or GARRISON_FOLLOWER_ON_MISSION)) or v.status
- if (not skipTT) then self:AddLine(nil,fullname[id],status or AVAILABLE,v.quality) end
+ if (not skipTT) then self:AddLine(nil,v.name,status,v.quality) end
end
- for id,i in pairs(traits) do
- local v=followers[i]
+ for id,v in pairs(traits) do
local status=(v.status == GARRISON_FOLLOWER_ON_MISSION and (timers[id] or GARRISON_FOLLOWER_ON_MISSION)) or v.status
- if (not skipTT) then self:AddLine(nil,fullname[id],status or AVAILABLE,v.quality) end
+ if (not skipTT) then self:AddLine(nil,v.name,status,v.quality) end
end
if (not skipTT) then GameTooltip:AddLine(PARTY,C.White()) end
partyshown=true
- local enemies = select(8,C_Garrison.GetMissionInfo(missionID))
- --local missionInfo=C_Garrison.GetBasicMissionInfo(missionID)
+ local enemies = select(8,G.GetMissionInfo(missionID))
+ --local missionInfo=G.GetBasicMissionInfo(missionID)
--@debug@
--DevTools_Dump(fellas)
--@end-debug@
for _,enemy in pairs(enemies) do
for i,mechanic in pairs(enemy.mechanics) do
---@debug@
- self.db.global.abilities[i .. '.' .. mechanic.name]=mechanic.description
---@end-debug@
local menace=mechanic.name
local res
- menaces=menaces+1
if (fellas[menace]) then
- local follower=followers[fellas[menace]]
- if (follower.status and skipBusy) then
- elseif (pushFollower(follower.followerID)) then
- res=fullname[follower.followerID]
+ local followerID=fellas[menace].id
+ res=fellas[menace].name
+ local rc,code=pcall(G.AddFollowerToMission,missionID,followerID)
+ if (rc and code) then
+ tinsert(added,followerID)
end
end
if (not skipTT) then
@@ -328,35 +962,50 @@ function addon:TooltipAdder(missionID,skipTT)
end
end
end
- if (roomInParty() and next(traits)) then
- for id,i in pairs(traits) do
- local follower=followers[i]
- if (follower.status and skipBusy) then
- elseif (pushFollower(id)) then
- if (not skipTT) then GameTooltip:AddDoubleLine(ENVIRONMENT_SUBHEADER,fullname[id],0,1,0) end
+ perc=select(4,G.GetPartyMissionInfo(missionID))
+ if (perc < 100 and #added < maxfollowers and next(traits)) then
+ for id,v in pairs(traits) do
+ local rc,code=pcall(G.AddFollowerToMission,missionID,id)
+ if (rc and code) then
+ tinsert(added,id)
+ if (not skipTT) then GameTooltip:AddDoubleLine(ENVIRONMENT_SUBHEADER,v.simple,v.quality) end
break
end
end
+ perc=select(4,G.GetPartyMissionInfo(missionID))
end
end
-- And then fill the roster
- if (roomInParty()) then
- for index=1,#followers do
+ local partysize=#added
+ if (partysize < maxfollowers ) then
+ for j=1,#followerList do
+ local index=followerList[j]
local follower=followers[index]
- if (follower.status and skipBusy) then
- elseif (pushFollower(follower.followerID)) then
- if (not partyshown) then
- if (not skipTT) then GameTooltip:AddLine(PARTY,1) end
- partyshown=true
- end
- if (not skipTT) then
- GameTooltip:AddDoubleLine(SPELL_TARGET_TYPE4_DESC,follower.name,C.Orange.r,C.Orange.g,C.Orange.b)--SPELL_TARGET_TYPE1_DESC)
+ if (not follower.isCollected) then
+ break
+ end
+ if (follower.status and self:GetBoolean('IGM')) then
+ else
+ local rc,code=pcall(G.AddFollowerToMission,missionID,follower.followerID)
+ if (rc and code) then
+ if (not partyshown) then
+ if (not skipTT) then GameTooltip:AddLine(PARTY,1) end
+ partyshown=true
+ end
+ tinsert(added,follower.followerID)
+ if (not skipTT) then
+ GameTooltip:AddDoubleLine(SPELL_TARGET_TYPE4_DESC,follower.name,C.Orange.r,C.Orange.g,C.Orange.b)--SPELL_TARGET_TYPE1_DESC)
+ end
+ if (#added >= maxfollowers) then break end
+ else
+--@debug@
+ xprint("Failed adding",follower.name,follower.followerID,rc,code)
+--@end-debug@
end
- if (not roomInParty()) then break end
end
end
+ perc=select(4,G.GetPartyMissionInfo(missionID))
end
- perc=select(4,C_Garrison.GetPartyMissionInfo(missionID))
local q=self:GetDifficultyColor(perc)
if (not partyshown) then
if (not skipTT) then GameTooltip:AddDoubleLine(PARTY,ANYONE,C.White.r,C.White.g,C.White.b) end
@@ -364,15 +1013,21 @@ function addon:TooltipAdder(missionID,skipTT)
if (not skipTT) then GameTooltip:AddDoubleLine(GARRISON_MISSION_SUCCESS,format(GARRISON_MISSION_PERCENT_CHANCE,perc),nil,nil,nil,q.r,q.g,q.b) end
local b=GameTooltip:GetOwner()
successes[missionID]=perc
- threats[missionID]=menaces
if (availableFollowers < maxfollowers) then
if (not skipTT) then GameTooltip:AddLine(GARRISON_PARTY_NOT_FULL_TOOLTIP,C:Red()) end
+ else
+ end
+ if (not skipTT) then self:AddPerc(GameTooltip:GetOwner()) end
+ for _,id in pairs(added) do
+ local rc,code=pcall(G.RemoveFollowerFromMission,missionID,id)
+--@debug@
+ if (not rc) then xprint("Add",rc,code) end
+--@end-debug@
end
- --if (not skipTT) then self:AddPerc(GameTooltip:GetOwner()) end
- closeParty()
-- Add a signature
--local r,g,b=C:Silver()
--GameTooltip:AddDoubleLine("GarrisonCommander",self.version,r,g,b,r,g,b)
+ del(added)
--@debug@
--DevTools_Dump(fellas)
--@end-debug@
@@ -384,55 +1039,80 @@ function addon:TooltipAdder(missionID,skipTT)
end
function addon:FillFollowersList()
if (GarrisonFollowerList_UpdateFollowers) then
- GarrisonFollowerList_UpdateFollowers(GarrisonMissionFrame.FollowerList)
- end
-end
-function addon:CacheFollowers()
- followers=C_Garrison.GetFollowers()
- for i=1,#followers do
- if (not followers[i].isCollected) then
- followers[i]=nil
- end
+ GarrisonFollowerList_UpdateFollowers(GMF.FollowerList)
end
end
-function addon:GetRunningMissionData()
- local list=GarrisonMissionFrame.MissionTab.MissionList
- C_Garrison.GetInProgressMissions(list.inProgressMissions);
- --C_Garrison.GetAvailableMissions(list.availableMissions);
- if (#list.inProgressMissions > 0) then
- for i,mission in pairs(list.inProgressMissions) do
- for _,id in pairs(mission.followers) do
- timers[id]=mission.timeLeft
- end
+local function switch(flag)
+ if (GCF[flag]) then
+ local b=GCF[flag]
+ if (b:GetChecked()) then
+ b.text:SetTextColor(C.Green())
+ else
+ b.text:SetTextColor(C.Silver())
end
end
end
-function addon:ADDON_LOADED(event,addon)
- if (addon=="Blizzard_GarrisonUI") then
- self:UnregisterEvent("ADDON_LOADED")
- self:Init()
- end
-end
function addon:ApplyIGM(value)
- skipBusy=value
if (not GMF) then return end
- if (skipBusy) then
- GMF.GCIgnore.text:SetTextColor(C:Green())
+ switch("IGM")
+ dirty=true
+ self:RefreshMissions("Checked")
+end
+function addon:ApplyIGP(value)
+ if (not GMF) then return end
+ switch("IGP")
+ dirty=true
+ self:RefreshMissions("Checked")
+end
+function addon:GMF_OnDragStart(frame)
+ if (not self:GetBoolean('MOVEPANEL')) then return end
+ frame.IsSizingOrMoving=true
+ if (IsShiftKeyDown()) then
+ frame.IsSizing=true
+ frame:StartSizing("BOTTOMRIGHT")
+ frame:SetScript("OnUpdate",function(frame,elapsed)
+ if (frame.timepassed and frame.timepassed >1) then
+ self:RefreshMissions()
+ else
+ frame.timepassed=frame.timepassed or 0
+ frame.timepassed=frame.timepassed +elapsed
+ end
+ end)
else
- GMF.GCIgnore.text:SetTextColor(C:Red())
+ frame.IsSizing=nil
+ frame:StartMoving()
+ end
+end
+function addon:GMF_OnDragStop(frame)
+ frame:StopMovingOrSizing()
+ frame:SetScript("OnUpdate",nil)
+ if (frame.IsSizing) then
+ BIGSIZEW=frame:GetWidth()
+ SIZEV=frame:GetHeight()
+ BIGBUTTON=min(BIGSIZEW*0.55,BIGSIZEW-GCSIZE)
+ SMALLBUTTON=BIGBUTTON
+ if (not self:IsFollowerList()) then
+ HybridScrollFrame_CreateButtons(frame.MissionTab.MissionList.listScroll, "GarrisonMissionListButtonTemplate", 13, -8, nil, nil, nil, -4);
+ GarrisonMissionList_Update();
+ else
+ HybridScrollFrame_CreateButtons(frame.FollowerList.listScroll, "GarrisonMissionFollowerButtonTemplate", 7, -7, nil, nil, nil, -6);
+ end
end
- self:RefreshMissions()
+ frame.IsSizing=nil
+ frame.IsSizingOrMoving=nil
end
function addon:ApplyMOVEPANEL(value)
if (not GMF) then return end
+ switch("MOVEPANEL")
if (value) then
- GMF.GCLock.text:SetTextColor(C:Green())
- GMF:SetMovable(true)
- GMF:RegisterForDrag("LeftButton")
- GMF:SetScript("OnDragStart",function(frame) frame:StartMoving() end)
- GMF:SetScript("OnDragStop",function(frame) frame:StopMovingOrSizing() end)
+ xprint("GMF MOVABLE")
+ --GMF:SetMovable(true)
+ --GMF:SetResizable(true)
+ --GMF:RegisterForDrag("LeftButton")
+ --self:RawHookScript(GMF,"OnDragStart","GMF_OnDragStart")
+ --self:RawHookScript(GMF,"OnDragStop","GMF_OnDragStop")
else
- GMF.GCLock.text:SetTextColor(C:Red())
+ xprint("GMF UNMOVABLE")
GMF:SetScript("OnDragStart",nil)
GMF:SetScript("OnDragStop",nil)
GMF:ClearAllPoints()
@@ -440,92 +1120,423 @@ function addon:ApplyMOVEPANEL(value)
GMF:SetMovable(false)
end
end
+
+function addon:RefreshMissions(keepdata)
+ self:BuildMissionsCache()
+ if (self:IsAvailableMissionPage()) then
+ if (not keepdata) then
+ wipe(counters)
+ wipe(parties)
+ end
+ GarrisonMissionList_UpdateMissions()
+ end
+end
+function addon:GenerateDrawerPeriodic()
+ return function(self)
+ if (true) then return end
+ if (self:IsRewardPage()) then return end
+ if (GMF.IsMovingOrSizing) then return end
+ if (GMF:GetHeight()<600) then return end
+ if (GMF:GetWidth()< BIGSIZEW or GMF:GetHeight() < SIZEV) then
+ xprint("Periodic redraw")
+ self:GrowPanel(true)
+ end
+ end
+end
+
+function addon:GenerateTimersPeriodic()
+ return coroutine.wrap(
+ function(self)
+ repeat
+ local t=new()
+ G.GetInProgressMissions(t)
+ wipe(timers)
+ wipe(onMission)
+ for index=1,#t do
+ local mission=t[index]
+ for i=1,mission.numFollowers do
+ timers[mission.followers[i]]=mission.timeLeft
+ onMission[mission.followers[i]]=mission.missionID
+ end
+ end
+ coroutine.yield()
+ until false
+ end
+ )
+end
+function addon:BuildMissionsCache()
+--@debug@
+ local start=GetTime()
+ xprint("Start")
+ --for x=1,10 do -- stress test
+--@end-debug@
+ local t=new()
+ G.GetAvailableMissions(t)
+ for index=1,#t do
+ local missionID=t[index].missionID
+ self:BuildMissionCache(missionID,t[index])
+ self:MatchMaker(missionID,self:GetMissionData(missionID),parties[missionID],true)
+ end
+ del(t)
+--@debug@
+ --end
+ xprint("Done in",GetTime()-start)
+--@end-debug@
+end
+function addon:BuildMissionCache(id,data)
+ if (not dbcache.seen[id]) then
+ dbcache.seen[id]=time()
+ end
+ local mission=cache.missions[id]
+ if (mission.name=="<newmission>") then
+
+ for k,v in pairs(mission) do
+ if (data[k]) then mission[k]=data[k]end
+ end
+ mission.rank=mission.level < 100 and mission.level or mission.iLevel
+ mission.xp=true
+ mission.resources=false
+ for k,v in pairs(data.rewards) do
+ if (not v.followerXP) then mission.xp=false end
+ if (v.currencyID and v.currencyID==824) then mission.resource=false end
+ end
+ local _,xp,type,typeDesc,typeIcon,_,_,enemies=G.GetMissionInfo(id)
+ if (not type) then
+ xprint(true,"No type",id,data.name)
+ else
+ self.db.global.types[type]={name=typeDesc,icon=typeIcon}
+ end
+ wipe(mission.slots)
+ local slots=mission.slots
+
+ for i=1,#enemies do
+ local mechanics=enemies[i].mechanics
+ for i,mechanic in pairs(mechanics) do
+ tinsert(slots,{name=mechanic.name,icon=mechanic.icon})
+ self.db.global.abilities[mechanic.name]={desc=mechanic.description,icon=mechanic.icon}
+ end
+ end
+ if (type) then
+ tinsert(slots,{name=TYPE,icon=typeIcon})
+ end
+ end
+ self:FillCounters(id,mission)
+ --self:MatchMaker(id,mission)
+ mission.basePerc=select(4,G.GetPartyMissionInfo(id))
+end
+function addon:SetDbDefaults(default)
+ default.global=default.global or {}
+ default.global["*"]={
+ }
+end
+function addon:CreatePrivateDb()
+ self.privatedb=self:RegisterDatabase(
+ GetAddOnMetadata(me,"X-Database")..'perChar',
+ {
+ profile={
+ seen={},
+ history={
+ ['*']={
+ }
+ } }
+ },
+ true)
+ self.private=self:RegisterDatabase(
+ "GACPrivateVolatile",
+ {
+ profile={
+ missions={
+ ["*"]={
+ missionID=0,
+ counters={},
+ countered={
+ ["*"]={}
+ },
+ counterers={
+ ["*"]={}
+ },
+ slots={
+ ["*"]=0
+ },
+ numFollowers=0,
+ name="<newmission>",
+ basePerc=0,
+ durationSeconds=0,
+ rewards={},
+ level=0,
+ iLevel=0,
+ rank=0,
+ locPrefix=false
+ }
+ }
+ }
+ }
+ ,
+ true)
+ dbcache=self.privatedb.profile
+ cache=self.private.profile
+end
+function addon:SetClean()
+ dirty=false
+end
+function addon:wipe(i)
+ DevTools_Dump(i)
+ privatedb:ResetDB()
+end
function addon:OnInitialized()
--@debug@
LoadAddOn("Blizzard_DebugTools")
+ self:DebugEvents()
--@end-debug@
- self.OptionsTable.args.on=nil
- self.OptionsTable.args.off=nil
- self.OptionsTable.args.standby=nil
- self:AddToggle("MOVEPANEL",true,L["Makes Garrison Mission Panel Movable"]).width="full"
- self:AddToggle("IGM",false,IGNORE_UNAIVALABLE_FOLLOWERS,IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL).width="full"
- self:loadHelp()
- self.DbDefaults.global["*"]={}
- self.db:RegisterDefaults(self.DbDefaults)
- skipBusy=self:GetBoolean("IGM")
- self:MasterPlanDetection(true)
- self:ScheduleTimer("MasterPlanDetection",2)
- pcall(self.FillFollowersList,self)
- self:CacheFollowers()
- self:SecureHook("GarrisonMissionButton_AddThreatsToTooltip",function(id) self:TooltipAdder(id) end)
- self:SecureHook("GarrisonMissionButton_SetRewards","AddPerc")
- self:HookScript(GMF,"OnHide","CleanUp")
- self:Options()
- self:ApplyMOVEPANEL(self:GetBoolean("MOVEPANEL"))
- -- Forcing refresh when needed without possibly disrupting Blizzard Logic
- self:SecureHook("GarrisonMissionPage_Close","RefreshMissions") -- Missino started
- self:SecureHook("GarrisonMissionFrame_HideCompleteMissions","RefreshMissions") -- Mission reward completed
- self:CacheFollowers()
- self:RegisterEvent("GARRISON_MISSION_STARTED","RefreshMissions")
-
+ self:CreatePrivateDb()
+ if (self.db.char.missionsCache) then
+ self.db.char.missionsCache=nil
+ for i,v in pairs(self.db.char.seen) do
+ dbcache.seen[i]=v
+ end
+ self.db.char.seen=nil
+ end
+ self:RegisterEvent("GARRISON_MISSION_NPC_CLOSED",function(...) print(...) GCF:Hide() end)
+ self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",print)
+ self:RegisterEvent("GARRISON_MISSION_STARTED")
+ self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE")
+ self:SafeHookScript("GarrisonMissionFrame","OnShow","SetUp",true)
+ self:AddToggle("MOVEPANEL",true,L["Unlock Garrison Panel"])
+ self:AddToggle("IGM",true,IGNORE_UNAIVALABLE_FOLLOWERS,IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL)
+ self:AddToggle("IGP",true,L["Ignore maxed followers for xp only one follower missions"])
+ print("Booting movepanel",self:GetBoolean("MOVEPANEL"))
--@debug@
--Only Used for development
self:RegisterEvent("GARRISON_MISSION_LIST_UPDATE",print)
self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE",print) --This event is quite useless, fires too often
- self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGEDE",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGED",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_ADDED",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_REMOVED",print)
self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_LOOT",print)
self:RegisterEvent("GARRISON_MISSION_FINISHED",print)
self:RegisterEvent("GARRISON_MISSION_COMPLETE_RESPONSE",print)
self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE",print)
- self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",print)
- self:SafeHookScript("GarrisonMissionFrameTab1","OnCLick")
- self:SafeHookScript("GarrisonMissionFrameTab2","OnCLick")
- self:SafeHookScript("GarrisonMissionFrameTab3","OnCLick")
- self:SafeHookScript("GarrisonMissionFrameMissionsTab1","OnCLick")
- self:SafeHookScript("GarrisonMissionFrameMissionsTab3","OnCLick")
- self:SafeHookScript(GMFMissions,"OnShow")
- self:SafeHookScript(GMFMissions,"OnHide")
- self:SafeHookScript(GMFFollowers,"OnShow")
- self:SafeHookScript(GMFFollowers,"OnHide")
- self:SafeHookScript(GMF.MissionTab.MissionPage.CloseButton,"OnClick")
+ self:RegisterEvent("GARRISON_UPDATE",print)
+ self:RegisterEvent("GARRISON_USE_PARTY_GARRISON_CHANGED",print)
--@end-debug@
return true
end
-function addon:Options()
- local f=GMF:CreateFontString()
- f:SetFontObject(GameFontNormalSmall)
- --f:SetHeight(32)
- f:SetText(me .. L[" Options:"])
- --f:SetTextColor(C:Azure())
- f:Show()
- GMF.GCLabel=f
- local b=CreateFrame("CheckButton","GACOptions",GMF,"UICheckButtonTemplate")
- b.text:SetText(L["Ignore busy followers"])
- b:SetChecked(self:GetBoolean('IGM'))
- b:SetScript("OnCLick",function(b) self:ApplyIGM(b:GetChecked()) end)
+function addon:WipeMission(missionID)
+ cache.missions[missionID]=nil
+ counters[missionID]=nil
+ dbcache.seen[missionID]=nil
+ parties[missionID]=nil
+ collectgarbage("step")
+
+
+end
+function addon:GARRISON_MISSION_NPC_CLOSED(event,...)
+--@debug@
+ print(event,...)
+--@end-debug@
+ GCF:Hide()
+end
+function addon:GARRISON_MISSION_STARTED(event,missionID)
+--@debug@
+ print(event,missionID)
+--@end-debug@
+ for i=1,3 do
+ local m=parties[missionID].members[i]
+ if (m) then
+ onMission[m]=missionID
+ end
+ end
+ dbcache.seen[missionID]=nil
+ wipe(counters)
+ wipe(parties)
+ self:RefreshMissions(false)
+end
+function addon:GARRISON_MISSION_BONUS_ROLL_COMPLETE(event,missionID,completed,success)
+--@debug@
+ print(event,missionID)
+--@end-debug@
+ dbcache.seen[missionID]=nil
+ tinsert(dbcache.history[missionID],{completed=time(),result=100,success=success})
+ wipe(parties)
+ wipe(counters)
+end
+function addon:GARRISON_MISSION_COMPLETE_RESPONSE(event,missionID,completed,success)
+--@debug@
+ print(event,missionID)
+--@end-debug@
+ dbcache.seen[missionID]=nil
+ tinsert(dbcache.history[missionID],{completed=time(),result=100,success=success})
+ wipe(parties)
+ wipe(counters)
+end
+
+function addon:OptionOnClick(checkbox)
+ self:SetBoolean(checkbox.flag,checkbox:GetChecked())
+ self:Trigger(checkbox.flag)
+end
+function addon:Option(obj,rel,name,text)
+ local b=CreateFrame("CheckButton",nil,obj,"UICheckButtonTemplate")
+ b.text:SetText(text)
+ b.flag=name
+ self:HookScript(b,"OnCLick","OptionOnClick")
+ obj[name]=b
+ b:SetChecked(self:GetBoolean(name))
+ switch(name,self:GetBoolean(name))
+ b:SetPoint("LEFT",rel,"RIGHT",10,0)
b:Show()
- GMF.GCIgnore=b
- self:ApplyIGM(self:GetBoolean('IGM'))
- local l=CreateFrame("CheckButton","GACLock",GMF,"UICheckButtonTemplate")
- l.text:SetText(L["Unlock Panel"])
- l:SetChecked(self:GetBoolean('MOVEPANEL'))
- l:SetScript("OnCLick",function(b) self:ApplyMOVEPANEL(b:GetChecked()) end)
- l:Show()
- GMF.GCLock=l
+ return b.text
+end
+local elapsed=0
+local interval=0.05
+local lastmin=0
+function addon:Clock(frame,ts)
+ elapsed=elapsed+ts
+ if (elapsed > interval ) then
+ for k,d in pairs(coroutines) do
+ local co=coroutines[k]
+ if (not co.func) then
+ co.func=self["Generate"..k.."Periodic"](self)
+ if (type(co.func) ~="function") then
--@debug@
- local s=CreateFrame("Frame","GACStatus",GMF)
- s:SetHeight(32)
- local st=s:CreateFontString()
- s.text=st
- st:SetFontObject(GameFontNormalSmall)
- st:Show()
- st:SetAllPoints()
- f:SetPoint("BOTTOMLEFT",GMF,"TOPLEFT",10,15)
- b:SetPoint("TOPLEFT",f,"TOPRIGHT",10,10)
- l:SetPoint("TOPLEFT",b,"TOPRIGHT",10+b.text:GetWidth(),0)
- s:SetPoint("TOPLEFT",l,"TOPRIGHT",10+l.text:GetWidth(),0)
- self:HookScript(s,"OnUpdate","Status")
+ print("Periodic inesistente",k)
--@end-debug@
+ co.func=function() end
+ end
+ end
+ co.elapsed=co.elapsed+elapsed
+ if not co.paused and co.elapsed > co.interval then
+ co.elapsed=0
+ co.paused=co.func(self)
+ end
+ end
+ elapsed=0
+ end
+ local h,m=GetGameTime()
+ if (m~=lastmin) then
+ lastmin=m
+ UpdateAddOnCPUUsage()
+ print("MP",GetAddOnCPUUsage("MasterPlan"))
+ print("GC",GetAddOnCPUUsage("GarrisonCommander"))
+ end
+end
+function addon:ActivateButton(button,OnClick,Tooltiptext,persistent)
+ print("Activting")
+ button:SetScript("OnClick",function(...) self[OnClick](self,...) end )
+ if (Tooltiptext) then
+ button.tooltip=Tooltiptext
+ button:SetScript("OnEnter",function(...) self:ShowTT(...) end )
+ button:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
+ else
+ button:SetScript("OnEnter",nil)
+ button:SetScript("OnLeave",nil)
+ end
+end
+function addon:ShowTT(this)
+ GameTooltip:SetOwner(this, "ANCHOR_CURSOR_RIGHT")
+ GameTooltip:SetText(this.tooltip)
+ GameTooltip:Show()
+end
+function addon:Shrink(button)
+ local f=button.Toggle
+ local name=f:GetName() or "Unnamed"
+ print("Toggling",name)
+ if (f:GetHeight() > 200) then
+ f.savedHeight=f:GetHeight()
+ f:SetHeight(200)
+ else
+ f:SetHeight(f.savedHeight)
+ end
+end
+local helpwindow -- pseudo static
+function addon:ShowHelpWindow(button)
+ if (not helpwindow) then
+ local AG=LibStub("AceGUI-3.0")
+ helpwindow=AG:Create("Window")
+ local r=AG:Create("Label")
+ r:SetFullHeight(true)
+ r:SetFullWidth(true)
+ r:SetFontObject(GameFontNormalLarge2)
+ r:SetText([[
+Garrison Commander enhancec standard Garrison UI by adding a Menu header and a secondary list of mission button to the right of the standard list.
+Secondary button list:
+ * Time since the first time we saw this mission in log
+ * Success percent with the current followers selection guidelines
+ * A "Good" party composition, on each member countered mechanics are shown.
+ *** Green border means full counter, Orange border low level counter
+Hovering on it shows a tooltip with:
+ * Overall mission status
+ * All members which can possibly play a role in the mission
+Standard button enhancement
+ * In rewards, actual quantity is shown (xp, money and resources) ot iLevel (item rewards)
+ * Countered status
+Menu Header:
+ * Quick selection of which follower ignore for match making
+ * Quick mission list order selection
+----------------------------------------------------------------------------------------------------------
+N.B. I dont love to replicate feature already found in other addons, but I was forced to replicate at least
+those given by MasterPlan because MasterPlan clashes with GarrisonCommander.
+
+ ]])
+ helpwindow:AddChild(r)
+ helpwindow:SetTitle("Garrison Commander Help")
+ end
+ if (helpwindow:IsShown()) then
+ helpwindow:Hide()
+ else
+ helpwindow:ClearAllPoints()
+ helpwindow:SetPoint("CENTER")
+ helpwindow:Show()
+ end
+end
+function addon:Toggle(button)
+ local f=button.Toggle
+ local name=f:GetName() or "Unnamed"
+ print("Toggling",name)
+ if (f:IsShown()) then print("Hiding",name) f:Hide() else print("Showing",name) f:Show() end
+ if (button.SetChecked) then
+ button:SetChecked(f:IsShown())
+ end
+end
+function addon:Options()
+ print("Loading options setters")
+ local base=CreateFrame("Frame",nil,UIParent,"GarrisonCommanderTitle")
+ GCF=base
+ GCF:SetWidth(BIGSIZEW)
+ GCF:SetPoint("TOP",UIParent,0,-60)
+ base:SetHeight(40)
+ base:EnableMouse(true)
+ self:RawHookScript(base,"OnUpdate","Clock")
+ GCF:SetMovable(true)
+ GCF:RegisterForDrag("LeftButton")
+ GCF:SetScript("OnDragStart",function(frame)frame:StartMoving() end)
+ GCF:SetScript("OnDragStop",function(frame) frame:StopMovingOrSizing() end)
+ local rel=base.Signature
+ rel=self:Option(base,rel,'IGM',L["Ignore busy followers"])
+ rel=self:Option(base,rel,'IGP',L["Ignore maxed followers for xp only one follower missions"])
+ rel=self:Option(base,rel,'MOVEPANEL',L["Unlock Panel"])
+ --HelpButton
+ local h=CreateFrame("Button",nil,base,"UIPanelCloseButton")
+ h:SetFrameLevel(999)
+ h:SetNormalTexture("interface\\buttons\\ui-microbutton-help-up")
+ h:SetPushedTexture("interface\\buttons\\ui-microbutton-help-down")
+ h:SetHeight(64)
+ h:SetWidth(32)
+ h:SetPoint("BOTTOMLEFT")
+ self:ActivateButton(h,"ShowHelpWindow",L["Click to toggle Help page"])
+ GCF.gcHELP=h
+ --MinimizeButton
+ local h=CreateFrame("Button",nil,base,"UIPanelCloseButton")
+ h:SetFrameLevel(999)
+ h:SetNormalTexture("Interface\\BUTTONS\\UI-Panel-CollapseButton-Up")
+ h:SetPushedTexture("Interface\\BUTTONS\\UI-Panel-CollapseButton-Down")
+ h:SetHeight(32)
+ h:SetWidth(32)
+ h.Toggle=GMF
+ h:SetPoint("TOPRIGHT")
+ self:ActivateButton(h,"Shrink",L["Click to toggle Garrison Mission Frame"])
+ GCF.gcHIDE=h
+ self:Trigger("MOVEPANEL")
+ self.Options=function() end
end
function addon:ScriptTrace(hook,frame,...)
@@ -533,20 +1544,10 @@ function addon:ScriptTrace(hook,frame,...)
print("Triggered " .. C(hook,"red").." script on",C(frame,"Azure"),...)
--@end-debug@
end
-function addon:Status(frame)
- frame.text:SetText(format("PM:%s AM:%s FL:%s RP:%s MP:%s",
- self:IsProgressMission() and 'Yes' or 'Not',
- self:IsAvailableMission() and 'Yes' or 'Not',
- self:IsFollowerList() and 'Yes' or 'Not',
- self:IsRewardPage() and 'Yes' or 'Not',
- self:IsMissionPage() and 'Yes' or 'Not')
- )
- frame:SetWidth(frame.text:GetWidth())
-end
-function addon:IsProgressMission()
+function addon:IsProgressMissionPage()
return GMF:IsShown() and GarrisonMissionFrameMissionsListScrollFrame:IsShown() and GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
end
-function addon:IsAvailableMission()
+function addon:IsAvailableMissionPage()
return GMF:IsShown() and GarrisonMissionFrameMissionsListScrollFrame:IsShown() and not GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
end
function addon:IsFollowerList()
@@ -554,15 +1555,54 @@ function addon:IsFollowerList()
end
--GMFMissions.CompleteDialog
function addon:IsRewardPage()
- return GMF:IsShown() and GMF.MissionComplete:IsShown() and not GMFFollowers:IsShown()
+ return GMF:IsShown() and GMF.MissionComplete:IsShown()
+
end
function addon:IsMissionPage()
return GMF:IsShown() and GMFMissionPage:IsShown() and GMFFollowers:IsShown()
end
-function addon:AddPerc(b,...)
- if (GMFMissions.CompleteDialog:IsShown()) then return end
+function addon:SafeHookScript(frame,hook,method,postHook)
+ local name="Unknown"
+ if (type(frame)=="string") then
+ name=frame
+ frame=_G[frame]
+ else
+ if (frame and frame.GetName) then
+ name=frame:GetName()
+ end
+ end
+ if (frame) then
+ if (method) then
+ if (postHook) then
+ self:SecureHookScript(frame,hook,method)
+--@debug@
+ print("PostHooked",name,hook)
+--@end-debug@
+ else
+ self:HookScript(frame,hook,method)
+--@debug@
+ print("PreHooked",name,hook)
+--@end-debug@
+ end
+ else
+ if (postHook) then
+ self:SecureHookScript(frame,hook,function(...) self:ScriptTrace(name,hook,...) end)
+ print("DummyPostHooked:",name,hook)
+ else
+ self:HookScript(frame,hook,function(...) self:ScriptTrace(name,hook,...) end)
+ print("DummyPreHooked:",name,hook)
+ end
+ end
+--@debug@
+ else
+ print(C("Attempted hook for non existent:","red"),name,hook)
+--@end-debug@
+ end
+end
+function addon:_AddPerc(b,...)
if (b and b.info and b.info.missionID and b.info.missionID ) then
if (GMF.MissionTab.MissionList.showInProgress) then
+ self:RenderButton(b)
if (b.ProgressHidden) then
return
else
@@ -581,26 +1621,26 @@ function addon:AddPerc(b,...)
local Perc=successes[missionID] or -2
if (not b.Success) then
b.Success=b:CreateFontString()
- b.Success:SetFontObject("GameFontNormalLarge2")
if (masterplan) then
- b.Success:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",200,-3)
+ b.Success:SetFontObject("GameFontNormal")
else
- b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+ b.Success:SetFontObject("GameFontNormalLarge2")
end
+ b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
end
if (not b.NotEnough) then
b.NotEnough=b:CreateFontString()
if (masterplan) then
- b.NotEnough:SetFontObject("GameFontNormalSmall2")
- b.NotEnough:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+ b.NotEnough:SetFontObject("GameFontNormal")
+ b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",150,-3)
else
- b.NotEnough:SetFontObject("GameFontNormalSmall")
+ b.NotEnough:SetFontObject("GameFontNormalSmall2")
b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",0,-3)
end
b.NotEnough:SetText("(".. GARRISON_PARTY_NOT_FULL_TOOLTIP .. ")")
b.NotEnough:SetTextColor(C:Red())
end
- if (Perc <0) then
+ if (Perc <0 and not b:IsMouseOver()) then
self:TooltipAdder(missionID,true)
Perc=successes[missionID] or -2
end
@@ -608,7 +1648,7 @@ function addon:AddPerc(b,...)
if (masterplan) then
b.Success:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,successes[missionID])
else
- b.Success:SetFormattedText(BUTTON_INFO,C_Garrison.GetMissionMaxFollowers(missionID),successes[missionID])
+ b.Success:SetFormattedText(BUTTON_INFO,G.GetMissionMaxFollowers(missionID),successes[missionID])
end
local q=self:GetDifficultyColor(successes[missionID])
b.Success:SetTextColor(q.r,q.g,q.b)
@@ -618,7 +1658,7 @@ function addon:AddPerc(b,...)
end
b.Success:Show()
if (not requested[missionID]) then
- requested[missionID]=C_Garrison.GetMissionMaxFollowers(missionID)
+ requested[missionID]=G.GetMissionMaxFollowers(missionID)
end
if (requested[missionID]>availableFollowers) then
b.NotEnough:Show()
@@ -628,91 +1668,697 @@ function addon:AddPerc(b,...)
b.ProgressHidden=false
end
end
-function addon:CleanUp()
- collectgarbage("step",10)
+function addon:GarrisonMissionFrame_HideCompleteMissions()
+ self:GrowPanel(true)
+ self:RefreshMissions("MissionCompleteClose")
end
-
-function addon:RefreshMissions()
- if (self:IsAvailableMission()) then
- --@debug@
- print("Refresh missions called")
- --@end-debug@
- self:CacheFollowers()
- wipe(successes)
- GarrisonMissionList_UpdateMissions()
+function addon:GarrisonFollowerListButton_OnClick(frame,button)
+ if (button=="LeftButton" and not GarrisonMissionFrame.FollowerTab.Model:IsShown()) then
+ if (frame.info.isCollected) then
+ self:GarrisonFollowerPage_ShowFollower(frame.info,id)
+ end
end
end
-function addon:SafeHookScript(frame,hook,method)
- local name="Unknown"
- if (type(frame)=="string") then
- name=frame
- frame=_G[frame]
+-- Shamelessly stolen from Blizzard Code
+function addon:FillMissionButton(button)
+ local mission=button.info
+ button.Title:SetWidth(0);
+ button.Title:SetText(mission.name);
+ button.Level:SetText(mission.level);
+ if ( mission.durationSeconds >= GARRISON_LONG_MISSION_TIME ) then
+ local duration = format(GARRISON_LONG_MISSION_TIME_FORMAT, mission.duration);
+ button.Summary:SetFormattedText(PARENS_TEMPLATE, duration);
else
- if (frame and frame.GetName) then
- name=frame:GetName()
+ button.Summary:SetFormattedText(PARENS_TEMPLATE, mission.duration);
+ end
+ if ( button.Title:GetWidth() + button.Summary:GetWidth() + 8 < 275 - mission.numRewards * 65 ) then
+ button.Title:SetPoint("LEFT", 165, 0);
+ button.Summary:ClearAllPoints();
+ button.Summary:SetPoint("BOTTOMLEFT", button.Title, "BOTTOMRIGHT", 8, 0);
+ else
+ button.Title:SetPoint("LEFT", 165, 10);
+ button.Title:SetWidth(275 - mission.numRewards * 65);
+ button.Summary:ClearAllPoints();
+ button.Summary:SetPoint("TOPLEFT", button.Title, "BOTTOMLEFT", 0, -4);
+ end
+ if ( mission.locPrefix ) then
+ button.LocBG:Show();
+ button.LocBG:SetAtlas(mission.locPrefix.."-List");
+ else
+ button.LocBG:Hide();
+ end
+ if (mission.isRare) then
+ button.RareOverlay:Show();
+ button.RareText:Show();
+ button.IconBG:SetVertexColor(0, 0.012, 0.291, 0.4)
+ else
+ button.RareOverlay:Hide();
+ button.RareText:Hide();
+ button.IconBG:SetVertexColor(0, 0, 0, 0.4)
+ end
+ local showingItemLevel = false;
+ if ( mission.level == GARRISON_FOLLOWER_MAX_LEVEL and mission.iLevel > 0 ) then
+ button.ItemLevel:SetFormattedText(NUMBER_IN_PARENTHESES, mission.iLevel);
+ button.ItemLevel:Show();
+ showingItemLevel = true;
+ else
+ button.ItemLevel:Hide();
+ end
+ if ( showingItemLevel and mission.isRare ) then
+ button.Level:SetPoint("CENTER", button, "TOPLEFT", 40, -22);
+ else
+ button.Level:SetPoint("CENTER", button, "TOPLEFT", 40, -36);
+ end
+
+ --button:Enable();
+ if (mission.inProgress) then
+ button.Overlay:Show();
+ button.Summary:SetText(mission.timeLeft.." "..RED_FONT_COLOR_CODE..GARRISON_MISSION_IN_PROGRESS..FONT_COLOR_CODE_CLOSE);
+ else
+ button.Overlay:Hide();
+ end
+ button.MissionType:SetAtlas(mission.typeAtlas);
+ GarrisonMissionButton_SetRewards(button, mission.rewards, mission.numRewards);
+ button:Show();
+
+end
+function addon:GarrisonFollowerPage_ShowFollower(frame,followerID)
+ local MAXMISSIONS=6
+ local MINPERC=60
+ local i=0
+ -- frame has every info you can need on a follower, but here I dont really need them, maybe just counters
+ --DevTools_Dump(table.Counters)
+ local followerName=self:GetFollowerData(followerID,'name')
+ local dbg=followerName=="Qiana Moonshadow"
+ repeat -- a poor man goto
+ if (type(frame.followerID)=="number") then
+ GCFBusyStatus:SetText(NOT_COLLECTED)
+ GCFBusyStatus:SetTextColor(C.Red())
+ break
+ end
+
+ local index=new()
+ local partyIndex=new()
+
+ local status=self:GetFollowerStatus(followerID)
+ local list
+ local m1,m2,m3,perc,numFollowers=nil,nil,nil,0,""
+ if (status ~= AVAILABLE and status ~= GARRISON_FOLLOWER_IN_PARTY) then
+ if (status==GARRISON_FOLLOWER_ON_MISSION) then
+ local missionID=onMission[followerID]
+ list=GMF.MissionTab.MissionList.inProgressMissions
+ m1=followerID
+ perc=select(4,G.GetPartyMissionInfo(missionID))
+ for j=1,#list do
+ index[list[j].missionID]=j
+ end
+ tinsert(partyIndex,-missionID)
+ GCFBusyStatus:SetText("")
+ else
+ GCFBusyStatus:SetText(self:GetFollowerStatus(followerID,false,true)) -- no time, colored
+ end
+ else
+ GCFBusyStatus:SetText("")
+ list=GMF.MissionTab.MissionList.availableMissions
+ for j=1,#list do
+ index[list[j].missionID]=j
+ end
+ for k,_ in pairs(parties) do
+ tinsert(partyIndex,k)
+ end
+ table.sort(partyIndex,function(a,b) return parties[a].perc > parties[b].perc end)
+ end
+ for z = 1,#partyIndex do
+ local missionID=partyIndex[z]
+ if (missionID>0) then
+ local p=parties[missionID]
+ m1,m2,m3,perc=p.members[1],p.members[2],p.members[3],tonumber(p.perc) or 0
+ if (m3) then
+ numFollowers=3
+ elseif(m2) then
+ numFollowers=2
+ else
+ numFollowers=1
+ end
+ else
+ missionID=abs(missionID)
+ end
+ if (perc>MINPERC and ( m1 == followerID or m2==followerID or m3==followerID)) then
+ i=i+1
+ local mission=list[index[missionID]]
+ local panel=GCFMissions.Missions[i]
+ if (not panel) then
+ panel=CreateFrame("Button",nil,GCFMissions,"GarrisonCommanderMissionListButtonTemplate")
+ panel:SetPoint("TOPLEFT",GCFMissions.Missions[i-1],"BOTTOMLEFT")
+ panel:SetPoint("TOPRIGHT",GCFMissions.Missions[i-1],"BOTTOMRIGHT")
+ tinsert(GCFMissions.Missions,panel)
+ --Creo una riga nuova
+ end
+ panel.info=mission
+ panel.id=index[missionID]
+ panel.fromFollowerPage=true
+ panel.LocBG:SetPoint("LEFT")
+ self:FillMissionButton(panel)
+ local q=self:GetDifficultyColor(perc)
+ panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
+ panel.Percent:SetTextColor(q.r,q.g,q.b)
+ panel.NumMembers:SetFormattedText(GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS,numFollowers)
+ panel:Show()
+ if (i>= MAXMISSIONS) then break end
+ end
end
+ del(partyIndex)
+ del(index)
+ until true
+ i=i+1
+ for x=i,#GCFMissions.Missions do GCFMissions.Missions[x]:Hide() end
+end
+function addon:SetUp(...)
+ SIZEV=GMF:GetHeight()
+ self:Options()
+ self:StartUp()
+end
+function addon:StartUp(...)
+ self:Unhook(GMF,"OnShow")
+ self:PermanentEvents()
+ GCF:Show()
+ GMF:ClearAllPoints()
+ GMF:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
+ GMF:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
+ GMFRewardSplash:ClearAllPoints()
+ GMFRewardSplash:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
+ GMFRewardSplash:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
+ GMFRewardPage:ClearAllPoints()
+ GMFRewardPage:SetPoint("TOPLEFT",GCF,"BOTTOMLEFT")
+ GMFRewardPage:SetPoint("TOPRIGHT",GCF,"BOTTOMRIGHT")
+ if (not GCFMissions) then
+ local ml=CreateFrame("Frame","GCFMissions",GMFFollowers,"GarrisonCommanderFollowerMissionList")
+ ml:SetPoint("TOPLEFT",GMFFollowers,"TOPRIGHT")
+ ml:SetPoint("BOTTOMLEFT",GMFFollowers,"BOTTOMRIGHT")
+ ml:SetWidth(450)
+ ml:Show()
+ GCFMissions=ml
+ local fs=GMFFollowers:CreateFontString(nil, "BACKGROUND", "GameFontNormalHugeBlack")
+ fs:SetPoint("TOPLEFT",GMFFollowers,"TOPRIGHT")
+ fs:SetPoint("BOTTOMLEFT",GMFFollowers,"BOTTOMRIGHT")
+ fs:SetText(AVAILABLE)
+ fs:SetWidth(450)
+ fs:Show()
+ GCFBusyStatus=fs
end
- if (frame) then
- if (method) then
- local rc,msg=pcall(self.HookScript,self,frame,hook,method)
- --@debug@
- if (not rc) then
- print("ERROR attempting hook:",name,hook,":",msg)
+ self:GrowPanel(self:GetBoolean("BIGPANEL"))
+ self:SecureHook("GarrisonMissionFrame_CheckCompleteMissions",function(...) print("GarrisonMissionFrame_CheckCompleteMissions",...) end)
+ self:SecureHook("GarrisonMissionButton_AddThreatsToTooltip",function(id) self:TooltipAdder(id) end)
+ self:SecureHook("GarrisonMissionButton_SetRewards","RenderButton")
+ self:SecureHook("GarrisonFollowerListButton_OnClick")--,function(...) print("GarrisonFollowerListButton_OnClick",...) end)
+ self:SecureHook("GarrisonFollowerPage_ShowFollower")--,function(...) print("GarrisonFollowerPage_ShowFollower",...) end)
+ self:SecureHook("GarrisonMissionButton_OnClick")
+ self:HookScript(GCF,"OnHide","CleanUp")
+ -- Forcing refresh when needed without possibly disrupting Blizzard Logic
+ self:SecureHook("GarrisonMissionFrame_HideCompleteMissions") -- Mission reward completed
+ self:SafeHookScript(GMFMissions,"OnShow",function (f,...) print(f:GetName(),'OnShow') self:GrowPanel(true) end )
+ self:SafeHookScript(GMFFollowers,"OnShow",function (f,...) print(f:GetName(),'OnShow') self:GrowPanel(false) end )
+ self:SecureHook("GarrisonMissionPage_ShowMission","UpdateMissionPage")
+ self:BuildMissionsCache()
+ GarrisonMissionList_UpdateMissions();
+end
+function addon:PermanentEvents()
+ self:RegisterEvent("GARRISON_MISSION_COMPLETE_RESPONSE")
+ self:RegisterEvent("GARRISON_MISSION_STARTED")
+ self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE")
+ self:RegisterEvent("GARRISON_MISSION_NPC_CLOSED")
+ self:DebugEvents()
+end
+function addon:DebugEvents()
+ self:RegisterEvent("GARRISON_MISSION_LIST_UPDATE",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE",print) --This event is quite useless, fires too often
+ self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGED",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_ADDED",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_REMOVED",print)
+ self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_LOOT",print)
+ self:RegisterEvent("GARRISON_MISSION_FINISHED",print)
+ self:RegisterEvent("GARRISON_UPDATE",print)
+ self:RegisterEvent("GARRISON_USE_PARTY_GARRISON_CHANGED",print)
+ self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",print)
+end
+
+function addon:CleanUp()
+ self:UnhookAll()
+ self:HookScript(GMF,"OnSHow","StartUp",true)
+ self:PermanentEvents() -- Reattaching permanent events
+ collectgarbage("collect")
+ print("Cleaning up")
+end
+function addon:GetFollowerData(key,subkey)
+ local k=followersCacheIndex[key]
+ if (not followersCache[1]) then
+ followersCache=G.GetFollowers()
+ for i,v in pairs(followersCache) do
+ if (not v.isCollected) then
+ followersCache[i]=nil
+ else
+ v.rank=v.level==100 and v.iLevel or v.level
+ end
+ end
+ end
+ local t=followersCache
+ if (not k) then
+ for i=1,#t do
+ if (t[i] and (t[i].followerID == key or t[i].name==key)) then
+ followersCacheIndex[t[i].followerID]=i
+ followersCacheIndex[t[i].name]=i
+ k=i
+ break
+ end
+ end
+ end
+ if (k) then
+ if (subkey) then
+ if (subkey=='rank') then
+ return t[k].level==100 and t[k].iLevel or t[k].level
+ else
+ return t[k][subkey]
end
else
- print("DummyHook:",name,hook)
- self:HookScript(frame,hook,function(...) self:ScriptTrace(name,hook,...) end)
- --@end-debug@
+ return t[k]
end
---@debug@
else
- print(C("Attempted hook for non existent:","red"),name,hook)
---@end-debug@
+ return nil
end
end
-function addon:FixButtons()
- local self = GMF.MissionTab.MissionList
- local scrollFrame = self.listScroll
- local buttons = scrollFrame.buttons
- if (masterplan) then
- for i =1,#buttons do
- local b=buttons[i]
- b.Success:ClearAllPoints()
- b.Success:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",200,-3)
- b.NotEnough:SetFontObject("GameFontNormalSmall2")
- b.NotEnough:ClearAllPoints()
- b.NotEnough:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+function addon:GetMissionData(missionID,subkey)
+ local missionCache=cache.missions[missionID]
+ if (missionCache.name=="<newmission>") then
+ print("Found a new mission",missionID,"Refreshing mission list")
+ self:BuildMissionCache(missionID)
+ end
+ if (subkey) then
+ return missionCache[subkey]
+ end
+ return missionCache
+end
+function addon:GetFollowerStatusForMission(followerID,skipbusy)
+ if (not skipbusy) then
+ return true
+ else
+ return self:GetFollowerStatus(followerID) == AVAILABLE
+ end
+end
+function addon:GetFollowerStatus(followerID,withTime,colored)
+ local status=G.GetFollowerStatus(followerID)
+ if (status and status== GARRISON_FOLLOWER_ON_MISSION and withTime) then
+ status=timers[followerID]
+ end
+ if (status) then
+ return colored and C(status,"Red") or status
+ else
+ return colored and C(AVAILABLE,"Green") or AVAILABLE
+ end
+end
+
+function addon:ClearFollowers()
+ wipe(followers)
+end
+local AceGUI=LibStub("AceGUI-3.0")
+function addon:GetScroller(title)
+ local scrollerWindow=AceGUI:Create("Frame")
+ scrollerWindow:SetTitle(title)
+ scrollerWindow:SetLayout("Fill")
+ --local scrollcontainer = AceGUI:Create("SimpleGroup") -- "InlineGroup" is also good
+ --scrollcontainer:SetFullWidth(true)
+ --scrollcontainer:SetFullHeight(true) -- probably?
+ --scrollcontainer:SetLayout("Fill") -- important!
+ --scrollerWindow:AddChild(scrollcontainer)
+ local scroll = AceGUI:Create("ScrollFrame")
+ scroll:SetLayout("Flow") -- probably?
+ scroll:SetFullWidth(true)
+ scroll:SetFullHeight(true)
+ scrollerWindow:AddChild(scroll)
+ scrollerWindow:SetCallback("OnClose","Release")
+ scrollerWindow:SetHeight(800)
+ scrollerWindow:SetWidth(400)
+ scrollerWindow:SetPoint("CENTER")
+ scrollerWindow:Show()
+ return scroll
+end
+function addon:AddLabel(obj,text,...)
+ local l=AceGUI:Create("Label")
+ l:SetText(text)
+ l:SetColor(...)
+ l:SetFullWidth(true)
+ obj:AddChild(l)
+end
+function addon:cuttyPrint(scroll,level,k,v)
+ if (type(level)=="table") then
+ for k,v in pairs(level) do
+ self:cuttyPrint(scroll,"",k,v)
+ end
+ return
+ end
+ if (type(v)=="table") then
+ self:AddLabel(scroll,level..C(k,"Azure")..":" ..C("Table","Orange"))
+ for kk,vv in pairs(v) do
+ self:cuttyPrint(scroll,level .. " ",kk,vv)
end
else
- for i =1,#buttons do
- local b=buttons[i]
- b.Success:ClearAllPoints()
- b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
- b.NotEnough:SetFontObject("GameFontNormalSmall")
- b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",0,-3)
+ if (type(v)=="string" and v:sub(1,2)=='0x') then
+ v=v.. " " ..tostring(self:GetFollowerData(v,'name'))
+ end
+ self:AddLabel(scroll,level..C(k,"White")..":" ..C(v,"Yellow"))
+ end
+end
+function addon:DumpFollowerMissions(missionID)
+ local scroll=self:GetScroller("FollowerMissions " .. self:GetMissionData(missionID,'name'))
+ self:cuttyPrint(scroll,followerMissions.missions[missionID])
+end
+function addon:DumpMission(missionID)
+ local scroll=self:GetScroller("MissionCache " .. self:GetMissionData(missionID,'name'))
+ self:cuttyPrint(scroll,cache.missions[missionID])
+end
+function addon:DumpCounters(missionID)
+ local scroll=self:GetScroller("Counters " .. self:GetMissionData(missionID,'name'))
+ self:cuttyPrint(scroll,counters[missionID])
+ self:cuttyPrint(scroll,"Lista per follower","","")
+ self:cuttyPrint(scroll,counterFollowerIndex[missionID])
+ self:cuttyPrint(scroll,"Lista per threat","","")
+ self:cuttyPrint(scroll,counterThreatIndex[missionID])
+end
+function addon:DumpCounterers(missionID)
+ local scroll=self:GetScroller("Counterers " .. self:GetMissionData(missionID,'name'))
+ self:cuttyPrint(scroll,cache.missions[missionID].counterers)
+end
+function addon:DumpParty(missionID)
+ local scroll=self:GetScroller("Party " .. self:GetMissionData(missionID,'name'))
+ self:cuttyPrint(scroll,parties[missionID])
+end
+function addon:UpdateMissionPage(missionInfo)
+--@debug@
+ print("UpdateMissionPage for",missionInfo.missionID)
+--@end-debug@
+ --DevTools_Dump(missionInfo)
+ --self:BuildMissionData(missionInfo.missionID.missionInfo)
+ local mission=self:GetMissionData(missionInfo.missionID)
+ local t=new()
+ t.members=new()
+ self:MatchMaker(mission.missionID,mission,t,true)
+ local members=t.members
+ for i=1,#members do
+ GarrisonMissionPage_ClearFollower(GMFMissionPageFollowers[i])
+ end
+ for i=1,#members do
+ local info=self:GetFollowerData(members[i])
+ print(members[i],info.name)
+ GarrisonMissionPage_SetFollower(GMFMissionPageFollowers[i],info)
+ end
+ GarrisonMissionPage_UpdateMissionForParty()
+ del(t.members)
+ del(t)
+end
+local firstcall=true
+function addon:GrowPanel(enlarge)
+ if (not GMFRewardSplash:IsShown()) then
+ --GMF:SetWidth(BIGSIZEW)
+ GMF:SetHeight(BIGSIZEH)
+ --GMFMissions:SetWidth(890)
+ --GMFMissions:ClearAllPoints()
+ --GMFMissions:SetPoint("TOPLEFT",GMF,25,-64)
+ GMFMissions:SetPoint("BOTTOMRIGHT",GMF,-25,35)
+ GMFFollowers:SetPoint("BOTTOMLEFT",GMF,-35,65)
+ --GMFMissionsListScrollFrame:SetWidth(500)
+ GMFMissionsListScrollFrameScrollChild:ClearAllPoints()
+ GMFMissionsListScrollFrameScrollChild:SetPoint("TOPLEFT",GMFMissionsListScrollFrame)
+ GMFMissionsListScrollFrameScrollChild:SetPoint("BOTTOMRIGHT",GMFMissionsListScrollFrame)
+ GMFFollowersListScrollFrameScrollChild:SetPoint("BOTTOMLEFT",GMFFollowersListScrollFrame,-35,35)
+ end
+end
+function addon:GetBiasColor(followerID,missionID)
+ local rc,followerBias = pcall(G.GetFollowerBiasForMission,missionID,followerID)
+ if (not rc) then
+ print(followerID,missionID,followerBias)
+ return "White"
+ end
+ if (followerBias==-1) then
+ return "Red"
+ elseif (followerBias < 0) then
+ return "Orange"
+ end
+ return "White"
+end
+function addon:FillFollowerButton(frame,followerID,missionID)
+ if (not frame) then return end
+ local dbg=missionID==(tonumber(_G.MW) or 0)
+ for i=1,#frame.Threats do
+ frame.Threats[i]:Hide()
+ end
+ frame.NotFull:Hide()
+ if (not followerID) then
+ frame.PortraitFrame.Empty:Show()
+ frame.Name:Hide()
+ frame.Class:Hide()
+ frame.Status:Hide()
+ frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_LevelBorder");
+ frame.PortraitFrame.LevelBorder:SetWidth(58);
+ frame.PortraitFrame.Level:SetText("")
+ frame:SetScript("OnEnter",nil)
+ GarrisonFollowerPortrait_Set(frame.PortraitFrame.Portrait)
+ return
+ end
+ local info=G.GetFollowerInfo(followerID)
+ --local info=followers[ID]
+ frame.info=info
+ frame.Name:Show();
+ frame.Name:SetText(info.name);
+ local color=self:GetBiasColor(followerID,missionID)
+ frame.Name:SetTextColor(C[color]())
+ xprint(dbg,G.GetFollowerStatus(followerID))
+ frame.Status:SetText(self:GetFollowerStatus(followerID,true,true))
+ frame.Status:Show()
+ if (frame.Class) then
+ frame.Class:Show();
+ frame.Class:SetAtlas(info.classAtlas);
+ end
+ frame.PortraitFrame.Empty:Hide();
+
+ local showItemLevel;
+ if (info.level == GarrisonMissionFrame.followerMaxLevel ) then
+ frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_iLvlBorder");
+ frame.PortraitFrame.LevelBorder:SetWidth(70);
+ showItemLevel = true;
+ else
+ frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_LevelBorder");
+ frame.PortraitFrame.LevelBorder:SetWidth(58);
+ showItemLevel = false;
+ end
+ GarrisonMissionFrame_SetFollowerPortrait(frame.PortraitFrame, info, showItemLevel);
+ -- Counters icon
+ local tohide=1
+ if (not GMF.MissionTab.MissionList.showInProgress) then
+ local mission=self:GetMissionData(missionID)
+ local c=mission.counterers[followerID]
+ for i=1,min(#c, 4) do
+ local t=frame.Threats[i]
+ local tx=self.db.global.abilities[c[i]]
+ if (tx) then
+ t.Icon:SetTexture(tx.icon)
+ else
+ t.Icon:SetTexture(c[i])
+ end
+ t:Show()
+ tohide=i+1
+ end
+ end
+ for i=tohide,4 do frame.Threats[i]:Show() end
+ frame:SetScript("OnEnter",GarrisonMissionPageFollowerFrame_OnEnter)
+end
+function addon:MissionButton_OnClick(frame,button)
+ _G.MW=frame:GetParent().info.missionID
+ print("Clicked",frame:GetParent():GetName(),button)
+ if (button=="LeftButton") then
+ self:RenderButton(frame:GetParent(),{},0)
+ end
+end
+-- pseudo static
+local scale=0.9
+local x1,y1,x2,y2=10,0,12*scale,0
+function addon:PrepareExtraButton(bg,limit)
+ limit=limit or 3
+ for numMembers=1,limit do
+ local f=bg.Party[numMembers]
+ if (not f) then
+ f=CreateFrame("Button",nil,bg,"GarrisonCommanderMissionPageFollowerTemplate")
+ f:SetPoint("LEFT",bg.Party[numMembers-1],"RIGHT",x2,y2)
+ --f:SetFrameStrata("HIGH")
+ tinsert(bg.Party,f)
+ end
+ for numThreats=1,4 do
+ local threatFrame =f.Threats[numThreats];
+ if ( not threatFrame ) then
+ threatFrame = CreateFrame("Frame", nil, f, "GarrisonAbilityCounterTemplate");
+ threatFrame:SetPoint("LEFT", f.Threats[numThreats - 1], "RIGHT", 10, 0);
+ tinsert(f.Threats, threatFrame);
+ end
+ threatFrame:Hide()
end
end
end
-function addon:MasterPlanDetection(novar,...)
- local _,_,_,loadable,reason=GetAddOnInfo("MasterPlan")
- masterplan=false
- if (loadable or reason=="DEMAND_LOADED") then
- if (novar) then
- masterplan=true
+function addon:BuildExtraButton(button)
+ local bg=CreateFrame("Button",nil,button,"GarrisonCommanderMissionButton")
+ --button.LocBG:ClearAllPoints()
+ --button.LocBG:SetPoint("RIGHT",200,0)
+ button.Title:ClearAllPoints()
+ button.Title:SetPoint("TOPLEFT",165,-5)
+ button.Summary:ClearAllPoints()
+ button.Summary:SetPoint("BOTTOMLEFT",165,5)
+ button.LocBG:SetPoint("LEFT")
+ bg:SetPoint("TOPLEFT",button,"TOPRIGHT")
+ bg:SetPoint("RIGHT",GarrisonMissionFrameMissionsListScrollFrame,"RIGHT",-25,0)
+ bg.button=button
+ bg:SetScript("OnEnter",function(this) GarrisonMissionButton_OnEnter(this.button) end)
+ bg:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
+ bg:RegisterForClicks("AnyUp")
+ self:RawHookScript(bg,"OnClick","MissionButton_OnClick")
+ button.gcPANEL=bg
+ self:PrepareExtraButton(bg)
+end
+function addon:GarrisonMissionButton_SetRewards(button,rewards,numrewards)
+end
+function addon:GarrisonMissionButton_OnClick(tab,button)
+ print("Interceptd",button,tab.fromFollowerPage)
+ if (tab.fromFollowerPage) then
+ GarrisonMissionFrame_SelectTab(1)
+ end
+end
+function addon:RenderButton(button,rewards,numRewards)
+--@debug@
+ if (not button or not button.Title) then
+ error(strconcat("Called on I dunno what ",tostring(button)," ", tostring(button:GetName())))
+ return
+ end
+--@end-debug@
+ if (self:IsRewardPage()) then return end
+ if (numRewards > 0) then
+ local index=1
+ for id,reward in pairs(rewards) do
+ local Reward = button.Rewards[index];
+ Reward.Quantity:SetTextColor(C.Yellow())
+ if (reward.followerXP) then
+ Reward.Quantity:SetText(reward.followerXP)
+ Reward.Quantity:Show()
+ elseif (reward.currencyID==0) then
+ Reward.Quantity:SetFormattedText("%d",reward.quantity/10000)
+ Reward.Quantity:Show()
+ elseif (reward.itemID and reward.quantity==1) then
+ local _,_,q,i=GetItemInfo(reward.itemID)
+ local c=ITEM_QUALITY_COLORS[q]
+ if (not c) then c={r=1,g=1,b=1} end
+ Reward.Quantity:SetText(i)
+ Reward.Quantity:SetTextColor(c.r,c.g,c.b)
+ Reward.Quantity:Show()
+ end
+ index=index+1
+ end
+ end
+ if (button.fromFollowerPage) then
+ --button.Title:ClearAllPoints()
+ --button.Title:SetPoint("TOPLEFT",165,-5)
+ --button.Summary:ClearAllPoints()
+ --button.Summary:SetPoint("BOTTOMLEFT",165,5)
+ --button:SetHeight(70)
+ return
+ end
+ local width=GMF.MissionTab.MissionList.showInProgress and BIGBUTTON or SMALLBUTTON
+ button:SetWidth(width)
+ if (not button.gcPANEL) then
+ self:BuildExtraButton(button)
+ else
+ -- Summary is a bit stubborn, it must be moved every time
+ button.Summary:ClearAllPoints()
+ button.Summary:SetPoint("BOTTOMLEFT",165,5)
+ end
+ local panel=button.gcPANEL
+ local missionInfo=button.info
+ local missionID=missionInfo.missionID
+ local dbg=missionID==(tonumber(_G.MW) or 0)
+ xprint(dbg,C("Rendering button for mission "..missionID,"Red"))
+ if (GMF.MissionTab.MissionList.showInProgress) then
+ if (not button.inProgressFresh) then
+ local perc=select(4,G.GetPartyMissionInfo(missionID))
+ panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
+ panel.Age:Hide()
+ local q=self:GetDifficultyColor(perc)
+ panel.Percent:SetTextColor(q.r,q.g,q.b)
+ button.inProgressFresh=true
+ for i=1,3 do
+ local frame=panel.Party[i]
+ if (missionInfo.followers[i]) then
+ self:FillFollowerButton(frame,missionInfo.followers[i],missionID)
+ frame:Show()
+ else
+ frame:Hide()
+ end
+ end
+ end
+ return
+ end
+ button.inProgressFresh=false
+ local mission=self:GetMissionData(missionID)
+ local party=parties[missionID]
+ xprint("Rendering mission",button.info.missionID)
+ if (#party.members==0) then
+ self:MatchMaker(missionID,mission,party)
+ else
+ xprint("Using old party",#party.members)
+ end
+ local perc=party.perc
+ local notFull=false
+ for i=1,3 do
+ local frame=button.gcPANEL.Party[i]
+ if (i>mission.numFollowers) then
+ frame:Hide()
else
- if (_G.MasterPlanConfig or _G.MasterPlanData ) then
- masterplan=true
+ if (party.members[i]) then
+ self:FillFollowerButton(frame,party.members[i],missionID)
+ frame.NotFull:Hide()
+ else
+ self:FillFollowerButton(frame,false)
+ frame.NotFull:Show()
end
+ frame:Show()
end
end
- if (masterplan and not self:IsHooked("GarrisonMissionList_UpdateMissions")) then
- self:SecureHook("GarrisonMissionList_UpdateMissions","RestoreTooltip")
+ if ( mission.locPrefix ) then
+ panel.LocBG:Show();
+ panel.LocBG:SetAtlas(mission.locPrefix.."-List");
+ else
+ panel.LocBG:Hide();
end
- pcall(self.FixButtons,self)
+ panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
+ local q=self:GetDifficultyColor(perc)
+ panel.Percent:SetTextColor(q.r,q.g,q.b)
+ panel.Percent:SetWidth(80)
+ panel.Percent:SetJustifyH("RIGHT")
+ local age=tonumber(dbcache.seen[missionID])
+ if (age) then
+ local day=60*24
+ age=floor((time()-age)/60)
+ local days=floor(age/day)
+ if (days==0) then
+ local hours=floor(age/60)
+ panel.Age:SetFormattedText(AGE_HOURS,hours, age -hours*60 )
+ else
+ panel.Age:SetFormattedText(AGE_DAYS,days,(age-days*day)/60)
+ end
+ else
+ panel.Age:SetText(UNKNOWN)
+ end
+ panel.Age:Show()
+ panel.Percent:Show()
end
---@do-not-package@
_G.GAC=addon
+--@do-not-package@
--[[
+MasterPlan final button
+GMFMissions.CompleteDialog.BorderFrame.CompleteAll
Garrison page structure
Tab selection:
Managed by
@@ -733,5 +2379,185 @@ Missions tab selected
+GarrisonMissionFrameMissionsListScrollFrameButtonx.info:
+Dump: value=GarrisonMissionFrameMissionsListScrollFrameButton1.info
+[1]={
+ description="In a remote corner of Talador, a small faction of draenei has embraced the worship of Sargeras. Stop their cult before it spreads.",
+ cost=10,
+ duration="4 hr",
+ durationSeconds=14400,
+ level=100,
+ type="Combat",
+ locPrefix="GarrMissionLocation-Talador",
+ rewards={
+ [290]={
+ title="Money Reward",
+ quantity=600000,
+ icon="Interface\\Icons\\inv_misc_coin_01",
+ currencyID=0
+ }
+ },
+ numRewards=1,
+ numFollowers=2,
+ state=-2,
+ iLevel=0,
+ name="Cult of Sargeras",
+ followers={
+ },
+ location="Talador",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=126
+}
+Dump: value=G.GetFollowerInfo("0x000000000002F5E1")
+[1]={
+ displayHeight=0.5,
+ iLevel=600,
+ scale=0.60000002384186,
+ classAtlas="GarrMission_ClassIcon-Druid",
+ garrFollowerID="0x0000000000000022",
+ displayScale=1,
+ status="On Mission",
+ level=100,
+ quality=4,
+ portraitIconID=1066112,
+ isFavorite=false,
+ xp=0,
+ className="Guardian Druid",
+ classSpec=8,
+ name="Qiana Moonshadow",
+ followerID="0x000000000002F5E1",
+ height=1.3999999761581,
+ displayID=55047,
+ levelXP=0,
+ isCollected=true
+}
+value=GarrisonMissionFrame.MissionTab.MissionList.availableMissions[13]
+[1]={
+ description="Scouts report a many-headed beast named Festerbloom waylaying travelers crossing the Murkbog. Clear the path for everyone's sake.",
+ cost=20,
+ duration="10 hr",
+ durationSeconds=36000,
+ level=96,
+ type="Combat",
+ locPrefix="GarrMissionLocation-SpiresofArak",
+ rewards={
+ [778]={
+ title="Bonus Follower XP",
+ followerXP=1400,
+ tooltip="+1,400 XP",
+ icon="Interface\\Icons\\XPBonus_Icon",
+ name="+1,400 XP"
+ }
+ },
+ numRewards=1,
+ numFollowers=3,
+ state=-2,
+ iLevel=0,
+ name="Murkbog Terror",
+ followers={
+ },
+ location="Spires of Arak",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=374
+}
+Dump: value=GarrisonMissionFrame.MissionTab.MissionList.inProgressMissions
+[1]={
+ description="The voidlords and voidcallers plaguing Shadowmoon Valley are being summoned by someone. Find and kill whoever is responsible.",
+ cost=15,
+ duration="6 hr",
+ durationSeconds=21600,
+ level=100,
+ timeLeft="1 hr 12 min",
+ type="Combat",
+ inProgress=true,
+ locPrefix="GarrMissionLocation-ShadowmoonValley",
+ rewards={
+ [251]={
+ title="Bonus Follower XP",
+ followerXP=8000,
+ tooltip="+8,000 XP",
+ icon="Interface\\Icons\\XPBonus_Icon",
+ name="+8,000 XP"
+ }
+ },
+ numRewards=1,
+ numFollowers=3,
+ state=-1,
+ iLevel=0,
+ name="Twisting the Nether",
+ followers={
+ [1]="0x000000000002F5E1",
+ [2]="0x0000000000079D62",
+ [3]="0x00000000001307EF"
+ },
+ location="Shadowmoon Valley",
+ isRare=false,
+ typeAtlas="GarrMission_MissionIcon-Combat",
+ missionID=114
+}
+Dump: value=G.GetMissionInfo(119)
+local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = C_Garrison.GetMissionInfo(missionID);
+[1]="Nagrand",
+[2]=1500,
+[3]="Orc",
+[4]="Lok'tar ogar!",
+[5]="Interface\\ICONS\\Achievement_Boss_General_Nazgrim.blp",
+[6]="GarrMissionLocation-Nagrand",
+[7]=false,
+[8]={
+ [1]={
+ portraitFileDataID=1067358,
+ displayID=56189,
+ name="Warsong Earthcaller",
+ mechanics={
+ [4]={
+ description="A dangerous harmful effect that should be dispelled.",
+ name="Magic Debuff",
+ icon="Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp"
+ },
+ [8]={
+ description="A dangerous spell that should be interrupted.",
+ name="Powerful Spell",
+ icon="Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp"
+ }
+ }
+ }
+}
+local totalTimeString, totalTimeSeconds, isMissionTimeImproved, successChance, partyBuffs, isEnvMechanicCountered, xpBonus, materialMultiplier = C_Garrison.GetPartyMissionInfo(MISSION_PAGE_FRAME.missionInfo.missionID);
+Dump: value=C_Garrison.GetPartyMissionInfo(118)
+[1]="8 hr",
+[2]=28800,
+[3]=false,
+[4]=0,
+[5]={
+},
+[6]=false,
+[7]=0,
+[8]=1
+Dump: value=table returned by GetFollowerInfo for a collected follower
+[1]={
+ displayHeight=0.5,
+ iLevel=600,
+ isCollected=true,
+ classAtlas="GarrMission_ClassIcon-Druid",
+ garrFollowerID="0x0000000000000022",
+ displayScale=1,
+ level=100,
+ quality=4,
+ portraitIconID=1066112,
+ isFavorite=false,
+ xp=0,
+ className="Guardian Druid",
+ classSpec=8,
+ name="Qiana Moonshadow",
+ followerID="0x000000000002F5E1",
+ height=1.3999999761581,
+ displayID=55047,
+ scale=0.60000002384186,
+ levelXP=0
+}
+ local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = G.GetMissionInfo(missionID)
--]]
--@end-do-not-package@
diff --git a/GarrisonCommander.toc b/GarrisonCommander.toc
index e4b18a7..3c1b732 100644
--- a/GarrisonCommander.toc
+++ b/GarrisonCommander.toc
@@ -5,15 +5,16 @@
## Notes-frFR: Vous aide au moment de choisir le droit utilisateur pour la bonne mission
## Author: Alar of Daggerspine
## Version: @project-version@ @project-abbreviated-hash@
-## X-Version: 1.1.7
+## X-Version: 2.0.0
## X-Revision: @project-abbreviated-hash@
## eMail: alar@aspide.it
## URL: http://wow.aspide.it
-## OptionalDeps: AlarArtRemover,MasterPlan
+## OptionalDeps:
## DefaultState: Enabled
## LoadOnDemand: 1
## LoadWith: Blizzard_GarrisonUI
## SavedVariables: dbGAC
+## SavedVariablesPerCharacter: dbGACperChar
## X-ID: GAC
## X-Database:dbGAC
## X-Category: Garrison
diff --git a/GarrisonCommander.xml b/GarrisonCommander.xml
index c65c12d..a9ddff1 100644
--- a/GarrisonCommander.xml
+++ b/GarrisonCommander.xml
@@ -1,38 +1,8 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
- <Script file="bigframe.lua"/>
- <Button name="GarrisonCommanderButtonsBackground" virtual="true">
- <Size x="800" y="80"/>
+ <Script file="GarrisonCommander.lua"/>
+ <Frame name="GarrisonCommanderBackground" virtual ="true">
<Layers>
- <Layer level="ARTWORK">
- <FontString parentKey="Percent" inherits="NumberFont_Outline_Huge" justifyH="CENTER" justifyV="CENTER" text="100%" >
- <Size x="150" y="70"/>
- <Anchors>
- <Anchor point="TOPLEFT" relativeKey="$parent" relativePoint="TOPLEFT" x="10" y="-10"/>
- </Anchors>
- </FontString>
-<!--
- <FontString parentKey="Chance" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="TOP" text="Chance (Estimated)">
- <Anchors>
- <Anchor point="TOPLEFT" relativeKey="$parent.Percent" relativePoint="BOTTOMLEFT" y="-4"/>
- </Anchors>
- <Color r="0.745" g="0.745" b="0.745" a="1"/>
- </FontString>
--->
- <Texture parentKey="XPBar">
- <Size x="205" y="4"/>
- <Anchors>
- <Anchor point="TOPLEFT" relativeKey="$parent.BG" relativePoint="BOTTOMLEFT" x="24" y="6"/>
- </Anchors>
- <Color r="0.212" g="0" b="0.337" a="1"/>
- </Texture>
- <FontString parentKey="Status" inherits="GameFontHighlightSmall" justifyH="LEFT">
- <Anchors>
- <Anchor point="TOPLEFT" relativeKey="$parent.ILevel" relativePoint="TOPRIGHT" x="4" y="0"/>
- </Anchors>
- <Color r="0.698" g="0.941" b="1" a="1"/>
- </FontString>
- </Layer>
<Layer level="BACKGROUND">
<Texture atlas="GarrMission_MissionParchment" useAtlasSize="true" vertTile="true" horizTile="true">
<Anchors>
@@ -81,9 +51,111 @@
<TexCoords left="1.0" right="0.0" top="1.0" bottom="0.0"/>
</Texture>
</Layer>
+ <Layer level="BACKGROUND" textureSubLevel="3">
+ <Texture parentKey="IconBG" atlas="Garr_MissionList-IconBG" useAtlasSize="true">
+ <Anchors>
+ <Anchor point="TOPLEFT" y="-1"/>
+ </Anchors>
+ <Color r="0" g="0" b="0" a="0.4"/>
+ </Texture>
+ </Layer>
+ <Layer level="ARTWORK" textureSubLevel="2">
+ <Texture parentKey="LocBG">
+ <Size x="792" y="78"/>
+ <Anchors>
+ <Anchor point="RIGHT"/>
+ </Anchors>
+ </Texture>
+ </Layer>
+ <Layer level="HIGHLIGHT" textureSubLevel="1">
+ <Texture parentKey="HighlightTL" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
+ <Anchors>
+ <Anchor point="TOPLEFT" x="-5" y="4"/>
+ </Anchors>
+ </Texture>
+ <Texture parentKey="HighlightTR" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
+ <Anchors>
+ <Anchor point="TOPRIGHT" x="4" y="4"/>
+ </Anchors>
+ <TexCoords left="1.0" right="0.0" top="0.0" bottom="1.0"/>
+ </Texture>
+ <Texture parentKey="HighlightBL" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
+ <Anchors>
+ <Anchor point="BOTTOMLEFT" x="-5" y="-4"/>
+ </Anchors>
+ <TexCoords left="0.0" right="1.0" top="1.0" bottom="0.0"/>
+ </Texture>
+ <Texture parentKey="HighlightBR" atlas="GarrMission_TopBorderCorner-Highlight" useAtlasSize="true">
+ <Anchors>
+ <Anchor point="BOTTOMRIGHT" x="4" y="-4"/>
+ </Anchors>
+ <TexCoords left="1.0" right="0.0" top="1.0" bottom="0.0"/>
+ </Texture>
+ <Texture parentKey="Highlight" atlas="GarrMission_ListGlow-Highlight" useAtlasSize="true">
+ <Anchors>
+ <Anchor point="TOPLEFT" y="0"/>
+ <Anchor point="TOPRIGHT" y="0"/>
+ </Anchors>
+ </Texture>
+ </Layer>
</Layers>
- </Button>
+ </Frame>
+ <Frame name="GarrisonCommanderTitle" inherits="GarrisonCommanderBackground" virtual="true">
+ <Size x="150" y="32"/>
+ <Layers>
+ <Layer level="ARTWORK">
+ <Button name="help" inherits="UIPanelInfoButton">
+ <Size x="32" y="32"/>
+ <Anchors>
+ <Anchor point="LEFT" x="0" y="0"/>
+ </Anchors>
+ </Button>
+ <Texture parentKey="Shield" file="Interface\ACHIEVEMENTFRAME\UI-ACHIEVEMENT-SHIELDS-NOPOINTS">
+ <Size x="32" y="32"/>
+ <Anchors>
+ <Anchor point="LEFT" x="32" y="0"/>
+ </Anchors>
+ <TexCoords left="0" right="0.5" top="0.5" bottom="1"/>
+ </Texture>
+ <FontString parentKey="Signature" inherits="QuestTitleFontBlackShadow" justifyH="LEFT" justifyV="CENTER" text="Garrison Commander" >
+ <Size x="200" y="32"/>
+ <Anchors>
+ <Anchor point="LEFT" relativeKey="$parent.Shield" relativePoint="RIGHT" x="10" y="0"/>
+ </Anchors>
+ </FontString>
+ </Layer>
+ </Layers>
+ </Frame>
<Frame name="GarrisonCommanderMissionPageFollowerTemplate" inherits="GarrisonMissionPageFollowerTemplate" virtual="true">
+ <Size x="170" y="58"/>
+ <Layers>
+ <Layer level="OVERLAY">
+ <FontString parentKey="Status" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="TOP" text="Available">
+ <Size x="100" y="30" />
+ <Anchors>
+ <Anchor point="TOPLEFT" relativeKey="$parent" relativePoint="TOPLEFT" x="10" y="-5"/>
+ <Anchor point="TOPRIGHT" relativeKey="$parent" relativePoint="TOPRIGHT" x="0" y="+5"/>
+ </Anchors>
+ <Color r="0.698" g="0.941" b="1" a="1"/>
+ </FontString>
+ <FontString parentKey="NotFull" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="CENTER" text="GARRISON_PARTY_NOT_FULL_TOOLTIP" hidden="true">
+ <Size x="100" y="58"/>
+ <Anchors>
+ <Anchor point="TOPLEFT" relativeKey="$parent.PortraitFrame" relativePoint="TOPRIGHT" x="0" y="0"/>
+ <Anchor point="TOPRIGHT" relativeKey="$parent" relativePoint="TOPRIGHT" x="-10" y="0"/>
+ </Anchors>
+ <Color r="1.0" g="0.0" b="0.0" a="0.5" />
+ </FontString>
+ </Layer>
+
+ </Layers>
+ <Frames>
+ <Frame parentArray="Threats" inherits="GarrisonAbilityCounterTemplate">
+ <Anchors>
+ <Anchor point="LEFT" x="55" y="-3"/>
+ </Anchors>
+ </Frame>
+ </Frames>
<Scripts>
<OnLoad/>
<OnDragStart/>
@@ -94,4 +166,62 @@
<OnMouseUp />
</Scripts>
</Frame>
+ <Button name="GarrisonCommanderMissionButton" inherits="GarrisonCommanderBackground" virtual="true">
+ <Size x="600" y="80"/>
+ <Layers>
+ <Layer level="ARTWORK">
+ <FontString parentKey="Age" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="TOP" >
+ <Size x="60" y="70"/>
+ <Anchors>
+ <Anchor point="TOPLEFT" relativeKey="$parent" relativePoint="TOPLEFT" x="10" y="-5"/>
+ </Anchors>
+ <Color r="0.698" g="0.941" b="1" a="1"/>
+ </FontString>
+ <FontString parentKey="Percent" inherits="NumberFontNormalHuge" justifyH="RIGHT" justifyV="BOTTOM" >
+ <Size x="60" y="70"/>
+ <Anchors>
+ <Anchor point="BOTTOMLEFT" relativeKey="$parent" relativePoint="BOTTOMLEFT" x="0" y="10"/>
+ </Anchors>
+ </FontString>
+ </Layer>
+ </Layers>
+ <Frames>
+ <Frame parentArray="Party" name="$parentFollower" inherits="GarrisonCommanderMissionPageFollowerTemplate">
+ <Anchors>
+ <Anchor point="BOTTOMLEFT" relativeKey="$parent.Percent" relativePoint="BOTTOMRIGHT" x="40" y="0"/>
+ </Anchors>
+ </Frame>
+ </Frames>
+ </Button>
+ <Button name="GarrisonCommanderMissionListButtonTemplate" inherits="GarrisonMissionListButtonTemplate" virtual="true">
+ <Layers>
+ <Layer level="OVERLAY" >
+ <FontString parentKey="NumMembers" inherits="GameFontHighlightSmall" justifyH="CENTER" justifyV="CENTER" maxLines="3" >
+ <Size x="90" y="40" />
+ <Anchors>
+ <Anchor point="TOPLEFT" x="68" y="-2"/>
+ </Anchors>
+ <Color r="1" g="1" b="1"/>
+ </FontString>
+ <FontString parentKey="Percent" inherits="NumberFontNormalHuge" justifyH="CENTER" justifyV="CENTER" maxLines="3" >
+ <Size x="90" y="40" />
+ <Anchors>
+ <Anchor point="BOTTOMLEFT" x="68" y="+2"/>
+ </Anchors>
+ <Color r="1" g="1" b="1"/>
+ </FontString>
+ </Layer>
+ </Layers>
+ </Button>
+ <Frame name="GarrisonCommanderFollowerMissionList" virtual="true">
+ <Size x="400" y="400" />
+ <Frames>
+ <Button parentArray="Missions" name="$parentMissions" inherits="GarrisonCommanderMissionListButtonTemplate" >
+ <Size x="450" y="80" />
+ <Anchors>
+ <Anchor point="TOPLEFT" />
+ </Anchors>
+ </Button>
+ </Frames>
+ </Frame>
</Ui>
\ No newline at end of file
diff --git a/bigframe.lua b/bigframe.lua
deleted file mode 100644
index 1af94d4..0000000
--- a/bigframe.lua
+++ /dev/null
@@ -1,1714 +0,0 @@
-local me, ns = ...
-local addon=LibStub("LibInit"):NewAddon(me,'AceHook-3.0','AceTimer-3.0','AceEvent-3.0') --#Addon
-local C=addon:GetColorTable()
-local L=addon:GetLocale()
-local print=ns.print or print
-local debug=ns.debug or print
-local dump=ns.dump or print
-local pairs=pairs
-print("Loaded bigframe")
----TODO:
--- Colorare i seguaci in base ala disponbilita' (verdi disponibili, rossi in altre missioni. Magary gialli se working?)
--- Memorizzare la percentuale di successo delle missioni partire, per visualizzarla nel pannello in progress
--- Rifare il tooltip
--- Decidere come (se) usare lo spazio che rimane a destra delle icone
-
---@debug@
-local function tcopy(obj, seen)
- if type(obj) ~= 'table' then return obj end
- if seen and seen[obj] then return seen[obj] end
- local s = seen or {}
- local res = setmetatable({}, getmetatable(obj))
- s[obj] = res
- for k, v in pairs(obj) do res[tcopy(k, s)] = tcopy(v, s) end
- return res
-end
---@end-debug@
------------------------------------------------------------------
--- Recycling function from ACE3
-----newcount, delcount,createdcount,cached = 0,0,0
-local new, del, copy
-do
- local pool = setmetatable({},{__mode="k"})
- function new()
- --newcount = newcount + 1
- local t = next(pool)
- if t then
- pool[t] = nil
- return t
- else
- --createdcount = createdcount + 1
- return {}
- end
- end
- function copy(t)
- local c = new()
- for k, v in pairs(t) do
- c[k] = v
- end
- return c
- end
- function del(t)
- --delcount = delcount + 1
- wipe(t)
- pool[t] = true
- end
--- function cached()
--- local n = 0
--- for k in pairs(pool) do
--- n = n + 1
--- end
--- return n
--- end
-end
-local function capitalize(s)
- s=tostring(s)
- return strupper(s:sub(1,1))..strlower(s:sub(2))
-end
--- Name is here just for doc, I will be using the localized one
-
-local abilities={
- {
- ["name"] = "Wild Aggression",
- ["icon"] = "Interface\\ICONS\\Spell_Nature_Reincarnation.blp",
- }, -- [1]
- {
- ["name"] = "Massive Strike",
- ["icon"] = "Interface\\ICONS\\Ability_Warrior_SavageBlow.blp",
- }, -- [2]
- {
- ["name"] = "Group Damage",
- ["icon"] = "Interface\\ICONS\\Spell_Fire_SelfDestruct.blp",
- }, -- [3]
- {
- ["name"] = "Magic Debuff",
- ["icon"] = "Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp",
- }, -- [4]
- nil, -- [5]
- {
- ["name"] = "Danger Zones",
- ["icon"] = "Interface\\ICONS\\spell_Shaman_Earthquake.blp",
- }, -- [6]
- {
- ["name"] = "Minion Swarms",
- ["icon"] = "Interface\\ICONS\\Spell_DeathKnight_ArmyOfTheDead.blp",
- }, -- [7]
- {
- ["name"] = "Powerful Spell",
- ["icon"] = "Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp",
- }, -- [8]
- {
- ["name"] = "Deadly Minions",
- ["icon"] = "Interface\\ICONS\\Achievement_Boss_TwinOrcBrutes.blp",
- }, -- [9]
- {
- ["name"] = "Timed Battle",
- ["icon"] = "Interface\\ICONS\\SPELL_HOLY_BORROWEDTIME.BLP",
- }, -- [10]
-}
---- upvalues
-local AVAILABLE=AVAILABLE -- "Available"
-local BUTTON_INFO=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS.. " " .. GARRISON_MISSION_PERCENT_CHANCE
-local ENVIRONMENT_SUBHEADER=ENVIRONMENT_SUBHEADER -- "Environment"
-local G=C_Garrison
-local GARRISON_BUILDING_SELECT_FOLLOWER_TITLE=GARRISON_BUILDING_SELECT_FOLLOWER_TITLE -- "Select a Follower";
-local GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP=GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP -- "Click here to assign a Follower";
-local GARRISON_FOLLOWERS=GARRISON_FOLLOWERS -- "Followers"
-local GARRISON_FOLLOWER_CAN_COUNTER=GARRISON_FOLLOWER_CAN_COUNTER -- "This follower can counter:"
-local GARRISON_FOLLOWER_EXHAUSTED=GARRISON_FOLLOWER_EXHAUSTED -- "Recovering (1 Day)"
-local GARRISON_FOLLOWER_INACTIVE=GARRISON_FOLLOWER_INACTIVE --"Inactive"
-local GARRISON_FOLLOWER_IN_PARTY=GARRISON_FOLLOWER_IN_PARTY
-local GARRISON_FOLLOWER_ON_MISSION=GARRISON_FOLLOWER_ON_MISSION -- "On Mission"
-local GARRISON_FOLLOWER_WORKING=GARRISON_FOLLOWER_WORKING -- "Working
-local GARRISON_MISSION_PERCENT_CHANCE=GARRISON_MISSION_PERCENT_CHANCE
-local GARRISON_MISSION_SUCCESS=GARRISON_MISSION_SUCCESS -- "Success"
-local GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS -- "%d Follower mission";
-local GARRISON_PARTY_NOT_FULL_TOOLTIP=GARRISON_PARTY_NOT_FULL_TOOLTIP -- "You do not have enough followers on this mission."
-local GMF=GarrisonMissionFrame
-local GMFFollowerPage=GMF.FollowerTab
-local GMFFollowers=GarrisonMissionFrameFollowers
-local GMFMissionPage=GMF.MissionTab
-local GMFMissionPageFollowers = GMFMissionPage.MissionPage.Followers
-local GMFMissions=GarrisonMissionFrameMissions
-local GMFMissionsTab1=GarrisonMissionFrameMissionsTab1
-local GMFMissionsTab2=GarrisonMissionFrameMissionsTab2
-local GMFMissionsTab3=GarrisonMissionFrameMissionsTab2
-local GMFRewardPage=GMFMissions.MissionComplete
-local GMFRewardSplash=GMFMissions.CompleteDialog
-local GMFMissionsListScrollFrameScrollChild=GarrisonMissionFrameMissionsListScrollFrameScrollChild
-local GMFMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
-local GMFTab1=GarrisonMissionFrameTab1
-local GMFTab2=GarrisonMissionFrameTab2
-local GMFTab3=GarrisonMissionFrameTab3
-local GarrisonMissionFrameMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
-local IGNORE_UNAIVALABLE_FOLLOWERS=IGNORE.. ' ' .. UNAVAILABLE .. ' ' .. GARRISON_FOLLOWERS
-local IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=IGNORE.. ' ' .. GARRISON_FOLLOWER_INACTIVE .. ',' .. GARRISON_FOLLOWER_ON_MISSION ..',' .. GARRISON_FOLLOWER_WORKING.. ','.. GARRISON_FOLLOWER_EXHAUSTED .. ' ' .. GARRISON_FOLLOWERS
-local PARTY=PARTY -- "Party"
-local SPELL_TARGET_TYPE1_DESC=capitalize(SPELL_TARGET_TYPE1_DESC) -- any
-local SPELL_TARGET_TYPE4_DESC=capitalize(SPELL_TARGET_TYPE4_DESC) -- party member
-local ANYONE='('..SPELL_TARGET_TYPE1_DESC..')'
-local UNKNOWN_CHANCE=GARRISON_MISSION_PERCENT_CHANCE:gsub('%%d%%%%',UNKNOWN)
-IGNORE_UNAIVALABLE_FOLLOWERS=capitalize(IGNORE_UNAIVALABLE_FOLLOWERS)
-IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=capitalize(IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL)
--- Panel sizes
-local BIGSIZEW=1500
-local BIGSIZEH=662
-local SIZEW=950
-local SIZEH=662
-local BIGBUTTON=BIGSIZEW-700
-local SMALLBUTTON=BIGSIZEW-900
-local GameTooltip=GameTooltip
--- Want to know what I call!!
-local GarrisonMissionButton_OnEnter=GarrisonMissionButton_OnEnter
-local GarrisonFollowerList_UpdateFollowers=GarrisonFollowerList_UpdateFollowers
-local GarrisonMissionList_UpdateMissions=GarrisonMissionList_UpdateMissions
-local GarrisonMissionPage_ClearFollower=GarrisonMissionPage_ClearFollower
-local GarrisonMissionPage_UpdateMissionForParty=GarrisonMissionPage_UpdateMissionForParty
-local GarrisonMissionPage_SetFollower=GarrisonMissionPage_SetFollower
-
-local ITEM_QUALITY_COLORS=ITEM_QUALITY_COLORS
-function addon:GetDifficultyColor(perc)
- if(perc >90) then
- return QuestDifficultyColors['standard']
- elseif (perc >74) then
- return QuestDifficultyColors['difficult']
- elseif(perc>49) then
- return QuestDifficultyColors['verydifficult']
- elseif(perc >20) then
- return QuestDifficultyColors['impossible']
- else
- return ITEM_QUALITY_COLORS[4]
- end
-end
-if (LibDebug) then LibDebug() end
------ Local variables
-local masterplan
-local availableFollowers=0 -- Total numner of non in mission followers
-local followersCache={}
-local followersCacheIndex={}
-local dirty=false
---- Parties storage
---
-local parties=setmetatable({},{
- __index=function(t,k) rawset(t,k,{members={},perc=0,full=false}) return t[k] end
-})
-
---- Follower Missions Info
---
-local followerMissions=setmetatable({},{
- __index=function(t,k) rawset(t,k,{}) return t[k] end
-})
-
------------------------------------------------------
--- Temporary party management
-local openParty,isInParty,pushFollower,removeFollower,closeParty,roomInParty,storeFollowers
-
-do
- local ID,frames,members,maxFollowers=0,{},{},1
- ---@function [parent=#local] openParty
- function openParty(missionID,followers)
- if (#frames > 0 or #members > 0) then
- error("Unbalanced openParty/closeParty")
- end
- maxFollowers=followers
- frames={GetFramesRegisteredForEvent('GARRISON_FOLLOWER_LIST_UPDATE')}
- for i=1,#frames do
- frames[i]:UnregisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
- end
- ID=missionID
- end
- ---@function [parent=#local] isInParty
- function isInParty(followerID)
- for i=1,maxFollowers do
- if (followerID==members[i]) then return true end
- end
- end
- ---@function [parent=#local] roomInParty
- function roomInParty()
- return not members[maxFollowers]
- end
- ---@function [parent=#local] pushFollower
- function pushFollower(followerID)
- if (followerID:sub(1,2) ~= '0x') then error(followerID .. "is not an id") end
- if (roomInParty()) then
- local rc,code=pcall (C_Garrison.AddFollowerToMission,ID,followerID)
- if (rc and code) then
- tinsert(members,followerID)
- return true
---@debug@
- else
- print("Error adding ", followerID,"to",ID,code)
---@end-debug@
- end
- end
- end
- ---@function [parent=#local] removeFollowers
- function removeFollower(followerID)
- for i=1,maxFollowers do
- if (followerID==members[i]) then
- tremove(members,i)
- local rc,code=pcall(C_Garrison.RemoveFollowerFromMission,ID,followerID)
---@debug@
- if (not rc) then print("Error removing", members[i],"from",ID,code) end
---@end-debug@
- return true end
- end
- end
-
- ---@function [parent=#local] storeFollowers
- function storeFollowers(table)
- wipe(table)
- for i=1,#members do
- tinsert(table,members[i])
- end
- return #table
- end
-
- ---@function [parent=#local] closeParty
- function closeParty()
- local perc=select(4,G.GetPartyMissionInfo(ID))
- for i=1,3 do
- if (members[i]) then
- local rc,code=pcall(C_Garrison.RemoveFollowerFromMission,ID,members[i])
---@debug@
- if (not rc) then print("Error popping ", members[i]," from ",ID,code) end
---@end-debug@
-
- else
- break
- end
- end
- for i=1,#frames do
- frames[i]:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
- end
- wipe(frames)
- wipe(members)
- return perc
- end
-end
--- ProgressBar
-
-function addon:AddLine(icon,name,status,quality,...)
- local r2,g2,b2=C.Red()
- local q=ITEM_QUALITY_COLORS[quality or 1] or {}
- if (status==AVAILABLE) then
- r2,g2,b2=C.Green()
- elseif (status==GARRISON_FOLLOWER_WORKING) then
- r2,g2,b2=C.Orange()
- end
- --GameTooltip:AddDoubleLine(name, status or AVAILABLE,r,g,b,r2,g2,b2)
- --GameTooltip:AddTexture(icon)
- GameTooltip:AddDoubleLine(icon and "|T" .. tostring(icon) .. ":0|t " .. name or name, status,q.r,q.g,q.b,r2,g2,b2)
-end
-
-
-function addon:RestoreTooltip()
- local self = GMF.MissionTab.MissionList;
- local scrollFrame = self.listScroll;
- local buttons = scrollFrame.buttons;
- for i =1,#buttons do
- buttons[i]:SetScript("OnEnter",GarrisonMissionButton_OnEnter)
- end
-end
--- This is a ugly hack while I rewrite this code for 2.0
-
-local function cmp(a,b)
- if (a.name==TYPE and b.name~=TYPE) then return false end
- if (b.name==TYPE and a.name~=TYPE) then return true end
- if (a.name~=b.name) then return a.name < b.name end
- if (a.bias==-1) then return false end
- if (b.bias==-1) then return true end
- if (a.bias~=b.bias) then return (a.bias>b.bias) end
- if (a.rank ~= b.rank) then return (a.rank > b.rank) end
- return a.quality > b.quality
-end
-
-
-function addon:FillCounters(missionID,mission)
---[[
- [12]={
- description="Iron Horde raiders have descended on nearby draenei villages. Find the raiders' camp and raid it. Turnabout, they say, is fair play.",
- cost=15,
- duration="4 hr",
- slots={
- ["Minion Swarms"]=1,
- Type=1,
- ["Deadly Minions"]=1
- },
- durationSeconds=14400,
- party={
- party2="<empty>",
- party1="<empty>"
- },
- level=100,
- type="Combat",
- counters={
- ["0x00000000001BE95D"]={
- [1]={
- counterIcon="Interface\\ICONS\\Ability_Rogue_FanofKnives.blp",
- name="Minion Swarms",
- counterName="Fan of Knives",
- icon="Interface\\ICONS\\Spell_DeathKnight_ArmyOfTheDead.blp",
- description="An enemy with many allies. Susceptible to area-of-effect damage."
- }
- },
- ["0x00000000002D61EB"]={
- [1]={
- counterIcon="Interface\\ICONS\\Spell_Shaman_Hex.blp",
- name="Deadly Minions",
- counterName="Hex",
- icon="Interface\\ICONS\\Achievement_Boss_TwinOrcBrutes.blp",
- description="An enemy with powerful allies that should be neutralized."
- }
- }
- },
- traits={
- ["0x00000000001BE95D"]={
- [1]={
- traitID=236,
- icon="Interface\\ICONS\\Item_Hearthstone_Card.blp"
- }
- }
- },
- locPrefix="GarrMissionLocation-Nagrand",
- rewards={
- [795]={
- itemID=120301,
- quantity=1
- }
- },
- numRewards=1,
- numFollowers=2,
- state=-2,
- iLevel=0,
- name="Raiding the Raiders",
- followers={
- },
- location="Nagrand",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=380
- }
-}
---]]
- if (not mission) then return end
- local slots=mission.slots
- wipe(mission.counters)
- for id,d in pairs(G.GetBuffedFollowersForMission(missionID)) do
- local rank=self:GetFollowerData(id,'rank')
- local quality=self:GetFollowerData(id,'quality')
- local bias= G.GetFollowerBiasForMission(missionID,id);
- for i,l in pairs(d) do
- -- i is meaningful
- -- l.counterIcon
- -- l.name
- -- l.counterName
- -- l.icon
- -- l.description
- tinsert(mission.counters,{name=l.name,follower=id,bias=bias,rank=rank,quality=quality})
- followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
- end
- end
- for id,d in pairs(G.GetFollowersTraitsForMission(missionID)) do
- local level=self:GetFollowerData(id,'level')
- local bias= G.GetFollowerBiasForMission(missionID,id);
- local rank=self:GetFollowerData(id,'rank')
- local quality=self:GetFollowerData(id,'quality')
- for i,l in pairs(d) do
- --l.traitID
- --l.icon
- if (l.traitID ~= 236) then
- followerMissions[id][missionID]=1+ (tonumber(followerMissions[id][missionID]) or 0)
- tinsert(mission.counters,{name=TYPE,follower=id,bias=bias,rank=rank,quality=quality})
- end
- end
- end
- table.sort(mission.counters,cmp)
-end
-function addon:Check(missionID)
-
-end
-function addon:MatchMaker(missionID,mission,party,skipbusy)
- if (not mission) then return end
- if (GMFRewardSplash:IsShown()) then return end
-
- local dbg=missionID==(tonumber(_G.MW) or 0)
- if dbg then print(C("Matchmaker debug for " .. mission.name,"Yellow")) end
- if (not skipbusy) then
- skipbusy=self:GetBoolean("IGM")
- end
- local slots=mission.slots
- if (slots) then
- local countered=new()
- local counters=mission.counters
- if (dbg) then print("Preparying party") end
- openParty(missionID,mission.numFollowers)
- for i=1,#counters do
- local f=counters[i]
- local menace=f.name
- countered[menace]=countered[menace] or slots[menace] or 0
- if (countered[menace] > 0) then
- if (dbg) then print("Considering ",self:GetFollowerData(f.follower,'name'),"for",menace) end
- if (roomInParty() and self:GetFollowerStatusForMission(f.follower,skipbusy) and pushFollower(f.follower)) then
- if (dbg) then print("Taken ",self:GetFollowerData(f.follower,'name'),"for",menace) end
- countered[menace]=countered[menace]-1
- end
- end
- end
- del(countered)
- local perc=select(4,G.GetPartyMissionInfo(missionID)) -- If percentage is already 100, I'll try and add the most useless character
- local candidateMissions=10000
- local candidateRank=10000
- local candidateQuality=9999
- for x=1,3 do
- if dbg then print("Party filling") end
- if (not roomInParty()) then break end
- if dbg then print("Party is not full") end
- local candidate
- local candidatePerc=perc
- for _,data in pairs(followersCache) do
- local followerID=data.followerID
- if (not isInParty(followerID) and self:GetFollowerStatusForMission(followerID,skipbusy)) then
- local missions=#followerMissions[followerID]
- local rank=data.rank
- local quality=data.quality
- if (dbg) then print("Verifying",self:GetFollowerData(followerID,'name'),missions,rank,quality) end
- local skipMinimize
- if (perc<=100) then
- pushFollower(followerID)
- local newperc=select(4,G.GetPartyMissionInfo(missionID))
- removeFollower(followerID)
- if (newperc > candidatePerc) then
- candidatePerc=newperc
- candidate=followerID
- candidateMissions=missions
- candidateRank=rank
- candidateQuality=quality
- skipMinimize=true -- Improvement, go with him
- elseif (newperc < candidatePerc) then
- skipMinimize=true -- Deprovement, go away
- end
- end
- if (not skipMinimize) then
- if (missions<candidateMissions) then
- candidate=followerID
- candidateMissions=missions
- candidateRank=rank
- candidateQuality=quality
- elseif(missions==candidateMissions and rank<candidateRank) then
- candidate=followerID
- candidateMissions=missions
- candidateRank=rank
- candidateQuality=quality
- elseif(missions==candidateMissions and rank==candidateRank and quality<candidateQuality) then
- candidate=followerID
- candidateMissions=missions
- candidateRank=rank
- candidateQuality=quality
- end
- end
- end
- end
- if (candidate) then
- pushFollower(candidate)
- perc=select(4,G.GetPartyMissionInfo(missionID))
- end
-
- end
- storeFollowers(party.members)
- party.full= not roomInParty()
- party.perc=closeParty()
- if (dbg) then print(C("Matchmaker end","silver")) end
- end
-end
-function addon:TooltipAdder(missionID)
- local mission=self:GetMissionData(missionID)
---@debug@
- GameTooltip:AddLine("ID:" .. tostring(missionID))
- if (not mission) then GameTooltip:AddLine("E dove minchia è finita??") return end
---@end-debug@
- local party=parties[missionID]
- GameTooltip:AddDoubleLine("Base",mission.basePerc)
- GameTooltip:AddDoubleLine("Free",party.perc)
- for i=1,mission.numFollowers do
- local fid=party.members[i]
- if (fid) then
- GameTooltip:AddLine(self:GetFollowerData(fid,'name'))
- end
- end
- if (IsAltKeyDown()) then
- print("Alt down")
- _G.MW=missionID
- wipe(parties[missionID])
- self:RenderButton(GetMouseFocus(),true)
- _G.MW=nil
- end
-
-end
-
-function addon:TooltipAdderx(missionID,skipTT)
---@debug@
- if (not skipTT) then GameTooltip:AddLine("ID:" .. tostring(missionID)) end
---@end-debug@
- self:MatchMaker(missionID)
- local perc=select(4,G.GetPartyMissionInfo(missionID))
- self:GetRunningMissionData()
- local q=self:GetDifficultyColor(perc)
- if (not skipTT) then GameTooltip:AddDoubleLine(GARRISON_MISSION_SUCCESS,format(GARRISON_MISSION_PERCENT_CHANCE,perc),nil,nil,nil,q.r,q.g,q.b) end
- local buffed=new()
- local traited=new()
- local buffs=new()
- local traits=new()
- local fellas=new()
- availableFollowers=0
- self:GetRunningMissionData()
- for id,d in pairs(G.GetBuffedFollowersForMission(missionID)) do
- buffed[id]=d
- end
- for id,d in pairs(G.GetFollowersTraitsForMission(missionID)) do
- for x,y in pairs(d) do
---@debug@
- self.db.global.traits[y.traitID]=y.icon
---@end-debug@
- if (y.traitID~=236) then --Ignore hearthstone traits
- traited[id]=d
- break
- end
- end
- end
- local followerList=GarrisonMissionFrameFollowers.followersList
-
- for j=1,#followerList do
- local index=followerList[j]
- local follower=followers[index]
- follower.rank=follower.level < 100 and follower.level or follower.iLevel
- if (not follower.isCollected) then break end
- if (not follower.status) then
- availableFollowers=availableFollowers+1
- end
- if (follower.status and self:GetBoolean('IGM')) then
- else
- local id=follower.followerID
- local b=buffed[id]
- local t=traited[id]
- local followerBias = G.GetFollowerBiasForMission(missionID,id);
- follower.bias=followerBias
- local formato=C("%3d","White")
- if (followerBias==-1) then
- formato=C("%3d","Red")
- elseif (followerBias < 0) then
- formato=C("%3d","Orange")
- end
- formato=formato.." %s"
---@debug@
- formato=formato .. " 0x+(0*8) " .. id:sub(11)
---@end-debug@
- if (b) then
- if (not buffs[id]) then
- buffs[id]={rank=follower.rank,simple=follower.name,name=format(formato,follower.rank,follower.name),quality=follower.quality,status=(follower.status or AVAILABLE)}
- end
- for _,ability in pairs(b) do
- buffs[id].name=buffs[id].name .. " |T" .. tostring(ability.icon) .. ":0|t"
- if (not follower.status) then
- local aname=ability.name
- if (not fellas[aname]) then
- fellas[aname]={}
- end
- fellas[aname]={id=follower.followerID,rank=follower.rank,level=follower.level,iLevel=follower.iLevel,name=follower.name}
- end
- end
- end
- if (t) then
- if (not traits[id]) then
- traits[id]={rank=follower.rank,simple=follower.name,name=format(formato,follower.rank,follower.name),quality=follower.quality,status=follower.status or AVAILABLE}
- end
- for _,ability in pairs(t) do
- traits[id].name=traits[id].name .. " |T" .. tostring(ability.icon) .. ":0|t"
- end
- end
- end
- end
- local added=new()
- local maxfollowers=G.GetMissionMaxFollowers(missionID)
- requested[missionID]=maxfollowers
- local partyshown=false
- local perc=0
- if (next(traits) or next(buffs) ) then
- if (not skipTT) then GameTooltip:AddLine(GARRISON_FOLLOWER_CAN_COUNTER) end
- for id,v in pairs(buffs) do
- local status=(v.status == GARRISON_FOLLOWER_ON_MISSION and (timers[id] or GARRISON_FOLLOWER_ON_MISSION)) or v.status
- if (not skipTT) then self:AddLine(nil,v.name,status,v.quality) end
- end
- for id,v in pairs(traits) do
- local status=(v.status == GARRISON_FOLLOWER_ON_MISSION and (timers[id] or GARRISON_FOLLOWER_ON_MISSION)) or v.status
- if (not skipTT) then self:AddLine(nil,v.name,status,v.quality) end
- end
- if (not skipTT) then GameTooltip:AddLine(PARTY,C.White()) end
- partyshown=true
- local enemies = select(8,G.GetMissionInfo(missionID))
- --local missionInfo=G.GetBasicMissionInfo(missionID)
---@debug@
- --DevTools_Dump(fellas)
---@end-debug@
- for _,enemy in pairs(enemies) do
- for i,mechanic in pairs(enemy.mechanics) do
---@debug@
- self.db.global.abilities[i]={name=mechanic.name,icon=mechanic.icon}
---@end-debug@
- local menace=mechanic.name
- local res
- if (fellas[menace]) then
- local followerID=fellas[menace].id
- res=fellas[menace].name
- local rc,code=pcall(G.AddFollowerToMission,missionID,followerID)
- if (rc and code) then
- tinsert(added,followerID)
- end
- end
- if (not skipTT) then
- if (res) then
- GameTooltip:AddDoubleLine(menace,res,0,1,0)
- else
- GameTooltip:AddDoubleLine(menace,' ',1,0,0)
- end
- end
- end
- end
- perc=select(4,G.GetPartyMissionInfo(missionID))
- if (perc < 100 and #added < maxfollowers and next(traits)) then
- for id,v in pairs(traits) do
- local rc,code=pcall(G.AddFollowerToMission,missionID,id)
- if (rc and code) then
- tinsert(added,id)
- if (not skipTT) then GameTooltip:AddDoubleLine(ENVIRONMENT_SUBHEADER,v.simple,v.quality) end
- break
- end
- end
- perc=select(4,G.GetPartyMissionInfo(missionID))
- end
- end
- -- And then fill the roster
- local partysize=#added
- if (partysize < maxfollowers ) then
- for j=1,#followerList do
- local index=followerList[j]
- local follower=followers[index]
- if (not follower.isCollected) then
- break
- end
- if (follower.status and self:GetBoolean('IGM')) then
- else
- local rc,code=pcall(G.AddFollowerToMission,missionID,follower.followerID)
- if (rc and code) then
- if (not partyshown) then
- if (not skipTT) then GameTooltip:AddLine(PARTY,1) end
- partyshown=true
- end
- tinsert(added,follower.followerID)
- if (not skipTT) then
- GameTooltip:AddDoubleLine(SPELL_TARGET_TYPE4_DESC,follower.name,C.Orange.r,C.Orange.g,C.Orange.b)--SPELL_TARGET_TYPE1_DESC)
- end
- if (#added >= maxfollowers) then break end
- else
---@debug@
- print("Failed adding",follower.name,follower.followerID,rc,code)
---@end-debug@
- end
- end
- end
- perc=select(4,G.GetPartyMissionInfo(missionID))
- end
- local q=self:GetDifficultyColor(perc)
- if (not partyshown) then
- if (not skipTT) then GameTooltip:AddDoubleLine(PARTY,ANYONE,C.White.r,C.White.g,C.White.b) end
- end
- if (not skipTT) then GameTooltip:AddDoubleLine(GARRISON_MISSION_SUCCESS,format(GARRISON_MISSION_PERCENT_CHANCE,perc),nil,nil,nil,q.r,q.g,q.b) end
- local b=GameTooltip:GetOwner()
- successes[missionID]=perc
- if (availableFollowers < maxfollowers) then
- if (not skipTT) then GameTooltip:AddLine(GARRISON_PARTY_NOT_FULL_TOOLTIP,C:Red()) end
- else
- end
- if (not skipTT) then self:AddPerc(GameTooltip:GetOwner()) end
- for _,id in pairs(added) do
- local rc,code=pcall(G.RemoveFollowerFromMission,missionID,id)
---@debug@
- if (not rc) then print("Add",rc,code) end
---@end-debug@
- end
- -- Add a signature
- --local r,g,b=C:Silver()
- --GameTooltip:AddDoubleLine("GarrisonCommander",self.version,r,g,b,r,g,b)
- del(added)
---@debug@
- --DevTools_Dump(fellas)
---@end-debug@
- del(buffed)
- del(traited)
- del(buffs)
- del(traits)
- del(fellas)
-end
-function addon:FillFollowersList()
- if (GarrisonFollowerList_UpdateFollowers) then
- GarrisonFollowerList_UpdateFollowers(GMF.FollowerList)
- end
-end
-local function switch(obj,value)
- if (not obj) then return end
- if (value) then
- obj.text:SetTextColor(C:Green())
- else
- obj.text:SetTextColor(C:Silver())
- end
- obj:SetChecked(value)
-end
-function addon:ApplyIGM(value)
- if (not GMF) then return end
- print("ApplyIGM")
- dirty=true
- switch(GMF.gcIGM,value)
- self:RefreshMissions("Checked")
-end
-function addon:ApplyMOVEPANEL(value)
- if (not GMF) then return end
- print("ApplyMOVEPANEL",GMF.gcMOVEPANEL,value)
- switch(GMF.gcMOVEPANEL,value)
- if (value) then
- GMF:SetMovable(true)
- GMF:SetResizable(true)
- GMF:RegisterForDrag("LeftButton")
- GMF:SetScript("OnDragStart",function(frame) if (IsShiftKeyDown()) then frame:StartSizing("BOTTOMRIGHT") else frame:StartMoving() end end)
- GMF:SetScript("OnDragStop",function(frame) frame:StopMovingOrSizing() end)
- else
- GMF:SetScript("OnDragStart",nil)
- GMF:SetScript("OnDragStop",nil)
- GMF:ClearAllPoints()
- GMF:SetPoint("CENTER",UIParent)
- GMF:SetMovable(false)
- end
-end
-
-function addon:RefreshMissions(event)
---@debug@
- print("Refreshing due to",event)
---@end-debug@
- if (self:IsAvailableMissionPage()) then
- availableFollowers=0
- self:PrefillMissionList()
- wipe(parties)
- --@debug@
- print("Refresh missions called")
- --@end-debug@
- GarrisonMissionList_UpdateMissions()
- end
-end
-function addon:FixButtons()
- local self = GMF.MissionTab.MissionList
- local scrollFrame = self.listScroll
- local buttons = scrollFrame.buttons
- if (masterplan) then
- for i =1,#buttons do
- local b=buttons[i]
- b.Success:ClearAllPoints()
- if (b.Expire) then
- b.Success:SetPoint("TOPLEFT",b.Expire,"TOPRIGHT",5,0)
- else
- b.Success:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",200,-3)
- end
- b.NotEnough:SetFontObject("GameFontNormalSmall2")
- b.NotEnough:ClearAllPoints()
- b.NotEnough:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
- end
- else
- for i =1,#buttons do
- local b=buttons[i]
- b.Success:ClearAllPoints()
- b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
- b.NotEnough:SetFontObject("GameFontNormalSmall")
- b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",0,-3)
- end
- end
-end
-function addon:FixForSure()
- local rc=pcall(self.FixButtons,self)
- if (not rc) then
- self:ScheduleTimer("FixForSure",1)
- end
-end
-function addon:MasterPlanDetection(novar,...)
- local _,_,_,loadable,reason=GetAddOnInfo("MasterPlan")
- masterplan=false
- if (loadable or reason=="DEMAND_LOADED") then
- masterplan=true
- print("Rehooking tooltip")
- self:SecureHook("GarrisonMissionList_UpdateMissions","RestoreTooltip")
- self:FixForSure()
- end
-end
-function addon:PrefillMissionList()
---@debug@
- local start=GetTime()
- print("Start")
- --for x=1,10 do -- stress test
---@end-debug@
- local t=new()
- G.GetAvailableMissions(t)
- for index=1,#t do
- local id=t[index].missionID
- self:BuildMissionCache(id,t[index])
- end
- del(t)
---@debug@
- --end
- print("Done in",GetTime()-start)
---@end-debug@
-end
-function addon:BuildMissionCache(id,data)
- if (not self.db.char.seen[id]) then
- self.db.char.seen[id]=time()
- end
- local missionCache=self.db.char.missionsCache[id]
- if (missionCache.name=="<newmission>") then
- for k,v in pairs(missionCache) do
- if (data[k]) then missionCache[k]=data[k]end
- end
- missionCache.rank=missionCache.level < 100 and missionCache.level or missionCache.iLevel
- missionCache.seen=time()
- end
- missionCache.xp=true
- missionCache.resources=false
- for k,v in pairs(data.rewards) do
- if (not v.followerXP) then missionCache.xp=false end
- if (v.currencyID and v.currencyID==824) then missionCache.resource=false end
- end
- local slots=missionCache.slots
- local enemies=select(8,G.GetMissionInfo(id))
- for i=1,#enemies do
- local mechanics=enemies[i].mechanics
- for _,mechanic in pairs(mechanics) do
- slots[mechanic.name]= (slots[mechanic] or 0) +1
- end
- end
- slots[TYPE]=1
- self:FillCounters(id,missionCache)
- --self:MatchMaker(id,missionCache)
- missionCache.basePerc=select(4,G.GetPartyMissionInfo(id))
-end
-function addon:SetDbDefaults(default)
-
- default.global=default.global or {}
- default.global["*"]={}
- default.char=default.char or {}
- default.char.seen={}
- default.char.missionsCache={
- ["*"]={
- missionID=0,
- counters={},
- slots={},
- numFollowers=0,
- name="<newmission>",
- basePerc=0,
- durationSeconds=0,
- rewards={},
- level=0,
- iLevel=0
- }
- }
- default.char.lastnumericversion=0
-end
-function addon:SetClean()
- dirty=false
-end
-function addon:UseCommonProfile()
- return true
-end
-function addon:OnInitializedx()
- self:RegisterEvent("GARRISON_MISSION_LIST_UPDATE",print)
- self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE",print) --This event is quite useless, fires too often
- self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGED",print)
- self:RegisterEvent("GARRISON_FOLLOWER_ADDED",print)
- self:RegisterEvent("GARRISON_FOLLOWER_REMOVED",print)
- self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_LOOT",print)
- self:RegisterEvent("GARRISON_MISSION_FINISHED",print)
- self:RegisterEvent("GARRISON_MISSION_STARTED",print)
- self:RegisterEvent("GARRISON_MISSION_COMPLETE_RESPONSE",print)
- self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE",print)
- self:RegisterEvent("GARRISON_UPDATE",print)
- self:RegisterEvent("GARRISON_USE_PARTY_GARRISON_CHANGED",print)
- self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",print)
- self:RegisterEvent("GARRISON_MISSION_NPC_CLOSED",print)
- for i=1,20 do
- self:SafeHookScript("GarrisonMissionFrameFollowersListScrollFrameButton"..i,"OnClick",print)
- end
- print("Ho registrato in allegria")
-end
-function addon:OnInitialized()
---@debug@
- LoadAddOn("Blizzard_DebugTools")
---@end-debug@
- self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",print)
- self:RegisterEvent("GARRISON_MISSION_NPC_CLOSED",print)
---@debug@
- --Only Used for development
- self:RegisterEvent("GARRISON_MISSION_LIST_UPDATE",print)
- self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE",print) --This event is quite useless, fires too often
- self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGED",print)
- self:RegisterEvent("GARRISON_FOLLOWER_ADDED",print)
- self:RegisterEvent("GARRISON_FOLLOWER_REMOVED",print)
- self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_LOOT",print)
- self:RegisterEvent("GARRISON_MISSION_FINISHED",print)
- self:RegisterEvent("GARRISON_MISSION_COMPLETE_RESPONSE",print)
- self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE",print)
- self:RegisterEvent("GARRISON_UPDATE",print)
- self:RegisterEvent("GARRISON_USE_PARTY_GARRISON_CHANGED",print)
- self:RegisterEvent("GARRISON_MISSION_STARTED")
- self:SafeHookScript("GarrisonMissionFrameTab1","OnCLick")
- self:SafeHookScript("GarrisonMissionFrameTab2","OnCLick")
- self:SafeHookScript("GarrisonMissionFrameTab3","OnCLick")
- self:SafeHookScript(GMFMissions,"OnHide")
- self:SafeHookScript(GMFFollowers,"OnHide")
- self:SafeHookScript(GMF.MissionTab.MissionPage.CloseButton,"OnClick")
---@end-debug@
- self:SafeHookScript("GarrisonMissionFrame","OnShow","SetUp",true)
- self:AddToggle("MOVEPANEL",true,L["Makes Garrison Mission Panel Movable"]).width="full"
- self:AddToggle("IGM",true,IGNORE_UNAIVALABLE_FOLLOWERS,IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL).width="full"
- self:AddToggle("BIGPANEL",true,L["Uses a bigger mission panel"],L["Show a party preview"]).width="full"
- return true
-end
-function addon:GARRISON_MISSION_STARTED(event,missionid)
---@debug@
- print(event,missionid)
---@end-debug@
- wipe(self.db.char.missionsCache[missionid])
- self.db.char.seen[missionid]=nil
- dirty=true
- self:RefreshMissions(event)
-end
-function addon:Options()
- local f=GMF:CreateFontString()
- f:SetFontObject(GameFontNormalSmall)
- --f:SetHeight(32)
- f:SetText(me .. L[" Options:"])
- --f:SetTextColor(C:Azure())
- f:Show()
- GMF.GCLabel=f
- local b=CreateFrame("CheckButton","gcIGM",GMF,"UICheckButtonTemplate")
- b.text:SetText(L["Ignore busy followers"])
- b:SetScript("OnCLick",function(b) self:Trigger('IGM',b:GetChecked()) end)
- b:Show()
- GMF.gcIGM=b
- local l=CreateFrame("CheckButton","gcMOVEPANEL",GMF,"UICheckButtonTemplate")
- l.text:SetText(L["Unlock Panel"])
- l:SetScript("OnCLick",function(b) self:Trigger('MOVEPANEL',b:GetChecked()) end)
- l:Show()
- GMF.gcMOVEPANEL=l
- self:ApplyIGM(self:GetBoolean('IGM'))
- self:ApplyMOVEPANEL(self:GetBoolean('MOVEPANEL'))
---@debug@
- local s=CreateFrame("Frame","GACStatus",GMF)
- s:SetHeight(32)
- local st=s:CreateFontString()
- s.text=st
- st:SetFontObject(GameFontNormalSmall)
- st:Show()
- st:SetAllPoints()
- f:SetPoint("BOTTOMLEFT",GMF,"TOPLEFT",10,15)
- b:SetPoint("TOPLEFT",f,"TOPRIGHT",10,10)
- l:SetPoint("TOPLEFT",b,"TOPRIGHT",10+b.text:GetWidth(),0)
- s:SetPoint("TOPLEFT",l,"TOPRIGHT",10+l.text:GetWidth(),0)
- self:HookScript(s,"OnUpdate","Status")
---@end-debug@
-end
-
-function addon:ScriptTrace(hook,frame,...)
---@debug@
- print("Triggered " .. C(hook,"red").." script on",C(frame,"Azure"),...)
---@end-debug@
-end
-
-function addon:Status(frame)
- frame.text:SetText(format("PM:%s AM:%s FL:%s RP:%s MP:%s Av Fol: %d",
- self:IsProgressMissionPage() and 'Yes' or 'Not',
- self:IsAvailableMissionPage() and 'Yes' or 'Not',
- self:IsFollowerList() and 'Yes' or 'Not',
- self:IsRewardPage() and 'Yes' or 'Not',
- self:IsMissionPage() and 'Yes' or 'Not'),
- availableFollowers
- )
- frame:SetWidth(frame.text:GetWidth())
-end
-function addon:IsProgressMissionPage()
- return GMF:IsShown() and GarrisonMissionFrameMissionsListScrollFrame:IsShown() and GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
-end
-function addon:IsAvailableMissionPage()
- return GMF:IsShown() and GarrisonMissionFrameMissionsListScrollFrame:IsShown() and not GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
-end
-function addon:IsFollowerList()
- return GMF:IsShown() and GMFFollowers:IsShown()
-end
---GMFMissions.CompleteDialog
-function addon:IsRewardPage()
- return GMF:IsShown() and GMF.MissionComplete:IsShown()
-
-end
-function addon:IsMissionPage()
- return GMF:IsShown() and GMFMissionPage:IsShown() and GMFFollowers:IsShown()
-end
-function addon:SafeHookScript(frame,hook,method,postHook)
- local name="Unknown"
- if (type(frame)=="string") then
- name=frame
- frame=_G[frame]
- else
- if (frame and frame.GetName) then
- name=frame:GetName()
- end
- end
- if (frame) then
- if (method) then
- if (postHook) then
- self:SecureHookScript(frame,hook,method)
---@debug@
- print("PostHooked",name,hook)
---@end-debug@
- else
- self:HookScript(frame,hook,method)
---@debug@
- print("PreHooked",name,hook)
---@end-debug@
- end
- else
- if (postHook) then
- self:SecureHookScript(frame,hook,function(...) self:ScriptTrace(name,hook,...) end)
- print("DummyPostHooked:",name,hook)
- else
- self:HookScript(frame,hook,function(...) self:ScriptTrace(name,hook,...) end)
- print("DummyPreHooked:",name,hook)
- end
- end
---@debug@
- else
- print(C("Attempted hook for non existent:","red"),name,hook)
---@end-debug@
- end
-end
-function addon:AddPerc(b,...)
- if (b and b.info and b.info.missionID and b.info.missionID ) then
- if (GMF.MissionTab.MissionList.showInProgress) then
- self:RenderButton(b)
- if (b.ProgressHidden) then
- return
- else
- b.ProgressHidden=true
- if (b.Success) then
- b.Success:Hide()
- end
- if (b.NotEnough) then
- b.NotEnough:Hide()
- end
- return
- end
-
- end
- local missionID=b.info.missionID
- local Perc=successes[missionID] or -2
- if (not b.Success) then
- b.Success=b:CreateFontString()
- if (masterplan) then
- b.Success:SetFontObject("GameFontNormal")
- else
- b.Success:SetFontObject("GameFontNormalLarge2")
- end
- b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
- end
- if (not b.NotEnough) then
- b.NotEnough=b:CreateFontString()
- if (masterplan) then
- b.NotEnough:SetFontObject("GameFontNormal")
- b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",150,-3)
- else
- b.NotEnough:SetFontObject("GameFontNormalSmall2")
- b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",0,-3)
- end
- b.NotEnough:SetText("(".. GARRISON_PARTY_NOT_FULL_TOOLTIP .. ")")
- b.NotEnough:SetTextColor(C:Red())
- end
- if (Perc <0 and not b:IsMouseOver()) then
- self:TooltipAdder(missionID,true)
- Perc=successes[missionID] or -2
- end
- if (Perc>=0) then
- if (masterplan) then
- b.Success:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,successes[missionID])
- else
- b.Success:SetFormattedText(BUTTON_INFO,G.GetMissionMaxFollowers(missionID),successes[missionID])
- end
- local q=self:GetDifficultyColor(successes[missionID])
- b.Success:SetTextColor(q.r,q.g,q.b)
- else
- b.Success:SetText(UNKNOWN_CHANCE)
- b.Success:SetTextColor(1,1,1)
- end
- b.Success:Show()
- if (not requested[missionID]) then
- requested[missionID]=G.GetMissionMaxFollowers(missionID)
- end
- if (requested[missionID]>availableFollowers) then
- b.NotEnough:Show()
- else
- b.NotEnough:Hide()
- end
- b.ProgressHidden=false
- end
-end
-function addon:SetUp(...)
- self:Options()
- self:MasterPlanDetection()
- self:StartUp()
-end
-function addon:StartUp(...)
- self:Unhook(GMF,"OnShow")
- self:GrowPanel(self:GetBoolean("BIGPANEL"))
- self:SecureHook("GarrisonMissionFrame_CheckCompleteMissions",function(...) print("GarrisonMissionFrame_CheckCompleteMissions",...) end)
- self:SecureHook("GarrisonMissionButton_AddThreatsToTooltip",function(id) self:TooltipAdder(id) end)
- self:SecureHook("GarrisonMissionButton_SetRewards","RenderButton")
- self:HookScript(GMF,"OnHide","CleanUp")
- -- Forcing refresh when needed without possibly disrupting Blizzard Logic
- self:SecureHook("GarrisonMissionFrame_HideCompleteMissions",function() addon:RefreshMissions("MissionCompleteClose") end) -- Mission reward completed
- self:SafeHookScript(GMFMissions,"OnShow",function (f,...) print(f:GetName(),'OnShow') self:GrowPanel(true) end )
- self:SafeHookScript(GMFFollowers,"OnShow",function (f,...) print(f:GetName(),'OnShow') self:GrowPanel(false) end )
- self:SecureHook("GarrisonMissionPage_ShowMission","UpdateMissionPage")
- self:RefreshMissions()
-end
-function addon:CleanUp()
- self:UnhookAll()
- self:SafeHookScript("GarrisonMissionFrame","OnSHow","StartUp",true)
- collectgarbage("collect")
-end
-function addon:GetFollowerData(key,subkey)
- local k=followersCacheIndex[key]
- if (not followersCache[1]) then
- followersCache=G.GetFollowers()
- for i,v in pairs(followersCache) do
- if (not v.isCollected) then
- followersCache[i]=nil
- else
- v.rank=v.level==100 and v.iLevel or v.level
- end
- end
- end
- local t=followersCache
- if (not k) then
- for i=1,#t do
- if (t[i] and (t[i].followerID == key or t[i].name==key)) then
- followersCacheIndex[t[i].followerID]=i
- followersCacheIndex[t[i].name]=i
- k=i
- break
- end
- end
- end
- if (k) then
- if (subkey) then
- if (subkey=='rank') then
- return t[k].level==100 and t[k].iLevel or t[k].level
- else
- return t[k][subkey]
- end
- else
- return t[k]
- end
- else
- return nil
- end
-end
-function addon:GetMissionData(missionID)
- local missionCache=self.db.char.missionsCache[missionID]
- if (missionCache.name=="<newmission>") then
- print("Found a new mission",missionID,"Refreshing mission list")
- self:PrefillMissionList()
- end
- return missionCache
-end
-function addon:GetFollowerStatusForMission(followerID,skipbusy)
- if (not skipbusy) then
- return true
- else
- return self:GetFollowerStatus(followerID) == AVAILABLE
- end
-end
-function addon:GetFollowerStatus(followerID,withTime)
- local status=G.GetFollowerStatus(followerID)
- if (status and status== GARRISON_FOLLOWER_ON_MISSION and withTime) then
- local t=GMF.MissionTab.MissionList.inProgressMissions
- for i=1,#t do
- for k=1,#t.followers do
- if (t.followers[k]==followerID) then
- return t.timeLeft
- end
- end
- end
- end
- return status or AVAILABLE
-end
-
-function addon:ClearFollowers()
- wipe(followers)
-end
-function addon:GarrisonMissionListTab_OnClick(frame, button)
- local id=frame:GetID()
- if (id==1) then
- self:CacheFollowers()
- end
- self.hooks[frame].OnClick(frame)
- GarrisonMissionFrame_SelectTab(id);
- if (true) then return end
- if (id == 1) then
- GMF:SetWidth(1600)
- GMFMissions:SetWidth(890+1600-1250)
- GMFFollowers:Show()
- GMFMissions:ClearAllPoints()
- GMFMissions:SetPoint("TOPLEFT",GMF,"TOPLEFT",GMFFollowers:GetWidth()+35,-65)
- else
- GMF:SetWidth(930)
- end
-end
-function addon:DumpFollowerMissions()
- for k,v in pairs(followerMissions) do
- print(self:GetFollowerData(k,'name'))
- for kk,vv in pairs(v) do
- print(kk,vv)
- end
- end
-end
-function addon:UpdateMissionPage(missionInfo)
---@debug@
- print("UpdateMissionPage for",missionInfo.missionID)
---@end-debug@
- --DevTools_Dump(missionInfo)
- --self:BuildMissionData(missionInfo.missionID.missionInfo)
- local mission=self:GetMissionData(missionInfo.missionID)
- local t=new()
- t.members=new()
- self:MatchMaker(mission.missionID,mission,t,true)
- local members=t.members
- for i=1,#members do
- GarrisonMissionPage_ClearFollower(GMFMissionPageFollowers[i])
- end
- for i=1,#members do
- local info=self:GetFollowerData(members[i])
- print(members[i],info.name)
- GarrisonMissionPage_SetFollower(GMFMissionPageFollowers[i],info)
- end
- GarrisonMissionPage_UpdateMissionForParty()
- del(t.members)
- del(t)
-end
-local firstcall=true
-function addon:GrowPanel(enlarge)
- if (enlarge and not GMFRewardSplash:IsShown()) then
- print("GrowPanel","big")
- GMF:SetWidth(BIGSIZEW)
- GMF:SetHeight(BIGSIZEH)
- --GMFMissions:SetWidth(890)
- GMFMissions:ClearAllPoints()
- GMFMissions:SetPoint("TOPLEFT",GMF,25,-43)
- GMFMissions:SetPoint("BOTTOMRIGHT",GMF,-25,20)
- --GMFMissionsListScrollFrame:SetWidth(500)
- GMFMissionsListScrollFrameScrollChild:ClearAllPoints()
- GMFMissionsListScrollFrameScrollChild:SetPoint("TOPLEFT",GMFMissionsListScrollFrame)
- GMFMissionsListScrollFrameScrollChild:SetPoint("BOTTOMRIGHT",GMFMissionsListScrollFrame)
- if (firstcall) then
- local h=CreateFrame("Frame",nil,GMF,"UIPanelDialogTemplate")
- h:SetFrameLevel(999)
- h:SetWidth(400)
- h:SetHeight(600)
- h:SetFrameStrata("DIALOG")
- h:SetFrameLevel(999)
- h.title:SetText("Garrison Commander Help")
- h:Show()
- GMF.gcHELPDIALOG=h
- local f=CreateFrame("Frame",nil,GMF)
- local s=f:CreateFontString("GarrisonCommanderTitle","OVERLAY")
- f:SetFrameStrata("HIGH")
- f:SetFrameLevel(999)
- s:SetFontObject("QuestTitleFontBlackShadow")
- s:SetPoint("TOPLEFT")
- s:SetPoint("BOTTOMRIGHT",-40,0)
- f:SetHeight(50)
- f:SetWidth(400)
- s:SetText("Garrison Commander")
- f.text=s
- f:SetPoint("TOP",GMF,"TOP",0,-15)
- GMF.gcTITLE=f
- local h=CreateFrame("Button",nil,f,"UIPanelCloseButton")
- h:SetFrameLevel(999)
- h:SetNormalTexture("interface\\buttons\\ui-microbutton-help-up")
- h:SetPushedTexture("interface\\buttons\\ui-microbutton-help-down")
- h:SetHighlightTexture("interface\\buttons\\ui-microbutton-hilight")
- h:SetHeight(48)
- h:SetWidth(32)
- h:SetScript("OnClick",function() GMF.gcHELPDIALOG:SetPoint("TOP") GMF.gcHELPDIALOG:Show() end)
- h:SetPoint("TOPRIGHT")
- h:SetScript("OnEnter",function(this)
- GameTooltip:SetOwner(this, "ANCHOR_CURSOR_RIGHT")
- GameTooltip:SetText(L["Click to show help page"])
- GameTooltip:Show()
- end
- )
- h:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
- h.tooltip="tooltip"
- h.toolTip="toolTip"
- h.ToolTip="ToolTip"
- h.Tooltip="Tooltip"
- GMF.gcHELP=h
- firstcall=nil
- end
- GMF.gcTITLE:Show()
- else
- print("GrowPanel","small")
- GMF:SetWidth(SIZEW)
- GMF:SetHeight(SIZEH)
- if (GMF.gcTITLE) then GMF.gcTITLE:Hide() end
- end
-end
-function addon:FillFollowerButton(frame,ID,useful)
- if (not frame) then return end
- if (not ID) then
- frame.PortraitFrame.Empty:Show()
- print("Requested",ID,type(ID))
- if (type(ID)=="boolean") then
- frame.Name:SetText(GARRISON_PARTY_NOT_FULL_TOOLTIP)
- frame.Name:SetTextColor(C.Red())
- frame.Name:Show()
- frame.Name:SetWidth(200)
- else
- frame.Name:Hide()
- end
- frame.Class:Hide()
- frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_LevelBorder");
- frame.PortraitFrame.LevelBorder:SetWidth(58);
- frame:SetScript("OnEnter",nil)
- return
- end
- local info=G.GetFollowerInfo(ID)
- --local info=followers[ID]
- frame.info=info
- frame.Name:Show();
- frame.Name:SetText(info.name);
- if (useful) then
- frame.Name:SetTextColor(C.Green())
- else
- frame.Name:SetTextColor(C.Yellow())
- end
- if (frame.Class) then
- frame.Class:Show();
- frame.Class:SetAtlas(info.classAtlas);
- end
- frame.PortraitFrame.Empty:Hide();
-
- local showItemLevel;
- if (info.level == GarrisonMissionFrame.followerMaxLevel ) then
- frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_iLvlBorder");
- frame.PortraitFrame.LevelBorder:SetWidth(70);
- showItemLevel = true;
- else
- frame.PortraitFrame.LevelBorder:SetAtlas("GarrMission_PortraitRing_LevelBorder");
- frame.PortraitFrame.LevelBorder:SetWidth(58);
- showItemLevel = false;
- end
- GarrisonMissionFrame_SetFollowerPortrait(frame.PortraitFrame, info, showItemLevel);
- frame:SetScript("OnEnter",GarrisonMissionPageFollowerFrame_OnEnter)
-end
-function addon:BuildExtraButton(button)
- local bg=CreateFrame("Button",nil,button,"GarrisonCommanderButtonsBackground")
- bg:SetPoint("TOPLEFT",button,"TOPRIGHT")
- bg:SetPoint("RIGHT",GarrisonMissionFrameMissionsListScrollFrame,"RIGHT",-25,0)
- bg.button=button
- bg:SetScript("OnEnter",function(this) GarrisonMissionButton_OnEnter(this.button) end)
- bg:SetScript("OnLeave",function() GameTooltip:FadeOut() end)
- bg:SetScript("OnClick",function() bg.button:Click() end)
- button.gcPANEL=bg
- button.Party={}
- for i=1,3 do
- local f=CreateFrame("Button",nil,button,"GarrisonCommanderMissionPageFollowerTemplate")
- f:RegisterForClicks()
- f:SetScript("OnDragStart",nil)
- f:SetScript("OnDragStop",nil)
- f:SetScript("OnReceiveDrag",nil)
- f:SetScript("OnClick",nil)
- f:SetScale(0.8)
- f:SetFrameStrata("HIGH")
- button.Party[i]=f
- f:ClearAllPoints()
- if (i==1) then
- f:SetPoint("BOTTOMLEFT",bg.Percent,"BOTTOMRIGHT",10,10)
- else
- f:SetPoint("LEFT",button.Party[i-1],"RIGHT",12,0)
- end
- end
-end
-function addon:RenderButton(button,dbg)
- if (not button or not button.Title) then print("Called on I dunno what",button,button:GetName()) return end
- if (self:IsRewardPage()) then return end
- local width=GMF.MissionTab.MissionList.showInProgress and BIGBUTTON or SMALLBUTTON
- button:SetWidth(width)
- if (not button.gcPANEL) then
- self:BuildExtraButton(button)
- end
- local panel=button.gcPANEL
- local missionInfo=button.info
- if (GMF.MissionTab.MissionList.showInProgress) then
- if (not button.inProgressFresh) then
- panel.Percent:SetText(UNKNOWN_CHANCE)
- button.inProgressFresh=true
- for i=1,3 do
- local frame=button.Party[i]
- if (missionInfo.followers[i]) then
- self:FillFollowerButton(frame,missionInfo.followers[i])
- frame:Show()
- else
- frame:Hide()
- end
- end
- end
- return
- end
- button.inProgressFresh=false
- local missionID=missionInfo.missionID
- if (dbg) then print("RenderButton",missionID) end
- local mission=self:GetMissionData(missionID)
- local party=parties[missionID]
- if (#party.members==0) then
- self:MatchMaker(missionID,mission,party)
- end
- local perc=party.perc
- for i=1,3 do
- local frame=button.Party[i]
- if (i>mission.numFollowers) then
- frame:Hide()
- else
- if (party.members[i]) then
- self:FillFollowerButton(frame,party.members[i])
- else
- self:FillFollowerButton(frame,false)
- end
- frame:Show()
- end
- end
- if (perc>=0) then
- panel.Percent:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,perc)
- local q=self:GetDifficultyColor(perc)
- panel.Percent:SetTextColor(q.r,q.g,q.b)
- else
- panel.Percent:SetText(UNKNOWN_CHANCE)
- panel.Percent:SetTextColor(C.Silver())
- end
- panel.Percent:Show()
-end
-_G.GAC=addon
---@do-not-package@
---[[
-Garrison page structure
-Tab selection:
-Managed by
-GarrisonMissionFrameTab(1|2) onclick:
-->GarrisonMissionFrameTab_OnClick(self)
---->GarrisonMissionFrame_SelectTab(self:GetID()) - 1 for Missions, 2 for followers
-
-Main Container is GarrisonMissionFrame
-Followers tab selected:
-->GarrisonMissionFrameFollowers -> anchored GarrisonMissionFrame TOPLEFT 33,-64
--->GarrisonMissionFrameFollowersListScrollFrame
---->GarrisonMissionFrameFollowersListScrooFrameScrollChild
----->GarrisonMissionFrameFollowersListScrooFrameButton(1..9)
-->GarrisonMissionFrame.FollowerTab -> abcuored GarrisonMissionFrame TOPRIGHT -35 -64
-Missions tab selected
-->GarrisonMissionFrameMissions -> anchored (parent)e TOPLEFT 35,-65
-
-
-
-
-GarrisonMissionFrameMissionsListScrollFrameButtonx.info:
-Dump: value=GarrisonMissionFrameMissionsListScrollFrameButton1.info
-[1]={
- description="In a remote corner of Talador, a small faction of draenei has embraced the worship of Sargeras. Stop their cult before it spreads.",
- cost=10,
- duration="4 hr",
- durationSeconds=14400,
- level=100,
- type="Combat",
- locPrefix="GarrMissionLocation-Talador",
- rewards={
- [290]={
- title="Money Reward",
- quantity=600000,
- icon="Interface\\Icons\\inv_misc_coin_01",
- currencyID=0
- }
- },
- numRewards=1,
- numFollowers=2,
- state=-2,
- iLevel=0,
- name="Cult of Sargeras",
- followers={
- },
- location="Talador",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=126
-}
-Dump: value=G.GetFollowerInfo("0x000000000002F5E1")
-[1]={
- displayHeight=0.5,
- iLevel=600,
- scale=0.60000002384186,
- classAtlas="GarrMission_ClassIcon-Druid",
- garrFollowerID="0x0000000000000022",
- displayScale=1,
- status="On Mission",
- level=100,
- quality=4,
- portraitIconID=1066112,
- isFavorite=false,
- xp=0,
- className="Guardian Druid",
- classSpec=8,
- name="Qiana Moonshadow",
- followerID="0x000000000002F5E1",
- height=1.3999999761581,
- displayID=55047,
- levelXP=0,
- isCollected=true
-}
-value=GarrisonMissionFrame.MissionTab.MissionList.availableMissions[13]
-[1]={
- description="Scouts report a many-headed beast named Festerbloom waylaying travelers crossing the Murkbog. Clear the path for everyone's sake.",
- cost=20,
- duration="10 hr",
- durationSeconds=36000,
- level=96,
- type="Combat",
- locPrefix="GarrMissionLocation-SpiresofArak",
- rewards={
- [778]={
- title="Bonus Follower XP",
- followerXP=1400,
- tooltip="+1,400 XP",
- icon="Interface\\Icons\\XPBonus_Icon",
- name="+1,400 XP"
- }
- },
- numRewards=1,
- numFollowers=3,
- state=-2,
- iLevel=0,
- name="Murkbog Terror",
- followers={
- },
- location="Spires of Arak",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=374
-}
-Dump: value=GarrisonMissionFrame.MissionTab.MissionList.inProgressMissions
-[1]={
- description="The voidlords and voidcallers plaguing Shadowmoon Valley are being summoned by someone. Find and kill whoever is responsible.",
- cost=15,
- duration="6 hr",
- durationSeconds=21600,
- level=100,
- timeLeft="1 hr 12 min",
- type="Combat",
- inProgress=true,
- locPrefix="GarrMissionLocation-ShadowmoonValley",
- rewards={
- [251]={
- title="Bonus Follower XP",
- followerXP=8000,
- tooltip="+8,000 XP",
- icon="Interface\\Icons\\XPBonus_Icon",
- name="+8,000 XP"
- }
- },
- numRewards=1,
- numFollowers=3,
- state=-1,
- iLevel=0,
- name="Twisting the Nether",
- followers={
- [1]="0x000000000002F5E1",
- [2]="0x0000000000079D62",
- [3]="0x00000000001307EF"
- },
- location="Shadowmoon Valley",
- isRare=false,
- typeAtlas="GarrMission_MissionIcon-Combat",
- missionID=114
-}
-Dump: value=G.GetMissionInfo(119)
-local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = C_Garrison.GetMissionInfo(missionID);
-[1]="Nagrand",
-[2]=1500,
-[3]="Orc",
-[4]="Lok'tar ogar!",
-[5]="Interface\\ICONS\\Achievement_Boss_General_Nazgrim.blp",
-[6]="GarrMissionLocation-Nagrand",
-[7]=false,
-[8]={
- [1]={
- portraitFileDataID=1067358,
- displayID=56189,
- name="Warsong Earthcaller",
- mechanics={
- [4]={
- description="A dangerous harmful effect that should be dispelled.",
- name="Magic Debuff",
- icon="Interface\\ICONS\\Spell_Shadow_ShadowWordPain.blp"
- },
- [8]={
- description="A dangerous spell that should be interrupted.",
- name="Powerful Spell",
- icon="Interface\\ICONS\\Spell_Shadow_ShadowBolt.blp"
- }
- }
- }
-}
-local totalTimeString, totalTimeSeconds, isMissionTimeImproved, successChance, partyBuffs, isEnvMechanicCountered, xpBonus, materialMultiplier = C_Garrison.GetPartyMissionInfo(MISSION_PAGE_FRAME.missionInfo.missionID);
-Dump: value=C_Garrison.GetPartyMissionInfo(118)
-[1]="8 hr",
-[2]=28800,
-[3]=false,
-[4]=0,
-[5]={
-},
-[6]=false,
-[7]=0,
-[8]=1
-Dump: value=table returned by GetFollowerInfo for a collected follower
-[1]={
- displayHeight=0.5,
- iLevel=600,
- isCollected=true,
- classAtlas="GarrMission_ClassIcon-Druid",
- garrFollowerID="0x0000000000000022",
- displayScale=1,
- level=100,
- quality=4,
- portraitIconID=1066112,
- isFavorite=false,
- xp=0,
- className="Guardian Druid",
- classSpec=8,
- name="Qiana Moonshadow",
- followerID="0x000000000002F5E1",
- height=1.3999999761581,
- displayID=55047,
- scale=0.60000002384186,
- levelXP=0
-}
- local location, xp, environment, environmentDesc, environmentTexture, locPrefix, isExhausting, enemies = G.GetMissionInfo(missionID)
---]]
---@end-do-not-package@
diff --git a/bkGarrisonCommander.lua b/bkGarrisonCommander.lua
new file mode 100644
index 0000000..0697754
--- /dev/null
+++ b/bkGarrisonCommander.lua
@@ -0,0 +1,737 @@
+local __FILE__=tostring(debugstack(1,2,0):match("(.*):1:")) -- MUST BE LINE 1
+print("Loading GarrisonCommander")
+local toc=select(4,GetBuildInfo())
+local me, ns = ...
+local pp=print
+if (LibDebug) then LibDebug() end
+local L=LibStub("AceLocale-3.0"):GetLocale(me,true)
+local C=LibStub("AlarCrayon-3.0"):GetColorTable()
+local addon=LibStub("AlarLoader-3.0")(__FILE__,me,ns):CreateAddon(me,true) --#Addon
+local print=ns.print or print
+local debug=ns.debug or print
+local dump=ns.dump or print
+--@debug@
+ns.debugEnable('on')
+local function tcopy(obj, seen)
+ if type(obj) ~= 'table' then return obj end
+ if seen and seen[obj] then return seen[obj] end
+ local s = seen or {}
+ local res = setmetatable({}, getmetatable(obj))
+ s[obj] = res
+ for k, v in pairs(obj) do res[tcopy(k, s)] = tcopy(v, s) end
+ return res
+end
+--@end-debug@
+-----------------------------------------------------------------
+-- Recycling function from ACE3
+----newcount, delcount,createdcount,cached = 0,0,0
+local new, del, copy
+do
+ local pool = setmetatable({},{__mode="k"})
+ function new()
+ --newcount = newcount + 1
+ local t = next(pool)
+ if t then
+ pool[t] = nil
+ return t
+ else
+ --createdcount = createdcount + 1
+ return {}
+ end
+ end
+ function copy(t)
+ local c = new()
+ for k, v in pairs(t) do
+ c[k] = v
+ end
+ return c
+ end
+ function del(t)
+ --delcount = delcount + 1
+ wipe(t)
+ pool[t] = true
+ end
+-- function cached()
+-- local n = 0
+-- for k in pairs(pool) do
+-- n = n + 1
+-- end
+-- return n
+-- end
+end
+local function capitalize(s)
+ s=tostring(s)
+ return strupper(s:sub(1,1))..strlower(s:sub(2))
+end
+local masterplan
+local followers
+local successes={}
+local requested={}
+local threats={}
+local availableFollowers=0
+local skipBusy
+local wipe=wipe
+local GMF=GarrisonMissionFrame
+local GMFFollowers=GarrisonMissionFrameFollowers
+local GMFMissions=GarrisonMissionFrameMissions
+local GMFMissionPage=GMF.MissionTab
+local GMFRewardPage
+local GMFFollowerPage=GMF.FollowerTab
+local GMFTab1=GarrisonMissionFrameTab1
+local GMFTab2=GarrisonMissionFrameTab2
+local GMFMissionsTab1=GarrisonMissionFrameMissionsTab1
+local GMFMissionsTab2=GarrisonMissionFrameMissionsTab2
+local GarrisonMissionFrameMissionsListScrollFrame=GarrisonMissionFrameMissionsListScrollFrame
+local GARRISON_FOLLOWER_WORKING=GARRISON_FOLLOWER_WORKING -- "Working
+local GARRISON_FOLLOWER_ON_MISSION=GARRISON_FOLLOWER_ON_MISSION -- "On Mission"
+local GARRISON_FOLLOWER_INACTIVE=GARRISON_FOLLOWER_INACTIVE --"Inactive"
+local GARRISON_FOLLOWER_EXHAUSTED=GARRISON_FOLLOWER_EXHAUSTED -- "Recovering (1 Day)"
+local GARRISON_FOLLOWER_IN_PARTY=GARRISON_FOLLOWER_IN_PARTY
+local GARRISON_BUILDING_SELECT_FOLLOWER_TITLE=GARRISON_BUILDING_SELECT_FOLLOWER_TITLE -- "Select a Follower";
+local GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP=GARRISON_BUILDING_SELECT_FOLLOWER_TOOLTIP -- "Click here to assign a Follower";
+local GARRISON_FOLLOWER_CAN_COUNTER=GARRISON_FOLLOWER_CAN_COUNTER -- "This follower can counter:"
+local GARRISON_MISSION_SUCCESS=GARRISON_MISSION_SUCCESS -- "Success"
+local GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS -- "%d Follower mission";
+local UNKNOWN_CHANCE=GARRISON_MISSION_PERCENT_CHANCE:gsub('%%d%%%%',UNKNOWN)
+local GARRISON_MISSION_PERCENT_CHANCE=GARRISON_MISSION_PERCENT_CHANCE .. " (Estimated)"
+local BUTTON_INFO=GARRISON_MISSION_TOOLTIP_NUM_REQUIRED_FOLLOWERS.. " " .. GARRISON_MISSION_PERCENT_CHANCE
+local GARRISON_FOLLOWERS=GARRISON_FOLLOWERS -- "Followers"
+local GARRISON_PARTY_NOT_FULL_TOOLTIP=GARRISON_PARTY_NOT_FULL_TOOLTIP -- "You do not have enough followers on this mission."
+local AVAILABLE=AVAILABLE -- "Available"
+local PARTY=PARTY -- "Party"
+local ENVIRONMENT_SUBHEADER=ENVIRONMENT_SUBHEADER -- "Environment"
+local SPELL_TARGET_TYPE4_DESC=capitalize(SPELL_TARGET_TYPE4_DESC) -- party member
+local SPELL_TARGET_TYPE1_DESC=capitalize(SPELL_TARGET_TYPE1_DESC) -- any
+local ANYONE='('..SPELL_TARGET_TYPE1_DESC..')'
+local IGNORE_UNAIVALABLE_FOLLOWERS=IGNORE.. ' ' .. UNAVAILABLE .. ' ' .. GARRISON_FOLLOWERS
+local IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=IGNORE.. ' ' .. GARRISON_FOLLOWER_INACTIVE .. ',' .. GARRISON_FOLLOWER_ON_MISSION ..',' .. GARRISON_FOLLOWER_WORKING.. ','.. GARRISON_FOLLOWER_EXHAUSTED .. ' ' .. GARRISON_FOLLOWERS
+IGNORE_UNAIVALABLE_FOLLOWERS=capitalize(IGNORE_UNAIVALABLE_FOLLOWERS)
+IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL=capitalize(IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL)
+local GameTooltip=GameTooltip
+local GetItemQualityColor=GetItemQualityColor
+local hookedListUpdate
+local timers={}
+function addon:AddLine(icon,name,status,quality,...)
+ local r2,g2,b2=C.Red()
+ local q=ITEM_QUALITY_COLORS[quality or 1] or {}
+ if (status==AVAILABLE) then
+ r2,g2,b2=C.Green()
+ elseif (status==GARRISON_FOLLOWER_WORKING) then
+ r2,g2,b2=C.Orange()
+ end
+ --GameTooltip:AddDoubleLine(name, status or AVAILABLE,r,g,b,r2,g2,b2)
+ --GameTooltip:AddTexture(icon)
+ GameTooltip:AddDoubleLine(icon and "|T" .. tostring(icon) .. ":0|t " .. name or name, status,q.r,q.g,q.b,r2,g2,b2)
+end
+function addon:GetDifficultyColor(perc)
+ local difficulty='trivial'
+ if(perc >90) then
+ difficulty='standard'
+ elseif (perc >74) then
+ difficulty='difficult'
+ elseif(perc>49) then
+ difficulty='verydifficult'
+ elseif(perc >20) then
+ difficulty='impossible'
+ end
+ return QuestDifficultyColors[difficulty]
+end
+function addon:RestoreTooltip()
+ local self = GMF.MissionTab.MissionList;
+ local scrollFrame = self.listScroll;
+ local buttons = scrollFrame.buttons;
+ for i =1,#buttons do
+ buttons[i]:SetScript("OnEnter",GarrisonMissionButton_OnEnter)
+ end
+end
+local openParty,isInParty,pushFollower,closeParty,roomInParty
+
+do
+ local ID,frames=0,nil
+ local members={}
+ local max=1
+ function openParty(missionID,maxfollowers)
+ max=maxfollowers
+ local frames={GetFramesRegisteredForEvent('GARRISON_FOLLOWER_LIST_UPDATE')}
+ for i=1,#frames do
+ frames[i]:UnregisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
+ end
+ ID=missionID
+ end
+ function isInParty(followerID)
+ for i=1,maxfollowers do
+ if (followerID==members[i]) then return true end
+ end
+ end
+ function roomInParty()
+ return not members[max]
+ end
+ function pushFollower(followerID)
+ if (roomInParty()) then
+ local rc,code=pcall (C_Garrison.AddFollowerToMission,ID,followerID)
+ if (rc and code) then
+ tinsert(members,followerID)
+ return true
+ end
+ end
+ end
+ function closeParty()
+ for i=1,3 do
+ if (members[i]) then
+ C_Garrison.RemoveFollowerFromMission(ID,members[i])
+ else
+ break
+ end
+ end
+ if (frames) then
+ for i=1,#frames do
+ frames[i]:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE")
+ end
+ end
+ frames=nil
+ wipe(members)
+ end
+end
+
+-- This is a ugly hack while I rewrite this code for 2.0
+function addon:TooltipAdder(missionID,skipTT)
+--@debug@
+ if (not skipTT) then GameTooltip:AddLine("ID:" .. tostring(missionID)) end
+--@end-debug@
+ self:GetRunningMissionData()
+ local perc=select(4,C_Garrison.GetPartyMissionInfo(missionID))
+ local q=self:GetDifficultyColor(perc)
+ if (not skipTT) then GameTooltip:AddDoubleLine(GARRISON_MISSION_SUCCESS,format(GARRISON_MISSION_PERCENT_CHANCE,perc),nil,nil,nil,q.r,q.g,q.b) end
+ local buffed=new()
+ local traited=new()
+ local buffs=new()
+ local traits=new()
+ local fellas=new()
+ local fullname=new()
+ for id,d in pairs(C_Garrison.GetBuffedFollowersForMission(missionID)) do
+ buffed[id]=d
+ end
+ for id,d in pairs(C_Garrison.GetFollowersTraitsForMission(missionID)) do
+ for x,y in pairs(d) do
+--@debug@
+ self.db.global.traits[y.traitID]=y.icon
+--@end-debug@
+ if (y.traitID~=236) then --Ignore hearthstone traits
+ traited[id]=d
+ break
+ end
+ end
+ end
+ availableFollowers=0
+ for index=1,#followers do
+ local follower=followers[index]
+ follower.rank=follower.level < 100 and follower.level or follower.iLevel
+ if (not follower.isCollected) then break end
+ follower.status=C_Garrison.GetFollowerStatus(follower.followerID)
+ followers[index].status=follower.status
+ if (not follower.status) then
+ availableFollowers=availableFollowers+1
+ end
+ if (follower.status and skipBusy) then
+ else
+ local id=follower.followerID
+ local b=buffed[id]
+ local t=traited[id]
+ local followerBias = C_Garrison.GetFollowerBiasForMission(missionID,id);
+ follower.bias=followerBias
+ local formato=C("%3d","White")
+ if (followerBias==-1) then
+ formato=C("%3d","Red")
+ elseif (followerBias < 0) then
+ formato=C("%3d","Orange")
+ end
+ formato=formato.." %s"
+--@debug@
+ formato=formato .. " 0x+(0*8) " .. id:sub(11)
+--@end-debug@
+ if (b) then
+ if (not buffs[id]) then
+ buffs[id]=index
+ fullname[id]=format(formato,follower.rank,follower.name)
+ end
+ for _,ability in pairs(b) do
+ fullname[id]=fullname[id] .. " |T" .. tostring(ability.icon) .. ":0|t"
+ if (not follower.status or not skipBusy) then
+ local aname=ability.name
+ if (tonumber(fellas[aname])) then
+ local previous=followers[tonumber(fellas[aname])]
+ if (previous.rank>=follower.rank) then
+ break
+ end
+ end
+ fellas[aname]=index
+ end
+ end
+ end
+ if (t) then
+ if (not traits[id]) then
+ traits[id]=index
+ fullname[id]=format(formato,follower.rank,follower.name)
+ end
+ for _,ability in pairs(t) do
+ fullname[id]=fullname[id] .. " |T" .. tostring(ability.icon) .. ":0|t"
+ end
+ end
+ end
+ end
+ local maxfollowers=C_Garrison.GetMissionMaxFollowers(missionID)
+ requested[missionID]=maxfollowers
+ local partyshown=false
+ local perc=0
+ local menaces=0
+ openParty(missionID,maxfollowers)
+ if (next(traits) or next(buffs) ) then
+ if (not skipTT) then GameTooltip:AddLine(GARRISON_FOLLOWER_CAN_COUNTER) end
+ for id,i in pairs(buffs) do
+ local v=followers[i]
+ local status=(v.status == GARRISON_FOLLOWER_ON_MISSION and (timers[id] or GARRISON_FOLLOWER_ON_MISSION)) or v.status
+ if (not skipTT) then self:AddLine(nil,fullname[id],status or AVAILABLE,v.quality) end
+ end
+ for id,i in pairs(traits) do
+ local v=followers[i]
+ local status=(v.status == GARRISON_FOLLOWER_ON_MISSION and (timers[id] or GARRISON_FOLLOWER_ON_MISSION)) or v.status
+ if (not skipTT) then self:AddLine(nil,fullname[id],status or AVAILABLE,v.quality) end
+ end
+ if (not skipTT) then GameTooltip:AddLine(PARTY,C.White()) end
+ partyshown=true
+ local enemies = select(8,C_Garrison.GetMissionInfo(missionID))
+ --local missionInfo=C_Garrison.GetBasicMissionInfo(missionID)
+--@debug@
+ --DevTools_Dump(fellas)
+--@end-debug@
+ for _,enemy in pairs(enemies) do
+ for i,mechanic in pairs(enemy.mechanics) do
+--@debug@
+ self.db.global.abilities[i .. '.' .. mechanic.name]=mechanic.description
+--@end-debug@
+ local menace=mechanic.name
+ local res
+ menaces=menaces+1
+ if (fellas[menace]) then
+ local follower=followers[fellas[menace]]
+ if (follower.status and skipBusy) then
+ elseif (pushFollower(follower.followerID)) then
+ res=fullname[follower.followerID]
+ end
+ end
+ if (not skipTT) then
+ if (res) then
+ GameTooltip:AddDoubleLine(menace,res,0,1,0)
+ else
+ GameTooltip:AddDoubleLine(menace,' ',1,0,0)
+ end
+ end
+ end
+ end
+ if (roomInParty() and next(traits)) then
+ for id,i in pairs(traits) do
+ local follower=followers[i]
+ if (follower.status and skipBusy) then
+ elseif (pushFollower(id)) then
+ if (not skipTT) then GameTooltip:AddDoubleLine(ENVIRONMENT_SUBHEADER,fullname[id],0,1,0) end
+ break
+ end
+ end
+ end
+ end
+ -- And then fill the roster
+ if (roomInParty()) then
+ for index=1,#followers do
+ local follower=followers[index]
+ if (follower.status and skipBusy) then
+ elseif (pushFollower(follower.followerID)) then
+ if (not partyshown) then
+ if (not skipTT) then GameTooltip:AddLine(PARTY,1) end
+ partyshown=true
+ end
+ if (not skipTT) then
+ GameTooltip:AddDoubleLine(SPELL_TARGET_TYPE4_DESC,follower.name,C.Orange.r,C.Orange.g,C.Orange.b)--SPELL_TARGET_TYPE1_DESC)
+ end
+ if (not roomInParty()) then break end
+ end
+ end
+ end
+ perc=select(4,C_Garrison.GetPartyMissionInfo(missionID))
+ local q=self:GetDifficultyColor(perc)
+ if (not partyshown) then
+ if (not skipTT) then GameTooltip:AddDoubleLine(PARTY,ANYONE,C.White.r,C.White.g,C.White.b) end
+ end
+ if (not skipTT) then GameTooltip:AddDoubleLine(GARRISON_MISSION_SUCCESS,format(GARRISON_MISSION_PERCENT_CHANCE,perc),nil,nil,nil,q.r,q.g,q.b) end
+ local b=GameTooltip:GetOwner()
+ successes[missionID]=perc
+ threats[missionID]=menaces
+ if (availableFollowers < maxfollowers) then
+ if (not skipTT) then GameTooltip:AddLine(GARRISON_PARTY_NOT_FULL_TOOLTIP,C:Red()) end
+ end
+ --if (not skipTT) then self:AddPerc(GameTooltip:GetOwner()) end
+ closeParty()
+ -- Add a signature
+ --local r,g,b=C:Silver()
+ --GameTooltip:AddDoubleLine("GarrisonCommander",self.version,r,g,b,r,g,b)
+--@debug@
+ --DevTools_Dump(fellas)
+--@end-debug@
+ del(buffed)
+ del(traited)
+ del(buffs)
+ del(traits)
+ del(fellas)
+end
+function addon:FillFollowersList()
+ if (GarrisonFollowerList_UpdateFollowers) then
+ GarrisonFollowerList_UpdateFollowers(GarrisonMissionFrame.FollowerList)
+ end
+end
+function addon:CacheFollowers()
+ followers=C_Garrison.GetFollowers()
+ for i=1,#followers do
+ if (not followers[i].isCollected) then
+ followers[i]=nil
+ end
+ end
+end
+function addon:GetRunningMissionData()
+ local list=GarrisonMissionFrame.MissionTab.MissionList
+ C_Garrison.GetInProgressMissions(list.inProgressMissions);
+ --C_Garrison.GetAvailableMissions(list.availableMissions);
+ if (#list.inProgressMissions > 0) then
+ for i,mission in pairs(list.inProgressMissions) do
+ for _,id in pairs(mission.followers) do
+ timers[id]=mission.timeLeft
+ end
+ end
+ end
+end
+function addon:ADDON_LOADED(event,addon)
+ if (addon=="Blizzard_GarrisonUI") then
+ self:UnregisterEvent("ADDON_LOADED")
+ self:Init()
+ end
+end
+function addon:ApplyIGM(value)
+ skipBusy=value
+ if (not GMF) then return end
+ if (skipBusy) then
+ GMF.GCIgnore.text:SetTextColor(C:Green())
+ else
+ GMF.GCIgnore.text:SetTextColor(C:Red())
+ end
+ self:RefreshMissions()
+end
+function addon:ApplyMOVEPANEL(value)
+ if (not GMF) then return end
+ if (value) then
+ GMF.GCLock.text:SetTextColor(C:Green())
+ GMF:SetMovable(true)
+ GMF:RegisterForDrag("LeftButton")
+ GMF:SetScript("OnDragStart",function(frame) frame:StartMoving() end)
+ GMF:SetScript("OnDragStop",function(frame) frame:StopMovingOrSizing() end)
+ else
+ GMF.GCLock.text:SetTextColor(C:Red())
+ GMF:SetScript("OnDragStart",nil)
+ GMF:SetScript("OnDragStop",nil)
+ GMF:ClearAllPoints()
+ GMF:SetPoint("CENTER",UIParent)
+ GMF:SetMovable(false)
+ end
+end
+function addon:OnInitialized()
+--@debug@
+ LoadAddOn("Blizzard_DebugTools")
+--@end-debug@
+ self.OptionsTable.args.on=nil
+ self.OptionsTable.args.off=nil
+ self.OptionsTable.args.standby=nil
+ self:AddToggle("MOVEPANEL",true,L["Makes Garrison Mission Panel Movable"]).width="full"
+ self:AddToggle("IGM",false,IGNORE_UNAIVALABLE_FOLLOWERS,IGNORE_UNAIVALABLE_FOLLOWERS_DETAIL).width="full"
+ self:loadHelp()
+ self.DbDefaults.global["*"]={}
+ self.db:RegisterDefaults(self.DbDefaults)
+ skipBusy=self:GetBoolean("IGM")
+ self:MasterPlanDetection(true)
+ self:ScheduleTimer("MasterPlanDetection",2)
+ pcall(self.FillFollowersList,self)
+ self:CacheFollowers()
+ self:SecureHook("GarrisonMissionButton_AddThreatsToTooltip",function(id) self:TooltipAdder(id) end)
+ self:SecureHook("GarrisonMissionButton_SetRewards","AddPerc")
+ self:HookScript(GMF,"OnHide","CleanUp")
+ self:Options()
+ self:ApplyMOVEPANEL(self:GetBoolean("MOVEPANEL"))
+ -- Forcing refresh when needed without possibly disrupting Blizzard Logic
+ self:SecureHook("GarrisonMissionPage_Close","RefreshMissions") -- Missino started
+ self:SecureHook("GarrisonMissionFrame_HideCompleteMissions","RefreshMissions") -- Mission reward completed
+ self:CacheFollowers()
+ self:RegisterEvent("GARRISON_MISSION_STARTED","RefreshMissions")
+
+--@debug@
+ --Only Used for development
+ self:RegisterEvent("GARRISON_MISSION_LIST_UPDATE",print)
+ self:RegisterEvent("GARRISON_FOLLOWER_LIST_UPDATE",print) --This event is quite useless, fires too often
+ self:RegisterEvent("GARRISON_FOLLOWER_XP_CHANGEDE",print)
+ self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_LOOT",print)
+ self:RegisterEvent("GARRISON_MISSION_FINISHED",print)
+ self:RegisterEvent("GARRISON_MISSION_COMPLETE_RESPONSE",print)
+ self:RegisterEvent("GARRISON_MISSION_BONUS_ROLL_COMPLETE",print)
+ self:RegisterEvent("GARRISON_MISSION_NPC_OPENED",print)
+ self:SafeHookScript("GarrisonMissionFrameTab1","OnCLick")
+ self:SafeHookScript("GarrisonMissionFrameTab2","OnCLick")
+ self:SafeHookScript("GarrisonMissionFrameTab3","OnCLick")
+ self:SafeHookScript("GarrisonMissionFrameMissionsTab1","OnCLick")
+ self:SafeHookScript("GarrisonMissionFrameMissionsTab3","OnCLick")
+ self:SafeHookScript(GMFMissions,"OnShow")
+ self:SafeHookScript(GMFMissions,"OnHide")
+ self:SafeHookScript(GMFFollowers,"OnShow")
+ self:SafeHookScript(GMFFollowers,"OnHide")
+ self:SafeHookScript(GMF.MissionTab.MissionPage.CloseButton,"OnClick")
+--@end-debug@
+ return true
+end
+function addon:Options()
+ local f=GMF:CreateFontString()
+ f:SetFontObject(GameFontNormalSmall)
+ --f:SetHeight(32)
+ f:SetText(me .. L[" Options:"])
+ --f:SetTextColor(C:Azure())
+ f:Show()
+ GMF.GCLabel=f
+ local b=CreateFrame("CheckButton","GACOptions",GMF,"UICheckButtonTemplate")
+ b.text:SetText(L["Ignore busy followers"])
+ b:SetChecked(self:GetBoolean('IGM'))
+ b:SetScript("OnCLick",function(b) self:ApplyIGM(b:GetChecked()) end)
+ b:Show()
+ GMF.GCIgnore=b
+ self:ApplyIGM(self:GetBoolean('IGM'))
+ local l=CreateFrame("CheckButton","GACLock",GMF,"UICheckButtonTemplate")
+ l.text:SetText(L["Unlock Panel"])
+ l:SetChecked(self:GetBoolean('MOVEPANEL'))
+ l:SetScript("OnCLick",function(b) self:ApplyMOVEPANEL(b:GetChecked()) end)
+ l:Show()
+ GMF.GCLock=l
+--@debug@
+ local s=CreateFrame("Frame","GACStatus",GMF)
+ s:SetHeight(32)
+ local st=s:CreateFontString()
+ s.text=st
+ st:SetFontObject(GameFontNormalSmall)
+ st:Show()
+ st:SetAllPoints()
+ f:SetPoint("BOTTOMLEFT",GMF,"TOPLEFT",10,15)
+ b:SetPoint("TOPLEFT",f,"TOPRIGHT",10,10)
+ l:SetPoint("TOPLEFT",b,"TOPRIGHT",10+b.text:GetWidth(),0)
+ s:SetPoint("TOPLEFT",l,"TOPRIGHT",10+l.text:GetWidth(),0)
+ self:HookScript(s,"OnUpdate","Status")
+--@end-debug@
+end
+
+function addon:ScriptTrace(hook,frame,...)
+--@debug@
+ print("Triggered " .. C(hook,"red").." script on",C(frame,"Azure"),...)
+--@end-debug@
+end
+function addon:Status(frame)
+ frame.text:SetText(format("PM:%s AM:%s FL:%s RP:%s MP:%s",
+ self:IsProgressMission() and 'Yes' or 'Not',
+ self:IsAvailableMission() and 'Yes' or 'Not',
+ self:IsFollowerList() and 'Yes' or 'Not',
+ self:IsRewardPage() and 'Yes' or 'Not',
+ self:IsMissionPage() and 'Yes' or 'Not')
+ )
+ frame:SetWidth(frame.text:GetWidth())
+end
+function addon:IsProgressMission()
+ return GMF:IsShown() and GarrisonMissionFrameMissionsListScrollFrame:IsShown() and GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
+end
+function addon:IsAvailableMission()
+ return GMF:IsShown() and GarrisonMissionFrameMissionsListScrollFrame:IsShown() and not GMFMissions.showInProgress and not GMFFollowers:IsShown() and not GMF.MissionComplete:IsShown()
+end
+function addon:IsFollowerList()
+ return GMF:IsShown() and GMFFollowers:IsShown()
+end
+--GMFMissions.CompleteDialog
+function addon:IsRewardPage()
+ return GMF:IsShown() and GMF.MissionComplete:IsShown() and not GMFFollowers:IsShown()
+end
+function addon:IsMissionPage()
+ return GMF:IsShown() and GMFMissionPage:IsShown() and GMFFollowers:IsShown()
+end
+function addon:AddPerc(b,...)
+ if (GMFMissions.CompleteDialog:IsShown()) then return end
+ if (b and b.info and b.info.missionID and b.info.missionID ) then
+ if (GMF.MissionTab.MissionList.showInProgress) then
+ if (b.ProgressHidden) then
+ return
+ else
+ b.ProgressHidden=true
+ if (b.Success) then
+ b.Success:Hide()
+ end
+ if (b.NotEnough) then
+ b.NotEnough:Hide()
+ end
+ return
+ end
+
+ end
+ local missionID=b.info.missionID
+ local Perc=successes[missionID] or -2
+ if (not b.Success) then
+ b.Success=b:CreateFontString()
+ b.Success:SetFontObject("GameFontNormalLarge2")
+ if (masterplan) then
+ b.Success:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",200,-3)
+ else
+ b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+ end
+ end
+ if (not b.NotEnough) then
+ b.NotEnough=b:CreateFontString()
+ if (masterplan) then
+ b.NotEnough:SetFontObject("GameFontNormalSmall2")
+ b.NotEnough:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+ else
+ b.NotEnough:SetFontObject("GameFontNormalSmall")
+ b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",0,-3)
+ end
+ b.NotEnough:SetText("(".. GARRISON_PARTY_NOT_FULL_TOOLTIP .. ")")
+ b.NotEnough:SetTextColor(C:Red())
+ end
+ if (Perc <0) then
+ self:TooltipAdder(missionID,true)
+ Perc=successes[missionID] or -2
+ end
+ if (Perc>=0) then
+ if (masterplan) then
+ b.Success:SetFormattedText(GARRISON_MISSION_PERCENT_CHANCE,successes[missionID])
+ else
+ b.Success:SetFormattedText(BUTTON_INFO,C_Garrison.GetMissionMaxFollowers(missionID),successes[missionID])
+ end
+ local q=self:GetDifficultyColor(successes[missionID])
+ b.Success:SetTextColor(q.r,q.g,q.b)
+ else
+ b.Success:SetText(UNKNOWN_CHANCE)
+ b.Success:SetTextColor(1,1,1)
+ end
+ b.Success:Show()
+ if (not requested[missionID]) then
+ requested[missionID]=C_Garrison.GetMissionMaxFollowers(missionID)
+ end
+ if (requested[missionID]>availableFollowers) then
+ b.NotEnough:Show()
+ else
+ b.NotEnough:Hide()
+ end
+ b.ProgressHidden=false
+ end
+end
+function addon:CleanUp()
+ collectgarbage("step",10)
+end
+
+function addon:RefreshMissions()
+ if (self:IsAvailableMission()) then
+ --@debug@
+ print("Refresh missions called")
+ --@end-debug@
+ self:CacheFollowers()
+ wipe(successes)
+ GarrisonMissionList_UpdateMissions()
+ end
+end
+function addon:SafeHookScript(frame,hook,method)
+ local name="Unknown"
+ if (type(frame)=="string") then
+ name=frame
+ frame=_G[frame]
+ else
+ if (frame and frame.GetName) then
+ name=frame:GetName()
+ end
+ end
+ if (frame) then
+ if (method) then
+ local rc,msg=pcall(self.HookScript,self,frame,hook,method)
+ --@debug@
+ if (not rc) then
+ print("ERROR attempting hook:",name,hook,":",msg)
+ end
+ else
+ print("DummyHook:",name,hook)
+ self:HookScript(frame,hook,function(...) self:ScriptTrace(name,hook,...) end)
+ --@end-debug@
+ end
+--@debug@
+ else
+ print(C("Attempted hook for non existent:","red"),name,hook)
+--@end-debug@
+ end
+end
+function addon:FixButtons()
+ local self = GMF.MissionTab.MissionList
+ local scrollFrame = self.listScroll
+ local buttons = scrollFrame.buttons
+ if (masterplan) then
+ for i =1,#buttons do
+ local b=buttons[i]
+ b.Success:ClearAllPoints()
+ b.Success:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",200,-3)
+ b.NotEnough:SetFontObject("GameFontNormalSmall2")
+ b.NotEnough:ClearAllPoints()
+ b.NotEnough:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+ end
+ else
+ for i =1,#buttons do
+ local b=buttons[i]
+ b.Success:ClearAllPoints()
+ b.Success:SetPoint("BOTTOMLEFT",b.Title,"TOPLEFT",0,3)
+ b.NotEnough:SetFontObject("GameFontNormalSmall")
+ b.NotEnough:SetPoint("TOPLEFT",b.Title,"BOTTOMLEFT",0,-3)
+ end
+ end
+end
+function addon:MasterPlanDetection(novar,...)
+ local _,_,_,loadable,reason=GetAddOnInfo("MasterPlan")
+ masterplan=false
+ if (loadable or reason=="DEMAND_LOADED") then
+ if (novar) then
+ masterplan=true
+ else
+ if (_G.MasterPlanConfig or _G.MasterPlanData ) then
+ masterplan=true
+ end
+ end
+ end
+ if (masterplan and not self:IsHooked("GarrisonMissionList_UpdateMissions")) then
+ self:SecureHook("GarrisonMissionList_UpdateMissions","RestoreTooltip")
+ end
+ pcall(self.FixButtons,self)
+end
+--@do-not-package@
+_G.GAC=addon
+--[[
+Garrison page structure
+Tab selection:
+Managed by
+GarrisonMissionFrameTab(1|2) onclick:
+->GarrisonMissionFrameTab_OnClick(self)
+--->GarrisonMissionFrame_SelectTab(self:GetID()) - 1 for Missions, 2 for followers
+
+Main Container is GarrisonMissionFrame
+Followers tab selected:
+->GarrisonMissionFrameFollowers -> anchored GarrisonMissionFrame TOPLEFT 33,-64
+-->GarrisonMissionFrameFollowersListScrollFrame
+--->GarrisonMissionFrameFollowersListScrooFrameScrollChild
+---->GarrisonMissionFrameFollowersListScrooFrameButton(1..9)
+->GarrisonMissionFrame.FollowerTab -> abcuored GarrisonMissionFrame TOPRIGHT -35 -64
+Missions tab selected
+->GarrisonMissionFrameMissions -> anchored (parent)e TOPLEFT 35,-65
+
+
+
+
+--]]
+--@end-do-not-package@
diff --git a/embeds.xml b/embeds.xml
index 6dd6f54..e2c177d 100644
--- a/embeds.xml
+++ b/embeds.xml
@@ -1,18 +1,3 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/">
- <Script file="libs\Ace3\LibStub\LibStub.lua"/>
- <Include file="libs\Ace3\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
- <Include file="libs\Ace3\AceAddon-3.0\AceAddon-3.0.xml"/>
- <Include file="libs\Ace3\AceHook-3.0\AceHook-3.0.xml"/>
- <Include file="libs\Ace3\AceEvent-3.0\AceEvent-3.0.xml"/>
- <Include file="libs\Ace3\AceTimer-3.0\AceTimer-3.0.xml"/>
- <Include file="libs\Ace3\AceConsole-3.0\AceConsole-3.0.xml"/>
- <Include file="libs\Ace3\AceLocale-3.0\AceLocale-3.0.xml"/>
- <Include file="libs\Ace3\AceGUI-3.0\AceGUI-3.0.xml"/>
- <Include file="libs\Ace3\AceConfig-3.0\AceConfig-3.0.xml"/>
- <Include file="libs\Ace3\AceDB-3.0\AceDB-3.0.xml"/>
- <Include file="libs\Ace3\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
- <Include file="libs\AlarShared-3.0\lib.xml"/>
- <Include file="libs\LibDeformat-3.0\lib.xml"/>
- <Include file="libs\LibItemUpgradeInfo-1.0\LibItemUpgradeInfo-1.0.xml"/>
<Include file="libs\LibInit\LibInit.xml"/>
</Ui>