--[[######################################################## --## Name: CharacterProfiler --## Author: calvin --## Addon Details & License can be found in 'readme.txt' --######################################################--]] --[[######################################################## --## RPGOCP object data --######################################################--]] RPGOCP = { TITLE = "CharacterProfiler"; ABBR = "CP"; PROVIDER = "rpgo"; VERSION = GetAddOnMetadata("CharacterProfiler", "Version"); AUTHOR = GetAddOnMetadata("CharacterProfiler", "Author"); EMAIL = GetAddOnMetadata("CharacterProfiler", "X-Email"); URL = GetAddOnMetadata("CharacterProfiler", "X-Website"); DATE = GetAddOnMetadata("CharacterProfiler", "X-Date"); PROFILEDB = "2.0.0"; FRAME = "rpgoCPframe"; TOOLTIP = "rpgoCPtooltip"; } RPGOCP.PREFS={ enabled=true,tooltip=true,tooltipshtml=true,fixtooltip=true,fixquantity=true,fixicon=true,fixcolor=true,reagentfull=true,talentsfull=true,questsfull=false,lite=true,button=true,debug=false,ver=020000, scan={inventory=true,talents=true,honor=true,reputation=true,spells=true,pet=true,equipment=true,mail=true,professions=true,skills=true,quests=true,bank=true}, }; RPGOCP.events={"PLAYER_LEVEL_UP","TIME_PLAYED_MSG", "CRAFT_SHOW","CRAFT_UPDATE","TRADE_SKILL_SHOW","TRADE_SKILL_UPDATE", "CHARACTER_POINTS_CHANGED", "BANKFRAME_OPENED","BANKFRAME_CLOSED","MAIL_SHOW","MAIL_CLOSED", "MERCHANT_CLOSED","UNIT_QUEST_LOG_CHANGED","QUEST_FINISHED","PET_STABLE_CLOSED", "ZONE_CHANGED","ZONE_CHANGED_INDOORS","PLAYER_CONTROL_LOST","PLAYER_CONTROL_GAINED", }; RPGOCP.usage={ {"/cp","-- usage/help"}, {"/cp [on|off]","-- turns on|off"}, {"/cp export","-- force export"}, {"/cp show","-- show current session scan"}, {"/cp lite [on|off]","-- turns on|off lite scanning"}, {"/cp list","-- list current profiles"}, {"/cp purge [all|server|char]","-- purge info"}, }; --[[## Events --######################################################--]] RPGOCP.event1={ VARIABLES_LOADED = function() RPGOCP:InitPref(); RPGOCP:InitState(); RPGOCP:RegisterEvents(); RPGOCP.frame:UnregisterEvent("VARIABLES_LOADED"); return true; end, }; RPGOCP.event2={ CRAFT_UPDATE = function(a1,a2) RPGOCP:TradeTimer(a1,a2); return true; end, TRADE_SKILL_UPDATE = function(a1,a2) RPGOCP:TradeTimer(a1,a2); return true; end, UNIT_INVENTORY_CHANGED = function(a1) RPGOCP:UpdateEqScan(a1); return true; end, BAG_UPDATE = function(a1) RPGOCP:UpdateBagScan(a1); return true; end, PLAYERBANKSLOTS_CHANGED = function() RPGOCP:UpdateBagScan(BANK_CONTAINER); return true; end, TIME_PLAYED_MSG = function(a1,a2) RPGOCP:UpdatePlayed(a1,a2); return true; end, ZONE_CHANGED = function() RPGOCP:UpdateZone(); return true; end, ZONE_CHANGED_INDOORS = function() RPGOCP:UpdateZone(); return true; end, PLAYER_CONTROL_LOST = function() RPGOCP.frame:UnregisterEvent("ZONE_CHANGED"); RPGOCP.frame:UnregisterEvent("ZONE_CHANGED_INDOORS"); return true; end, PLAYER_CONTROL_GAINED = function() RPGOCP.frame:RegisterEvent("ZONE_CHANGED"); RPGOCP.frame:RegisterEvent("ZONE_CHANGED_INDOORS"); RPGOCP:UpdateZone(); return true; end, }; RPGOCP.event3={ RPGOCP_SCAN = function() RPGOCP:UpdateProfile(); end, RPGOCP_EXPORT = function() RPGOCP:ForceExport(); end, SPELLBOOK = function() RPGOCP:GetSpellBook(); RPGOCP:GetPetSpellBook(); end, BANKFRAME_OPENED = function() RPGOCP:State("_bank",true); RPGOCP:GetBank(); end, BANKFRAME_CLOSED = function() RPGOCP:GetBank(); RPGOCP:GetInventory(); RPGOCP:GetEquipment(); RPGOCP:State("_bank",nil); end, MAIL_SHOW = function() RPGOCP:State("_mail",true); end, MAIL_CLOSED = function() RPGOCP:GetMail(); RPGOCP:GetInventory(); RPGOCP:GetEquipment(); RPGOCP:State("_mail",nil); end, MERCHANT_CLOSED = function() RPGOCP:GetInventory(); RPGOCP:GetEquipment(); end, TRADE_SKILL_SHOW = function() RPGOCP:GetSkills(); RPGOCP:GetTradeSkill('trade'); end, CRAFT_SHOW = function() RPGOCP:GetSkills(); RPGOCP:GetTradeSkill('craft'); end, PLAYER_LEVEL_UP = function() RPGOCP:UpdateProfile(); end, QUEST_FINISHED = function() RPGOCP:GetQuests(force); end, UNIT_QUEST_LOG_CHANGED = function() RPGOCP:GetQuests(force); end, CHARACTER_POINTS_CHANGED = function() RPGOCP:GetTalents(); end, PET_STABLE_CLOSED = function() RPGOCP:ScanPetStable(); end, }; RPGOCP.funcs={ fixicon = function(a1) if(a1) then rpgo.scanIcon = function(str) if(not str) then return str; end return table.remove({ strsplit("\\", str) }); end else rpgo.scanIcon = function(str) return str end ; end end, fixcolor = function(a1) if(a1) then rpgo.scanColor = function(str) if(not str) then return str; end local c; _,_,c = string.find(str,"%x%x(%x%x%x%x%x%x)"); return c end else rpgo.scanColor = function(str) return str end ; end end, button = function() RPGOCP:ButtonHandle(); end }; --[ChatCommand] RPGOCP.command={ off = function() RPGOCP:Toggle(false); end, on = function() RPGOCP:Toggle(true); end, show = function() RPGOCP:Show(); end, list = function() RPGOCP:ProfileList(); end, export = function() RPGOCP:EventHandler('RPGOCP_EXPORT'); end, purge = function(argv) RPGOCP:Purge(argv); end, }; --########################################################## local timePlayed=-1; local timeLevelPlayed=-1; local TradeSkillCode={optimal=4,medium=3,easy=2,trivial=1,header=0}; local UnitPower={"Rage","Focus","Energy","Happiness"};UnitPower[0]="Mana"; local UnitSlots={"Head","Neck","Shoulder","Shirt","Chest","Waist","Legs","Feet","Wrist","Hands","Finger0","Finger1","Trinket0","Trinket1","Back","MainHand","SecondaryHand","Ranged","Tabard"};UnitSlots[0]="Ammo"; local UnitStatName={"Strength","Agility","Stamina","Intellect","Spirit"}; local UnitSchoolName={"Physical","Holy","Fire","Nature","Frost","Shadow","Arcane"}; local UnitResistanceName={"Holy","Fire","Nature","Frost","Shadow","Arcane"}; --[[######################################################## --## rpgoCP Core Functions --######################################################--]] --[OnLoad] function RPGOCP:Init() SLASH_RPGOCP1="/cp"; SLASH_RPGOCP2="/rpgocp"; SLASH_RPGOCP3="/profiler"; SlashCmdList["RPGOCP"] = function(a1) return self:ChatCommand(a1) end; self.frame = CreateFrame("Frame",self.FRAME,CharacterNameFrame); self.frame:RegisterEvent("VARIABLES_LOADED"); self.frame:SetScript("OnEvent", function() return self:EventHandler(event,arg1,arg2) end ); self.frame:SetScript("OnHide" , function() return self:EventHandler('RPGOCP_SCAN') end ); self.tooltip = CreateFrame("GameTooltip",self.TOOLTIP,UIParent,"GameTooltipTemplate"); self.tooltip:SetOwner(UIParent,"ANCHOR_NONE"); self:PrintTitle("loaded.",true,true); end --[EventHandler] function RPGOCP:EventHandler(event,arg1,arg2) if(not event) then return end --if(rpgoDebugArg) then -- rpgoDebugArg(self.ABBR,event,arg1,arg2); --end if(RPGOCP.event1[event]) then local retVal=RPGOCP.event1[event](arg1,arg2); if(retVal~=nil) then return retVal; end end if( not self.prefs or not self.prefs.enabled ) then return; end if( self:LiteScan(event) ) then return; end if( RPGOCP.event2[event] ) then if( self:State("_loaded") ) then local retVal=RPGOCP.event2[event](arg1,arg2); if(retVal~=nil) then return retVal; end else return false; end end --debugprofilestart(); --local mem=gcinfo(); if( ( not self:State("_lock") ) ) then self:State("_lock",true); if(not self:State("_loaded")) then self:InitProfile(); end if(RPGOCP.event3[event]) then RPGOCP.event3[event](arg1,arg2); end self:State("_lock",nil); end --self:PrintDebug("time",debugprofilestop().."ms",gcinfo()-mem.."kb"); end rpgoCP_EventHandler = function(event,arg1,arg2) return RPGOCP:EventHandler(event,arg1,arg2) end ; --[ChatCommand] function RPGOCP:ChatCommand(argline) --self:PrintDebug("ChatCommand ("..argline..") "); local argv=rpgo.Str2Ary(argline); if(argv and argv[1]) then local argcase = string.lower(argv[1]); table.remove(argv,1); if(self.command[argcase]) then return self.command[argcase](argv); elseif(self.PREFS[argcase]~=nil) then return self:TogglePref(argcase,argv[1]); end end self:PrintUsage(); self:TogglePref("enabled"); end --[InitState] function RPGOCP:InitState() --self:PrintDebug("InitState"); local _,tmpClass=UnitClass("player"); self.state = { _loaded=nil,_lock=nil,_bag=nil,_bank=nil,_mail=nil, _server=GetRealmName(),_player=UnitName("player"),_class=tmpClass, _skills={}, Equipment=0, Guild=nil, GuildNum=nil, Skills=0, Talents=0,TalentPts=0, Reputation=0, Quests=0, QuestsLog=0, Mail=nil, Honor=0, Bag={},Inventory={},Bank={}, Professions={}, SpellBook={}, Pets={}, Stable={}, PetSpell={}, }; end --[InitPref] function RPGOCP:InitPref() if(not self.PREFS) then return; end if(not rpgoCPpref) then rpgoCPpref={}; end self.prefs = rpgoCPpref; --self:PrintDebug("InitPref"); self:PrefTidy(); self:PrefInit(); self:ButtonHandle(); self:FrameHookCreate(); self.funcs["fixcolor"](self.prefs["fixcolor"]); self.funcs["fixicon"](self.prefs["fixicon"]); self:PrintDebug("running in DEBUG MODE"); end --[Toggle] function RPGOCP:Toggle(val) if( self.prefs["enabled"]~=val ) then self:TogglePref("enabled",val); self:RegisterEvents(); if(val) then self:InitState(); if(not self:State("_loaded")) then self:InitProfile(); end else self:State("_loaded",nil); end else self:TogglePref("enabled",val); end end --[ButtonHandle] function RPGOCP:ButtonHandle() if(self.prefs.button) then local button = CreateFrame("Button","rpgoCPUISaveButton",PaperDollFrame,"UIPanelButtonTemplate"); button:SetPoint("TOPLEFT",PaperDollFrame,"TOPLEFT",73,-35); button:SetHeight(20); button:SetWidth(40); button:SetToplevel(true); button:SetText(RPGOCP_SAVE_TEXT); button:Show(); button:SetScript("OnClick", function() return self:EventHandler('RPGOCP_EXPORT') end ); button:SetScript("OnEnter", function() return rpgo.SetTooltip(RPGOCP_SAVE_TOOLTIP) end ); button:SetScript("OnLeave", function() return GameTooltip:Hide() end ); elseif(rpgoCPUISaveButton) then local button = rpgoCPUISaveButton button:Hide(); end end --[FrameHookCreate] function RPGOCP:FrameHookCreate() rpgoCPSpellBook = CreateFrame("Frame","rpgoCPSpellBook",SpellBookFrame); rpgoCPSpellBook:SetScript("OnShow", function() return self:EventHandler('SPELLBOOK') end ); function rpgoCPTradeSkillFrame_OnUpdate() if(TradeSkillFrame and TradeSkillFrame:IsVisible()) then self:EventHandler('TRADE_SKILL_UPDATE','TRADE_SKILL_UPDATE',arg1); end end rpgoCPTradeSkillFrame = CreateFrame("Frame","rpgoCPTradeSkillFrame",TradeSkillFrame); rpgoCPTradeSkillFrame:SetScript("OnUpdate", rpgoCPTradeSkillFrame_OnUpdate ); function rpgoCPCraftFrame_OnUpdate() if(CraftFrame and CraftFrame:IsVisible()) then self:EventHandler('CRAFT_UPDATE','CRAFT_UPDATE',arg1); end end rpgoCPCraftFrame = CreateFrame("Frame","rpgoCPCraftFrame",CraftFrame); rpgoCPCraftFrame:SetScript("OnUpdate", rpgoCPCraftFrame_OnUpdate ); end --[InitProfile] function RPGOCP:InitProfile() --self:PrintDebug("InitProfile"); if( not myProfile ) then myProfile={}; end if( not myProfile[self.state["_server"]] ) then myProfile[self.state["_server"]]={}; end if( not myProfile[self.state["_server"]]["Character"] ) then myProfile[self.state["_server"]]["Character"]={}; end if( not myProfile[self.state["_server"]]["Character"][self.state["_player"]] ) then myProfile[self.state["_server"]]["Character"][self.state["_player"]]={}; end if( myProfile[self.state["_server"]][self.state["_player"]] ) then myProfile[self.state["_server"]][self.state["_player"]]=nil; end if( not self.db ) then self.db = myProfile[self.state["_server"]]["Character"][self.state["_player"]]; end if( self.db ) then self.db["CPversion"] = self.VERSION; self.db["CPprovider"] = self.PROVIDER; self.db["DBversion"] = self.PROFILEDB; self.db["Name"] = self.state["_player"]; self.db["Server"] = self.state["_server"]; self.db["Locale"] = GetLocale(); self.db["Race"],self.db["RaceEn"]=UnitRace("player") self.db["Class"],self.db["ClassEn"]=UnitClass("player"); self.db["Sex"],self.db["SexId"]=rpgo.UnitSexString("player"); self.db["FactionEn"],self.db["Faction"]=UnitFactionGroup("player"); self.db["HasRelicSlot"] =UnitHasRelicSlot("player")==1 or false; self:UpdateDate(); self:State("_loaded",true); end return self:State("_loaded"); end --[UpdateProfile] function RPGOCP:UpdateProfile() --self:PrintDebug("UpdateProfile"); if( self:State("_bank") ) then self:GetBank(); end if( self:State("_mail") ) then self:GetMail(); end self:GetGuild(force); self:GetBuffs(self.db); self:GetInventory(); self:GetEquipment(); self:GetTalents(); self:GetSkills(); self:GetSpellBook(); self:GetReputation(); self:GetQuests(); self:GetHonor(); self:ScanPetInfo(); self:UpdateZone(); self:UpdatePlayed(); self:UpdateDate(); end --[ForceExport] function RPGOCP:ForceExport() local tmpState=self.state; self:InitState(); self.state["Bank"]=tmpState["Bank"]; self.state["Mail"]=tmpState["Mail"]; self.state["Professions"]=tmpState["Professions"]; self.state["Pets"]=tmpState["Pets"]; self.state["Stable"]=tmpState["Stable"]; self.state["PetSpell"]=tmpState["PetSpell"]; self.state["_litemsg"]=tmpState["_litemsg"]; self.state["_bank"]=tmpState["_bank"]; self.state["_mail"]=tmpState["_mail"]; self:InitProfile(); self:UpdateProfile(); self:ScanPetInfo(); self:Show(); end --[Purge] function RPGOCP:Purge(argv) local tmpPurged,msg; if(argv and argv[1]) then msg = " ["..argv[1].."]"; if(myProfile) then if(argv[1]=="all") then myProfile=nil; tmpPurged=true; elseif(argv[1]=="char") then local charProfile=self:State("_player"); if(argv[2]) then charProfile=argv[2]; end msg = msg.." '"..charProfile.."'"; if(myProfile[self:State("_server")] and myProfile[self:State("_server")]["Character"] and myProfile[self:State("_server")]["Character"][charProfile]) then myProfile[self:State("_server")]["Character"][charProfile]=nil; tmpPurged=true; end elseif(argv[1]=="server") then local serverProfile=self:State("_server"); if(argv[2]) then serverProfile=argv[2]; end msg = msg.." '"..serverProfile.."'"; if(myProfile[serverProfile] and myProfile[serverProfile]["Character"]) then myProfile[serverProfile]["Character"]=nil; tmpPurged=true; end elseif(argv[1] and argv[2]) then msg = " '"..argv[2].."@"..argv[1].."'"; if(myProfile[argv[1]] and myProfile[argv[1]]["Character"] and myProfile[argv[1]]["Character"][argv[2]]) then myProfile[argv[1]]["Character"][argv[2]]=nil; tmpPurged=true; elseif(myProfile[argv[2]] and myProfile[argv[2]]["Character"] and myProfile[argv[2]]["Character"][argv[1]]) then msg = " '"..argv[1].."@"..argv[2].."'"; myProfile[argv[2]]["Character"][argv[1]]=nil; tmpPurged=true; end end end end if(not tmpPurged and not msg) then self:PrintTitle("Usage: /cp purge [all|server|char]"); else if(tmpPurged) then self:InitState(); msg = msg.." was "..rpgo.StringColorize(rpgo.colorGreen,"purged|r"); else msg = msg.." was "..rpgo.StringColorize(rpgo.colorRed,"not purged|r"); end self:PrintTitle(msg); end end --[ProfileList] function RPGOCP:ProfileList() local server,guild,char; if(myProfile) then self:PrintTitle("stored character profiles"); for _,server in pairs( self.GetServers() ) do rpgo.PrintMsg(" Server: "..server); for _,guild in pairs( self.GetGuilds(server) ) do rpgo.PrintMsg(" Guild: "..guild); end for _,char in pairs( self.GetCharacters(server) ) do rpgo.PrintMsg(" Char: "..char.." (L:" .. self.GetParam("Level",char,server) .. ") "..self:GetProfileDate(server,char)); end end else self:PrintTitle("no stored character profiles"); end end --[Show] function RPGOCP:Show() if(self.prefs["enabled"]) then if(self:State("_player") and self:State("_loaded")) then local msg=""; local item; local tsort={}; msg="Profile for: " .. self:State("_player") .. " @" .. self:State("_server"); if(self.db["Level"]) then msg=msg.." (lvl "..self.db["Level"]..")" end self:PrintTitle(msg); if(self:State("Guild")==0) then elseif(self:State("Guild")) then msg="Guild: "; if(self.db["Guild"]["Name"] and self.db["Guild"]["Title"]) then msg=msg.."Name:"..self.db["Guild"]["Name"].." Title:"..self.db["Guild"]["Title"]; else msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned"); end else msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned"); end rpgo.PrintMsg(" "..msg); msg="Zone: "; if(self.db["Zone"]) then msg=msg..self.db["Zone"]; if(self.db["SubZone"] and self.db["SubZone"]~="") then msg=msg.."/"..self.db["SubZone"]; end else msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned"); end rpgo.PrintMsg(" "..msg); msg=""; msg=msg .. "Equip:"..self:State("Equipment").."/"..table.getn(UnitSlots); msg=msg .. " Skill:" ..self:State("Skills"); msg=msg .. " Talent:" ..self:State("Talents"); msg=msg .. " Rep:" ..self:State("Reputation"); msg=msg .. " Quest:" ..self:State("Quests"); if(self:State("Mail")) then msg=msg .. " Mail:" ..self:State("Mail"); end if(self:State("Honor")~=0 and self.db["Honor"]["RankName"]) then msg=msg .. " Honor:" ..self.db["Honor"]["RankName"]; else msg=msg .. " Honor:"..NONE; end rpgo.PrintMsg(" " .. msg); msg="Professions:"; tsort={}; table.foreach(self.state["Professions"], function (k,v) table.insert(tsort,k) end ); table.sort(tsort); if(table.getn(tsort)==0) then msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned")..". to scan: open each profession"; else for _,item in pairs(tsort) do msg=msg .. " " .. item..":"..self.state["Professions"][item]; end end rpgo.PrintMsg(" " .. msg); msg="Spells:"; tsort={}; table.foreach(self.state["SpellBook"], function(k,v) table.insert(tsort,k) end ); table.sort(tsort); if(table.getn(tsort)==0) then msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned")..". to scan: open your spellbook"; else for _,item in pairs(tsort) do msg=msg .. " " .. item..":"..self.state["SpellBook"][item]; end end rpgo.PrintMsg(" " .. msg); msg="Inventory:"; tsort={}; table.foreach(self.state["Inventory"], function(k,v) table.insert(tsort,k) end ); table.sort(tsort); if(table.getn(tsort)==0) then msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned")..". to scan: open your bank or 'character info'"; else for _,item in pairs(tsort) do msg=msg .. " " .. item.."]"..self.state["Inventory"][item]["inv"].."/"..self.state["Inventory"][item]["slot"]; end end rpgo.PrintMsg(" " .. msg); msg="Bank:"; tsort={}; table.foreach(self.state["Bank"], function(k,v) table.insert(tsort,k) end ); table.sort(tsort); if(table.getn(tsort)==0) then msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned")..". to scan: open your bank"; else for _,item in pairs(tsort) do msg=msg .. " " .. item.."]"..self.state["Bank"][item]["inv"].."/"..self.state["Bank"][item]["slot"]; end end rpgo.PrintMsg(" " .. msg); if( (self:State("_class")=="HUNTER" and UnitLevel("player")>9) or self:State("_class")=="WARLOCK") then msg="Pets: "; tsort={}; table.foreach(self.state["Pets"], function(k,v) table.insert(tsort,k) end ); table.sort(tsort); if(table.getn(tsort)==0) then msg=msg..rpgo.StringColorize(rpgo.colorRed," not scanned"); else for _,item in pairs(tsort) do msg=msg..item.." "; if(self.state["PetSpell"][item]) then msg=msg.."(spells:"..self.state["PetSpell"][item]..") "; end end end rpgo.PrintMsg(" " .. msg); end else self:PrintTitle(rpgo.StringColorize(rpgo.colorRed,"no character scanned")); rpgo.PrintMsg(" to scan open your character frame ('C')"); rpgo.PrintMsg(" or force the export with '/cp export'"); end else self:TogglePref("enabled"); end end --[[######################################################## --## rpgoCP data functions --######################################################--]] function RPGOCP.GetVersion() local _,_,vVersion,vMajor,vMinor=string.find(RPGOCP.VERSION,"^(%d+).(%d+).(%d+)"); return tonumber(vVersion) + tonumber(vMajor)/100 + tonumber(vMinor)/10000; end function RPGOCP.GetServers() local tbl={}; for server in pairs(myProfile) do table.insert(tbl,server); end table.sort(tbl); return tbl end function RPGOCP.GetCharacters(server) if(not server) then server = GetRealmName() end local tbl={}; for char in pairs(myProfile[server]["Character"]) do table.insert(tbl,char); end table.sort(tbl); return tbl; end function RPGOCP.GetGuilds(server) if(not server) then server = RPGOCP.state["_server"] end local tbl={}; for guild in pairs(myProfile[server]["Guild"]) do table.insert(tbl,guild); end table.sort(tbl); return tbl; end function RPGOCP.GetParam(param,char,server) if(not server) then server = RPGOCP.state["_server"] end if(not char) then char = RPGOCP.state["_player"] end if ( not param ) then return nil; -- param elseif( not myProfile or not myProfile[server] or not myProfile[server]["Character"][char] ) then return nil; -- data end local val; local db = myProfile[server]["Character"][char]; if( db[param] ) then return db[param]; else param = string.lower(param); for k,v in pairs(db) do if(param == string.lower(k)) then return db[k]; end end end return "none"; end --[[######################################################## --## rpgoCP CPapi functions --######################################################--]] CPapi={}; CPapi.GetVersion = RPGOCP.GetVersion; CPapi.GetServers = RPGOCP.GetServers; CPapi.GetCharacters = RPGOCP.GetCharacters; CPapi.GetParam = RPGOCP.GetParam; --[[######################################################## --## OverLoaded functions --######################################################--]] --[Quit] rpgo_Quit_old=Quit; function Quit() if(RPGOCP.prefs and RPGOCP.prefs["enabled"] and RPGOCP:State("_loaded")) then RPGOCP:EventHandler('RPGOCP_SCAN'); RequestTimePlayed(); end return rpgo_Quit_old(); end --[Logout] rpgo_Logout_old=Logout; function Logout() if(RPGOCP.prefs and RPGOCP.prefs["enabled"] and RPGOCP:State("_loaded")) then RPGOCP:EventHandler('RPGOCP_SCAN'); RequestTimePlayed(); end return rpgo_Logout_old(); end --[PetAbandon] rpgo_PetAbandon_old=PetAbandon; function PetAbandon() if(RPGOCP.prefs and RPGOCP.prefs["enabled"]) then petName=UnitName("pet"); if (RPGOCP.state["Stable"][petName]) then RPGOCP.state["Stable"][petName]=nil; end if (RPGOCP.state["Pets"][petName]) then RPGOCP.state["Pets"][petName]=nil; end if (RPGOCP.state["PetSpell"][petName]) then RPGOCP.state["PetSpell"][petName]=nil; end if (RPGOCP.db["Pets"] and RPGOCP.db["Pets"][petName]) then RPGOCP.db["Pets"][petName]=nil; end end return rpgo_PetAbandon_old(); end --[[######################################################## --## rpgoCP Extract functions --######################################################--]] --[GetGuild] function RPGOCP:GetGuild(force) --self:PrintDebug("GetGuild"); if( not IsInGuild() ) then self:State("Guild",0); self.db["Guild"]=nil; return; end local numGuildMembers=GetNumGuildMembers(); if(force or not self:State("Guild") or self:State("GuildNum")~=numGuildMembers) then --self:PrintDebug(" ==> scan"); local guildName,guildRankName,guildRankIndex=GetGuildInfo("player"); if(guildName) then self.db["Guild"]={ Name=guildName, Title=guildRankName, Rank=guildRankIndex}; self:State("Guild",1); self:State("GuildNum",numGuildMembers); end end end --[GetSkills] function RPGOCP:GetSkills() --self:PrintDebug("GetSkills"); if(not self.prefs["scan"]["skills"]) then self.db["Skills"]=nil; return; end local TRADE_SKILLS2; self.db["Skills"]={}; self:State("Skills",0);self:State("_skills",{}); local toCollapse={}; for idx=GetNumSkillLines(),1,-1 do local skillName,isHeader,isExpanded,_,_,_,_,_,_,_,_,_=GetSkillLineInfo(idx); if(isHeader and not isExpanded) then table.insert(toCollapse,idx); ExpandSkillHeader(idx); end end local skillheader,order,structSkill = nil,1,self.db["Skills"]; for idx=1,GetNumSkillLines() do local skillName,isHeader,isExpanded,skillRank,numTempPoints,skillModifier,skillMaxRank,isAbandonable,stepCost,rankCost,minLevel,skillCostType=GetSkillLineInfo(idx); if(isHeader==1) then skillheader=skillName; structSkill[skillheader]={Order=order}; TRADE_SKILLS2 = strsub(SECONDARY_SKILLS,1,strlen(skillheader)); order=order+1; elseif(skillheader) then structSkill[skillheader][skillName]=strjoin(":", skillRank,skillMaxRank); if(skillheader==TRADE_SKILLS or skillheader==TRADE_SKILLS2) then self.state["_skills"][skillName]=skillRank; end end self:State("Skills",'++'); end table.sort(toCollapse) for _,idx in pairs(toCollapse) do CollapseSkillHeader(idx); end end --[GetReputation] function RPGOCP:GetReputation() --self:PrintDebug("GetReputation"); if(not self.prefs["scan"]["reputation"]) then self.db["Reputation"]=nil; return; end self.db["Reputation"]={}; self:State("Reputation",0); local toCollapse={}; for idx=GetNumFactions(),1,-1 do local _,_,_,_,_,_,_,_,isHeader,isCollapsed=GetFactionInfo(idx); if(isHeader and isCollapsed) then table.insert(toCollapse,idx); ExpandFactionHeader(idx); end end local thisHeader,numFactions=NONE,GetNumFactions(); local structRep=self.db["Reputation"]; structRep["Count"]=numFactions; for idx=1,numFactions do local name,description,standingID,barMin,barMax,barValue,atWar,canToggle,isHeader,isCollapsed=GetFactionInfo(idx); if(not atWar) then atWar=0; end if(isHeader) then thisHeader=name; structRep[thisHeader]={}; elseif(standingID) then structRep[thisHeader][name]={ Standing = getglobal("FACTION_STANDING_LABEL"..standingID), AtWar = atWar, Value = barValue-barMin..":"..barMax-barMin}; end self:State("Reputation",'++'); end table.sort(toCollapse) for _,idx in pairs(toCollapse) do CollapseFactionHeader(idx); end end --[GetHonor] function RPGOCP:GetHonor() --self:PrintDebug("GetHonor"); if(not self.prefs["scan"]["honor"]) then self.db["Honor"]=nil; return; end local lifetimeHK,lifetimeRank=GetPVPLifetimeStats(); local sessionHK,sessionCP=GetPVPSessionStats(); if(self:State("Honor")~=lifetimeHK+sessionCP) then --self:PrintDebug(" ==> scan"); self.db["Honor"]={}; local currRankIcon,currRankProgress,structHonor="",0,self.db["Honor"]; local rankName,rankNumber=GetPVPRankInfo(lifetimeRank); if ( not rankName ) then rankName=NONE; end structHonor["Lifetime"]={ Rank=rankNumber, Name=rankName, HK=lifetimeHK}; rankName,rankNumber=GetPVPRankInfo(UnitPVPRank("player")); if ( not rankName ) then rankName=NONE; end if ( rankNumber > 0 ) then currRankIcon=format("%s%02d","PvPRank",rankNumber); if(not self.prefs["fixicon"]) then texture="Interface\\PvPRankBadges\\"..currRankIcon; end end currRankProgress=rpgo.round(GetPVPRankProgress()*100,2); structHonor["Current"]={ Rank=rankNumber, Name=rankName, Icon=currRankIcon, Progress=currRankProgress, HonorPoints=GetHonorCurrency(), ArenaPoints=GetArenaCurrency() }; structHonor["Session"]={HK=sessionHK,CP=sessionCP}; structHonor["Yesterday"]=rpgo.Arg2Tab("HK","CP",GetPVPYesterdayStats()); self:State("Honor",lifetimeHK+sessionCP); end end --[GetTalents] function RPGOCP:GetTalents() --self:PrintDebug("GetTalents"); if(not self.prefs["scan"]["talents"] or UnitLevel("player") < 10 ) then self.db["Talents"]=nil; return; end local numTabs,numPts=GetNumTalentTabs(),UnitCharacterPoints("player"); if( (self:State("Talents")~=numTabs+numPts) ) then --self:PrintDebug(" ==> scan"); self.db["TalentPoints"]=numPts; self.db["Talents"]={}; self:State("Talents",numPts); local structTalent=self.db["Talents"]; for tabIndex=1,numTabs do local tabName,texture,points,fileName=GetTalentTabInfo(tabIndex); if(not self.prefs["fixicon"]) then fileName="Interface\\TalentFrame\\"..fileName; end structTalent[tabName]={ Background=fileName, PointsSpent=points, Order=tabIndex }; for talentIndex=1,GetNumTalents(tabIndex) do local nameTalent,iconTexture,iconX,iconY,currentRank,maxRank=GetTalentInfo(tabIndex,talentIndex); if(currentRank > 0 or self.prefs["talentsfull"]) then self.tooltip:SetTalent(tabIndex,talentIndex) structTalent[tabName][nameTalent]={ Rank=strjoin(":", currentRank,maxRank), Location=strjoin(":", iconX,iconY), Icon=rpgo.scanIcon(iconTexture), Tooltip=self:ScanTooltip() }; end end self:State("Talents",'++'); end end end --[GetQuests] function RPGOCP:GetQuests(force) --self:PrintDebug("GetQuests"); if(not self.prefs["scan"]["quests"]) then self.db["Quests"]=nil; return; end local selected=GetQuestLogSelection(); local toCollapse={}; for idx=GetNumQuestLogEntries(),1,-1 do _,_,_,_,isHeader,isCollapsed,_ = GetQuestLogTitle(idx); if(isHeader and isCollapsed) then table.insert(toCollapse,idx); ExpandQuestHeader(idx); end end local numEntries,numQuests=GetNumQuestLogEntries(); if( force or (self:State("QuestsLog")~=numEntries) ) then --self:PrintDebug(" ==> scan"); self.db["Quests"]={}; self:State("Quests",0);self:State("QuestsLog",0); local structQuest=self.db["Quests"]; local slot,num,header = 1,nil,UNKNOWN; for idx=1,numEntries do local questDescription,questObjective; local questTitleText,level,questTag,suggestedGroup,isHeader,isCollapsed,isComplete = GetQuestLogTitle(idx); if(questTitleText) then if(isHeader) then header=questTitleText; if(not structQuest[header]) then structQuest[header]={} end else SelectQuestLogEntry(idx); if(suggestedGroup and tonumber(suggestedGroup) and suggestedGroup<=1) then suggestedGroup=nil; end if(self.prefs["questsfull"]) then questDescription,questObjective = GetQuestLogQuestText(idx); end structQuest[header][slot]={ Title=questTitleText, Level=level, Complete=isComplete, Tag=questTag, Group=suggestedGroup, Description=questDescription, Objective=questObjective}; num=GetNumQuestLeaderBoards(idx); if(num and num > 0) then structQuest[header][slot]["Tasks"]={}; for idx2=1,num do structQuest[header][slot]["Tasks"][idx2]=rpgo.Arg2Tab("Note","Type","Done",GetQuestLogLeaderBoard(idx2,idx)); end end num=GetQuestLogRewardMoney(idx); if(num and num > 0) then structQuest[header][slot]["RewardMoney"]=num; end num=GetNumQuestLogRewards(idx); if(num and num > 0) then structQuest[header][slot]["Rewards"]={}; for idx2=1,num do _,curItemTexture,itemCount,_,_=GetQuestLogRewardInfo(idx2); self.tooltip:SetQuestLogItem("reward",idx2); table.insert(structQuest[header][slot]["Rewards"],self:ScanItemInfo(GetQuestLogItemLink("reward",idx2),curItemTexture,itemCount)); end end num=GetNumQuestLogChoices(idx); if(num and num > 0) then structQuest[header][slot]["Choice"]={}; for idx2=1,num do _,curItemTexture,itemCount,_,_=GetQuestLogChoiceInfo(idx2); self.tooltip:SetQuestLogItem("choice",idx2); table.insert(structQuest[header][slot]["Choice"],self:ScanItemInfo(GetQuestLogItemLink("choice",idx2),curItemTexture,itemCount)); end end slot=slot+1; self:State("Quests",'++'); end end self:State("QuestsLog",'++'); end end table.sort(toCollapse) for _,idx in pairs(toCollapse) do CollapseQuestHeader(idx); end SelectQuestLogEntry(selected); end --[GetStats] function RPGOCP:GetStats(structStats,unit) --self:PrintDebug("GetStats"); if(not unit) then unit="player"; end if( unit=="player" and (UnitIsDeadOrGhost("player") or rpgo.UnitHasResSickness("player")) ) then return end if(not structStats["Attributes"]) then structStats["Attributes"]={}; end structStats["Level"]=UnitLevel(unit); structStats["Health"]=UnitHealthMax(unit); structStats["Mana"]=UnitManaMax(unit); structStats["Power"]=UnitPower[UnitPowerType(unit)]; structStats["Attributes"]["Stats"]={}; for i=1,table.getn(UnitStatName) do local stat,effectiveStat,posBuff,negBuff=UnitStat(unit,i); structStats["Attributes"]["Stats"][UnitStatName[i]] = strjoin(":", (stat - posBuff - negBuff),posBuff,negBuff); end local base,posBuff,negBuff,modBuff,effBuff,stat; base,modBuff = UnitDefense(unit); posBuff,negBuff = 0,0; if ( modBuff > 0 ) then posBuff = modBuff; elseif ( modBuff < 0 ) then negBuff = modBuff; end structStats["Attributes"]["Defense"] = {}; structStats["Attributes"]["Defense"]["Defense"] = strjoin(":", base,posBuff,negBuff); base,effBuff,stat,posBuff,negBuff=UnitArmor(unit); structStats["Attributes"]["Defense"]["Armor"] = strjoin(":", base,posBuff,negBuff); structStats["Attributes"]["Defense"]["ArmorReduction"] = PaperDollFrame_GetArmorReduction(effBuff, UnitLevel("player")); base,posBuff,negBuff = GetCombatRating(CR_DEFENSE_SKILL),GetCombatRatingBonus(CR_DEFENSE_SKILL),0; structStats["Attributes"]["Defense"]["DefenseRating"]=strjoin(":", base,posBuff,negBuff); structStats["Attributes"]["Defense"]["DefensePercent"]=GetDodgeBlockParryChanceFromDefense(); base,posBuff,negBuff = GetCombatRating(CR_DODGE),GetCombatRatingBonus(CR_DODGE),0; structStats["Attributes"]["Defense"]["DodgeRating"]=strjoin(":", base,posBuff,negBuff); structStats["Attributes"]["Defense"]["DodgeChance"]=rpgo.round(GetDodgeChance(),2); base,posBuff,negBuff = GetCombatRating(CR_BLOCK),GetCombatRatingBonus(CR_BLOCK),0; structStats["Attributes"]["Defense"]["BlockRating"]=strjoin(":", base,posBuff,negBuff); structStats["Attributes"]["Defense"]["BlockChance"]=rpgo.round(GetBlockChance(),2); base,posBuff,negBuff = GetCombatRating(CR_PARRY),GetCombatRatingBonus(CR_PARRY),0; structStats["Attributes"]["Defense"]["ParryRating"]=strjoin(":", base,posBuff,negBuff); structStats["Attributes"]["Defense"]["ParryChance"]=rpgo.round(GetParryChance(),2); structStats["Attributes"]["Defense"]["Resilience"]={}; structStats["Attributes"]["Defense"]["Resilience"]["Melee"]=GetCombatRating(CR_CRIT_TAKEN_MELEE); structStats["Attributes"]["Defense"]["Resilience"]["Ranged"]=GetCombatRating(CR_CRIT_TAKEN_RANGED); structStats["Attributes"]["Defense"]["Resilience"]["Spell"]=GetCombatRating(CR_CRIT_TAKEN_SPELL); structStats["Attributes"]["Resists"]={}; for i=1,table.getn(UnitResistanceName) do local base,resistance,positive,negative=UnitResistance(unit,i); structStats["Attributes"]["Resists"][UnitResistanceName[i]] = strjoin(":", base,positive,negative); end if(unit=="player") then structStats["Hearth"]=GetBindLocation(); structStats["Money"]=rpgo.Arg2Tab("Gold","Silver","Copper",rpgo.GetMoney()); structStats["IsResting"]=IsResting() == 1 or false; local XPrest=GetXPExhaustion(); if(not XPrest) then XPrest=0; end structStats["Experience"]=strjoin(":", UnitXP("player"),UnitXPMax("player"),XPrest); self.db["timestamp"]["Attributes"]=time(); end self:GetAttackRating(structStats["Attributes"],unit); end function RPGOCP:CharacterDamageFrame(unit,prefix) if(not unit) then unit="player"; end if(not prefix) then prefix="PlayerStatFrameLeft"; end local damageFrame = getglobal(prefix.."2"); self.tooltip:ClearLines(); -- Main hand weapon self.tooltip:SetText(INVTYPE_WEAPONMAINHAND, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b); self.tooltip:AddDoubleLine(ATTACK_SPEED_COLON, format("%.2f", damageFrame.attackSpeed), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); self.tooltip:AddDoubleLine(DAMAGE_COLON, damageFrame.damage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); self.tooltip:AddDoubleLine(DAMAGE_PER_SECOND, format("%.1f", damageFrame.dps), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); -- Check for offhand weapon if ( damageFrame.offhandAttackSpeed ) then self.tooltip:AddLine("\n"); self.tooltip:AddLine(INVTYPE_WEAPONOFFHAND, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b); self.tooltip:AddDoubleLine(ATTACK_SPEED_COLON, format("%.2f", damageFrame.offhandAttackSpeed), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); self.tooltip:AddDoubleLine(DAMAGE_COLON, damageFrame.offhandDamage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); self.tooltip:AddDoubleLine(DAMAGE_PER_SECOND, format("%.1f", damageFrame.offhandDps), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); end end function RPGOCP:CharacterRangedDamageFrame(unit,prefix) if(not unit) then unit="player"; end if(not prefix) then prefix="PlayerStatFrameLeft"; end local damageFrame = getglobal(prefix.."2"); if (not damageFrame.damage) then return; end self.tooltip:ClearLines(); self.tooltip:SetText(INVTYPE_RANGED, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b); self.tooltip:AddDoubleLine(ATTACK_SPEED_COLON, format("%.2f", damageFrame.attackSpeed), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); self.tooltip:AddDoubleLine(DAMAGE_COLON, damageFrame.damage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); self.tooltip:AddDoubleLine(DAMAGE_PER_SECOND, format("%.1f", damageFrame.dps), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); end function RPGOCP:GetAttackRating(structAttack,unit,prefix) if(not unit) then unit="player"; end if(not prefix) then prefix="PlayerStatFrameLeft"; end UpdatePaperdollStats(prefix, "PLAYERSTAT_MELEE_COMBAT"); local stat2 = getglobal(prefix.."2"); local stat2Text = getglobal(prefix.."2".."StatText"); local mainHandAttackBase,mainHandAttackMod,offHandAttackBase,offHandAttackMod = UnitAttackBothHands(unit); local speed,offhandSpeed = UnitAttackSpeed(unit); structAttack["Melee"]={}; structAttack["Melee"]["MainHand"]={}; structAttack["Melee"]["MainHand"]["AttackSpeed"]=rpgo.round(speed,2); structAttack["Melee"]["MainHand"]["AttackDPS"]=rpgo.round(stat2.dps,1); structAttack["Melee"]["MainHand"]["AttackSkill"]=mainHandAttackBase+mainHandAttackMod; structAttack["Melee"]["MainHand"]["AttackRating"]=strjoin(":", mainHandAttackBase,mainHandAttackMod,0); local tt=stat2Text:GetText(); tt=rpgo.StripColor(tt); structAttack["Melee"]["MainHand"]["DamageRange"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)$","%1:%2"); self:CharacterDamageFrame(); local tt=self:ScanTooltip(); structAttack["Melee"]["DamageRangeTooltip"]=rpgo.StripColor(tt); if ( offhandSpeed ) then structAttack["Melee"]["OffHand"]={}; structAttack["Melee"]["OffHand"]["AttackSpeed"]=rpgo.round(offhandSpeed,2); structAttack["Melee"]["OffHand"]["AttackDPS"]=rpgo.round(stat2.offhandDps,1); structAttack["Melee"]["OffHand"]["AttackSkill"]=offHandAttackBase+offHandAttackMod; structAttack["Melee"]["OffHand"]["AttackRating"]=strjoin(":", offHandAttackBase,offHandAttackMod,0); tt=stat2.offhandDamage; tt=rpgo.StripColor(tt); structAttack["Melee"]["OffHand"]["DamageRange"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)","%1:%2"); else structAttack["Melee"]["OffHand"]=nil; end local stat4 = getglobal(prefix.."4"); local base,posBuff,negBuff; base,posBuff,negBuff = UnitAttackPower(unit); structAttack["Melee"]["AttackPower"] = strjoin(":", base,posBuff,negBuff); structAttack["Melee"]["AttackPowerDPS"]=rpgo.round(max((base+posBuff+negBuff), 0)/ATTACK_POWER_MAGIC_NUMBER,1); structAttack["Melee"]["AttackPowerTooltip"]=stat4.tooltip2; base,posBuff,negBuff = GetCombatRating(CR_HIT_MELEE),GetCombatRatingBonus(CR_HIT_MELEE),0; structAttack["Melee"]["HitRating"]=strjoin(":", base,posBuff,negBuff); base,posBuff,negBuff = GetCombatRating(CR_CRIT_MELEE),GetCombatRatingBonus(CR_CRIT_MELEE),0; structAttack["Melee"]["CritRating"]=strjoin(":", base,posBuff,negBuff); base,posBuff,negBuff = GetCombatRating(CR_HASTE_MELEE),GetCombatRatingBonus(CR_HASTE_MELEE),0; structAttack["Melee"]["HasteRating"]=strjoin(":", base,posBuff,negBuff); structAttack["Melee"]["CritChance"]=rpgo.round(GetCritChance(),2); if(unit=="player") then local rangedTexture = GetInventoryItemTexture("player",18); if ( not rangedTexture ) then structAttack["Ranged"]=nil; else UpdatePaperdollStats(prefix, "PLAYERSTAT_RANGED_COMBAT"); local damageFrame = getglobal(prefix.."2"); local damageFrameText = getglobal(prefix.."2".."StatText"); if(PaperDollFrame.noRanged) then structAttack["Ranged"]=nil; else local rangedAttackSpeed,minDamage,maxDamage,physicalBonusPos,physicalBonusNeg,percent = UnitRangedDamage(unit); structAttack["Ranged"]={}; structAttack["Ranged"]["AttackSpeed"]=rpgo.round(rangedAttackSpeed,1); structAttack["Ranged"]["AttackDPS"]=rpgo.round(damageFrame.dps,1); structAttack["Ranged"]["AttackSkill"]=UnitRangedAttack(unit); local rangedAttackBase,rangedAttackMod = UnitRangedAttack(unit); structAttack["Ranged"]["AttackRating"]=strjoin(":", rangedAttackBase,rangedAttackMod,0); tt=damageFrameText:GetText(); tt=rpgo.StripColor(tt); structAttack["Ranged"]["DamageRange"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)","%1:%2"); base,posBuff,negBuff = GetCombatRating(CR_HIT_RANGED),GetCombatRatingBonus(CR_HIT_RANGED),0; structAttack["Ranged"]["HitRating"]=strjoin(":", base,posBuff,negBuff); base,posBuff,negBuff = GetCombatRating(CR_CRIT_RANGED),GetCombatRatingBonus(CR_CRIT_RANGED),0; structAttack["Ranged"]["CritRating"]=strjoin(":", base,posBuff,negBuff); base,posBuff,negBuff = GetCombatRating(CR_HASTE_RANGED),GetCombatRatingBonus(CR_HASTE_RANGED),0; structAttack["Ranged"]["HasteRating"]=strjoin(":", base,posBuff,negBuff); structAttack["Ranged"]["CritChance"]=rpgo.round(GetRangedCritChance(),2); self:CharacterRangedDamageFrame(); local tt=self:ScanTooltip(); tt=rpgo.StripColor(tt); structAttack["Ranged"]["DamageRangeTooltip"]=tt; if( HasWandEquipped() ) then structAttack["Ranged"]["AttackPower"]=nil; structAttack["Ranged"]["AttackPowerDPS"]=nil; structAttack["Ranged"]["AttackPowerTooltip"]=nil; structAttack["Ranged"]["HasWandEquipped"]=true; else local base,pos,neg=UnitRangedAttackPower(unit); apDPS=base/ATTACK_POWER_MAGIC_NUMBER; structAttack["Ranged"]["AttackPower"] = strjoin(":", base,pos,neg); structAttack["Ranged"]["AttackPowerDPS"]=rpgo.round(apDPS,1); structAttack["Ranged"]["AttackPowerTooltip"]=format(RANGED_ATTACK_POWER_TOOLTIP,apDPS); structAttack["Ranged"]["HasWandEquipped"]=false; end end end structAttack["Spell"] = {}; structAttack["Spell"]["BonusHealing"] = GetSpellBonusHealing(); local holySchool = 2; structAttack["Spell"]["CritChance"]=rpgo.round(GetSpellCritChance(holySchool),2); local minModifier = GetSpellBonusDamage(holySchool); structAttack["Spell"]["School"]={}; for i=(holySchool+1),MAX_SPELL_SCHOOLS do bonusDamage = GetSpellBonusDamage(i); minModifier = min(minModifier,bonusDamage); structAttack["Spell"]["School"][UnitSchoolName[i]] = bonusDamage; end structAttack["Spell"]["BonusDamage"]=GetSpellBonusDamage(holySchool); base,posBuff,negBuff = GetCombatRating(CR_HIT_SPELL),GetCombatRatingBonus(CR_HIT_SPELL),0; structAttack["Spell"]["HitRating"]=strjoin(":", base,posBuff,negBuff); base,posBuff,negBuff = GetCombatRating(CR_CRIT_SPELL),GetCombatRatingBonus(CR_CRIT_SPELL),0; structAttack["Spell"]["CritRating"]=strjoin(":", base,posBuff,negBuff); base,posBuff,negBuff = GetCombatRating(CR_HASTE_SPELL),GetCombatRatingBonus(CR_HASTE_SPELL),0; structAttack["Spell"]["HasteRating"]=strjoin(":", base,posBuff,negBuff); structAttack["Spell"]["Penetration"] = GetSpellPenetration(); local base,casting = GetManaRegen(); base = floor( (base * 5.0) + 0.5); casting = floor( (casting * 5.0) + 0.5); structAttack["Spell"]["ManaRegen"] = strjoin(":", base,casting); end PaperDollFrame_UpdateStats(); end --[GetBuffs] function RPGOCP:GetBuffs(structBuffs,unit) --self:PrintDebug("GetBuffs"); if(not unit) then unit="player"; end local idx=1; if(not structBuffs["Attributes"]) then structBuffs["Attributes"]={}; end if(UnitBuff(unit,idx)) then structBuffs["Attributes"]["Buffs"]={}; while(UnitBuff(unit,idx)) do local name,rank,icon,count=UnitBuff(unit,idx); self.tooltip:SetUnitBuff(unit,idx); if(rank and rank=="") then rank=nil; end if(count and count<=1) then count=nil; end structBuffs["Attributes"]["Buffs"][idx]={ Name=name, Rank=rank, Count=count, Icon=rpgo.scanIcon(icon), Tooltip=self:ScanTooltip()}; idx=idx+1 end else structBuffs["Attributes"]["Buffs"]=nil; end idx=1; if(UnitDebuff(unit,idx)) then structBuffs["Attributes"]["Debuffs"]={}; while(UnitDebuff(unit,idx)) do local name,rank,icon,count=UnitDebuff(unit,idx); self.tooltip:SetUnitDebuff(unit,idx); if(rank and rank=="") then rank=nil; end if(count and count<=1) then count=nil; end structBuffs["Attributes"]["Debuffs"][idx]={ Name=name, Rank=rank, Count=count, Icon=rpgo.scanIcon(icon), Tooltip=self:ScanTooltip()}; idx=idx+1 end else structBuffs["Attributes"]["Debuffs"]=nil; end end function RPGOCP:GetEquipment(force) --self:PrintDebug("GetEquipment"); if(not self.prefs["scan"]["equipment"]) then self.db["Equipment"]=nil; return; end if( force or self:State("Equipment")==0 or not self:State("_eq") ) then --self:PrintDebug(" ==> scan"); local index,slot; self.db["Equipment"]={}; self:State("Equipment",0) local structEquip=self.db["Equipment"]; for index,slot in pairs(UnitSlots) do local curItemLink,itemCount; local curItemTexture=GetInventoryItemTexture("player",index); self.tooltip:SetInventoryItem("player",index); if(index==0) then if(curItemTexture) then local curItemName,_=rpgo.GetItemInfoTT(self.tooltip); _,curItemLink,_,_=rpgo.GetItemInfo(curItemName); end else curItemLink=GetInventoryItemLink("player",index); end if(curItemLink) then itemCount=GetInventoryItemCount("player",index); if(itemCount == 1) then itemCount=nil; end structEquip[slot]=self:ScanItemInfo(curItemLink,curItemTexture,itemCount); self.state["Equipment"]=self.state["Equipment"]+1; curItemLink=nil; end end self.db["timestamp"]["Equipment"]=time(); self:State("_eq",true); self.frame:RegisterEvent("UNIT_INVENTORY_CHANGED"); end self:GetStats(self.db); end function RPGOCP:GetMail() --self:PrintDebug("GetMail"); if(not self.prefs["scan"]["mail"]) then self.db["MailBox"]=nil; return; end if(self:State("_mail")) then --self:PrintDebug(" ==> scan"); local numMessages=GetInboxNumItems(); if( not self:State("Mail") or self:State("Mail")~=numMessages ) then self.db["MailBox"]={}; self:State("Mail",0); local itemstr,structMail=nil,self.db["MailBox"]; for idx=1,numMessages do local _,_,mailSender,mailSubject,mailCoin,_,mailDays=GetInboxHeaderInfo(idx); local itemstr,itemIcon,itemQty,itemQuality,_=GetInboxItem(idx); if(not mailSender) then mailSender=UNKNOWN; end structMail[idx]={ Sender = mailSender, Subject = mailSubject, Coin = mailCoin, CoinIcon= rpgo.scanIcon(GetCoinIcon(mailCoin)), Days = mailDays}; if(itemstr) then itemstr=GetInboxItemLink(idx); self.tooltip:SetHyperlink(itemstr); structMail[idx]["Item"]=self:ScanItemInfo(itemstr,itemIcon,itemQty); end self:State("Mail",'++'); end self.db["timestamp"]["MailBox"]=time(); end end end function RPGOCP:GetInventory() --self:PrintDebug("GetInventory"); if(not self.prefs["scan"]["inventory"]) then self.db["Inventory"]=nil; return; elseif(not self.db["Inventory"]) then self.db["Inventory"]={}; self:State("Inventory",{}); end local structInventory=self.db["Inventory"]; local containers={}; for bagid=0,NUM_BAG_FRAMES do table.insert(containers,bagid); end if(HasKey and HasKey()) then table.insert(containers,KEYRING_CONTAINER); end for bagidx,bagid in pairs(containers) do bagidx=bagidx-1; if(not self.state["Inventory"][bagidx] or not self.state["Bag"][bagid]) then structInventory["Bag"..bagidx]=self:ScanContainer("Inventory",bagidx,bagid); end end self.db["timestamp"]["Inventory"]=time(); end function RPGOCP:GetBank() --self:PrintDebug("GetBank"); if(not self.prefs["scan"]["bank"]) then self.db["Bank"]=nil; return; elseif(not self:State("_bank")) then return; elseif(not self.db["Bank"]) then self.db["Bank"]={}; self:State("Bank",{}); end local structBank=self.db["Bank"]; local containers={}; table.insert(containers,BANK_CONTAINER); for bagid=1,NUM_BANKBAGSLOTS do table.insert(containers,bagid+NUM_BAG_SLOTS); end for bagidx,bagid in pairs(containers) do bagidx=bagidx-1; if(not self.state["Bank"][bagidx] or not self.state["Bag"][bagid]) then structBank["Bag"..bagidx]=self:ScanContainer("Bank",bagidx,bagid); end end self.db["timestamp"]["Bank"]=time(); end function RPGOCP:ScanContainer(invgrp,bagidx,bagid) --self:PrintDebug(" ==> scan",invgrp,bagidx,bagid); local itemColor,itemID,itemName,itemIcon,itemLink; if(bagid==0) then itemName=GetBagName(bagid); itemIcon="Button-Backpack-Up"; if(not self.prefs["fixicon"]) then itemIcon="Interface\\Buttons\\"..itemIcon; end self.tooltip:SetText(itemName); self.tooltip:AddLine(format(CONTAINER_SLOTS,rpgo.GetContainerNumSlots(bagid),BAGSLOT)); elseif(bagid==BANK_CONTAINER) then itemName = "Bank Contents"; self.tooltip:ClearLines(); elseif(bagid==KEYRING_CONTAINER) then itemName = KEYRING; itemIcon="UI-Button-KeyRing"; if(not self.prefs["fixicon"]) then itemIcon="Interface\\Buttons\\"..itemIcon; end self.tooltip:SetText(itemName); self.tooltip:AddLine(format(CONTAINER_SLOTS,rpgo.GetContainerNumSlots(bagid),itemName)); else itemColor,_,itemID,itemName=rpgo.GetItemInfo( GetInventoryItemLink("player",ContainerIDToInventoryID(bagid)) ); itemIcon=GetInventoryItemTexture("player",ContainerIDToInventoryID(bagid)); self.tooltip:SetInventoryItem("player",ContainerIDToInventoryID(bagid)) end local bagInv,bagSlot=0,rpgo.GetContainerNumSlots(bagid); if(bagSlot==nil or bagSlot==0) then self.state[invgrp][bagidx]=nil return nil; end local container={ Name=itemName, Color=rpgo.scanColor(itemColor), Slots=rpgo.GetContainerNumSlots(bagid), Item=itemID, Icon=rpgo.scanIcon(itemIcon), Tooltip=self:ScanTooltip(), Contents={}}; for slot=1,bagSlot do local itemLink=GetContainerItemLink(bagid,slot); if(itemLink) then local itemIcon,itemCount,_,_=GetContainerItemInfo(bagid,slot); if(bagid==BANK_CONTAINER) then self.tooltip:SetInventoryItem("player",BankButtonIDToInvSlotID(slot)); elseif(bagid==KEYRING_CONTAINER) then self.tooltip:SetInventoryItem("player",KeyRingButtonIDToInvSlotID(slot)); else self.tooltip:SetBagItem(bagid,slot); end container["Contents"][slot]=self:ScanItemInfo(itemLink,itemIcon,itemCount); bagInv=bagInv+1; end end if(not self:State("_bag")) then self.frame:RegisterEvent("PLAYERBANKSLOTS_CHANGED"); self.frame:RegisterEvent("BAG_UPDATE"); self:State("_bag",true); end self.state["Bag"][bagid]=true; self.state[invgrp][bagidx]={slot=bagSlot,inv=bagInv}; return container end function RPGOCP:GetTradeSkill(tradeskill) --self:PrintDebug("GetTradeSkill"); if(not self.prefs["scan"]["professions"]) then self.db["Professions"]=nil; return; end local getTradeSkillLine,expandTradeSkills,getNumTradeSkills,getTradeSkillInfo,getTradeSkillIcon,getTradeSkillItem,getTradeSkillCool,getTradeSkillDesc,tradeSkillFrame; local getTradeSkillNumReagents,getTradeSkillReagentInfo,getTradeSkillReagentItem; if(tradeskill=='trade') then getTradeSkillLine = GetTradeSkillLine; expandTradeSkills = ExpandTradeSkillSubClass; getNumTradeSkills = GetNumTradeSkills; getTradeSkillInfo = GetTradeSkillInfo; getTradeSkillIcon = GetTradeSkillIcon; getTradeSkillItem = GetTradeSkillItemLink; getTradeSkillCool = GetTradeSkillCooldown; tradeSkillFrame = rpgoCPTradeSkillFrame; getTradeSkillNumReagents = GetTradeSkillNumReagents; getTradeSkillReagentInfo = GetTradeSkillReagentInfo; getTradeSkillReagentItem = GetTradeSkillReagentItemLink; elseif(tradeskill=='craft') then getTradeSkillLine = GetCraftDisplaySkillLine expandTradeSkills = CollapseCraftSkillLine getNumTradeSkills = GetNumCrafts getTradeSkillInfo = function(idx) local skillName,craftSubSpellName,skillType,numAvailable,isExpanded=GetCraftInfo(idx) return skillName,skillType,numAvailable,isExpanded end getTradeSkillIcon = GetCraftIcon getTradeSkillItem = GetCraftItemLink getTradeSkillDesc = GetCraftDescription tradeSkillFrame = rpgoCPCraftFrame getTradeSkillNumReagents = GetCraftNumReagents; getTradeSkillReagentInfo = GetCraftReagentInfo; getTradeSkillReagentItem = GetCraftReagentItemLink; else return; end local skillLineName,skillLineRank,skillLineMaxRank=getTradeSkillLine(); if(not skillLineName or skillLineName=="" or skillLineName==UNKNOWN) then return; end expandTradeSkills(0); if ( not self.db["Professions"] ) then self.db["Professions"]={}; end if ( not self.db["timestamp"]["Professions"] ) then self.db["timestamp"]["Professions"]={}; end local structProf=self.db["Professions"]; self:State("_reagentError",nil); local skillHeader=nil; local numTradeSkills=getNumTradeSkills(); if(numTradeSkills>0 and (not self.state["Professions"][skillLineName] or numTradeSkills~=self.state["Professions"][skillLineName]) ) then local TradeSkillTemp=nil; if(not structProf[skillLineName]) then structProf[skillLineName]={}; elseif(structProf[skillLineName]) then TradeSkillTemp=structProf[skillLineName]; structProf[skillLineName]={}; end self.state["Professions"][skillLineName]=0; if(tradeskill=='craft') then skillHeader=skillLineName; if(not structProf[skillLineName][skillHeader]) then structProf[skillLineName][skillHeader]={}; end end for idx=1,numTradeSkills do local skillName,skillType,numAvailable,isExpanded=getTradeSkillInfo(idx); if( skillType=="header" and skillName~="" ) then skillHeader=skillName; structProf[skillLineName][skillHeader]={}; self.state["Professions"][skillLineName]=self.state["Professions"][skillLineName]+1; elseif( skillHeader and skillName and skillName~="" ) then local cooldown,reagents=nil,{}; local skillIcon=getTradeSkillIcon(idx); if(not skillIcon) then skillIcon=""; end local itemColor,_,itemLink,_=rpgo.GetItemInfo(getTradeSkillItem(idx)); if(getTradeSkillDesc) then local tt = getTradeSkillDesc(idx) if(tt) then self.tooltip:SetText(getTradeSkillDesc(idx)); end elseif(not MarsProfessionOrganizer_SetTradeSkillItem) then self.tooltip:SetTradeSkillItem(idx); end if(getTradeSkillCool) then cooldown = getTradeSkillCool(idx); if(cooldown) then self.tooltip:AddLine(COOLDOWN_REMAINING.." "..SecondsToTime(cooldown)); end end reagents={}; for ridx=1,getTradeSkillNumReagents(idx) do local reagentName,reagentTexture,reagentCount,_=getTradeSkillReagentInfo(idx,ridx); if(not reagentName) then reagentName=UNKNOWN; self:State("_reagentError",true); end if(not reagentTexture) then reagentTexture=""; end if(self.prefs["reagentfull"]) then local _,itemID,_ = rpgo.GetItemID(getTradeSkillReagentItem(idx,ridx)); table.insert(reagents, { Name=reagentName, Count=reagentCount, itemID=itemID }); else table.insert(reagents, reagentName .. " x" .. reagentCount); end end if(not self.prefs["reagentfull"]) then reagents = table.concat(reagents,"
"); end structProf[skillLineName][skillHeader][skillName]={ Icon=rpgo.scanIcon(skillIcon), Difficulty=TradeSkillCode[skillType], Color=rpgo.scanColor(itemColor), Item=itemLink, Tooltip=self:ScanTooltip(), Reagents=reagents}; if(cooldown) then structProf[skillLineName][skillHeader][skillName]["Cooldown"]=cooldown; structProf[skillLineName][skillHeader][skillName]["DateUTC"]=date("!%Y-%m-%d %H:%M:%S"); structProf[skillLineName][skillHeader][skillName]["timestamp"]=time(); end self.state["Professions"][skillLineName]=self.state["Professions"][skillLineName]+1; end end if( (self.state["Professions"][skillLineName]==0) or (self.state["_reagentError"]) ) then self:State("_skillError",true); self.state["Professions"][skillLineName]=0; structProf[skillLineName]=TradeSkillTemp; if(self.state["_reagentError"]) then self:PrintTitle(skillLineName..rpgo.StringColorize(rpgo.colorRed," reagents not scanned; CP will rescan")); else self:PrintTitle(skillLineName..rpgo.StringColorize(rpgo.colorRed," not scanned; CP will rescan")); end tradeSkillFrame:Show(); else if(self.state["_skillError"]) then self:PrintTitle(skillLineName.." rescanned successfully"); self:State("_skillError",nil); self:State("_reagentError",nil); end tradeSkillFrame:Hide(); self:TidyProfessions(); self.db["timestamp"]["Professions"][skillLineName]=time(); end TradeSkillTemp=nil; end end function RPGOCP:TidyProfessions() if(self:State("_loaded")) then for skillName in pairs(self.db["Professions"]) do if(not self.state["_skills"][skillName]) then self.db["Professions"][skillName]=nil; end end end end function RPGOCP:GetSpellBook() if(not self.prefs["scan"]["spells"]) then self.db["SpellBook"]=nil; return; end if ( not self.db["SpellBook"] ) then self.db["SpellBook"]={}; end local structSpell=self.db["SpellBook"]; for spelltab=1,GetNumSpellTabs() do local spelltabname,spelltabtexture,offset,numSpells=GetSpellTabInfo(spelltab); local idx=0; if(not self.state["SpellBook"][spelltabname] or self.state["SpellBook"][spelltabname]~=numSpells) then structSpell[spelltabname]={Icon=rpgo.scanIcon(spelltabtexture)}; structSpell[spelltabname]["Spells"]={}; self.state["SpellBook"][spelltabname]=0; idx=0; for spellId=1+offset,numSpells+offset do spellName,spellRank=GetSpellName( spellId,BOOKTYPE_SPELL ); spellTexture=GetSpellTexture( spellId,spelltab ); self.tooltip:SetSpell(spellId,BOOKTYPE_SPELL); structSpell[spelltabname]["Spells"][spellName]={ Rank=spellRank, Icon=rpgo.scanIcon(spellTexture), Tooltip=self:ScanTooltip()}; idx=idx+1; end self.state["SpellBook"][spelltabname]=idx; structSpell[spelltabname]["Count"]=numSpells; end self.db["timestamp"]["SpellBook"]=time(); end end function RPGOCP:ScanPetInit(name) if(name) then if(not self.db["Pets"]) then self.db["Pets"]={}; end if(not self.db["Pets"][name]) then self.db["Pets"][name]={}; end if(not self.db["timestamp"]["Pets"]) then self.db["timestamp"]["Pets"]={}; end end end function RPGOCP:ScanPetStable() if(self.prefs["scan"]["pet"] and (self.state["_class"]=="HUNTER" and UnitLevel("player")>9)) then local structPets; for petIndex=0,GetNumStableSlots() do local petIcon,petName,petLevel,petType,petLoyalty=GetStablePetInfo(petIndex); if(petName) then self:ScanPetInit(petName); structPets=self.db["Pets"]; structPets[petName]["Slot"]=petIndex; structPets[petName]["Icon"]=rpgo.scanIcon(petIcon); structPets[petName]["Name"]=petName; structPets[petName]["Level"]=petLevel; structPets[petName]["Type"]=petType; structPets[petName]["Loyalty"]=petLoyalty; self.db["timestamp"]["Pets"][petName]=time(); end self.state["Stable"][petIndex]=petName; end self:ScanPetInfo(); elseif(self.db) then self.db["Pets"]=nil; self.state["Pets"]={}; end end function RPGOCP:ScanPetInfo() if(self.prefs["scan"]["pet"]) then if(HasPetUI()) then petName=UnitName("pet"); self:ScanPetInit(petName); local structPet=self.db["Pets"][petName]; structPet["Name"]=petName; structPet["Type"]=UnitCreatureFamily("pet"); structPet["TalentPoints"],structPet["TalentPointsUsed"]=GetPetTrainingPoints(); local currXP,nextXP=GetPetExperience(); structPet["Experience"]=strjoin(":", currXP,nextXP); self:GetStats(structPet,"pet"); self:GetBuffs(structPet,"pet"); self:GetPetSpellBook(); self.state["Pets"][petName]=1; self.db["timestamp"]["Pets"][petName]=time(); end elseif(self.db) then self.db["Pets"]=nil; self.state["Pets"]={}; end end function RPGOCP:GetPetSpellBook() if(self.prefs["scan"]["spells"]) then numSpells,_=HasPetSpells(); petName=UnitName("pet"); if(numSpells) then self:ScanPetInit(petName); if (not self.db["Pets"][petName]["SpellBook"]) then self.db["Pets"][petName]["SpellBook"]={}; end local structPetSpell=self.db["Pets"][petName]["SpellBook"]; for petSpellId=1,numSpells do local spellName,spellRank=GetSpellName(petSpellId,BOOKTYPE_PET); local spellTexture=GetSpellTexture(petSpellId,BOOKTYPE_PET); if (spellName==nil) then break; end if (not structPetSpell["Spells"]) then structPetSpell["Spells"]={}; end structPetSpell["Spells"][spellName]={}; structPetSpell["Spells"][spellName]["Rank"]=spellRank; structPetSpell["Spells"][spellName]["Icon"]=rpgo.scanIcon(spellTexture); structPetSpell["Count"]=petSpellId; end self.state["PetSpell"][petName]=numSpells; end end end function RPGOCP:TradeTimer(event,arg1) local skill; if(not self.state["ProfTimer"]) then self.state["ProfTimer"]={}; end if(event=="CRAFT_UPDATE") then skill=GetCraftDisplaySkillLine(); elseif(event=="TRADE_SKILL_UPDATE") then skill=GetTradeSkillLine(); end if(skill and skill~=UNKNOWN) then if( (not arg1) or (not self.state["ProfTimer"][skill]) ) then self.state["ProfTimer"][skill]=0; elseif(tonumber(arg1)) then self.state["ProfTimer"][skill]=self.state["ProfTimer"][skill]+arg1; end if(self.state["ProfTimer"][skill] > 1.5) then self.state["ProfTimer"][skill]=nil; self:EventHandler(string.gsub(event,'_UPDATE','_SHOW'),arg1); end else if(event=="CRAFT_UPDATE") then rpgoCPCraftFrame:Hide(); elseif(event=="TRADE_SKILL_UPDATE") then rpgoCPTradeSkillFrame:Hide(); end end end function RPGOCP:UpdatePlayed(arg1,arg2) if(arg1 and arg2) then timePlayed=arg1; timeLevelPlayed=arg2; end if(self.state["_loaded"] and self.db) then self.db["TimePlayed"]=timePlayed; self.db["TimeLevelPlayed"]=timeLevelPlayed; end end function RPGOCP:UpdateZone() self.db["Zone"]=GetZoneText(); self.db["SubZone"]=GetSubZoneText(); end function RPGOCP:UpdateBagScan(bagid) if(bagid~=nil and self.state["Bag"][bagid]) then self.state["Bag"][bagid]=nil; if(bagid==BANK_CONTAINER) then self.frame:UnregisterEvent("PLAYERBANKSLOTS_CHANGED"); elseif(table.maxn(self.state["Bag"])==0) then self:State("_bag",nil); self.frame:UnregisterEvent("BAG_UPDATE"); end end end function RPGOCP:UpdateEqScan(unit) if(unit=="player" and self:State("_eq") ) then self:State("_eq",nil); self.frame:UnregisterEvent("UNIT_INVENTORY_CHANGED"); end end function RPGOCP:GetProfileDate(server,char) local thisProfile,thisEpoch; if(myProfile and myProfile[server] and myProfile[server]["Character"] and myProfile[server]["Character"][char]) then thisProfile=myProfile[server]["Character"][char]; if(thisProfile["timestamp"] and thisProfile["timestamp"]["init"] and thisProfile["timestamp"]["init"]["TimeStamp"]) then thisEpoch=thisProfile["timestamp"]["init"]["TimeStamp"]; end if(thisEpoch) then return date("%Y-%m-%d",thisEpoch); end end return ""; end --[[## general rpgo functions: item --######################################################--]] --[function] itemlink,itemtexture,itemcount function RPGOCP:ScanItemInfo(itemstr,itemtexture,itemcount) local itemColor,itemLink,itemID,itemName if(itemstr) then itemColor,itemLink,itemID,itemName=rpgo.GetItemInfo(itemstr); local itemBlock={}; if(self.prefs["fixquantity"] and itemcount and itemcount<=1) then itemcount=nil end if(not itemName or not itemColor) then itemName,itemColor=rpgo.GetItemInfoTT(self.tooltip); end itemBlock["Name"]=itemName; itemBlock["Item"]=itemID; itemBlock["Color"]=rpgo.scanColor(itemColor); itemBlock["Quantity"]=itemcount; itemBlock["Icon"]=rpgo.scanIcon(itemtexture); itemBlock["Tooltip"]=self:ScanTooltip(); if(self.prefs["fixtooltip"] and itemBlock["Name"]==itemBlock["Tooltip"]) then itemBlock["Tooltip"]=nil end return itemBlock; end return nil; end --[[######################################################## --## object functions --######################################################--]] function RPGOCP:State(...) return rpgo.State(self,...); end function RPGOCP:LiteScan(event) if(event=="RPGOCP_EXPORT") then return false; end if(not self.state["_loaded"]) then return false; end return rpgo.LiteScan(self); end function RPGOCP:PrintTitle(...) return rpgo.PrintTitle(self,...); end function RPGOCP:ScanTooltip(...) return rpgo.ScanTooltipOO(self,...); end function RPGOCP:PrintUsage() return rpgo.PrintUsage(self); end function RPGOCP:PrintDebug(...) return rpgo.PrintDebug(self,...); end function RPGOCP:PrefInit(...) return rpgo.PrefInit(self,...); end function RPGOCP:PrefTidy(...) return rpgo.PrefTidy(self,...); end function RPGOCP:TogglePref(...) return rpgo.TogglePrefOO(self,...); end function RPGOCP:RegisterEvents(flagMode) if(not flagMode) then flagMode = (self.prefs.enabled); end self:PrintDebug("RegisterEvents ("..rpgo.PrefColorize(flagMode)..") "); return rpgo.RegisterEvents(self,flagMode); end function RPGOCP:UpdateDate(...) return rpgo.UpdateDate(self,...); end RPGOCP:Init();