vanilla-wow-addons – Rev 1
?pathlinks?
local dewdrop = DewdropLib:GetInstance('1.0')
local tablet = TabletLib:GetInstance('1.0')
local metrognome = Metrognome:GetInstance('1')
local chosenProfession = SkillsPlusFuLocals.FUBAR_LABEL
local toonSaveKey = ''
SkillsPlusFu = FuBarPlugin:GetInstance('1.2'):new({
name = SkillsPlusFuLocals.NAME,
description = SkillsPlusFuLocals.DESCRIPTION,
version = '0.6.'..string.sub('$Revision: 0 $', 12, -3),
releaseDate = string.sub('$Date: 2006-08-19 07:00 +0200 (Sat, 19 August 2006) $', 8, 17),
aceCompatible = 103,
-- fuCompatible = 102,
author = 'Jayhawk',
email = 'jaydehawk@gmail.com',
category = 'others',
db = AceDatabase:new('SkillsPlusFuDB'),
defaults = {
showSkillLabel = true,
showBooleanSkills = false,
showPlayerNames = true,
showNotification = false,
showOtherToonSkills = false,
cooldownSave = {},
skillsSave = {},
},
charDefaults = { hidden = {} },
-- cmd = AceChatCmd:new(SkillsPlusFuLocals.COMMANDS, SkillsPlusFuLocals.CMD_OPTIONS),
loc = SkillsPlusFuLocals,
hasIcon = 'Interface\\Icons\\Trade_Engineering',
clickableTooltip = true,
})
-- menu toggles
function SkillsPlusFu:IsShowingSkillLabel()
return self.data.showSkillLabel
end
function SkillsPlusFu:ToggleShowingSkillLabel()
self.data.showSkillLabel = not self.data.showSkillLabel
self:UpdateTooltip()
return self.data.showSkillLabel
end
function SkillsPlusFu:IsShowingOtherToonSkills()
return self.data.showOtherToonSkills
end
function SkillsPlusFu:ToggleOtherToonSkills()
self.data.showOtherToonSkills = not self.data.showOtherToonSkills
self:UpdateData()
self:UpdateTooltip()
return self.data.showOtherToonSkills
end
function SkillsPlusFu:IsShowingBooleanSkills()
return self.data.showBooleanSkills
end
function SkillsPlusFu:ToggleShowingBooleanSkills()
self.data.showBooleanSkills = not self.data.showBooleanSkills
self:UpdateTooltip()
return self.data.showBooleanSkills
end
function SkillsPlusFu:IsShowingPlayerNames()
return self.data.showPlayerNames
end
function SkillsPlusFu:ToggleShowingPlayerNames()
self.data.showPlayerNames = not self.data.showPlayerNames
self:UpdateTooltip()
return self.data.showPlayerNames
end
function SkillsPlusFu:IsShowNotification()
return self.data.showNotification
end
function SkillsPlusFu:ToggleShowNotification()
self.data.showNotification = not self.data.showNotification
self:UpdateTooltip()
return self.data.showNotification
end
-- update
function SkillsPlusFu:OnUpdate(difference)
if( self:IsShowNotification() ) then
for k, v in self.data.cooldownSave do
for itemName, itemTable in v do
local remaining = ((itemTable.Cooldown + itemTable.LastCheck) - time())
if (remaining <= self.loc.COOLDOWN_NOTIFYTIME) then
if (self.data.cooldownSave[k][itemName].IsReady ~= 1) then
local _, _, realm, player = string.find(k, '^(.+)\|(.+)$')
if (remaining <= 0) then
DEFAULT_CHAT_FRAME:AddMessage(format(self.loc.COOLDOWN_IS_READY, itemName, realm, player))
else
DEFAULT_CHAT_FRAME:AddMessage(format(self.loc.COOLDOWN_WILL_BE_READY, itemName, realm, player, floor(remaining+0.9)))
end
PlaySound('AuctionWindowOpen')
self.data.cooldownSave[k][itemName].IsReady = 1
self:Update()
end
end
end
end
end
end
-- init/exit functions
function SkillsPlusFu:Initialize()
-- load icons
self.ICON_ALCHEMY = 'Interface\\Icons\\Trade_Alchemy'
self.ICON_BLACKSMITHING = 'Interface\\Icons\\Trade_Blacksmithing'
self.ICON_COOKING = 'Interface\\Icons\\INV_Misc_Food_15'
self.ICON_DISENCHANTING = 'Interface\\Icons\\Spell_Holy_RemoveCurse'
self.ICON_ENCHANTING = 'Interface\\Icons\\Trade_Engraving'
self.ICON_ENGINEERING = 'Interface\\Icons\\Trade_Engineering'
self.ICON_FIRSTAID = 'Interface\\Icons\\Spell_Holy_SealOfSacrifice'
self.ICON_FISHING = 'Interface\\Icons\\Trade_Fishing'
self.ICON_LEATHERWORKING = 'Interface\\Icons\\Trade_Leatherworking'
self.ICON_LOCKPICKING = 'Interface\\Icons\\INV_Misc_Key_03'
self.ICON_POISONS = 'Interface\\Icons\\Trade_BrewPoison'
self.ICON_SMELTING = 'Interface\\Icons\\Trade_Mining'
self.ICON_TAILORING = 'Interface\\Icons\\Trade_Tailoring'
self.skillList = {}
end
function SkillsPlusFu:Enable()
-- skills management
self:RegisterEvent('SKILL_LINES_CHANGED','Update')
self:RegisterEvent('PLAYER_LEVEL_UP','Update')
-- cooldown management
metrognome:Register(self.name, self.OnUpdate, self.loc.COOLDOWN_TIMER_FREQUENCY, self)
metrognome:Start(self.name)
self:RegisterEvent('TRADE_SKILL_UPDATE')
self:RegisterEvent('CHAT_MSG_SPELL_TRADESKILLS')
self:RegisterEvent('CHAT_MSG_LOOT')
-- variables
toonSaveKey = GetCVar('realmName')..'|'..UnitName('player')
end
function SkillsPlusFu:Disable()
metrognome:Unregister(self.name)
end
-- cooldown management
function SkillsPlusFu:CooldownRemaining(timeStamp)
local timeRemaining = {}
timeRemaining.d = 0
timeRemaining.h = 0
timeRemaining.m = 0
timeRemaining.s = 0
-- 86,400 seconds equals one day
if (timeStamp >= 86400) then
timeRemaining.d = floor(timeStamp / 86400)
timeStamp = (timeStamp - (timeRemaining.d * 86400))
end
-- 3,600 seconds equals one hour
if (timeStamp >= 3600) then
timeRemaining.h = floor(timeStamp / 3600)
timeStamp = (timeStamp - (timeRemaining.h * 3600))
end
-- 60 seconds equals one minute
if ( timeStamp >= 60 ) then
timeRemaining.m = floor(timeStamp / 60)
timeStamp = (timeStamp - (timeRemaining.m * 60))
end
-- add remaining seconds
timeRemaining.s = timeStamp
return timeRemaining
end
function SkillsPlusFu:TRADE_SKILL_UPDATE()
local numSkills = GetNumTradeSkills()
for i=1, numSkills do
local itemName = GetTradeSkillInfo(i)
local cooldown = GetTradeSkillCooldown(i)
-- check for transmute only, all transmutes share the same cooldown
if (string.find(itemName, self.loc.COOLDOWN_TRANSMUTE_MATCH)) then
itemName = self.loc.COOLDOWN_TRANSMUTES
end
if (itemName == self.loc.COOLDOWN_TRANSMUTES or
itemName == self.loc.COOLDOWN_MOONCLOTH) then
if (cooldown == nil) then
cooldown = 0
end
if (self.data.cooldownSave[toonSaveKey] == nil) then
self.data.cooldownSave[toonSaveKey] = {}
end
if (self.data.cooldownSave[toonSaveKey][itemName] == nil) then
self.data.cooldownSave[toonSaveKey][itemName] = {}
end
self.data.cooldownSave[toonSaveKey][itemName].Cooldown = cooldown
self.data.cooldownSave[toonSaveKey][itemName].LastCheck = time()
self.data.cooldownSave[toonSaveKey][itemName].IsReady = 0
end
end
self:Update()
end
function SkillsPlusFu:CHAT_MSG_SPELL_TRADESKILLS()
local _, _, created
created = string.find(arg1, self.loc.COOLDOWN_CREATE_ITEM);
if (created and string.find(arg1, self.loc.COOLDOWN_SNOWBALL)) then
-- we found a snowball
local itemName = self.loc.COOLDOWN_SNOWMASTER
if (self.data.cooldownSave[toonSaveKey] == nil) then
self.data.cooldownSave[toonSaveKey] = {}
end
if (cooldownSave[toonSaveKey][itemName] == nil) then
cooldownSave[toonSaveKey][itemName] = {}
end
self.data.cooldownSave[toonSaveKey][itemName].Cooldown = 86400
self.data.cooldownSave[toonSaveKey][itemName].LastCheck = time()
self.data.cooldownSave[toonSaveKey][itemName].IsReady = 0
elseif (created and string.find(arg1, self.loc.COOLDOWN_REFINED_SALT)) then
-- we found refined salt
local itemName = self.loc.COOLDOWN_SALT_SHAKER
if (self.data.cooldownSave[toonSaveKey] == nil) then
self.data.cooldownSave[toonSaveKey] = {}
end
if (self.data.cooldownSave[toonSaveKey][itemName] == nil) then
self.data.cooldownSave[toonSaveKey][itemName] = {}
end
self.data.cooldownSave[toonSaveKey][itemName].Cooldown = 259200
self.data.cooldownSave[toonSaveKey][itemName].LastCheck = time()
self.data.cooldownSave[toonSaveKey][itemName].IsReady = 0
end
self:Update()
end
function SkillsPlusFu:CHAT_MSG_LOOT()
if (string.find(arg1, self.loc.COOLDOWN_ELUNE_STONE)) then
local itemName = self.loc.COOLDOWN_ELUNES_LANTERN
if (self.data.cooldownSave[toonSaveKey] == nil) then
self.data.cooldownSave[toonSaveKey] = {}
end
if (self.data.cooldownSave[toonSaveKey][itemName] == nil) then
self.data.cooldownSave[toonSaveKey][itemName] = {}
end
self.data.cooldownSave[toonSaveKey][itemName].Cooldown = 86400
self.data.cooldownSave[toonSaveKey][itemName].LastCheck = time()
self.data.cooldownSave[toonSaveKey][itemName].IsReady = 0
end
self:Update()
end
function SkillsPlusFu:ClearCooldownData()
self.data.cooldownSave = {}
self:Update()
end
-- skills management
function SkillsPlusFu:AddProfessionMenu(skillName)
if (skillName == self.loc.SKILL_ALCHEMY) then
dewdrop:AddLine(
'text', self.loc.SKILL_ALCHEMY,
'func', function() CastSpellByName(self.loc.SKILL_ALCHEMY)
self:UpdateText(self.loc.SKILL_ALCHEMY,self.ICON_ALCHEMY)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_BLACKSMITHING) then
dewdrop:AddLine(
'text', self.loc.SKILL_BLACKSMITHING,
'func', function() CastSpellByName(self.loc.SKILL_BLACKSMITHING)
self:UpdateText(self.loc.SKILL_BLACKSMITHING,self.ICON_BLACKSMITHING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_COOKING) then
dewdrop:AddLine(
'text', self.loc.SKILL_COOKING,
'func', function() CastSpellByName(self.loc.SKILL_COOKING)
self:UpdateText(self.loc.SKILL_COOKING,self.ICON_COOKING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_ENCHANTING) then
dewdrop:AddLine(
'text', self.loc.SKILL_DISENCHANTING,
'func', function() CastSpellByName(self.loc.SKILL_DISENCHANTING)
self:UpdateText(self.loc.SKILL_DISENCHANTING,self.ICON_DISENCHANTING)
end,
'arg1', self
)
dewdrop:AddLine(
'text', self.loc.SKILL_ENCHANTING,
'func', function() CastSpellByName(self.loc.SKILL_ENCHANTING)
self:UpdateText(self.loc.SKILL_ENCHANTING,self.ICON_ENCHANTING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_ENGINEERING) then
dewdrop:AddLine(
'text', self.loc.SKILL_ENGINEERING,
'func', function() CastSpellByName(self.loc.SKILL_ENGINEERING)
self:UpdateText(self.loc.SKILL_ENGINEERING,self.ICON_ENGINEERING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_FIRSTAID) then
dewdrop:AddLine(
'text', self.loc.SKILL_FIRSTAID,
'func', function() CastSpellByName(self.loc.SKILL_FIRSTAID)
self:UpdateText(self.loc.SKILL_FIRSTAID,self.ICON_FIRSTAID)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_FISHING) then
dewdrop:AddLine(
'text', self.loc.SKILL_FISHING,
'func', function() CastSpellByName(self.loc.SKILL_FISHING)
self:UpdateText(self.loc.SKILL_FISHING,self.ICON_FISHING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_LEATHERWORKING) then
dewdrop:AddLine(
'text', self.loc.SKILL_LEATHERWORKING,
'func', function() CastSpellByName(self.loc.SKILL_LEATHERWORKING)
self:UpdateText(self.loc.SKILL_LEATHERWORKING,self.ICON_LEATHERWORKING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_LOCKPICKING) then
dewdrop:AddLine(
'text', self.loc.SKILL_LOCKPICKING,
'func', function() CastSpellByName(self.loc.SKILL_PICKLOCK)
self:UpdateText(self.loc.SKILL_PICKLOCK,self.ICON_LOCKPICKING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_MINING) then
dewdrop:AddLine(
'text', self.loc.SKILL_SMELTING,
'func', function() CastSpellByName(self.loc.SKILL_SMELTING)
self:UpdateText(self.loc.SKILL_SMELTING,self.ICON_SMELTING)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_POISONS) then
dewdrop:AddLine(
'text', self.loc.SKILL_POISONS,
'func', function() CastSpellByName(self.loc.SKILL_POISONS)
self:UpdateText(self.loc.SKILL_POISONS,self.ICON_POISONS)
end,
'arg1', self
)
end
if (skillName == self.loc.SKILL_TAILORING) then
dewdrop:AddLine(
'text', self.loc.SKILL_TAILORING,
'func', function() CastSpellByName(self.loc.SKILL_TAILORING)
self:UpdateText(self.loc.SKILL_TAILORING,self.ICON_TAILORING)
end,
'arg1', self
)
end
end
function SkillsPlusFu:SaveProfession(skillName,skillRank,skillMaxRank,skillModifier)
if (skillName == self.loc.SKILL_ALCHEMY) or
(skillName == self.loc.SKILL_BLACKSMITHING) or
(skillName == self.loc.SKILL_COOKING) or
(skillName == self.loc.SKILL_ENCHANTING) or
(skillName == self.loc.SKILL_ENGINEERING) or
(skillName == self.loc.SKILL_FIRSTAID) or
(skillName == self.loc.SKILL_LEATHERWORKING) or
(skillName == self.loc.SKILL_TAILORING) then
if (self.data.skillsSave[toonSaveKey] == nil) then
self.data.skillsSave[toonSaveKey] = {}
end
if (self.data.skillsSave[toonSaveKey][skillName] == nil) then
self.data.skillsSave[toonSaveKey][skillName] = {}
end
self.data.skillsSave[toonSaveKey][skillName].Rank = skillRank
self.data.skillsSave[toonSaveKey][skillName].MaxRank = skillMaxRank
self.data.skillsSave[toonSaveKey][skillName].Modifier = skillModifier
end
end
-- general
function SkillsPlusFu:MenuSettings(level, value)
if level == 1 then
local cooldownFound = false
for _,category in self.skillList do
-- items are added with other toon skills following cooldown items
-- just stop adding skill menus when cooldown entry is found to stop
-- other toon skills showing up in the menu
if not cooldownFound then
if category.nonBooleanSkills > 0 then
for _,skill in category.skills do
self:AddProfessionMenu(skill.name)
end
end
cooldownFound = category.category == self.loc.COOLDOWN_CATEGORY
end
end
if (GetNumSkillLines() > 0) then dewdrop:AddLine() end
-- add regular menu options
dewdrop:AddLine(
'text', self.loc.MENU_SHOW_SKILL_LABEL, -- toggles skill name in fubar menu
'func', 'ToggleShowingSkillLabel',
'arg1', self,
'checked', self:IsShowingSkillLabel()
)
dewdrop:AddLine(
'text', self.loc.MENU_SHOW_BOOLEAN_SKILLS, -- toggles boolean skill visibility
'func', 'ToggleShowingBooleanSkills',
'arg1', self,
'checked', self:IsShowingBooleanSkills()
)
dewdrop:AddLine(
'text', self.loc.MENU_SHOW_OTHER_TOON_SKILLS, -- toggles other player skills
'func', 'ToggleOtherToonSkills',
'arg1', self,
'checked', self:IsShowingOtherToonSkills()
)
dewdrop:AddLine() -- separator
dewdrop:AddLine(
'text', self.loc.MENU_SHOW_TOON_NAMES, -- toggles player names in cooldown items
'func', 'ToggleShowingPlayerNames',
'arg1', self,
'checked', self:IsShowingPlayerNames()
)
dewdrop:AddLine(
'text', self.loc.MENU_SHOW_NOTIFICATION, -- toggles cooldown notification
'func', 'ToggleShowNotification',
'arg1', self,
'checked', self:IsShowNotification ()
)
dewdrop:AddLine(
'text', self.loc.MENU_CLEAR_COOLDOWN_DATA, -- clears saved cooldown data
'func', 'ClearCooldownData',
'arg1', self
)
end
end
function SkillsPlusFu:UpdateData()
local skillIndex = 0
local skillList = {}
local headerIndex = 0
local numSkills = GetNumSkillLines()
for skillIndex=1, numSkills do
local skillName, isHeader, isExpanded, skillRank, numTempPoints, skillModifier, skillMaxRank,
isAbandonable, stepCost, rankCost, minLevel, skillCostType,
skillDesc = GetSkillLineInfo(skillIndex)
if isHeader then
headerIndex = headerIndex + 1
table.insert(skillList, {category=skillName, skills={}, nonBooleanSkills = 0})
else
if skillMaxRank > 1 then
skillList[headerIndex].nonBooleanSkills = skillList[headerIndex].nonBooleanSkills + 1
end
table.insert(skillList[headerIndex].skills, {name = skillName, rank = skillRank,
maxrank = skillMaxRank, rankbonus = skillModifier})
self:SaveProfession(skillName,skillRank,skillMaxRank,skillModifier)
end
end
-- add cooldown header and items
local toonName = ''
headerIndex = headerIndex + 1
table.insert(skillList, {category=self.loc.COOLDOWN_CATEGORY, skills={}, nonBooleanSkills = 0})
for k, v in self.data.cooldownSave do
if self:IsShowingPlayerNames() then
toonName = string.sub(k,string.find(k,'|')+1)..': '
end
for itemName, itemTable in v do
skillList[headerIndex].nonBooleanSkills = skillList[headerIndex].nonBooleanSkills + 1
table.insert(skillList[headerIndex].skills, {name = toonName..itemName,
rank = itemTable.Cooldown,
maxrank = itemTable.LastCheck,
rankbonus = itemTable.IsReady}
)
end
end
-- add other toon skills
if self.data.showOtherToonSkills then
for k, v in self.data.skillsSave do
toonName = string.sub(k,string.find(k,'|')+1)
local realmName = string.sub(k,1,string.find(k,'|')-1)
if (toonName ~= UnitName('player')) and
(realmName == GetCVar('realmName'))
then
headerIndex = headerIndex + 1
table.insert(skillList, {category=toonName, skills={}, nonBooleanSkills = 0})
for skillName, skillTable in v do
skillList[headerIndex].nonBooleanSkills = skillList[headerIndex].nonBooleanSkills + 1
table.insert(skillList[headerIndex].skills, {name = skillName,
rank = skillTable.Rank,
maxrank = skillTable.MaxRank,
rankbonus = skillTable.Modifier}
)
end
end
end
end
self.skillList = skillList
end
function SkillsPlusFu:UpdateText(newProfession,newIcon)
if newProfession ~= nil then chosenProfession = newProfession end
if newIcon ~= nil then self:SetIcon(newIcon) end
-- add cooldown information
local cooldownInfo = ''
local totalItems = 0
local readyItems = 0
-- loop and add items and ready items
for k, v in self.data.cooldownSave do
for itemName, itemTable in v do
local remaining = ((itemTable.Cooldown + itemTable.LastCheck) - time())
totalItems = totalItems + 1
if (remaining <= 0) then
readyItems = readyItems + 1
end
end
end
-- set label text count colours
local colorCode = self.loc.COOLDOWN_COLOR_READY
if ( readyItems == 0 ) then
colorCode = self.loc.COOLDOWN_COLOR_NOTREADY
end
cooldownInfo = format(colorCode..self.loc.COOLDOWN_FORMAT..FONT_COLOR_CODE_CLOSE, readyItems, totalItems)
-- add skill label is toggle is true
if self:IsShowingSkillLabel() then
self.labelName = chosenProfession..' '..cooldownInfo
else
self.labelName = cooldownInfo
end
-- set the actual label
self:SetText(self.labelName)
dewdrop:Close()
end
function SkillsPlusFu:ToggleCategory(id, button)
if self.charData.hidden[id] then
self.charData.hidden[id] = false
else
self.charData.hidden[id] = true
end
-- refresh in place
self:UpdateTooltip()
end
function SkillsPlusFu:UpdateTooltip()
tablet:SetHint(self.loc.TOOLTIP_HINT)
-- skills
for _,category in self.skillList do
if category.nonBooleanSkills > 0 or self:IsShowingBooleanSkills() then
local tooltipLine = tablet:AddCategory('id', category.category, 'columns', 2,
'text', category.category,
'func', 'ToggleCategory', 'arg1', self, 'arg2', category.category,
'child_textR', 1, 'child_textG', 1, 'child_textB', 0,
'showWithoutChildren', true,
'checked', true, 'hasCheck', true, 'checkIcon',
self.charData.hidden[category.category] and 'Interface\\Buttons\\UI-PlusButton-Up' or 'Interface\\Buttons\\UI-MinusButton-Up'
)
if not self.charData.hidden[category.category] then
for _,skill in category.skills do
if category.category ~= self.loc.COOLDOWN_CATEGORY then
-- is either current toon skill or other toon skill
if skill.maxrank > 1 then
local rank = skill.rank
if skill.rankbonus > 0 then
rank = rank..'(+'..skill.rankbonus..')'
end
rank = rank..'/'..skill.maxrank
local r,g,b = FuBarUtils.GetThresholdColor((skill.rank+(skill.rankbonus or 0)) / skill.maxrank)
tooltipLine:AddLine('text', skill.name, 'text2', rank,
'text2R', r, 'text2G', g, 'text2B', b)
elseif self:IsShowingBooleanSkills() then
tooltipLine:AddLine('text', skill.name)
end
else -- is cooldown item
-- rank contains itemTable.Cooldown, max rank contains itemTable.LastCheck
local timeRemaining = ((skill.rank + skill.maxrank) - time())
local timeRemainingText = ''
if (timeRemaining <= 0) then
timeRemainingText = self.loc.COOLDOWN_COLOR_READY..self.loc.COOLDOWN_READY
else
local timeTable = self:CooldownRemaining(timeRemaining)
local timeString = string.format('%dD %02d:%02d', timeTable.d, timeTable.h, timeTable.m)
if ((timeTable.d == 0) and (timeTable.h == 0)) then
timeRemainingText = self.loc.COOLDOWN_COLOR_ALMOSTREADY..timeString
else
timeRemainingText = self.loc.COOLDOWN_COLOR_NOTREADY..timeString
end
end
tooltipLine:AddLine('text', skill.name, 'text2', timeRemainingText)
end
end
end
end
end
end
function SkillsPlusFu:OnClick()
if self.chosenProfession == self.loc.FUBAR_LABEL then
ToggleCharacter('SkillFrame')
else
CastSpellByName(chosenProfession)
end
end
SkillsPlusFu:RegisterForLoad()