Quantcast

2.7.0

Alar of Daggerspine [08-28-15 - 05:26]
2.7.0

Refactored reward and missions' classes list.
Added more rewards
Bumped version

Signed-off-by: Alar of Daggerspine <alar@aspide.it>
Filename
CHANGELOG.txt
GarrisonCommander.lua
GarrisonCommander.toc
Init.lua
MissionCache.lua
MissionControl.lua
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index e32a2cc..72cdccf 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,7 +1,8 @@
 *GarrisonCommander helps you when choosing the right follower for the right mission*

-* *2.6.15*
+* *2.7.0*
 Feature: Item rewards in Mission Control can be filtered on level
+Feature: Added quite a bunch of rewards in mission control
 Feature: All header menu are now context sensitive
 Feature: Header added to Shipyard
 Feature: One click ship upgrade
diff --git a/GarrisonCommander.lua b/GarrisonCommander.lua
index 190d0f4..c4dd396 100644
--- a/GarrisonCommander.lua
+++ b/GarrisonCommander.lua
@@ -825,7 +825,9 @@ function addon:CreatePrivateDb()
 					maxDuration = 24,
 					epicExp = false,
 					skipRare=true,
-					skipEpic=not addon:HasSalvageYard()
+					skipEpic=not addon:HasSalvageYard(),
+					minLevel=540,
+					minUpgrade=600
 				}
 			}
 		},
@@ -1574,7 +1576,7 @@ print("Adding Menu")
 		self:RenderFollowerPageMissionList(nil,GMF.FollowerTab.followerID)
 	elseif GMF.MissionControlTab:IsVisible() then
 		self.currentmenu=GMF.MissionControlTab
-		menu,size=self:CreateOptionsLayer('BIGSCREEN','GCSKIPRARE','GCSKIPEPIC','GCMINLEVEL')
+		menu,size=self:CreateOptionsLayer('BIGSCREEN','USEFUL','MOVEPANEL')
 	end
 --@debug@
 	self:AddOptionToOptionsLayer(menu,'DBG')
diff --git a/GarrisonCommander.toc b/GarrisonCommander.toc
index f627079..9eb9051 100644
--- a/GarrisonCommander.toc
+++ b/GarrisonCommander.toc
@@ -13,7 +13,7 @@
 ## Notes-zhCN: 發送所有的追隨者與點擊多任務
 ## Author: Alar of Daggerspine
 ## Version: @project-version@ 6.2.0
-## X-Version: 2.6.15
+## X-Version: 2.7.0
 ## X-Revision: @project-abbreviated-hash@
 ## eMail: alar@aspide.it
 ## URL: http://wow.aspide.it
diff --git a/Init.lua b/Init.lua
index d0b9841..cfa8db9 100644
--- a/Init.lua
+++ b/Init.lua
@@ -110,6 +110,9 @@ local backdrop = {
 		edgeSize=16,
 		insets={bottom=3,left=3,right=3,top=3}
 }
+---@function [parent=#ns] AddBackdrop
+--@param object frame Frame to add backdrop to
+--@param int r,g,b optional color
 function ns.AddBackdrop(frame,r,g,b)
 	r=r or 1
 	g=g or 0
diff --git a/MissionCache.lua b/MissionCache.lua
index 0bb4e3f..8bd317f 100644
--- a/MissionCache.lua
+++ b/MissionCache.lua
@@ -24,6 +24,7 @@ local rawget=rawget
 local time=time
 local empty={}
 local index={}
+local classes
 -- Mission caching is a bit different fron follower caching mission appears and disappears on a regular basis
 local module=addon:NewSubClass('MissionCache') --#module
 function module:OnInitialized()
@@ -62,6 +63,31 @@ function module:GetMission(id,noretry)
 	return self:GetMission(id,true)
 end
 function module:AddExtraData(mission)
+	local rewards=mission.rewards
+	if not rewards then
+		rewards=G.GetMissionRewardInfo(mission.missionID)
+	end
+	for i=1,#classes do
+		mission[classes[i].key]=0
+	end
+	mission.numrewards=0
+	mission.xpBonus=0
+	for k,v in pairs(rewards) do
+		if k==615 and v.followerXP then mission.xpBonus=mission.xpBonus+v.followerXP end
+		mission.numrewards=mission.numrewards+1
+		for i,c in ipairs(classes) do
+			local value=c.func(c,k,v)
+			if value then
+				mission[c.key]=mission[c.key]+value
+				mission.class=c.key
+				mission.maxable=c.maxable
+				mission.mat=c.mat
+				break
+			end
+		end
+	end
+end
+function module:AddExtraDataOld(mission)
 	mission.rank=mission.level < GARRISON_FOLLOWER_MAX_LEVEL and mission.level or mission.iLevel
 	mission.resources=0
 	mission.oil=0
@@ -75,6 +101,7 @@ function module:AddExtraData(mission)
 	mission.xp=mission.xp or 0
 	mission.rush=0
 	mission.chanceCap=100
+	mission.primalspirit=0
 	local numrewards=0
 	local rewards=mission.rewards
 	if not rewards then
@@ -91,7 +118,10 @@ function module:AddExtraData(mission)
 		if v.icon=="Interface\\Icons\\XPBonus_Icon" and v.followerXP then
 			mission.xpBonus=mission.xpBonus+v.followerXP
 		elseif (v.itemID) then
-			if v.itemID~=120205 then -- xp item
+			if v.itemID==120205 then -- xp item
+			elseif v.itemID==120945 then -- Primal Spirit
+					mission.primalspirit=v.quantity
+			else
 				local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount,itemEquipLoc, itemTexture, itemSellPrice = GetItemInfo(v.itemID)
 				if (not itemName or not itemTexture) then
 					mission.class="retry"
@@ -129,6 +159,10 @@ function module:AddExtraData(mission)
 		mission.class='apexis'
 		mission.maxable=true
 		mission.mat=true
+	elseif mission.primalspirit > 0 then
+		mission.class='primalspirit'
+		mission.maxable=false
+		mission.mat=false
 	elseif mission.seal > 0 then
 		mission.class='seal'
 		mission.maxable=fase
@@ -270,94 +304,7 @@ print("Could not find info for mission",missionID,G.GetMissionName(missionID))
 	end
 end
 function addon:AddExtraData(mission)
-	if newcache then return module:AddExtraData(mission) end
-	local _
-	_,mission.xp,mission.type,mission.typeDesc,mission.typeIcon,mission.locPrefix,_,mission.enemies=G.GetMissionInfo(mission.missionID)
-	mission.rank=mission.level < GARRISON_FOLLOWER_MAX_LEVEL and mission.level or mission.iLevel
-	mission.resources=0
-	mission.oil=0
-	mission.apexis=0
-	mission.seal=0
-	mission.gold=0
-	mission.followerUpgrade=0
-	mission.itemLevel=0
-	mission.xpBonus=0
-	mission.others=0
-	mission.xp=mission.xp or 0
-	mission.rush=0
-	mission.chanceCap=100
-	local numrewards=0
-	for k,v in pairs(mission.rewards) do
-		numrewards=numrewards+1
-		if k==615 and v.followerXP then mission.xpBonus=mission.xpBonus+v.followerXP end
-		if v.currencyID and v.currencyID==GARRISON_CURRENCY then mission.resources=v.quantity end
-		if v.currencyID and v.currencyID==GARRISON_SHIP_OIL_CURRENCY then mission.oil=v.quantity end
-		if v.currencyID and v.currencyID==823 then mission.apexis =mission.apexis+v.quantity end
-		if v.currencyID and v.currencyID==994 then mission.seal =mission.seal+v.quantity end
-		if v.currencyID and v.currencyID==0 then mission.gold =mission.gold+v.quantity/10000 end
-		if v.icon=="Interface\\Icons\\XPBonus_Icon" and v.followerXP then
-			mission.xpBonus=mission.xpBonus+v.followerXP
-		elseif (v.itemID) then
-			if v.itemID~=120205 then -- xp item
-				local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount,itemEquipLoc, itemTexture, itemSellPrice = GetItemInfo(v.itemID)
-				if (not itemName or not itemTexture) then
-					mission.class="retry"
-					return
-				end
-				if itemTexture:lower()==rushOrders then
-					mission.rush=mission.rush+v.quantity
-				elseif itemName and (not v.quantity or v.quantity==1) and not v.followerXP then
-					if (addon:IsFollowerUpgrade(v.itemID)) then
-						mission.followerUpgrade=itemRarity
-					else
-						itemLevel=addon:GetTrueLevel(v.itemID,itemLevel)
-						if itemLevel > 500  then
-							mission.itemLevel=itemLevel
-						else
-							mission.others=mission.others+v.quantity
-						end
-					end
-				else
-					mission.others=mission.others+v.quantity
-				end
-			end
-		end
-	end
-	mission.xpOnly=false
-	if mission.resources > 0 then
-		mission.class='resources'
-		mission.maxable=true
-		mission.mat=true
-	elseif mission.oil > 0 then
-		mission.class='oil'
-		mission.maxable=true
-		mission.mat=true
-	elseif mission.apexis > 0 then
-		mission.class='apexis'
-		mission.maxable=true
-		mission.mat=true
-	elseif mission.seal > 0 then
-		mission.class='seal'
-		mission.maxable=fase
-		mission.mat=false
-	elseif mission.gold >0 then
-		mission.class='gold'
-		mission.maxable=true
-		mission.mat=true
-	elseif mission.itemLevel >0 then
-		mission.class='itemLevel'
-	elseif mission.followerUpgrade>0 then
-		mission.class='followerUpgrade'
-	elseif mission.rush>0 then
-		mission.class='rush'
-	elseif mission.others >0 or numrewards > 1 then
-		mission.class='other'
-	else
-		mission.class='xp'
-		mission.xpOnly=true
-	end
-	mission.globalXp=(mission.xp+mission.xpBonus+(addon:GetParty(mission.missionID)['xpBonus'] or 0) )*mission.numFollowers
-
+	return module:AddExtraData(mission)
 end

 function addon:OnAllGarrisonMissions(func,inProgress)
@@ -368,3 +315,81 @@ local sorters={}
 function addon:GetMissionIterator(followerType,func)
 	return module:GetMissionIterator(followerType,func)
 end
+local function inList(self,id,reward)
+	if self.key=='xp'  then
+		if reward.followerXP then return reward.followerXp end
+	elseif self.key=='followerUpgrade' then
+		if not reward.itemID then return false end
+		local info=addon:IsFollowerUpgrade(reward.itemID)
+		if info then
+			local _,_,level=strsplit(':',info)
+			return 	tonumber(level) or 0
+		end
+	elseif self.key=='itemLevel' then
+		if not reward.itemID then return false end
+		local quality,level,minLevel=select(3,GetItemInfo(reward.itemID))
+		if quality then
+			level=addon:GetTrueLevel(reward.itemID,level)
+			if (level > 500 and minLevel >=90) or level >654 then
+				return level
+			end
+		else
+			return -1
+		end
+	elseif self.key=='other' then
+		return reward.quantity or 0
+	elseif reward.itemID and tcontains(self.list,reward.itemID) then
+		return reward.quantity or 1
+	elseif reward.currency and tcontains(self.list,reward.currency) then
+		return reward.quantity or 1
+	end
+	return false
+end
+local function isGearToken(self,id,reward)
+end
+local function isValid(self)
+	print(self.key,self.t)
+	for i=1,#self.list do
+		local id=self.list[i]
+		if id < 10000 then
+			print(GetCurrencyInfo(id))
+		else
+			print(GetItemInfo(id))
+		end
+	end
+end
+local c={}
+local function newMissionType(key,name,icon,maxable,mat,func,...)
+	return{
+		key=key,
+		t=name,
+		func=func or inList,
+		list={...},
+		i='Interface\\Icons\\' .. icon,
+		maxable=maxable,
+		mat=mat,
+		validate=isValid
+	}
+end
+classes={
+	newMissionType('xp',L['Follower experience'],'XPBonus_icon',false,false,nil,0),
+	newMissionType('resources',GetCurrencyInfo(GARRISON_CURRENCY),'inv_garrison_resource',true,true,nil,GARRISON_CURRENCY),
+	newMissionType('oil',GetCurrencyInfo(GARRISON_SHIP_OIL_CURRENCY),'garrison_oil',true,true,nil,GARRISON_SHIP_OIL_CURRENCY),
+	newMissionType('rush',L['Rush orders'],'INV_Scroll_12',false,false,nil,122595,122594,122596,122592,122590,122593,122591,122576),
+	newMissionType('apexis',GetCurrencyInfo(823),'inv_apexis_draenor',false,false,nil,823),
+	newMissionType('seal',GetCurrencyInfo(994),'ability_animusorbs',false,false,nil,824),
+	newMissionType('gold',BONUS_ROLL_REWARD_MONEY,'inv_misc_coin_01',false,false,nil,0),
+	newMissionType('followerUpgrade',L['Follower equipment set or upgrade'],'Garrison_ArmorUpgrade',false,false,nil,0),
+	newMissionType('itemLevel',L['Item Tokens'],'INV_Bracer_Cloth_Reputation_C_01',false,false,nil,0),
+	newMissionType('other',L['Other rewards'],'INV_Box_02',false,false,nil,0),
+	newMissionType('primalspirit',L['Reagents'],'6BF_Explosive_shard',false,false,nil,118472,120945,113261,113262,113263,113264),
+	newMissionType('ark',L['Archaelogy'],'achievement_character_orc_male',false,false,nil,829,828,821,108439,109585,109584), -- Fragments and completer
+	newMissionType('training',L['Follower Training'],'Spell_Holy_WeaponMastery',false,false,nil,123858,118354,118475,122582,122580,122584,118474),
+	newMissionType('legendary',L['Legendary Items'],'INV_Relics_Runestone',false,false,nil,115510,115280,128693),
+	newMissionType('toys',L['Toys and Mounts'],'INV_LesserGronnMount_Red',false,false,nil,128310,127748,128311),
+	newMissionType('reputation',L['Reputation Items'],'Spell_Shadow_DemonicCircleTeleport',false,false,nil,117492,128315),
+}
+function addon:GetRewardClasses()
+	return classes
+end
+
diff --git a/MissionControl.lua b/MissionControl.lua
index 5db5dd4..1044566 100644
--- a/MissionControl.lua
+++ b/MissionControl.lua
@@ -24,12 +24,15 @@ local tItems = {
 	{t = 'Enable/Disable oil awards.', i= 'Interface\\Icons\\garrison_oil', key = 'oil'},
 	{t = 'Enable/Disable rush scroll.', i= 'Interface\\ICONS\\INV_Scroll_12', key = 'rush'},
 	{t = 'Enable/Disable Follower XP Bonus rewards.', i = 'Interface\\Icons\\XPBonus_Icon', key = 'xp'},
-	{t = 'Enable/Disable follower equip enhancement.', i = 'Interface\\ICONS\\Garrison_ArmorUpgrade', key = 'followerUpgrade'},
+	{t = 'Enable/Disable Follower equip upgrade.', i = 'Interface\\ICONS\\Garrison_ArmorUpgrade', key = 'followerUpgrade'},
 	{t = 'Enable/Disable item tokens.', i = "Interface\\ICONS\\INV_Bracer_Cloth_Reputation_C_01", key = 'itemLevel'},
 	{t = 'Enable/Disable apexis.', i = "Interface\\Icons\\inv_apexis_draenor", key = 'apexis'},
-	{t = 'Enable/Disable other rewards.', i = "Interface\\ICONS\\INV_Box_02", key = 'other'},
-	{t = 'Enable/Disable Seal.', i = "Interface\\Icons\\ability_animusorbs", key = 'seal'}
+	{t = 'Enable/Disable generc rewards.', i = "Interface\\ICONS\\INV_Box_02", key = 'other'},
+	{t = 'Enable/Disable Seal of Tempered Fate.', i = "Interface\\Icons\\ability_animusorbs", key = 'seal'},
+	{t = 'Enable/Disable Primal Spirit.', i = "Interface\\Icons\\6BF_Explosive_shard", key = 'primalspirit'},
+	{t = 'Enable/Disable Follower Equip Set.', i = "Interface\\Icons\\Garrison_GreenArmor", key = 'followerSet'},
 }
+tItems=addon:GetRewardClasses()
 local tOrder
 local tSort={}
 local settings
@@ -42,7 +45,6 @@ function module:GMCCreateMissionList(workList)
 	--First get rid of unwanted rewards and missions that are too long
 	local settings=self.privatedb.profile.missionControl
 	local ar=settings.allowedRewards
-	local minlevel=addon:GetNumber('GCMINLEVEL')
 	wipe(workList)
 	for _,missionID in self:GetMissionIterator() do
 		local discarded=false
@@ -76,7 +78,7 @@ print(missionID,"discarded due to class == ", class)
 				break
 			end
 			if class=="itemLevel" then
-				if self:GetMissionData(missionID,'itemLevel') < minlevel then
+				if self:GetMissionData(missionID,'itemLevel') < settings.minLevel then
 --@debug@
 print(missionID,"discarded due to ilevel == ", self:GetMissionData(missionID,'itemLevel'))
 --@end-debug@
@@ -122,14 +124,14 @@ function module:GMCRunMission(missionID,start)
 		addon:RefreshFollowerStatus()
 		return
 	end
-	for i=1,#GMC.ml.Parties do
-		local party=GMC.ml.Parties[i]
+	for i=1,#GMC.list.Parties do
+		local party=GMC.list.Parties[i]
 --@debug@
 		print("Checking",party.missionID)
 --@end-debug@
 		if (missionID and party.missionID==missionID or not missionID) then
-			GMC.ml.widget:RemoveChild(party.missionID)
-			GMC.ml.widget:DoLayout()
+			GMC.list.widget:RemoveChild(party.missionID)
+			GMC.list.widget:DoLayout()
 			if (party.full) then
 				for j=1,#party.members do
 					G.AddFollowerToMission(party.missionID, party.members[j])
@@ -161,12 +163,12 @@ do
 				currentMission=0
 				x=0
 				self:Unhook(this,"OnUpdate")
-				GMC.ml.widget:SetTitle(READY)
-				GMC.ml.widget:SetTitleColor(C.Green())
+				GMC.list.widget:SetTitle(READY)
+				GMC.list.widget:SetTitleColor(C.Green())
 				wipe(GMCUsedFollowers)
 				this:Enable()
 				GMC.runButton:Enable()
-				if (#GMC.ml.Parties>0) then
+				if (#GMC.list.Parties>0) then
 					GMC.runButton:Enable()
 				end
 			end
@@ -181,7 +183,7 @@ do
 				timeElapsed=0.5
 			else
 				local missionID=aMissions[currentMission]
-				GMC.ml.widget:SetFormattedTitle("Processing mission %d of %d (%s)",currentMission,#aMissions,G.GetMissionName(missionID))
+				GMC.list.widget:SetFormattedTitle("Processing mission %d of %d (%s)",currentMission,#aMissions,G.GetMissionName(missionID))
 				local class=self:GetMissionData(missionID,"class")
 				--print(C("Processing ","Red"),missionID,addon:GetMissionData(missionID,"name"))
 				local minimumChance=0
@@ -191,7 +193,7 @@ do
 					minimumChance=tonumber(settings.rewardChance[class]) or 100
 				end
 				local party={members={},perc=0}
-				self:MCMatchMaker(missionID,party,addon:GetBoolean('GCSKIPEPIC'),minimumChance)
+				self:MCMatchMaker(missionID,party,settings.skipEpic,minimumChance)
 --@debug@
 				print(missionID,"  Requested",class,";",minimumChance,"Mission",party.perc,party.full,settings)
 --@end-debug@
@@ -204,13 +206,13 @@ do
 						GMCUsedFollowers[party.members[i]]=true
 					end
 					party.missionID=missionID
-					tinsert(GMC.ml.Parties,party)
-					GMC.ml.widget:PushChild(mb,missionID)
+					tinsert(GMC.list.Parties,party)
+					GMC.list.widget:PushChild(mb,missionID)
 					mb:SetFullWidth(true)
 					mb:SetMission(self:GetMissionData(missionID),party,false,"control")
 					mb:SetCallback("OnClick",function(...)
 						module:GMCRunMission(missionID)
-						GMC.ml.widget:RemoveChild(missionID)
+						GMC.list.widget:RemoveChild(missionID)
 					end
 					)
 				end
@@ -246,58 +248,71 @@ function module:GMC_OnClick_Start(this,button)
 --@debug@
 print(C("-------------------------------------------------","Yellow"))
 --@end-debug@
-	GMC.ml.widget:ClearChildren()
+	GMC.list.widget:ClearChildren()
 	if (self:GetTotFollowers(AVAILABLE) == 0) then
-		GMC.ml.widget:SetTitle("All followers are busy")
-		GMC.ml.widget:SetTitleColor(C.Orange())
+		GMC.list.widget:SetTitle("All followers are busy")
+		GMC.list.widget:SetTitleColor(C.Orange())
 		return
 	end
 	if ( G.IsAboveFollowerSoftCap(1) ) then
-		GMC.ml.widget:SetTitle(GARRISON_MAX_FOLLOWERS_MISSION_TOOLTIP)
-		GMC.ml.widget:SetTitleColor(C.Red())
+		GMC.list.widget:SetTitle(GARRISON_MAX_FOLLOWERS_MISSION_TOOLTIP)
+		GMC.list.widget:SetTitleColor(C.Red())
 		return
 	end
 	this:Disable()
-	GMC.ml.widget:SetTitleColor(C.Green())
+	GMC.list.widget:SetTitleColor(C.Green())
 	self:GMCCreateMissionList(aMissions)
 	wipe(GMCUsedFollowers)
-	wipe(GMC.ml.Parties)
+	wipe(GMC.list.Parties)
 	self:RefreshFollowerStatus()
 	if (#aMissions>0) then
-		GMC.ml.widget:SetFormattedTitle(L["Processing mission %d of %d"],1,#aMissions)
+		GMC.list.widget:SetFormattedTitle(L["Processing mission %d of %d"],1,#aMissions)
 	else
-		GMC.ml.widget:SetTitle("No mission matches your criteria")
-		GMC.ml.widget:SetTitleColor(C.Red())
+		GMC.list.widget:SetTitle("No mission matches your criteria")
+		GMC.list.widget:SetTitleColor(C.Red())
 	end
 	self:RawHookScript(GMC.startButton,'OnUpdate',"GMCCalculateMissions")

 end
 local chestTexture
-local function drawItemButtons()
+local function drawItemButtons(frame)
 	local GMC=GMF.MissionControlTab
-	local scale=1.1
+	frame=frame or GMC.rewards
+	local scale=0.8
 	local h=37 -- itemButtonTemplate standard size
 	local gap=5
 	local single=settings.useOneChance
 	--for j = 1, #tItems do
 		--local i=tOrder[j]
 	for j,i in ipairs(tOrder) do
-		local frame = GMC.ignoreFrames[j] or CreateFrame('BUTTON', "Priority" .. j, GMC.aif, 'ItemButtonTemplate')
+		local frame = GMC.ignoreFrames[j] or CreateFrame('BUTTON', "Priority" .. j, frame, 'ItemButtonTemplate')
 		GMC.ignoreFrames[j] = frame
 		frame:SetID(j)
 		frame:ClearAllPoints()
 		frame:SetScale(scale)
-		frame:SetPoint('TOPLEFT', 0,(j) * (-h -gap) * scale)
+			--frame:SetPoint('TOPLEFT', 10,(j) * ((-h * scale) -gap))
+		if j==1 then
+			frame:SetPoint('TOPLEFT', 35,-35)
+		else
+			frame:SetPoint('TOPLEFT', GMC.ignoreFrames[j-1],'BOTTOMLEFT',0,-6)
+		end
 		frame.icon:SetTexture(tItems[i].i)
 		frame.key=tItems[i].key
 		tSort[frame.key]=j
 		frame.tooltip=tItems[i].t
-		if ns.toc<60200 and frame.key=="oil" then
-			settings.allowedRewards[frame.key]=false
-		end
 		frame.allowed=settings.allowedRewards[frame.key]
 		frame.chance=settings.rewardChance[frame.key]
 		frame.icon:SetDesaturated(not frame.allowed)
+		if frame.key=="itemLevel" then
+			frame.Count:SetText(settings.minLevel)
+			frame.Count:SetPoint('BOTTOMRIGHT',0,5)
+			frame.Count:Show()
+		elseif frame.key=="followerUpgrade" then
+			frame.Count:SetText(settings.minUpgrade)
+			frame.Count:Show()
+		else
+			frame.Count:Hide()
+		end
 		-- Need to resave them asap in order to populate the array for future scans
 		settings.allowedRewards[frame.key]=frame.allowed
 		settings.rewardChance[frame.key]=frame.chance
@@ -321,7 +336,7 @@ local function drawItemButtons()
 		frame.chest:SetTexture('Interface\\Garrison\\GarrisonMissionUI2.blp')
 		frame.chest:SetAtlas(chestTexture)
 		frame.chest:SetSize((209-(209*0.25))*0.30, (155-(155*0.25)) * 0.30)
-		frame.chest:SetPoint('CENTER',frame.slider, 0, 25)
+		frame.chest:SetPoint('CENTER',frame.slider, 0, 15)
 		if (single) then
 			frame.chest:SetDesaturated(true)
 		else
@@ -392,16 +407,15 @@ print("from:",from,"to:",to)
 		frame.bottom=frame:GetBottom()
 	end
 	if not GMC.rewardinfo then
-		GMC.rewardinfo = GMC.aif:CreateFontString()
+		GMC.rewardinfo = frame:CreateFontString()
 		local info=GMC.rewardinfo
 		info:SetFontObject('GameFontHighlight')
 		info:SetText("Click to enable/disable a reward.\nDrag to reorder")
 		info:SetTextColor(1, 1, 1)
-		info:SetPoint("TOP",GMC.ignoreFrames[#tItems],"BOTTOM",256/2,-15)
+		info:SetPoint("BOTTOM",0,-5)
 	end
-	GMC.aif:SetSize(256, (scale*h+gap) * #tItems)
+	frame:SetWidth(200)
 	return GMC.ignoreFrames[#tItems]
-
 end
 local function dbfixV1()
 	if type(settings.allowedRewards['equip'])~='nil' then
@@ -417,7 +431,16 @@ local function dbfixV1()
 		settings.rewardChance['followerEquip']=nil
 	end
 end
-
+local function toggleEpicWarning(warning)
+	local GMC=GMF.MissionControlTab
+	if (settings.skipEpic) then
+		warning:Show()
+		GMC.duration:SetPoint("TOPLEFT",GMC.rewards,"TOPRIGHT",0,-30)
+	else
+		warning:Hide()
+		GMC.duration:SetPoint("TOPLEFT",GMC.rewards,"TOPRIGHT",0,0)
+	end
+end
 function module:OnInitialized()
 	local bigscreen=ns.bigscreen
 	db=addon.db.global
@@ -440,6 +463,11 @@ function module:OnInitialized()
 		end
 		_G.tOrder=tOrder
 	end
+	if #tOrder<#tItems then
+		for i=#tOrder+1,#tItems do
+			tOrder[i]=i
+		end
+	end
 	for i=1,#tOrder do
 		tSort[tItems[tOrder[i]].key]=i
 	end
@@ -451,121 +479,86 @@ function module:OnInitialized()
 	--GMC:SetPoint('LEFT')
 	--GMC:SetSize(GMF:GetWidth(), GMF:GetHeight())
 	GMC:Hide()
-	local chance=self:GMCBuildChance()
-	local duration=self:GMCBuildDuration()
-	local rewards=self:GMCBuildRewards()
-	local list=self:GMCBuildMissionList()
-	duration:SetPoint("TOPLEFT",bigscreen and 0 or -10,-50)
-	chance:SetPoint("TOPLEFT",duration,"BOTTOMLEFT",bigscreen and 0 or -10,-80)
-	rewards:SetPoint("TOPLEFT",duration,"TOPRIGHT",bigscreen and 50 or 0,0)
-	list:SetPoint("TOPLEFT",rewards,"TOPRIGHT",bigscreen and 10 or 0,-30)
-	list:SetPoint("BOTTOMRIGHT",GMF,"BOTTOMRIGHT",-25,25)
-	GMC.startButton = CreateFrame('BUTTON',nil,  list.frame, 'GameMenuButtonTemplate')
-	GMC.startButton:SetText('Calculate')
-	GMC.startButton:SetWidth(148)
-	GMC.startButton:SetPoint('TOPLEFT',10,25)
-	GMC.startButton:SetScript('OnClick', function(this,button) self:GMC_OnClick_Start(this,button) end)
-	GMC.startButton:SetScript('OnEnter', function() GameTooltip:SetOwner(GMC.startButton, 'ANCHOR_TOPRIGHT') GameTooltip:AddLine('Assign your followers to missions.') GameTooltip:Show() end)
-	GMC.startButton:SetScript('OnLeave', function() GameTooltip:Hide() end)
-	GMC.runButton = CreateFrame('BUTTON', nil,list.frame, 'GameMenuButtonTemplate')
-	GMC.runButton:SetText('Send all mission at once')
-	GMC.runButton:SetScript('OnEnter', function()
-		GameTooltip:SetOwner(GMC.runButton, 'ANCHOR_TOPRIGHT')
-		GameTooltip:AddLine(L["Submit all your mission at once. No question asked."])
-		GameTooltip:AddLine(L["You can also send mission one by one clicking on each button."])
-		GameTooltip:Show()
-	end)
-	GMC.runButton:SetScript('OnLeave', function() GameTooltip:Hide() end)
-	GMC.runButton:SetWidth(148)
-	GMC.runButton:SetScript('OnClick',function(this,button) self:GMC_OnClick_Run(this,button) end)
-	GMC.runButton:Disable()
-	GMC.runButton:SetPoint('TOPRIGHT',-10,25)
-	GMC.logoutButton=CreateFrame('BUTTON', nil,list.frame, 'GameMenuButtonTemplate')
-	GMC.logoutButton:SetText(LOGOUT)
-	GMC.logoutButton:SetWidth(ns.bigscreen and 148 or 90)
-	GMC.logoutButton:SetScript("OnClick",function() GMF:Hide() Logout() end )
-	GMC.logoutButton:SetPoint('TOP',0,25)
-	addon:AddLabel(L["Mission Control"])
-	addon:AddToggle("GCSKIPRARE",settings.skipRare,L["Ignore rare missions"],L["When checked, Mission Control ignores mission marked as rare"])
-	addon:AddToggle("GCSKIPEPIC",settings.skipRare,L["Ignore epic followers"],L["When checked, Mission Control ignores mission marked as rare"])
-	addon:AddSlider("GCMINLEVEL",600,540,715,L["Minimum Item Level"],L["For missions rewarding PC equipment, request this mimimum item level in rewards (not applied in real time)"],5)
-	local warning=GMC:CreateFontString(nil,"ARTWORK","CombatTextFont")
-	warning:SetText(L["Epic followers are NOT sent alone on xp only missions"])
-	warning:SetPoint("TOPLEFT",GMC,"TOPLEFT",0,-25)
-	warning:SetPoint("TOPRIGHT",GMC,"TOPRIGHT",0,-25)
-	warning:SetJustifyH("CENTER")
-	warning:SetTextColor(C.Orange())
-	GMC.warning=warning
-	if addon:GetBoolean('GCSKIPRARE') then warning:Show() else warning:Hide() end
+	GMC.chance=self:GMCBuildChance()
+	GMC.duration=self:GMCBuildDuration()
+	GMC.rewards=self:GMCBuildRewards()
+	GMC.list=self:GMCBuildMissionList()
+	GMC.flags=self:GMCBuildFlags()
+	local chance=GMC.chance
+	local duration=GMC.duration
+	local rewards=GMC.rewards
+	local list=GMC.list
+	local flags=GMC.flags
+	rewards:SetPoint("TOPLEFT",20,-25)
+	rewards:SetPoint("BOTTOMLEFT",20,25)
+	list.widget:SetPoint("TOPLEFT",duration,"TOPRIGHT",0,-30)
+	list.widget:SetPoint("BOTTOMRIGHT",GMF,"BOTTOMRIGHT",-25,25)
+	--duration:SetPoint("TOPLEFT",rewards,"TOPRIGHT",0,-50) Now, its position is decided in toggleEpicWarning
+	chance:SetPoint("TOPLEFT",duration,"BOTTOMLEFT",0,0)
+	flags:SetPoint("TOPLEFT",chance,"BOTTOMLEFT",0,0)
+--@debug@
+--	AddBackdrop(rewards)
+--	AddBackdrop(duration,0,1,0)
+--	AddBackdrop(chance,0,0,1)
+--	AddBackdrop(flags,0,1,1)
+--@end-debug@
 	GMC.Credits=GMC:CreateFontString(nil,"ARTWORK","QuestFont_Shadow_Small")
 	GMC.Credits:SetWidth(0)
 	GMC.Credits:SetFormattedText(C(L["Original concept and interface by %s"],'Yellow'),C("Motig","Red") )
-	GMC.Credits:SetJustifyH("LEFT")
-	GMC.Credits:SetPoint("BOTTOMLEFT",50,5)
+	GMC.Credits:SetJustifyH("RIGHT")
+	GMC.Credits:SetPoint("BOTTOMRIGHT",-50,5)
 	return GMC
 end
 local refreshTimer
 function module:Refresh()
-	if GMF.MissionControlTab.startButton:IsEnabled() then
+	if GMF.MissionControlTab.startButton:IsEnabled() and not IsMouseButtonDown("LeftButton") then
 		self:GMC_OnClick_Start(GMF.MissionControlTab.startButton,"LeftUp")
 	else
 		if refreshTimer then
 			self:CancelTimer(refreshTimer)
 			refreshTimer=nil
 		end
-		refreshTimer=self:ScheduleTimer("Refresh",1)
+		refreshTimer=self:ScheduleTimer("Refresh",0.5)
 	end
 end
-function addon:ApplyGCSKIPRARE(value)
-	module:Refresh()
-end
-function addon:ApplyGCMINLEVEL(value)
-	module:Refresh()
-end
-function addon:ApplyGCSKIPEPIC(value)
-	local warning=GMF.MissionControlTab.warning
-	if addon:GetBoolean('GCSKIPRARE') then warning:Show() else warning:Hide() end
-	module:Refresh()
-end
 function module:GMCBuildChance()
 	local GMC=GMF.MissionControlTab
 	--Chance
-	GMC.cf = CreateFrame('FRAME', nil, GMC)
-	GMC.cf:SetSize(256, 150)
+	local frame= CreateFrame('FRAME', nil, GMC)
+	frame:SetSize(210, 170)
+
+	GMC.cc = frame:CreateFontString() --title
+	GMC.cc:SetFontObject('GameFontNormalHuge')
+	GMC.cc:SetText(L['Success Chance'])
+	GMC.cc:SetPoint('TOP', 0, -5)
+	GMC.cc:SetTextColor(C:White())

-	GMC.cp = GMC.cf:CreateTexture(nil, 'BACKGROUND')
+	GMC.cp = frame:CreateTexture(nil, 'BACKGROUND') --Chest
 	GMC.cp:SetTexture('Interface\\Garrison\\GarrisonMissionUI2.blp')
 	GMC.cp:SetAtlas(chestTexture)
 	GMC.cp:SetDesaturated(not settings.useOneChance)
 	GMC.cp:SetSize((209-(209*0.25))*0.60, (155-(155*0.25))*0.60)
 	GMC.cp:SetPoint('CENTER', 0, 20)

-	GMC.cc = GMC.cf:CreateFontString()
-	GMC.cc:SetFontObject('GameFontNormalHuge')
-	GMC.cc:SetText(L['Success Chance'])
-	GMC.cc:SetPoint('TOP', 0, 0)
-	GMC.cc:SetTextColor(C:White())
-
-	GMC.ct = GMC.cf:CreateFontString()
+	GMC.ct = frame:CreateFontString() --Chance number
 	GMC.ct:SetFontObject('ZoneTextFont')
 	GMC.ct:SetFormattedText('%d%%',settings.minimumChance)
-	GMC.ct:SetPoint('TOP', 0, -40)
+	GMC.ct:SetPoint('CENTER', 0,20)
 	if settings.useOneChance then
 		GMC.ct:SetTextColor(C:Green())
 	else
 		GMC.ct:SetTextColor(C:Silver())
 	end
-	GMC.cs = factory:Slider(GMC.cf,0,100,settings.minimumChance,L['Minumum needed chance'])
-	GMC.cs:SetPoint('BOTTOM', 10, 0)
+	GMC.cs = factory:Slider(frame,0,100,settings.minimumChance,L['Minumum needed chance'],L["Mission with lower success chance will be ignored"]) -- Slider
+	GMC.cs:SetPoint('CENTER', 0, -25)
 	GMC.cs:SetScript('OnValueChanged', function(self, value)
 			local value = math.floor(value)
 			GMC.ct:SetText(value..'%')
 			settings.minimumChance = value
 	end)
 	GMC.cs:SetValue(settings.minimumChance)
-	GMC.ck=factory:Checkbox(GMC.cs,settings.useOneChance,L["Global success chance"])
-	GMC.ck.tooltip=L["Unchecking this will allow you to set specific success chance for each reward type"]
-	GMC.ck:SetPoint("TOPLEFT",GMC.cs,"BOTTOMLEFT",-25,-10)
+	GMC.ck=factory:Checkbox(frame,settings.useOneChance,L["Global success chance"],L["Unchecking this will allow you to set specific success chance for each reward type"])
+	GMC.ck:SetPoint("BOTTOM",0,5)
 	GMC.ck:SetScript("OnClick",function(this)
 		settings.useOneChance=this:GetChecked()
 		if (settings.useOneChance) then
@@ -577,7 +570,7 @@ function module:GMCBuildChance()
 		end
 		drawItemButtons()
 	end)
-	return GMC.cf
+	return frame
 end
 local function timeslidechange(this,value)
 	local GMC=GMF.MissionControlTab
@@ -594,62 +587,117 @@ local function timeslidechange(this,value)
 	GMC.mt:SetTextColor(1, c, c)
 	GMC.mt:SetFormattedText("%d-%dh",settings.minDuration,settings.maxDuration)
 end
+function module:GMCBuildFlags()
+	-- Duration
+	local GMC=GMF.MissionControlTab
+	local frame= CreateFrame('FRAME', nil, GMC) -- Flags frame
+	frame:SetSize(210, 30+40*5)
+	local title = frame:CreateFontString() -- Title
+	title:SetFontObject('GameFontNormalHuge')
+	title:SetText(L['Other settings'])
+	title:SetPoint('TOPLEFT', 0, -5)
+	title:SetPoint('TOPRIGHT', 0, -5)
+	title:SetTextColor(1, 1, 1)
+	title:SetJustifyH("CENTER")
+	GMC.skipRare=factory:Checkbox(frame,settings.skipRare,L["Ignore rare missions"],L["Rare missions will not be considered"])
+	GMC.skipRare:SetPoint("TOPLEFT",title,"BOTTOMLEFT",0,-5)
+	GMC.skipRare:SetScript("OnClick",function(this)
+		settings.skipRare=this:GetChecked()
+		module:GMC_OnClick_Start(GMC.startButton,"LeftUp")
+	end)
+	local warning=GMC:CreateFontString(nil,"ARTWORK","CombatTextFont")
+	warning:SetText(L["Epic followers are NOT sent alone on xp only missions"])
+	warning:SetPoint("TOPLEFT",GMC.rewards,"TOPRIGHT",0,0)
+	warning:SetPoint("TOPRIGHT",GMC,"TOPRIGHT",0,-25)
+	warning:SetJustifyH("CENTER")
+	warning:SetTextColor(C.Orange())
+	toggleEpicWarning(warning)
+	GMC.skipEpic=factory:Checkbox(frame,settings.skipEpic,L["Ignore epic for xp missions."],L["IF you have a Salvage Yard you probably dont want to have this one checked"])
+	GMC.skipEpic:SetPoint("TOPLEFT",GMC.skipRare,"BOTTOMLEFT",0,-5)
+	GMC.skipEpic:SetScript("OnClick",function(this)
+		settings.skipEpic=this:GetChecked()
+		toggleEpicWarning(warning)
+		module:Refresh()
+	end)
+	GMC.minLevel=factory:Slider(frame,540,715,settings.minLevel,L["Item minimum level"],L['Minimum requested level for equipment rewards'])
+	GMC.minLevel:SetPoint('TOP', GMC.skipEpic,"BOTTOM",0, -25)
+	GMC.minLevel:SetScript('OnValueChanged', function(self, value)
+			local value = math.floor(value)
+			settings.minLevel = value
+			drawItemButtons()
+			module:Refresh()
+	end)
+	--GMC.minLevel:SetValue(settings.minLevel)
+	GMC.minLevel:SetStep(15)
+	GMC.minUpgrade=factory:Slider(frame,600,675,settings.minUpgrade,L["Follower set minimum upgrade"],L['Minimum requested upgrade for followers set (Enhancements are always included)'])
+	GMC.minUpgrade:SetPoint('TOP', GMC.minLevel,"BOTTOM",0, -25)
+	GMC.minUpgrade:SetScript('OnValueChanged', function(self, value)
+			local value = math.floor(value)
+			settings.minUpgrade = value
+			drawItemButtons()
+			module:Refresh()
+	end)
+	--GMC.minUpgrade:SetValue(settings.minUpgrade)
+	GMC.minUpgrade:SetStep(15)
+	return frame
+end
 function module:GMCBuildDuration()
 	-- Duration
 	local GMC=GMF.MissionControlTab
-	GMC.tf = CreateFrame('FRAME', nil, GMC)
-	GMC.tf:SetSize(256, 180)
-	GMC.tf:SetPoint('LEFT', 80, 120)
+	local frame= CreateFrame('FRAME', nil, GMC) -- Dutation frame
+	frame:SetSize(210, 220)
+	frame:SetPoint('TOP',0, -20)
+
+	GMC.mdt = frame:CreateFontString() -- Title
+	GMC.mdt:SetFontObject('GameFontNormalHuge')
+	GMC.mdt:SetText(L['Mission Duration'])
+	GMC.mdt:SetPoint('TOP', 0, -5)
+	GMC.mdt:SetTextColor(1, 1, 1)
+

-	GMC.bg = GMC.tf:CreateTexture(nil, 'BACKGROUND')
-	GMC.bg:SetTexture('Interface\\Timer\\Challenges-Logo.blp')
-	GMC.bg:SetSize(100, 100)
-	GMC.bg:SetPoint('CENTER', 0, 0)
-	GMC.bg:SetBlendMode('ADD')
+	GMC.hg = frame:CreateTexture(nil, 'BACKGROUND') -- Hourglass
+	GMC.hg:SetTexture('Interface\\Timer\\Challenges-Logo.blp')
+	GMC.hg:SetSize(7, 70)
+	GMC.hg:SetPoint('CENTER', 0, 0)
+	GMC.hg:SetBlendMode('ADD')

-	GMC.tcf = GMC.tf:CreateTexture(nil, 'BACKGROUND')
+	GMC.rune = frame:CreateTexture(nil, 'BACKGROUND') --Rune
 	--bb:SetTexture('Interface\\Timer\\Challenges-Logo.blp')
 	--bb:SetTexture('dungeons\\textures\\devices\\mm_clockface_01.blp')
-	GMC.tcf:SetTexture('World\\Dungeon\\Challenge\\clockRunes.blp')
-	GMC.tcf:SetSize(110, 110)
-	GMC.tcf:SetPoint('CENTER', 0, 0)
-	GMC.tcf:SetBlendMode('ADD')
+	GMC.rune:SetTexture('World\\Dungeon\\Challenge\\clockRunes.blp')
+	GMC.rune:SetSize(80, 80)
+	GMC.rune:SetPoint('CENTER', 0, 0)
+	GMC.rune:SetBlendMode('ADD')

-	GMC.mdt = GMC.tf:CreateFontString()
-	GMC.mdt:SetFontObject('GameFontNormalHuge')
-	GMC.mdt:SetText('Mission Duration')
-	GMC.mdt:SetPoint('TOP', 0, 0)
-	GMC.mdt:SetTextColor(1, 1, 1)
-
-	GMC.mt = GMC.tf:CreateFontString()
+	GMC.mt = frame:CreateFontString() -- Duration string over hourglass
 	GMC.mt:SetFontObject('ZoneTextFont')
 	GMC.mt:SetFormattedText('%d-%dh',settings.minDuration,settings.maxDuration)
 	GMC.mt:SetPoint('CENTER', 0, 0)
 	GMC.mt:SetTextColor(1, 1, 1)

-	GMC.ms1 = factory:Slider(GMC.tf,0,24,settings.minDuration,L['Minimum mission duration.'])
-	GMC.ms2 = factory:Slider(GMC.tf,0,24,settings.maxDuration,L['Maximum mission duration.'])
-	GMC.ms1:SetPoint('BOTTOM', 0, 0)
-	GMC.ms2:SetPoint('TOP', GMC.ms1,"BOTTOM",0, -25)
+	GMC.ms1 = factory:Slider(frame,0,24,settings.minDuration,L['Minimum mission duration.'])
+	GMC.ms2 = factory:Slider(frame,0,24,settings.maxDuration,L['Maximum mission duration.'])
+	GMC.ms1:SetPoint('TOP', frame,'TOP',0, -45)
+	GMC.ms2:SetPoint('BOTTOM', frame,'BOTTOM',0, 15)
 	GMC.ms2.max=true
 	GMC.ms1:SetScript('OnValueChanged', timeslidechange)
 	GMC.ms2:SetScript('OnValueChanged', timeslidechange)
 	timeslidechange(GMC.ms1,settings.minDuration)
 	timeslidechange(GMC.ms2,settings.maxDuration)
-	return GMC.tf
+	return frame
 end
 function module:GMCBuildRewards()
 	--Allowed rewards
 	local GMC=GMF.MissionControlTab
-	GMC.aif = CreateFrame('FRAME', nil, GMC)
-	GMC.itf = GMC.aif:CreateFontString()
+	local frame = CreateFrame('FRAME', nil, GMC)
+	GMC.itf = frame:CreateFontString()
 	GMC.itf:SetFontObject('GameFontNormalHuge')
 	GMC.itf:SetText(L['Allowed Rewards'])
 	GMC.itf:SetPoint('TOP', 0, 0)
 	GMC.itf:SetTextColor(1, 1, 1)
 	GMC.ignoreFrames = {}
-	local ref=drawItemButtons()
-	return GMC.aif
+	drawItemButtons(frame)
+	return frame
 end

 function module:GMCBuildMissionList()
@@ -660,7 +708,31 @@ function module:GMCBuildMissionList()
 	ml.widget:SetTitleHeight(40)
 	ml.widget:SetParent(GMC)
 	ml.widget:Show()
-	GMC.ml=ml
-	return ml.widget
+	GMC.startButton = CreateFrame('BUTTON',nil,  ml.widget.frame, 'GameMenuButtonTemplate')
+	GMC.startButton:SetText('Calculate')
+	GMC.startButton:SetWidth(148)
+	GMC.startButton:SetPoint('TOPLEFT',10,25)
+	GMC.startButton:SetScript('OnClick', function(this,button) self:GMC_OnClick_Start(this,button) end)
+	GMC.startButton:SetScript('OnEnter', function() GameTooltip:SetOwner(GMC.startButton, 'ANCHOR_TOPRIGHT') GameTooltip:AddLine('Assign your followers to missions.') GameTooltip:Show() end)
+	GMC.startButton:SetScript('OnLeave', function() GameTooltip:Hide() end)
+	GMC.runButton = CreateFrame('BUTTON', nil,ml.widget.frame, 'GameMenuButtonTemplate')
+	GMC.runButton:SetText('Send all mission at once')
+	GMC.runButton:SetScript('OnEnter', function()
+		GameTooltip:SetOwner(GMC.runButton, 'ANCHOR_TOPRIGHT')
+		GameTooltip:AddLine(L["Submit all your mission at once. No question asked."])
+		GameTooltip:AddLine(L["You can also send mission one by one clicking on each button."])
+		GameTooltip:Show()
+	end)
+	GMC.runButton:SetScript('OnLeave', function() GameTooltip:Hide() end)
+	GMC.runButton:SetWidth(148)
+	GMC.runButton:SetScript('OnClick',function(this,button) self:GMC_OnClick_Run(this,button) end)
+	GMC.runButton:Disable()
+	GMC.runButton:SetPoint('TOPRIGHT',-10,25)
+	GMC.logoutButton=CreateFrame('BUTTON', nil,ml.widget.frame, 'GameMenuButtonTemplate')
+	GMC.logoutButton:SetText(LOGOUT)
+	GMC.logoutButton:SetWidth(ns.bigscreen and 148 or 90)
+	GMC.logoutButton:SetScript("OnClick",function() GMF:Hide() Logout() end )
+	GMC.logoutButton:SetPoint('TOP',0,25)
+	return ml

 end