--[[ -- ////////////////////////////////////////////// -- Variables Init -- ////////////////////////////////////////////// ]] local rpgoCP_TITLE ="CharacterProfiler"; local rpgoCP_ABBR ="CP"; local rpgoCP_AUTHOR ="calvin"; local rpgoCP_EMAIL ="calvin@rpgoutfitter.com"; local rpgoCP_URL ="www.rpgoutfitter.com"; local rpgoCP_DATE ="September 21, 2006"; local rpgoCP_PROVIDER ="rpgo"; local rpgoCP_VERSION ="1.6.3"; local rpgoCP_PROFILEDB ="1.6.2"; local rpgoCP_TOOLTIP ="rpgoCPtooltip"; local rpgoCP_OPTION =""; -- ////////////////////////////////////////////// if(not rpgoColorTitle) then rpgoColorTitle="909090"; end if(not rpgoColorGreen) then rpgoColorGreen="00cc00"; end if(not rpgoColorRed) then rpgoColorRed ="ff0000"; end -- ////////////////////////////////////////////// local timeWait=3; 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 UnitResistName={"Holy","Fire","Nature","Frost","Shadow","Arcane"}; local CPevents={"PLAYER_LOGIN","PLAYER_ENTERING_WORLD","PLAYER_LEVEL_UP","TIME_PLAYED_MSG", "SPELLS_CHANGED","CRAFT_SHOW","CRAFT_CLOSE","CRAFT_UPDATE","TRADE_SKILL_SHOW","TRADE_SKILL_UPDATE","TRADE_SKILL_CLOSE", "BANKFRAME_OPENED","BANKFRAME_CLOSED","PLAYERBANKBAGSLOTS_CHANGED","UNIT_INVENTORY_CHANGED", "MAIL_SHOW","MAIL_INBOX_UPDATE","MAIL_CLOSED", "MERCHANT_SHOW","MERCHANT_UPDATE","MERCHANT_CLOSED","MINIMAP_ZONE_CHANGED","GOSSIP_SHOW","GOSSIP_CLOSED", "PLAYER_CONTROL_LOST","PLAYER_CONTROL_GAINED","QUEST_FINISHED","PET_STABLE_CLOSED"}; local CPprefs={ enabled=true,tooltipshtml=true,reagenthtml=true,talentsfull=true,questsfull=false,lite=true,debug=false,honorold=true,ver=010500, 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} }; local 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","this will disable scanning while in raid or instance"}, {"/cp list","-- list current profiles"}, {"/cp purge [all|server|char]","-- purge info"}, }; --[[////////////////////////////////////////////// -- rpgoCP Core Functions -- OnLoad,RegisterEvents,LoadVar,EventHandler,InitState,InitPrefs -- ////////////////////////////////////////////]] --[[// OnLoad -- ////////////////////////////////////////////]] function rpgoCP_OnLoad() rpgoCPframe:RegisterEvent("ADDON_LOADED"); rpgoCPframe:RegisterEvent("VARIABLES_LOADED"); SLASH_RPGOCP1="/cp"; SLASH_RPGOCP2="/rpgocp"; SLASH_RPGOCP3="/profiler"; SlashCmdList["RPGOCP"]=function(msg) rpgoCP_ChatCommand(msg); end rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_TITLE).." [v" .. rpgoCP_VERSION .. "] loaded."); end --[[// RegisterEvents -- ////////////////////////////////////////////]] function rpgoCP_RegisterEvents() rpgoCP_debug("CP: RegisterEvents"); if(rpgoCPpref and rpgoCPpref["enabled"]) then rpgoCP_debug(" Events Registered"); for index,event in CPevents do rpgoCPframe:RegisterEvent(event); end else rpgoCP_debug(" Events Unregistered"); for index,event in CPevents do rpgoCPframe:UnregisterEvent(event); end end end --[[// EventHandler -- ////////////////////////////////////////////]] function rpgoCP_EventHandler(event,arg1,arg2) --if(rpgoDebugArg and event) then rpgoDebugArg(rpgoCP_ABBR,event,arg1,arg2); end if(event=="ADDON_LOADED" and arg1==rpgoCP_TITLE) then rpgoCP_myAddons(); rpgoCPframe:UnregisterEvent("ADDON_LOADED"); return; elseif(event=="VARIABLES_LOADED") then rpgoCP_InitState(); rpgoCP_InitPref(); rpgoCP_RegisterEvents(); rpgoCP_LoadVar(); rpgoCPframe:UnregisterEvent("VARIABLES_LOADED"); return; elseif(event=="PLAYER_LOGIN") then return; elseif(event=="PLAYER_ENTERING_WORLD") then return; elseif(event=="CRAFT_UPDATE") then rpgoCP_TradeTimer(event,arg1) return; elseif(event=="TRADE_SKILL_UPDATE") then rpgoCP_TradeTimer(event,arg1) return; elseif(not event) then return; end if(not rpgoCPpref or not rpgoCPpref["enabled"]) then return; end if(event=="SPELLS_CHANGED" and not rpgoCPstate["_loaded"]) then return; elseif(event=="MINIMAP_ZONE_CHANGED" and not rpgoCPstate["_loaded"]) then return; elseif(event=="PLAYER_LEAVING_WORLD" and not rpgoCPstate["_loaded"]) then return; elseif(event=="BAG_UPDATE") then rpgoCP_UpdateBagScan(arg1); return; elseif(event=="PLAYERBANKSLOTS_CHANGED") then rpgoCP_UpdateBagScan(BANK_CONTAINER); return; elseif(event=="UNIT_INVENTORY_CHANGED") then rpgoCP_UpdateEqScan(arg1); return; elseif(event=="TIME_PLAYED_MSG") then rpgoCP_UpdatePlayed(arg1,arg2); return; elseif(event=="PLAYER_CONTROL_LOST") then rpgoCPframe:UnregisterEvent("MINIMAP_ZONE_CHANGED"); return; elseif(event=="PLAYER_CONTROL_GAINED") then rpgoCPframe:RegisterEvent("MINIMAP_ZONE_CHANGED"); if(rpgoCPstate["_loaded"]) then rpgoCP_UpdateZone(); end return; end if(rpgo_LiteScan(rpgoCPpref["lite"]) and event~="RPGOCP_EXPORT") then return; end debugprofilestart(); if(not rpgoCPstate["_lock"] and rpgoCPplayer) then rpgoCPstate["_lock"]=1; if(not rpgoCPstate["_loaded"]) then rpgoCP_InitProfile(); rpgoCP_LoadProfile(); end if(event=="RPGOCP_SCAN") then rpgoCP_UpdateProfile(); elseif(event=="PLAYER_LEAVING_WORLD") then rpgoCP_UpdateProfile(); elseif(event=="RPGOCP_EXPORT") then rpgoCP_ForceExport(); elseif(event=="MINIMAP_ZONE_CHANGED") then rpgoCP_UpdateZone(); elseif(event=="SPELLS_CHANGED" and arg1=="LeftButton") then rpgoCP_GetSpellBook(); rpgoCP_GetPetSpellBook(); elseif(event=="BANKFRAME_OPENED") then rpgoCP_GetBank(); elseif(event=="BANKFRAME_CLOSED") then rpgoCP_GetBank(); rpgoCP_GetEquipment(); rpgoCP_GetInventory(); elseif(event=="MAIL_CLOSED") then rpgoCP_GetMail(); rpgoCP_GetEquipment(); rpgoCP_GetInventory(); elseif(event=="MERCHANT_CLOSED") then rpgoCP_GetEquipment(); rpgoCP_GetInventory(); elseif(event=="TRADE_SKILL_SHOW") then rpgoCP_GetSkills(); rpgoCP_GetTradeSkill(); elseif(event=="CRAFT_SHOW") then rpgoCP_GetSkills(); rpgoCP_GetCraft(); elseif(event=="PLAYER_LEVEL_UP") then rpgoCP_LoadProfile(); elseif(event=="QUEST_FINISHED") then rpgoCP_GetQuests(force); elseif(event=="PET_STABLE_CLOSED") then rpgoCP_ScanPetStable(); end rpgoCPstate["_lock"]=nil; end --rpgoCP_debug("time: "..debugprofilestop().."ms"); end --[[// InitState -- ////////////////////////////////////////////]] function rpgoCP_InitState(arg) local ttFrame=getglobal(rpgoCP_TOOLTIP); ttFrame:SetOwner(UIParent,"ANCHOR_NONE"); rpgoCP_debug("CP: InitState"); local _,tmpClass=UnitClass("player"); rpgoCPstate={ _vars=nil,_loaded=nil,_lock=nil,_bagevent=nil, _player=UnitName("player"),_server=GetRealmName(),_class=tmpClass, _skills={}, Equipment=0, EquipmentKey=0, Guild=nil, GuildNum=nil, Inventory={}, Bag={}, Bank={}, BankTime=0, Skills=0, Talents=0,TalentPts=0, SpellBook={}, Professions={}, Reputation=0, Quests=0, QuestsLog=0, Mail=nil, MailTime=0, Honor=0, Stable={}, Pets={}, PetSpell={}, }; end --[[// InitPrefs -- ////////////////////////////////////////////]] function rpgoCP_InitPref() rpgoCP_debug("CP: InitPref"); if(not CPprefs) then return; end if(not rpgoCPpref) then rpgoCPpref={}; elseif(rpgoCPpref and (not rpgoCPpref["ver"] or rpgoCPpref["ver"] < 010500) ) then rpgoCP_ConvertPref(); end rpgo_TidyPref(rpgoCPpref,CPprefs); rpgo_InitPref(rpgoCPpref,CPprefs); end --[[// ConvertPrefs -- ////////////////////////////////////////////]] function rpgoCP_ConvertPref() if(not rpgoCPprefNew) then rpgoCPprefNew={}; end if(rpgoCPpref and (not rpgoCPpref["ver"] or rpgoCPpref["ver"] < 010500) ) then rpgoCP_ConvertPrefSub(rpgoCPpref,rpgoCPprefNew); end rpgoCPpref=rpgoCPprefNew; rpgoCPpref["ver"]=010500; end --[[// LoadVar -- ////////////////////////////////////////////]] function rpgoCP_LoadVar() rpgoCP_debug("CP: LoadVar"); rpgoCPserver=GetRealmName(); rpgoCPplayer=UnitName("player"); _,rpgoCPclass=UnitClass("player"); rpgoCPstate["_vars"]=1; end --[[// OverLoaded functions -- PLAYER_QUITTING/PLAYER_LEAVING_WORLD -- PetAbandon - to grab drop of pet -- ////////////////////////////////////////////]] rpgoOldQuit=Quit; function Quit() if(rpgoCPpref and rpgoCPpref["enabled"] and rpgoCPstate["_loaded"]) then rpgoCP_EventHandler('RPGOCP_SCAN'); RequestTimePlayed(); end return rpgoOldQuit(); end rpgoOldLogout=Logout; function Logout() if(rpgoCPpref and rpgoCPpref["enabled"] and rpgoCPstate["_loaded"]) then rpgoCP_EventHandler('RPGOCP_SCAN'); RequestTimePlayed(); end return rpgoOldLogout(); end rpgoOldPetAbandon=PetAbandon; function PetAbandon() if(rpgoCPpref and rpgoCPpref["enabled"]) then petName=UnitName("pet"); if (rpgoCPstate["Stable"][petName]) then rpgoCPstate["Stable"][petName]=nil; end if (rpgoCPstate["Pets"][petName]) then rpgoCPstate["Pets"][petName]=nil; end if (rpgoCPstate["PetSpell"][petName]) then rpgoCPstate["PetSpell"][petName]=nil; end if (myProfile[rpgoCPserver][rpgoCPplayer]["Pets"] and myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][petName]) then myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][petName]=nil; end end return rpgoOldPetAbandon(); end --[[// ChatCommand -- ////////////////////////////////////////////]] function rpgoCP_ChatCommand(argline) arg=rpgo_Str2Ary(argline); if(arg[1]) then arg[1]=string.lower(arg[1]); if(arg[1]=="off") then rpgoCP_Toggle(false); return; elseif(arg[1]=="on") then rpgoCP_Toggle(true); return; elseif(arg[1]=="show") then rpgoCP_Show(); return; elseif(arg[1]=="list") then rpgoCP_ProfileList(); return; elseif(arg[1]=="export") then rpgoCP_EventHandler('RPGOCP_EXPORT'); return; elseif(arg[1]=="debug") then arg[2]=string.lower(arg[2]); rpgoCP_TogglePref("Debug",arg[2]); return; elseif(arg[1]=="purge") then table.remove(arg,1); rpgoCP_Purge(arg); return; elseif(CPprefs[arg[1]]) then arg[2]=string.lower(arg[2]); rpgoCP_TogglePref(arg[1],arg[2]); return; end end rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_TITLE).." Usage [v" .. rpgoCP_VERSION .. "]"); for index=1,table.getn(rpgoCP_Usage),1 do rpgo_VerboseMsg(rpgo_AssempleHelp(rpgoCP_Usage[index])); end rpgoCP_TogglePref("enabled"); end --[[// Toggle -- ////////////////////////////////////////////]] function rpgoCP_Toggle(val) if(rpgoCPpref["enabled"]~=val) then rpgoCP_TogglePref("enabled",val); rpgoCP_RegisterEvents(); if(val) then rpgoCP_InitState(1); rpgoCP_LoadVar(); if(not rpgoCPstate["_loaded"]) then rpgoCP_InitProfile(); rpgoCP_LoadProfile(); end else rpgoCPstate=nil; end else rpgoCP_TogglePref("enabled",val); end end function rpgoCP_TogglePref(pref,val) local msg="["..pref.."]"; if(val=="on") then val=true; elseif(val=="off") then val=false; end if(type(val)=="boolean" and rpgoCPpref[pref]~=val) then rpgoCPpref[pref]=val; msg=msg.." changed"; else msg=msg.." currently"; end rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..msg..": "..rpgo_ColorizePref(rpgoCPpref[pref])); end --[[// Show -- ////////////////////////////////////////////]] function rpgoCP_ProfileList() local server,char; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": character info scanned this session"); for server in myProfile do rpgo_VerboseMsg(" Server: "..server); for char in myProfile[server] do if(char ~= "Guild") then rpgo_VerboseMsg(" Char: "..char.." .. "..rpgoCP_GetProfileDate(server,char)); end end end end --[[// Show -- ////////////////////////////////////////////]] function rpgoCP_Show() if(rpgoCPpref["enabled"]) then if(rpgoCPplayer and rpgoCPstate["_loaded"]) then local msg=""; local item=nil; local count=0; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": character info scanned this session"); msg="Profile for: " .. rpgoCPplayer .. "@" .. rpgoCPserver; if(myProfile[rpgoCPserver][rpgoCPplayer]["Level"]) then msg=msg.." (lvl "..myProfile[rpgoCPserver][rpgoCPplayer]["Level"]..")" end rpgo_VerboseMsg(" "..msg); msg="Zone: "; if(myProfile[rpgoCPserver][rpgoCPplayer]["Zone"]) then msg=msg..myProfile[rpgoCPserver][rpgoCPplayer]["Zone"]; if(myProfile[rpgoCPserver][rpgoCPplayer]["SubZone"] and myProfile[rpgoCPserver][rpgoCPplayer]["SubZone"]~="") then msg=msg.."/"..myProfile[rpgoCPserver][rpgoCPplayer]["SubZone"]; end else msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned"); end rpgo_VerboseMsg(" "..msg); msg="Guild Info: "; if(rpgoCPstate["Guild"]==0) then msg=msg.."not in a guild"; elseif(rpgoCPstate["Guild"]) then if(myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]["GuildName"] and myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]["Title"]) then msg=msg.."Name:"..myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]["Name"].." Title:"..myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]["Title"]; else msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned1"); end else msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned2"); end rpgo_VerboseMsg(" " .. msg); msg=""; msg=msg .. "Equipment:"..rpgoCPstate["Equipment"].."/"..table.getn(UnitSlots); msg=msg .. " Skills:" ..rpgoCPstate["Skills"]; msg=msg .. " Talents:" ..rpgoCPstate["Talents"]; if(rpgoCPstate["Mail"]) then msg=msg .. " Mail:" ..rpgoCPstate["Mail"]; end rpgo_VerboseMsg(" " .. msg); msg=""; msg=msg .. "Quests:" ..rpgoCPstate["Quests"]; msg=msg .. " Reputation: " ..rpgoCPstate["Reputation"]; if(rpgoCPstate["Honor"]~=0 and myProfile[rpgoCPserver][rpgoCPplayer]["Honor"]["RankName"]) then msg=msg .. " Honor: " ..myProfile[rpgoCPserver][rpgoCPplayer]["Honor"]["RankName"]; else msg=msg .. " Honor: "..NONE; end rpgo_VerboseMsg(" " .. msg); count=0; msg="Professions:"; for item in rpgoCPstate["Professions"] do msg=msg .. " " .. item..":"..rpgoCPstate["Professions"][item]; count=count+1; end if(count==0) then msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned")..". to scan: open each profession"; end rpgo_VerboseMsg(" " .. msg); count=0; msg="SpellBook:"; for item in rpgoCPstate["SpellBook"] do msg=msg .. " " .. item..":"..rpgoCPstate["SpellBook"][item]; count=count+1; end if(count==0) then msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned")..". to scan: open your spellbook"; end rpgo_VerboseMsg(" " .. msg); count=0; msg="Inventory:"; for item in rpgoCPstate["Inventory"] do msg=msg .. " Bag" .. item..":"..rpgoCPstate["Inventory"][item]["inv"].."/"..rpgoCPstate["Inventory"][item]["slot"]; count=count+1; end if(count==0) then msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned")..". to scan: open your bank or 'character info'"; end rpgo_VerboseMsg(" " .. msg); count=0; msg="Bank:"; for item in rpgoCPstate["Bank"] do msg=msg .. " Bag" .. item .. ":".. rpgoCPstate["Bank"][item]["inv"].."/"..rpgoCPstate["Bank"][item]["slot"]; count=count+1; end if(count==0) then msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned")..". to scan: open your bank"; end rpgo_VerboseMsg(" " .. msg); if((rpgoCPclass=="HUNTER" and UnitLevel("player")>9) or rpgoCPclass=="WARLOCK") then count=0; msg="Pets: "; for item in rpgoCPstate["Pets"] do msg=msg..item.." "; if(rpgoCPstate["PetSpell"][item]) then msg=msg.."(spells:"..rpgoCPstate["PetSpell"][item]..") "; end count=count+1; end if(count==0) then msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned"); end rpgo_VerboseMsg(" " .. msg); end if(rpgoCPclass=="HUNTER" and UnitLevel("player")>9) then count=0; msg="Stable: "; for item in rpgoCPstate["Stable"] do msg=msg..rpgoCPstate["Stable"][item].." "; count=count+1; end if(count==0) then msg=msg..rpgo_ColorizeMsg(rpgoColorRed," not scanned")..". to scan: open the stable"; end rpgo_VerboseMsg(" " .. msg); end else rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..rpgo_ColorizeMsg(rpgoColorRed,"no character scanned")); end else rpgoCP_TogglePref("enabled"); end end --[[////////////////////////////////////////////// -- InitProfile -- ////////////////////////////////////////////]] function rpgoCP_InitProfile() if ( not myProfile ) then myProfile={}; end if ( not myProfile[rpgoCPserver] ) then myProfile[rpgoCPserver]={}; end if ( not myProfile[rpgoCPserver][rpgoCPplayer] ) then myProfile[rpgoCPserver][rpgoCPplayer]={}; end if ( not myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"] ) then myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]={}; end end --[[////////////////////////////////////////////// -- UpdateProfile -- ////////////////////////////////////////////]] function rpgoCP_UpdateProfile() rpgoCP_GetGuild(force); rpgoCP_GetBuffs(myProfile[rpgoCPserver][rpgoCPplayer]); rpgoCP_GetEquipment(); rpgoCP_GetInventory(); rpgoCP_GetTalents(); rpgoCP_GetSkills(); rpgoCP_GetReputation(); rpgoCP_GetQuests(); rpgoCP_GetHonor(); rpgoCP_UpdateZone(); rpgoCP_ScanPetInfo(); rpgoCP_UpdatePlayed(); rpgoCP_UpdateDate(); end --[[////////////////////////////////////////////// -- ForceExport -- ////////////////////////////////////////////]] function rpgoCP_ForceExport() local tmpState=rpgoCPstate; rpgoCP_InitState(1); rpgoCPstate["Bank"]=tmpState["Bank"]; rpgoCPstate["Professions"]=tmpState["Professions"]; rpgoCPstate["SpellBook"]=tmpState["SpellBook"]; rpgoCPstate["Stable"]=tmpState["Stable"]; rpgoCPstate["Pets"]=tmpState["Pets"]; rpgoCPstate["PetSpell"]=tmpState["PetSpell"]; rpgoCPstate["Mail"]=tmpState["Mail"]; rpgoCP_InitProfile(); rpgoCP_LoadProfile(); rpgoCP_UpdateProfile(); rpgoCP_ScanPetInfo(); rpgoCP_Show(); end --[[////////////////////////////////////////////// -- Purge -- ////////////////////////////////////////////]] function rpgoCP_Purge(arg) local tmpPurged,msg;msg=""; if(arg and arg[1] and myProfile) then msg = arg[1]; if(arg[1]=="char" and myProfile[rpgoCPserver]) then if(arg[2]) then msg = msg.." ["..arg[2].."]"; if(myProfile[rpgoCPserver][arg[2]]) then myProfile[rpgoCPserver][arg[2]]=nil; tmpPurged=true; end else msg = msg.." ["..rpgoCPplayer.."]"; myProfile[rpgoCPserver][rpgoCPplayer]=nil; tmpPurged=true; end elseif(arg[1]=="server") then if(arg[2]) then msg = msg.." ["..arg[2].."]"; if(myProfile[arg[2]]) then myProfile[arg[2]]=nil; tmpPurged=true; end else msg = msg.." ["..rpgoCPserver.."]"; myProfile[rpgoCPserver]=nil; tmpPurged=true; end elseif(arg[1]=="all") then myProfile=nil; tmpPurged=true; elseif(arg[1] and arg[2]) then msg = " ["..arg[2].."@"..arg[1].."]"; if(myProfile[arg[1]] and myProfile[arg[1]][arg[2]]) then myProfile[arg[1]][arg[2]]=nil; tmpPurged=true; elseif(myProfile[arg[2]] and myProfile[arg[2]][arg[1]]) then myProfile[arg[2]][arg[1]]=nil; tmpPurged=true; end end end if(tmpPurged) then rpgoCP_InitState(1); rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..msg.." was purged"); else rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..msg.." was not purged"); end end --[[////////////////////////////////////////////// -- LoadProfile -- ////////////////////////////////////////////]] function rpgoCP_LoadProfile() local structChar=myProfile[rpgoCPserver][rpgoCPplayer]; structChar["ProfilerVersion"]=rpgoCP_PROFILEDB; structChar["CPversion"]=rpgoCP_VERSION; structChar["CPprovider"]=rpgoCP_PROVIDER; structChar["DBversion"]=rpgoCP_PROFILEDB; structChar["Name"]=rpgoCPplayer; structChar["Server"]=rpgoCPserver; structChar["Locale"]=GetLocale(); structChar["Race"],structChar["RaceEn"]=UnitRace("player") structChar["Class"],structChar["ClassEn"]=UnitClass("player"); structChar["Sex"],structChar["SexId"]=rpgo_UnitSexString("player"); structChar["FactionEn"],structChar["Faction"]=UnitFactionGroup("player"); structChar["Hearth"]=GetBindLocation(); structChar["Zone"]=GetZoneText(); structChar["SubZone"]=GetSubZoneText(); structChar["TalentPoints"]=UnitCharacterPoints("player"); structChar["TimePlayed"]=timePlayed; structChar["TimeLevelPlayed"]=timeLevelPlayed; structChar["HasRelicSlot"]=UnitHasRelicSlot("player")==1 or false; rpgoCP_GetGuild(); rpgoCP_GetEquipment(); rpgoCP_UpdateZone(); rpgoCP_UpdateDate(); rpgoCPstate["_loaded"]=1; end --[[////////////////////////////////////////////// -- rpgoCP Extract functions -- ////////////////////////////////////////////]] function rpgoCP_GetGuild(force) local isGuildMember=IsInGuild(); if(not isGuildMember) then rpgoCPstate["Guild"]=0; myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]=nil; else local numGuildMembers=GetNumGuildMembers(); if(force or not rpgoCPstate["Guild"] or rpgoCPstate["GuildNum"]~=numGuildMembers) then myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]={} ; local structGuild=myProfile[rpgoCPserver][rpgoCPplayer]["Guild"]; local guildName,guildRankName,guildRankIndex=GetGuildInfo("player"); if(guildName) then structGuild["Name"]=guildName; structGuild["Title"]=guildRankName; structGuild["Rank"]=guildRankIndex; rpgoCPstate["Guild"]=1; rpgoCPstate["GuildNum"]=numGuildMembers; --toRemove structGuild["GuildName"]=structGuild["Name"]; end end end end function rpgoCP_GetSkills() if(rpgoCPpref["scan"]["skills"]) then local count=GetNumSkillLines(); --if(rpgoCPstate["Skills"]~=count) then myProfile[rpgoCPserver][rpgoCPplayer]["Skills"]={}; local structSkill=myProfile[rpgoCPserver][rpgoCPplayer]["Skills"]; local skillheader=""; local order=1; rpgoCPstate["Skills"]=0; for i=1,GetNumSkillLines(),1 do local skillName,isHeader,isExpanded,skillRank,numTempPoints,skillModifier,skillMaxRank,isAbandonable,stepCost,rankCost,minLevel,skillCostType=GetSkillLineInfo(i); if(isHeader==1) then skillheader=skillName; structSkill[skillheader]={}; structSkill[skillheader]["Order"]=order; order=order+1; else structSkill[skillheader][skillName]=skillRank..":"..skillMaxRank; if(skillMaxRank~=1) then rpgoCPstate["_skills"][skillName]=skillRank; end end rpgoCPstate["Skills"]=rpgoCPstate["Skills"]+1; end --end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Skills"]=nil; end end function rpgoCP_GetReputation() if(rpgoCPpref["scan"]["reputation"]) then local numFactions=GetNumFactions(); --if(rpgoCPstate["Reputation"]~=numFactions) then local thisHeader,name,description,standingID,barMin,barMax,barValue,atWar,canToggle,isHeader,isCollapsed; rpgoCPstate["Reputation"]=0; myProfile[rpgoCPserver][rpgoCPplayer]["Reputation"]={}; local structRep=myProfile[rpgoCPserver][rpgoCPplayer]["Reputation"]; structRep["Count"]=numFactions; thisHeader=NONE; for index=1,numFactions do name,description,standingID,barMin,barMax,barValue,atWar,canToggle,isHeader,isCollapsed=GetFactionInfo(index); if(not atWar) then atWar=0; end if(isHeader) then thisHeader=name; structRep[thisHeader]={}; elseif(standingID) then structRep[thisHeader][name]={}; structRep[thisHeader][name]["Standing"]=getglobal("FACTION_STANDING_LABEL"..standingID); structRep[thisHeader][name]["AtWar"]=atWar; structRep[thisHeader][name]["Value"]=barValue-barMin.."/"..barMax-barMin; end rpgoCPstate["Reputation"]=rpgoCPstate["Reputation"]+1; end --end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Reputation"]=nil; end end function rpgoCP_GetHonor() if(rpgoCPpref["scan"]["honor"]) then local lifetimeHK,lifetimeDK,lifetimeHighestRank=GetPVPLifetimeStats(); if(rpgoCPstate["Honor"]~=lifetimeHK) then local hk,dk,contrib,rank; local currRankName,currRankNumber,currRankDesc,currRankIcon,currRankProgress; local lifetimeRankName,lifetimeRankNumber=GetPVPRankInfo(lifetimeHighestRank); if ( not lifetimeRankName ) then lifetimeRankName=NONE; end local currRankName,currRankNumber=GetPVPRankInfo(UnitPVPRank("player")); if ( not currRankName ) then currRankName=NONE; end currRankIcon=""; if ( currRankNumber > 0 ) then currRankIcon=format("%s%02d","Interface\\PvPRankBadges\\PvPRank",currRankNumber); end currRankDesc="("..RANK.." "..currRankNumber..")"; currRankProgress=format("%02.02f",GetPVPRankProgress()*100); myProfile[rpgoCPserver][rpgoCPplayer]["Honor"]={}; local structHonor=myProfile[rpgoCPserver][rpgoCPplayer]["Honor"]; structHonor["Current"]=rpgo_Arg2Tab("Rank","Icon","Description","Progress",currRankName,currRankIcon,currRankDesc,currRankProgress); structHonor["Lifetime"]=rpgo_Arg2Tab("Rank","Name","HK","DK",lifetimeHighestRank,lifetimeRankName,lifetimeHK,lifetimeDK); structHonor["LastWeek"]=rpgo_Arg2Tab("HK","DK","Contribution","Rank",GetPVPLastWeekStats()); structHonor["ThisWeek"]=rpgo_Arg2Tab("HK","Contribution",GetPVPThisWeekStats()); structHonor["Yesterday"]=rpgo_Arg2Tab("HK","DK","Contribution",GetPVPYesterdayStats()); structHonor["Session"]=rpgo_Arg2Tab("HK","DK",GetPVPSessionStats()); --toRemove if(rpgoCPpref["honorold"]) then structHonor["RankName"]=currRankName; structHonor["RankInfo"]=currRankDesc; structHonor["RankIcon"]=currRankIcon; structHonor["LifetimeHighestRank"]=lifetimeHighestRank; structHonor["LifetimeRankName"]=lifetimeRankName; structHonor["LifetimeHK"]=lifetimeHK; structHonor["LifetimeDK"]=lifetimeDK; hk,dk,contrib,rank=GetPVPLastWeekStats(); structHonor["LastWeekHK"]=hk; structHonor["LastWeekDK"]=dk; structHonor["LastWeekContribution"]=contrib; structHonor["LastWeekRank"]=rank; hk,contrib=GetPVPThisWeekStats(); hk,dk,contrib=GetPVPYesterdayStats(); structHonor["YesterdayHK"]=hk; structHonor["YesterdayDK"]=dk; structHonor["YesterdayContribution"]=contrib; hk,dk=GetPVPSessionStats(); structHonor["SessionHK"]=hk; structHonor["SessionDK"]=dk; end rpgoCPstate["Honor"]=lifetimeHK; end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Honor"]=nil; end end function rpgoCP_GetTalents() if(rpgoCPpref["scan"]["talents"] and UnitLevel("player") > 9 ) then local numTabs=GetNumTalentTabs(); local numPts=UnitCharacterPoints("player"); if( (rpgoCPstate["Talents"]~=numTabs) or (rpgoCPstate["TalentPts"]~=numPts) ) then local numTalents,tabIndex,talentIndex local tabName,texture,points,fileName; local nameTalent,iconTexture,iconX,iconY,currentRank,maxRank; myProfile[rpgoCPserver][rpgoCPplayer]["TalentPoints"]=numPts; myProfile[rpgoCPserver][rpgoCPplayer]["Talents"]={}; local structTalent=myProfile[rpgoCPserver][rpgoCPplayer]["Talents"]; rpgoCPstate["Talents"]=0; for tabIndex=1,numTabs do numTalents=GetNumTalents(tabIndex); tabName,texture,points,fileName=GetTalentTabInfo(tabIndex); structTalent[tabName]={}; structTalent[tabName]["PointsSpent"]=points; structTalent[tabName]["Background"]="Interface\\TalentFrame\\" .. fileName; structTalent[tabName]["Order"]=tabIndex; for talentIndex=1,numTalents do nameTalent,iconTexture,iconX,iconY,currentRank,maxRank=GetTalentInfo(tabIndex,talentIndex); if(currentRank > 0 or rpgoCPpref["talentsfull"]) then structTalent[tabName][nameTalent]={ }; structTalent[tabName][nameTalent]["Rank"]=currentRank..":"..maxRank; structTalent[tabName][nameTalent]["Location"]=iconX..":"..iconY; structTalent[tabName][nameTalent]["Texture"]=iconTexture; end if(rpgoCPpref["talentsfull"]) then if(not structTalent[tabName][nameTalent]) then structTalent[tabName][nameTalent]={}; end rpgoCPtooltip:SetTalent(tabIndex,talentIndex) structTalent[tabName][nameTalent]["Tooltip"]=rpgo_TooltipScan(); end end rpgoCPstate["Talents"]=rpgoCPstate["Talents"]+1; end rpgoCPstate["TalentPts"]=numPts; end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Talents"]=nil; end end function rpgoCP_GetQuests(force) if(rpgoCPpref["scan"]["quests"]) then local numEntries,numQuests=GetNumQuestLogEntries(); if(force or rpgoCPstate["QuestsLog"]~=numEntries) then local header=UNKNOWN; myProfile[rpgoCPserver][rpgoCPplayer]["Quests"]={}; local structQuest=myProfile[rpgoCPserver][rpgoCPplayer]["Quests"]; local slot,index,num,j; slot=1; rpgoCPstate["Quests"]=0; for index=1,numEntries,1 do local questTitle,level,questTag,isHeader,isCollapsed,isComplete=GetQuestLogTitle(index); if(isHeader) then header=questTitle; structQuest[header]={} elseif(questTitle) then structQuest[header][slot]={} structQuest[header][slot]["Title"]=questTitle; structQuest[header][slot]["Level"]=level; structQuest[header][slot]["Complete"]=isComplete; if(questTag) then structQuest[header][slot]["Tag"]=questTag; end SelectQuestLogEntry(index); if(rpgoCPpref["questsfull"]) then structQuest[header][slot]["Description"],structQuest[header][slot]["Objective"]=GetQuestLogQuestText(index); elseif(structQuest[header][slot]["Description"]) then structQuest[header][slot]["Description"]=nil; structQuest[header][slot]["Objective"]=nil; end num=GetNumQuestLeaderBoards(index); if(num and num > 0) then structQuest[header][slot]["Tasks"]={}; for j=1,num,1 do structQuest[header][slot]["Tasks"][j]=rpgo_Arg2Tab("Note","Type","Done",GetQuestLogLeaderBoard(j,index)); end end num=GetQuestLogRewardMoney(index); if(num and num~=0) then structQuest[header][slot]["RewardMoney"]=num; end num=GetNumQuestLogRewards(index); if(num and num > 0) then structQuest[header][slot]["Rewards"]={}; for j=1,num,1 do _,curItemTexture,itemCount,_,_=GetQuestLogRewardInfo(j); rpgoCPtooltip:SetQuestLogItem("reward",j); table.insert(structQuest[header][slot]["Rewards"],rpgoCP_ScanItemInfo(GetQuestLogItemLink("reward",j),curItemTexture,itemCount,rpgo_TooltipScan())); end end num=GetNumQuestLogChoices(index); if(num and num > 0) then structQuest[header][slot]["Choice"]={}; for j=1,num,1 do _,curItemTexture,itemCount,_,_=GetQuestLogChoiceInfo(j); rpgoCPtooltip:SetQuestLogItem("choice",j); table.insert(structQuest[header][slot]["Choice"],rpgoCP_ScanItemInfo(GetQuestLogItemLink("choice",j),curItemTexture,itemCount,rpgo_TooltipScan())); end end slot=slot+1; rpgoCPstate["Quests"]=rpgoCPstate["Quests"]+1; end rpgoCPstate["QuestsLog"]=rpgoCPstate["QuestsLog"]+1; end end elseif ( myProfile[rpgoCPserver][rpgoCPplayer] ) then myProfile[rpgoCPserver][rpgoCPplayer]["Quests"]=nil; end end function rpgoCP_GetStats(structStats,unit) if(not unit) then unit="player"; end if( unit=="player" and (UnitIsDeadOrGhost("player") or rpgoCP_UnitHasResSickness("player")) ) then return end structStats["Level"]=UnitLevel(unit); structStats["Health"]=UnitHealthMax(unit); structStats["Mana"]=UnitManaMax(unit); structStats["Power"]=UnitPower[UnitPowerType(unit)]; structStats["Stats"]={}; for i=1,table.getn(UnitStatName),1 do local stat,effectiveStat,posBuff,negBuff=UnitStat(unit,i); structStats["Stats"][UnitStatName[i]]=(stat - posBuff - negBuff)..":"..effectiveStat..":"..posBuff..":"..negBuff; end local baseArm,effectiveArmor,armor,positiveArm,negativeArm=UnitArmor(unit); structStats["Armor"]=baseArm..":"..effectiveArmor..":"..positiveArm; structStats["Stats"]["Armor"]=baseArm..":"..effectiveArmor..":"..positiveArm..":"..negativeArm; local base,modifier = UnitDefense(unit); structStats["Defense"]=base; structStats["Stats"]["Defense"]=base..":"..base+modifier..":"..modifier..":0"; structStats["Resists"]={}; for i=1,table.getn(UnitResistName),1 do local base,resistance,positive,negative=UnitResistance(unit,i); structStats["Resists"][UnitResistName[i]]=base..":"..resistance..":"..positive..":"..negative; end if(unit=="player") then structStats["Money"]=rpgo_Arg2Tab("Gold","Silver","Copper",rpgo_GetMoney()); structStats["Experience"]=UnitXP("player")..":"..UnitXPMax("player"); structStats["IsResting"]=IsResting() == 1 or false; local XPrest=GetXPExhaustion(); if(not XPrest) then XPrest=0; end structStats["XP"]=structStats["Experience"]..":"..XPrest; structStats["DodgePercent"]=format("%02.02f",GetDodgeChance()); structStats["BlockPercent"]=format("%02.02f",GetBlockChance()); if(not structStats["CritPercent"]) then structStats["CritPercent"]="0"; end if(not structStats["ParryPercent"]) then structStats["ParryPercent"]="0"; end local mitigation=(effectiveArmor)/((85 * structStats["Level"])+400); mitigation=100*(mitigation/(mitigation+1)); structStats["MitigationPercent"]=format("%02.02f",mitigation); local spellIndex=1; local spellName,subSpellName=GetSpellName(spellIndex,BOOKTYPE_SPELL); local scanAttack=true; local scanParry=true; while spellName do if(spellName==ATTACK) then rpgoCPtooltip:SetSpell(spellIndex,BOOKTYPE_SPELL); if(rpgoCPtooltipTextLeft2:GetText()) then local ttText=rpgoCPtooltipTextLeft2:GetText(); local startString,endString=string.find(ttText,'(%d+)[,.](%d+)%% '); if(startString) then ttText=string.sub(ttText,startString,endString-2); structStats["CritPercent"]=string.gsub(ttText,"(%d+)[,.](%d+)","%1.%2"); end end rpgoCPtooltip:ClearLines(); scanAttack=nil; elseif(spellName==PARRY) then structStats["ParryPercent"]=format("%02.02f",GetParryChance()); scanParry=nil; end if(not scanAttack and not scanParry) then break; end spellIndex=spellIndex+1; spellName,subSpellName=GetSpellName(spellIndex,BOOKTYPE_SPELL); end myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Stats"]=time(); end rpgoCP_GetAttackRating(structStats,unit); end function rpgoCP_CharacterDamageFrame(unit,prefix) if(not unit) then unit="player"; end if(not prefix) then prefix="Character"; end local damageFrame = getglobal(prefix.."DamageFrame"); rpgoCPtooltip:ClearLines(); rpgoCPtooltip:SetText(INVTYPE_WEAPONMAINHAND); rpgoCPtooltip:AddDoubleLine(ATTACK_SPEED_COLON, format("%.2f", damageFrame.attackSpeed)); rpgoCPtooltip:AddDoubleLine(DAMAGE_COLON, damageFrame.damage); rpgoCPtooltip:AddDoubleLine(DAMAGE_PER_SECOND, format("%.1f", damageFrame.dps)); -- Check for offhand weapon if ( damageFrame.offhandAttackSpeed ) then rpgoCPtooltip:AddLine(" "); rpgoCPtooltip:AddLine(INVTYPE_WEAPONOFFHAND); rpgoCPtooltip:AddDoubleLine(ATTACK_SPEED_COLON, format("%.2f", damageFrame.offhandAttackSpeed)); rpgoCPtooltip:AddDoubleLine(DAMAGE_COLON, damageFrame.offhandDamage); rpgoCPtooltip:AddDoubleLine(DAMAGE_PER_SECOND, format("%.1f", damageFrame.offhandDps)); end end function rpgoCP_CharacterRangedDamageFrame(unit,prefix) if(not unit) then unit="player"; end if(not prefix) then prefix="Character"; end local damageFrame = getglobal(prefix.."RangedDamageFrame"); if (not damageFrame.damage) then return; end rpgoCPtooltip:ClearLines(); rpgoCPtooltip:SetText(INVTYPE_RANGED); rpgoCPtooltip:AddDoubleLine(ATTACK_SPEED_COLON, format("%.2f", damageFrame.attackSpeed)); rpgoCPtooltip:AddDoubleLine(DAMAGE_COLON, damageFrame.damage); rpgoCPtooltip:AddDoubleLine(DAMAGE_PER_SECOND, format("%.1f", damageFrame.dps)); end function rpgoCP_GetAttackRating(structAttack,unit,prefix) if(not unit) then unit="player"; end if(not prefix) then prefix="Character"; end PaperDollFrame_SetDamage(unit,prefix); PaperDollFrame_SetAttackPower(unit,prefix); PaperDollFrame_SetAttackBothHands(unit,prefix); local damageFrame = getglobal(prefix.."DamageFrame"); local damageText = getglobal(prefix.."DamageFrameStatText"); local mainHandAttackBase,mainHandAttackMod = UnitAttackBothHands(unit); structAttack["Melee Attack"]={}; structAttack["Melee Attack"]["AttackSpeed"]=format("%.2f", damageFrame.attackSpeed); structAttack["Melee Attack"]["AttackDPS"]=format("%.1f", damageFrame.dps); structAttack["Melee Attack"]["AttackRating"]=mainHandAttackBase+mainHandAttackMod; local tt=damageText:GetText(); tt=rpgo_StripColor(tt); structAttack["Melee Attack"]["DamageRange"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)$","%1:%2"); tt=damageFrame.damage; tt=rpgo_StripColor(tt); tt=string.gsub(tt,"%s++%d+$",""); structAttack["Melee Attack"]["DamageRangeBase"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)$","%1:%2"); rpgoCP_CharacterDamageFrame(); local tt=rpgo_TooltipScan(); tt=rpgo_StripColor(tt); structAttack["Melee Attack"]["DamageRangeTooltip"]=tt; if ( damageFrame.offhandAttackSpeed ) then structAttack["Melee Attack"]["AttackSpeed2"]=format("%.2f", damageFrame.offhandAttackSpeed); structAttack["Melee Attack"]["AttackDPS2"]=format("%.1f", damageFrame.offhandDps); tt=damageFrame.offhandDamage; tt=rpgo_StripColor(tt); structAttack["Melee Attack"]["DamageRange2"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)","%1:%2"); end local base,posBuff,negBuff = UnitAttackPower(unit); apDPS=max((base+posBuff+negBuff),0)/ATTACK_POWER_MAGIC_NUMBER; structAttack["Melee Attack"]["AttackPower"]=base+posBuff+negBuff; structAttack["Melee Attack"]["AttackPower2"]=base..":"..base+posBuff+negBuff..":"..posBuff..":"..negBuff; structAttack["Melee Attack"]["AttackPowerDPS"]=format("%.1f",apDPS); structAttack["Melee Attack"]["AttackPowerTooltip"]=format(MELEE_ATTACK_POWER_TOOLTIP,apDPS); if(unit=="player") then local rangedTexture = GetInventoryItemTexture("player",18); if ( not rangedTexture ) then structAttack["Ranged Attack"]=nil; else PaperDollFrame_SetRangedAttack(unit,prefix); PaperDollFrame_SetRangedDamage(unit,prefix); PaperDollFrame_SetRangedAttackPower(unit,prefix); local damageFrame = getglobal(prefix.."RangedDamageFrame"); local damageText = getglobal(prefix.."RangedDamageFrameStatText"); if(PaperDollFrame.noRanged) then structAttack["Ranged Attack"]=nil; else structAttack["Ranged Attack"]={}; structAttack["Ranged Attack"]["AttackSpeed"]=format("%.2f", damageFrame.attackSpeed); structAttack["Ranged Attack"]["AttackDPS"]=format("%.1f", damageFrame.dps); structAttack["Ranged Attack"]["AttackRating"]=UnitRangedAttack(unit); tt=damageText:GetText(); tt=rpgo_StripColor(tt); structAttack["Ranged Attack"]["DamageRange"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)","%1:%2"); tt=damageFrame.damage; tt=rpgo_StripColor(tt); tt=string.gsub(tt,"%s++%d+$",""); structAttack["Ranged Attack"]["DamageRangeBase"]=string.gsub(tt,"^(%d+)%s?-%s?(%d+)$","%1:%2"); rpgoCP_CharacterRangedDamageFrame(); local tt=rpgo_TooltipScan(); tt=rpgo_StripColor(tt); structAttack["Ranged Attack"]["DamageRangeTooltip"]=tt; if( HasWandEquipped() ) then structAttack["Ranged Attack"]["AttackPower"]=nil; structAttack["Ranged Attack"]["AttackPowerDPS"]=nil; structAttack["Ranged Attack"]["AttackPowerTooltip"]=nil; structAttack["Ranged Attack"]["HasWandEquipped"]=true; else local base,pos,neg=UnitRangedAttackPower(unit); apDPS=base/ATTACK_POWER_MAGIC_NUMBER; structAttack["Ranged Attack"]["AttackPower"]=base+pos+neg; structAttack["Ranged Attack"]["AttackPowerDPS"]=format("%.1f",apDPS); structAttack["Ranged Attack"]["AttackPowerTooltip"]=format(RANGED_ATTACK_POWER_TOOLTIP,apDPS); structAttack["Ranged Attack"]["HasWandEquipped"]=false; end end end end end function rpgoCP_GetBuffs(structBuffs,unit) if(not unit) then unit="player"; end local index=1; local buffTexture; if(UnitBuff(unit,index)) then structBuffs["Buffs"]={}; while(UnitBuff(unit,index)) do buffTexture=UnitBuff(unit,index); rpgoCPtooltip:SetUnitBuff(unit,index); structBuffs["Buffs"][index]={}; structBuffs["Buffs"][index]["Name"]=rpgo_GetItemInfoTT(); structBuffs["Buffs"][index]["Tooltip"]=rpgo_TooltipScan(); structBuffs["Buffs"][index]["Texture"]=buffTexture; index=index+1 end else structBuffs["Buffs"]=nil; end index=1; if(UnitDebuff(unit,index)) then structBuffs["Debuffs"]={}; while(UnitDebuff(unit,index)) do buffTexture=UnitDebuff(unit,index); rpgoCPtooltip:SetUnitDebuff(unit,index); structBuffs["Debuffs"][index]={}; structBuffs["Debuffs"][index]["Name"]=rpgo_GetItemInfoTT(); structBuffs["Debuffs"][index]["Tooltip"]=rpgo_TooltipScan(); structBuffs["Debuffs"][index]["Texture"]=buffTexture; index=index + 1 end else structBuffs["Debuffs"]=nil; end end function rpgoCP_GetEquipment(force) if(rpgoCPpref["scan"]["equipment"]) then if( force or rpgoCPstate["Equipment"]==0 or not rpgoCPstate["Eq"] ) then local id,curItemLink,curItemTexture,curItemName,curItemColor,itemCount,index,slot; rpgoCPstate["Equipment"]=0; rpgoCPstate["EquipmentKey"]=0; myProfile[rpgoCPserver][rpgoCPplayer]["Equipment"]={}; local structEquip=myProfile[rpgoCPserver][rpgoCPplayer]["Equipment"]; for index,slot in UnitSlots do curItemTexture=GetInventoryItemTexture("player",index); if(index==0) then --AmmoSlot magik if(curItemTexture) then rpgoCPtooltip:SetInventoryItem("player",index); curItemName,curItemColor=rpgo_GetItemInfoTT(); if(curItemName) then curItemLink="|c"..curItemColor.."|Hitem:0:0:0:0|h["..curItemName.."]|h|r"; id=1; end end else curItemLink=GetInventoryItemLink("player",index); _,id,_=rpgo_GetItemID(curItemLink); end if(curItemLink) then itemCount = GetInventoryItemCount("player",index); if(itemCount == 1) then itemCount=nil; end rpgoCPtooltip:SetInventoryItem("player",index); structEquip[slot]=rpgoCP_ScanItemInfo(curItemLink,curItemTexture,itemCount,rpgo_TooltipScan()); rpgoCPstate["Equipment"]=rpgoCPstate["Equipment"]+1; rpgoCPstate["EquipmentKey"]=rpgoCPstate["EquipmentKey"]+id; curItemLink=nil; end end myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Equipment"]=time(); rpgoCPstate["Eq"]=1; rpgoCPframe:RegisterEvent("UNIT_INVENTORY_CHANGED"); end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then structEquip=nil; end rpgoCP_GetStats(myProfile[rpgoCPserver][rpgoCPplayer]); end function rpgoCP_GetMail() if(rpgoCPpref["scan"]["mail"]) then numMessages=GetInboxNumItems(); if( (not rpgoCPstate["Mail"]) or (rpgoCPstate["Mail"]~=numMessages and numMessages~=0) ) then rpgoCPstate["Mail"]=0; myProfile[rpgoCPserver][rpgoCPplayer]["MailBox"]={}; local structMail=myProfile[rpgoCPserver][rpgoCPplayer]["MailBox"]; for index=1,numMessages do local _,_,mailSender,mailSubject,mailCoin,_,mailDays=GetInboxHeaderInfo(index); local itemName,itemIcon,itemQty,itemQuality,_=GetInboxItem(index); if(not mailSender) then mailSender=UNKNOWN; end structMail[index]={}; structMail[index]["Sender"]=mailSender; structMail[index]["Subject"]=mailSubject; structMail[index]["Coin"]=mailCoin; structMail[index]["CoinIcon"]=GetCoinIcon(mailCoin); structMail[index]["Days"]=mailDays; structMail[index]["Item"]={}; structMail[index]["Item"]["Name"]=itemName; structMail[index]["Item"]["Icon"]=itemIcon; structMail[index]["Item"]["Quantity"]=itemQty; rpgoCPtooltip:SetInboxItem(index); _,structMail[index]["Item"]["Color"]=rpgo_GetItemInfoTT(); structMail[index]["Item"]["Tooltip"]=rpgo_TooltipScan(); rpgoCPstate["Mail"]=rpgoCPstate["Mail"]+1; end myProfile[rpgoCPserver][rpgoCPplayer]["MailDateUTC"]=date("!%m/%d/%y %H:%M:%S"); myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["MailBox"]=time(); end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["MailBox"]=nil; myProfile[rpgoCPserver][rpgoCPplayer]["MailDateUTC"]=nil; end end function rpgoCP_GetInventory() local bagNum=0; if(rpgoCPpref["scan"]["inventory"]) then if(not bagContainerText) then bagContainerText=""; end if(not myProfile[rpgoCPserver][rpgoCPplayer]["Inventory"]) then myProfile[rpgoCPserver][rpgoCPplayer]["Inventory"]={}; rpgoCPstate["Inventory"]={}; end local structInventory=myProfile[rpgoCPserver][rpgoCPplayer]["Inventory"]; for bag=0,NUM_BAG_FRAMES,1 do bagName="Bag" .. bag; local bagname,link,texture,color,item,itemname; if(bag==KEYRING_CONTAINER) then bagname=KEYRING; baglink="|cffffffff|Hitem:0:0:0:0|h["..KEYRING.."]|h|r"; texture="Interface\\Buttons\\UI-Button-KeyRing"; rpgoCPtooltip:SetText(KEYRING); rpgoCPtooltip:AddLine(format(CONTAINER_SLOTS,rpgoCP_GetContainerNumSlots(KEYRING_CONTAINER),KEYRING)); elseif(bag==0) then bagname=GetBagName(bag); baglink="|cffffffff|Hitem:0:0:0:0|h["..bagname.."]|h|r"; texture="Interface\\Buttons\\Button-Backpack-Up"; rpgoCPtooltip:SetText(bagname); rpgoCPtooltip:AddLine(format(CONTAINER_SLOTS,rpgoCP_GetContainerNumSlots(bag),bagContainerText)); else baglink=GetInventoryItemLink("player",(ContainerIDToInventoryID(bag))); texture=GetInventoryItemTexture("player",(ContainerIDToInventoryID(bag))); rpgoCPtooltip:SetInventoryItem("player",(ContainerIDToInventoryID(bag))) end if(baglink) then if(not rpgoCPstate["Inventory"][bag] or not rpgoCPstate["Bag"][bag]) then structInventory[bagName]=rpgoCP_ScanBagInfo(bag,baglink,texture,rpgo_TooltipScan()); local bagContentsTemp=rpgoCP_GetContainerItems("Inventory",bag,bag); if(rpgoCPstate["Inventory"][bag]["inv"] ~= 0) then structInventory[bagName]["Contents"]=bagContentsTemp; bagContentsTemp=nil; end rpgoCPstate["Bag"][bag]=1; end else structInventory[bagName]=nil; end bagNum=bag; end if(HasKey and HasKey()) then local bagname,link,texture,color,item,itemname; local bag,bagnum; bag=KEYRING_CONTAINER; bagnum=bagNum+1; bagName="Bag" .. bagnum; texture="Interface\\Buttons\\UI-Button-KeyRing"; baglink="|cffffffff|Hitem:0:0:0:0|h["..KEYRING.."]|h|r"; rpgoCPtooltip:SetText(KEYRING); rpgoCPtooltip:AddLine(format(CONTAINER_SLOTS,rpgoCP_GetContainerNumSlots(bag),KEYRING)); if(baglink) then if(not rpgoCPstate["Inventory"][bagnum] or not rpgoCPstate["Bag"][bag]) then structInventory[bagName]=rpgoCP_ScanBagInfo(bag,baglink,texture,rpgo_TooltipScan()); local bagContentsTemp=rpgoCP_GetContainerItems("Inventory",bag,bagnum); if(rpgoCPstate["Inventory"][bagnum]["inv"] ~= nil) then structInventory[bagName]["Contents"]=bagContentsTemp; bagContentsTemp=nil; end rpgoCPstate["Bag"][bag]=1; end else structInventory[bagName]=nil; end end myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Inventory"]=time(); elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Inventory"]=nil; rpgoCPstate["Inventory"]={}; end end function rpgoCP_GetBank() if(rpgoCPpref["scan"]["bank"]) then if(rpgoCPstate["BankTime"] < GetTime()-timeWait) then if(not myProfile[rpgoCPserver][rpgoCPplayer]["Bank"]) then myProfile[rpgoCPserver][rpgoCPplayer]["Bank"]={}; rpgoCPstate["Bank"]={}; end local structBank=myProfile[rpgoCPserver][rpgoCPplayer]["Bank"]; local bag,bagnum; bag=BANK_CONTAINER; bagnum=0; if(not rpgoCPstate["Bank"][bagnum] or not rpgoCPstate["Bag"][bag]) then local bagContentsTemp=rpgoCP_GetContainerItems("Bank",bag,bagnum); if(rpgoCPstate["Bank"][bagnum]["inv"] ~= 0) then structBank["Contents"]=bagContentsTemp; bagContentsTemp=nil; end rpgoCPstate["Bag"][bag]=1; end local bag,size,slot,link; for bagnum=1,GetNumBankSlots() do bag=bagnum+4; bagName="Bag" .. bagnum; baglink=GetInventoryItemLink("player",(ContainerIDToInventoryID(bag))); texture=GetInventoryItemTexture("player",(ContainerIDToInventoryID(bag))); if(baglink) then if(not rpgoCPstate["Bank"][bagnum] or not rpgoCPstate["Bag"][bag]) then rpgoCPtooltip:SetInventoryItem("player",(ContainerIDToInventoryID(bag))) structBank[bagName]=rpgoCP_ScanBagInfo(bag,baglink,texture,rpgo_TooltipScan()); local bagContentsTemp=rpgoCP_GetContainerItems("Bank",bag,bagnum); if(rpgoCPstate["Bank"][bagnum]["inv"] ~= 0) then structBank[bagName]["Contents"]=bagContentsTemp; bagContentsTemp=nil; end rpgoCPstate["Bag"][bag]=1; end else rpgoCPstate["Bank"][bagnum]=nil; structBank[bagName]=nil; end end rpgoCPstate["BankTime"]=GetTime(); myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Bank"]=time(); end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Bank"]=nil; rpgoCPstate["Bank"]={}; end end function rpgoCP_GetContainerItems(container,bagID,bagnum) local bagContents={}; local itemlink,texture; local bagInv,bagSlot; bagSlot=0; bagInv=0; rpgoCPstate[container][bagnum]={}; for slot=1,rpgoCP_GetContainerNumSlots(bagID) do itemlink=GetContainerItemLink(bagID,slot); texture,itemCount,locked,quality=GetContainerItemInfo(bagID,slot); if(itemlink) then if(bagID==BANK_CONTAINER) then rpgoCPtooltip:SetInventoryItem("player",BankButtonIDToInvSlotID(slot)); else rpgoCPtooltip:SetBagItem(bagID,slot); end bagContents[slot]=rpgoCP_ScanItemInfo(itemlink,texture,itemCount,rpgo_TooltipScan()); bagInv=bagInv+1; end bagSlot=bagSlot+1; end if(not rpgoCPstate["_bagevent"]) then rpgoCPframe:RegisterEvent("PLAYERBANKSLOTS_CHANGED"); rpgoCPframe:RegisterEvent("BAG_UPDATE"); rpgoCPstate["_bagevent"]=1; end rpgoCPstate[container][bagnum]["slot"]=bagSlot; rpgoCPstate[container][bagnum]["inv"]=bagInv; return bagContents; end function rpgoCP_GetContainerNumSlots(bagID) if(bagID == KEYRING_CONTAINER) then return GetKeyRingSize(); else return GetContainerNumSlots(bagID); end end function rpgoCP_UnitHasResSickness(unit) local index=1; if(UnitDebuff(unit,index)) then while(UnitDebuff(unit,index)) do buffTexture=UnitDebuff(unit,index); if(buffTexture == "Interface\\Icons\\Spell_Shadow_DeathScream") then return true; end index=index+1; end end return nil; end function rpgoCP_GetTradeSkill() if(rpgoCPpref["scan"]["professions"]) then local reagentsUnknown=nil; local skillLineName,skillLineRank,skillLineMaxRank=GetTradeSkillLine(); if(not skillLineName) then return; elseif ( (skillLineName=="") or (skillLineName==UNKNOWN) ) then return; end -- expand the tree so we can see all the recipes ExpandTradeSkillSubClass(0); if(not rpgoCPstate["Professions"][skillLineName]) then rpgoCPstate["Professions"][skillLineName]={}; end if ( not myProfile[rpgoCPserver][rpgoCPplayer]["Professions"] ) then myProfile[rpgoCPserver][rpgoCPplayer]["Professions"]={}; end if ( not myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Professions"] ) then myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Professions"]={}; end local structProf=myProfile[rpgoCPserver][rpgoCPplayer]["Professions"]; -- get the number of recipes and loop through each one local numTradeSkills=GetNumTradeSkills(); local skillHeader=nil; if(numTradeSkills>0 and (not rpgoCPstate["Professions"][skillLineName] or numTradeSkills~=rpgoCPstate["Professions"][skillLineName]) ) then local TradeSkillTemp=nil; if(not structProf[skillLineName]) then structProf[skillLineName]={}; elseif(structProf[skillLineName]) then TradeSkillTemp=structProf[skillLineName]; structProf[skillLineName]={}; end rpgoCPstate["Professions"][skillLineName]=0; for itemIndex=1,numTradeSkills,1 do local skillName,skillDifficulty,numAvailable,isExpanded=GetTradeSkillInfo(itemIndex); local cooldown,reagents; if(skillDifficulty=="header" and skillName~="" and isExpanded) then skillHeader=skillName; structProf[skillLineName][skillHeader]={}; rpgoCPstate["Professions"][skillLineName]=rpgoCPstate["Professions"][skillLineName]+1; elseif(skillDifficulty=="header" and not isExpanded) then skillHeader=nil; elseif(skillHeader and skillName and skillName~="" ) then local skillIcon=GetTradeSkillIcon(itemIndex); if(not skillIcon) then skillIcon=""; end local Color,_,Link,_=rpgo_GetItemInfo(GetTradeSkillItemLink(itemIndex)); structProf[skillLineName][skillHeader][skillName]={}; structProf[skillLineName][skillHeader][skillName]["Texture"]=skillIcon; structProf[skillLineName][skillHeader][skillName]["Difficulty"]=TradeSkillCode[skillDifficulty]; structProf[skillLineName][skillHeader][skillName]["Color"]=Color; structProf[skillLineName][skillHeader][skillName]["Item"]=Link; if(not MarsProfessionOrganizer_SetTradeSkillItem) then rpgoCPtooltip:SetTradeSkillItem(itemIndex); end if(GetTradeSkillCooldown(itemIndex)) then structProf[skillLineName][skillHeader][skillName]["Cooldown"]=GetTradeSkillCooldown(itemIndex); structProf[skillLineName][skillHeader][skillName]["DateUTC"]=date("!%m/%d/%y %H:%M:%S"); rpgoCPtooltip:AddLine(COOLDOWN_REMAINING.." "..SecondsToTime(structProf[skillLineName][skillHeader][skillName]["Cooldown"])); elseif(structProf[skillLineName][skillHeader][skillName]["Cooldown"]) then structProf[skillLineName][skillHeader][skillName]["Cooldown"]=nil; end structProf[skillLineName][skillHeader][skillName]["Tooltip"]=rpgo_TooltipScan(); local numReagents=GetTradeSkillNumReagents(itemIndex); if(rpgoCPpref["reagenthtml"]) then reagents=""; else reagents={}; end for reagentIndex=1,numReagents,1 do local reagentName,reagentTexture,reagentCount,playerReagentCount=GetTradeSkillReagentInfo(itemIndex,reagentIndex); if(not reagentTexture) then reagentTexture=""; end if(not reagentName) then reagentName=UNKNOWN; reagentsUnknown=1; end if(rpgoCPpref["reagenthtml"]) then if(reagentIndex==numReagents) then reagents=reagents .. reagentName .. " x" .. reagentCount; else reagents=reagents .. reagentName .. " x" .. reagentCount .. "
"; end else local _,itemID,_ = rpgo_GetItemID(GetTradeSkillReagentItemLink(itemIndex,reagentIndex)); reagents[reagentIndex]={}; reagents[reagentIndex]["Name"]=reagentName; reagents[reagentIndex]["Count"]=reagentCount; reagents[reagentIndex]["itemID"]=itemID; end end structProf[skillLineName][skillHeader][skillName]["Reagents"]=reagents; rpgoCPstate["Professions"][skillLineName]=rpgoCPstate["Professions"][skillLineName]+1; end end if(rpgoCPstate["Professions"][skillLineName]==0) then _skillError=1; structProf[skillLineName]=TradeSkillTemp; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..skillLineName..rpgo_ColorizeMsg(rpgoColorRed," not scanned, rescanning or open again")); rpgoCPtrade:Show(); elseif(reagentsUnknown) then _skillError=1 structProf[skillLineName]=TradeSkillTemp; rpgoCPstate["Professions"][skillLineName]=0; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..skillLineName..rpgo_ColorizeMsg(rpgoColorRed," reagents not scanned, rescanning or open again")); rpgoCPtrade:Show(); else if(_skillError) then rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..skillLineName.." rescanned successfully"); _skillError=nil; end rpgoCPtrade:Hide(); end TradeSkillTemp=nil; end rpgoCP_TidyProfessions(); myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Professions"][skillLineName]=time(); elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Professions"]=nil; rpgoCPstate["Professions"]={}; end end function rpgoCP_GetCraft() if(rpgoCPpref["scan"]["professions"]) then local reagentsUnknown=nil; local skillLineName,skillLineRank,skillLineMaxRank=GetCraftDisplaySkillLine(); if(not skillLineName) then return; elseif ( (skillLineName=="") or (skillLineName==UNKNOWN) ) then return; end -- get the number of recipes and loop through each one local numCrafts=GetNumCrafts(); if ( not myProfile[rpgoCPserver][rpgoCPplayer]["Professions"] ) then myProfile[rpgoCPserver][rpgoCPplayer]["Professions"]={}; end if ( not myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Professions"] ) then myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Professions"]={}; end local structProf=myProfile[rpgoCPserver][rpgoCPplayer]["Professions"]; local skillHeader=nil; if(numCrafts>0 and (not rpgoCPstate["Professions"][skillLineName] or numCrafts~=rpgoCPstate["Professions"][skillLineName]) ) then local TradeSkillTemp=nil; if(not structProf[skillLineName]) then structProf[skillLineName]={}; elseif(structProf[skillLineName]) then TradeSkillTemp=structProf[skillLineName]; structProf[skillLineName]={}; end rpgoCPstate["Professions"][skillLineName]=0; skillHeader=skillLineName; for itemIndex=1,numCrafts,1 do local skillName,craftSubSpellName,skillDifficulty,numAvailable,isExpanded=GetCraftInfo(itemIndex); if( skillDifficulty=="header" and skillName~="" ) then skillHeader=skillName; structProf[skillLineName][skillHeader]={}; rpgoCPstate["Professions"][skillLineName]=rpgoCPstate["Professions"][skillLineName]+1; elseif( skillHeader and skillName and skillName~="" ) then if(not structProf[skillLineName][skillHeader]) then structProf[skillLineName][skillHeader]={}; end local skillIcon=GetCraftIcon(itemIndex); if(not skillIcon) then skillIcon=""; end local Color,_,Link,_=rpgo_GetItemInfo(GetTradeSkillItemLink(itemIndex)); local numReagents=GetCraftNumReagents(itemIndex); local reagents=""; structProf[skillLineName][skillHeader][skillName]={}; structProf[skillLineName][skillHeader][skillName]["Texture"]=skillIcon; structProf[skillLineName][skillHeader][skillName]["Difficulty"]=TradeSkillCode[skillDifficulty]; structProf[skillLineName][skillHeader][skillName]["Color"]=Color; structProf[skillLineName][skillHeader][skillName]["Item"]=Link; structProf[skillLineName][skillHeader][skillName]["Tooltip"]=GetCraftDescription(itemIndex); if(rpgoCPpref["reagenthtml"]) then reagents=""; else reagents={}; end for reagentIndex=1,numReagents,1 do local reagentName,reagentTexture,reagentCount,playerReagentCount=GetCraftReagentInfo(itemIndex,reagentIndex); if(not reagentTexture) then reagentTexture=""; end if(not reagentName) then reagentName=UNKNOWN; reagentsUnknown=1; end if(rpgoCPpref["reagenthtml"]) then if(reagentIndex==numReagents) then reagents=reagents .. reagentName .. " x" .. reagentCount; else reagents=reagents .. reagentName .. " x" .. reagentCount .. "
"; end else local _,itemID,_ = rpgo_GetItemID(GetCraftReagentItemLink(itemIndex,reagentIndex)); reagents[reagentIndex]={}; reagents[reagentIndex]["Name"]=reagentName; reagents[reagentIndex]["Count"]=reagentCount; reagents[reagentIndex]["itemID"]=itemID; end end structProf[skillLineName][skillHeader][skillName]["Reagents"]=reagents; rpgoCPstate["Professions"][skillLineName]=rpgoCPstate["Professions"][skillLineName]+1; end end if(rpgoCPstate["Professions"][skillLineName]==0) then _skillError=1; structProf[skillLineName]=TradeSkillTemp; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..skillLineName..rpgo_ColorizeMsg(rpgoColorRed," not scanned, rescanning or open again")); rpgoCPcraft:Show(); elseif(reagentsUnknown) then _skillError=1; structProf[skillLineName]=TradeSkillTemp; rpgoCPstate["Professions"][skillLineName]=0; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..skillLineName..rpgo_ColorizeMsg(rpgoColorRed," reagents not scanned, rescanning or open again")); rpgoCPcraft:Show(); else if(_skillError) then rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": "..skillLineName.." rescanned successfully"); _skillError=nil; end rpgoCPcraft:Hide(); end TradeSkillTemp=nil; end rpgoCP_TidyProfessions(); myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Professions"][skillLineName]=time(); elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Professions"]=nil; rpgoCPstate["Professions"]={}; end end function rpgoCP_TidyProfessions() if(rpgoCPstate["_loaded"]) then for skillName,_ in myProfile[rpgoCPserver][rpgoCPplayer]["Professions"] do if(not rpgoCPstate["_skills"][skillName]) then myProfile[rpgoCPserver][rpgoCPplayer]["Professions"][skillName]=nil; end end end end function rpgoCP_GetSpellBook() if(rpgoCPpref["scan"]["spells"]) then if ( not myProfile[rpgoCPserver][rpgoCPplayer]["SpellBook"] ) then myProfile[rpgoCPserver][rpgoCPplayer]["SpellBook"]={}; end local structSpell=myProfile[rpgoCPserver][rpgoCPplayer]["SpellBook"]; for spelltab=1,GetNumSpellTabs(),1 do local spelltabname,spelltabtexture,offset,numSpells=GetSpellTabInfo(spelltab); if(not rpgoCPstate["SpellBook"][spelltabname] or rpgoCPstate["SpellBook"][spelltabname]~=numSpells) then if ( not structSpell[spelltabname] ) then structSpell[spelltabname]={}; end structSpell[spelltabname]["Texture"]=spelltabtexture; structSpell[spelltabname]["Spells"]={}; rpgoCPstate["SpellBook"][spelltabname]=0; for spellId=offset + 1,numSpells + offset,1 do spellName,spellRank=GetSpellName( spellId,BOOKTYPE_SPELL ); spellTexture=GetSpellTexture( spellId,spelltab ); if ( not structSpell[spelltabname]["Spells"][spellName] ) then structSpell[spelltabname]["Spells"][spellName]={}; end structSpell[spelltabname]["Spells"][spellName]["Rank"]=spellRank; structSpell[spelltabname]["Spells"][spellName]["Texture"]=spellTexture; rpgoCPtooltip:SetSpell(spellId,BOOKTYPE_SPELL); structSpell[spelltabname]["Spells"][spellName]["Tooltip"]=rpgo_TooltipScan(); rpgoCPstate["SpellBook"][spelltabname]=rpgoCPstate["SpellBook"][spelltabname]+1; end structSpell[spelltabname]["Count"]=numSpells; end myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["SpellBook"]=time(); end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["SpellBook"]=nil; rpgoCPstate["SpellBook"]={}; end end function rpgoCP_ScanPetInit(name) if(not myProfile[rpgoCPserver][rpgoCPplayer]["Pets"]) then myProfile[rpgoCPserver][rpgoCPplayer]["Pets"]={}; end if(not myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][name]) then myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][name]={}; end if(not myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Pets"]) then myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Pets"]={}; end end function rpgoCP_ScanPetStable() if(rpgoCPpref["scan"]["pet"] and (rpgoCPclass=="HUNTER" and UnitLevel("player")>9)) then local structPets; for petIndex=0,GetNumStableSlots(),1 do local petIcon,petName,petLevel,petType,petLoyalty=GetStablePetInfo(petIndex); if(petName) then rpgoCP_ScanPetInit(petName); structPets=myProfile[rpgoCPserver][rpgoCPplayer]["Pets"]; structPets[petName]["Slot"]=petIndex; structPets[petName]["Icon"]=petIcon; structPets[petName]["Name"]=petName; structPets[petName]["Level"]=petLevel; structPets[petName]["Type"]=petType; structPets[petName]["Loyalty"]=petLoyalty; myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Pets"][petName]=time(); end rpgoCPstate["Stable"][petIndex]=petName; end rpgoCP_ScanPetInfo(); elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Pets"]=nil; rpgoCPstate["Pets"]={}; end end function rpgoCP_ScanPetInfo() if(rpgoCPpref["scan"]["pet"]) then if(HasPetUI()) then petName=UnitName("pet"); rpgoCP_ScanPetInit(petName); local structPet=myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][petName]; structPet["Name"]=petName; structPet["Type"]=UnitCreatureFamily("pet"); structPet["TalentPoints"],structPet["TalentPointsUsed"]=GetPetTrainingPoints(); local currXP,nextXP=GetPetExperience(); structPet["Experience"]=currXP..":"..nextXP; rpgoCP_GetStats(structPet,"pet"); rpgoCP_GetBuffs(structPet,"pet"); rpgoCP_GetPetSpellBook(); rpgoCPstate["Pets"][petName]=1; myProfile[rpgoCPserver][rpgoCPplayer]["timestamp"]["Pets"][petName]=time(); end elseif(myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["Pets"]=nil; rpgoCPstate["Pets"]={}; end end function rpgoCP_GetPetSpellBook() if(rpgoCPpref["scan"]["spells"]) then numSpells,_=HasPetSpells(); petName=UnitName("pet"); if(numSpells) then rpgoCP_ScanPetInit(petName); if (not myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][petName]["SpellBook"]) then myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][petName]["SpellBook"]={}; end local structPetSpell=myProfile[rpgoCPserver][rpgoCPplayer]["Pets"][petName]["SpellBook"]; for petSpellId=1,numSpells,1 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]["Texture"]=spellTexture; structPetSpell["Count"]=petSpellId; end rpgoCPstate["PetSpell"][petName]=numSpells; end end end function rpgoCP_TradeTimer(event,arg1) local skill; if(not rpgoCPstate["ProfTimer"]) then rpgoCPstate["ProfTimer"]={}; end if(event=="CRAFT_UPDATE") then skill=GetCraftDisplaySkillLine(); elseif(event=="TRADE_SKILL_UPDATE") then skill=GetTradeSkillLine(); end if(skill) then if( (not arg1) or (not rpgoCPstate["ProfTimer"][skill]) ) then rpgoCPstate["ProfTimer"][skill]=0; elseif(tonumber(arg1)) then rpgoCPstate["ProfTimer"][skill]=rpgoCPstate["ProfTimer"][skill]+arg1; end if(rpgoCPstate["ProfTimer"][skill] > 1) then rpgoCPstate["ProfTimer"][skill]=nil; rpgoCP_EventHandler(string.gsub(event,'_UPDATE','_SHOW'),arg1); end end end function rpgoCP_UpdatePlayed(arg1,arg2) if(arg1 and arg2) then timePlayed=arg1; timeLevelPlayed=arg2; end if(rpgoCPstate["_loaded"] and myProfile[rpgoCPserver][rpgoCPplayer]) then myProfile[rpgoCPserver][rpgoCPplayer]["TimePlayed"]=timePlayed; myProfile[rpgoCPserver][rpgoCPplayer]["TimeLevelPlayed"]=timeLevelPlayed; end end function rpgoCP_UpdateZone() myProfile[rpgoCPserver][rpgoCPplayer]["Zone"]=GetZoneText(); myProfile[rpgoCPserver][rpgoCPplayer]["SubZone"]=GetSubZoneText(); end function rpgoCP_UpdateBagScan(bagID) if(bagID~=nil and rpgoCPstate["Bag"][bagID]) then local x=0; rpgoCPstate["Bag"][bagID]=nil; for i,j in rpgoCPstate["Bag"] do x=1;break; end if(x==0) then rpgoCPstate["_bagevent"]=nil; rpgoCPframe:UnregisterEvent("PLAYERBANKSLOTS_CHANGED"); rpgoCPframe:UnregisterEvent("BAG_UPDATE"); end end end function rpgoCP_UpdateEqScan(unit) if(unit=="player" and rpgoCPstate["Eq"]) then rpgoCPstate["Eq"]=nil; rpgoCPframe:UnregisterEvent("UNIT_INVENTORY_CHANGED"); end end function rpgoCP_UpdateDate() local timestamp = time(); local thisProfile=myProfile[rpgoCPserver][rpgoCPplayer]; thisProfile["timestamp"]["init"]={}; thisProfile["timestamp"]["init"]["TimeStamp"]=timestamp; thisProfile["timestamp"]["init"]["Date"]=date("%m/%d/%y %H:%M:%S",timestamp); thisProfile["timestamp"]["init"]["DateUTC"]=date("!%m/%d/%y %H:%M:%S",timestamp); --toRemove thisProfile["Date"]=thisProfile["timestamp"]["init"]["Date"]; thisProfile["DateUTC"]=thisProfile["timestamp"]["init"]["DateUTC"]; local currHour,currMinute=GetGameTime(); thisProfile["timestamp"]["init"]["ServerTime"]=format("%02d:%02d",currHour,currMinute); thisProfile["ServerTime"]=thisProfile["timestamp"]["init"]["ServerTime"] --toRemove thisProfile["DateUpdated"]=thisProfile["timestamp"]["init"]["Date"]; end if(itemlink) then _,_,c,l,i,n=string.find(itemlink,"|c(%x+)|H(item:(%d+:%d+:%d+:%d+))|h%[(.-)%]|h|r"); end function rpgoCP_GetProfileDate(server,char) local thisProfile,thisProfileDate,thisProfileEpoch; if(myProfile and myProfile[server] and myProfile[server][char]) then thisProfile=myProfile[server][char]; if(thisProfile["timestamp"] and thisProfile["timestamp"]["init"] and thisProfile["timestamp"]["init"]["TimeStamp"]) then thisProfileEpoch=thisProfile["timestamp"]["init"]["TimeStamp"]; elseif(thisProfile["timestamp"] and thisProfile["timestamp"]["init"] and thisProfile["timestamp"]["init"]["Date"]) then thisProfileEpoch=thisProfile["timestamp"]["init"]["Date"]; elseif(thisProfile["Date"]) then thisProfileDate=thisProfile["Date"]; elseif(thisProfile["DateUpdated"]) then thisProfileDate=thisProfile["DateUpdated"]; end if(thisProfileDate) then thisProfileEpoch=rpgoCP_Date2Epoch(thisProfileDate); end if(thisProfileEpoch) then return date("%Y-%m-%d",thisProfileEpoch); end end return ""; end function rpgoCP_Date2Epoch(datestr) local epoch; if(datestr) then local _,_,m,d,y,h,n,s=string.find(datestr,"(%d%d)/(%d%d)/(%d%d) (%d%d):(%d%d):(%d%d)"); y=2000+y; epoch = time( {year=y,month=m,day=d,hour=h,min=n,sec=s} ); end return epoch; end --[[////////////////////////////////////////////// -- general functions -- ////////////////////////////////////////////]] function rpgoCP_ScanItemInfo(itemlink,itemtexture,itemcount,itemtooltip) local itemColor,itemLink,itemID,itemName=rpgo_GetItemInfo(itemlink); local itemBlock={}; itemBlock["Name"]=itemName; itemBlock["Item"]=itemID; itemBlock["Color"]=itemColor; itemBlock["Quantity"]=itemcount; itemBlock["Texture"]=itemtexture; itemBlock["Tooltip"]=itemtooltip; return itemBlock; end function rpgoCP_ScanBagInfo(bagindex,baglink,bagtexture,bagtooltip) local itemColor,bagLink,itemID,itemName=rpgo_GetItemInfo(baglink); local itemName,itemLink,itemRarity,itemMinLeveL,itemType,itemSubType,itemStackCount,itemEquipLoc=GetItemInfo(bagLink); local bagBlock={}; bagBlock["Name"]=GetBagName(bagindex); bagBlock["Slots"]=rpgoCP_GetContainerNumSlots(bagindex); bagBlock["Item"]=itemID; bagBlock["Color"]=itemColor; bagBlock["Texture"]=bagtexture; bagBlock["Tooltip"]=bagtooltip; bagContainerText=itemType; return bagBlock; end --[function] msg:string function rpgoCP_debug(msg) if (rpgoCPpref and rpgoCPpref["debug"]) then if(rpgoDebug) then rpgoDebug(rpgoCP_ABBR,msg); else rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": ".."[" .. msg .. "]",1,0,0); end end end --[function] rpgoCP_myAddons function rpgoCP_myAddons() if(myAddOnsFrame_Register) then rpgoCP_debug("myAddons: init"); local rpgoAddonsInfoCP={ name=rpgoCP_TITLE, version=rpgoCP_VERSION, releaseDate=rpgoCP_DATE, author=rpgoCP_AUTHOR, email=rpgoCP_EMAIL, website=rpgoCP_URL, category=MYADDONS_CATEGORY_OTHERS, frame="rpgoCPframe", }; local rpgoAddonsUsageCP={}; if(rpgoCP_Usage) then table.insert(rpgoAddonsUsageCP,rpgoCP_PROVIDER.."-"..rpgoCP_ABBR.." Usage (slash commands)"); for index=1,table.getn(rpgoCP_Usage),1 do table.insert(rpgoAddonsUsageCP,rpgo_AssempleHelp(rpgoCP_Usage[index])); end end local rpgoAddonsHelpCP={ "CharacterProfiler is an addon that extracts character info including stats, equipment, inventory, trade skills, spellbook. This information can then be uploaded to your website to display your character info.\n\n"..table.concat(rpgoAddonsUsageCP,"\n"), }; myAddOnsFrame_Register(rpgoAddonsInfoCP,rpgoAddonsHelpCP); end end --[[// general rpgo functions: unit -- ////////////////////////////////////////////]] --[function] arg1:unit function rpgo_UnitSexString(arg1) local UnitSexLabel={UNKNOWN,MALE,FEMALE}; local unitSexID=UnitSex(arg1); return UnitSexLabel[unitSexID],mod(unitSexID,2); end --[function] rpgo_GetMoney() function rpgo_GetMoney() local money=GetMoney(); local gold,silver,copper; local CopperPerGold=COPPER_PER_SILVER * SILVER_PER_GOLD; gold=floor(money/CopperPerGold); money=mod(money,CopperPerGold); silver=floor(money/COPPER_PER_SILVER); money=mod(money,CopperPerGold); copper=mod(money,COPPER_PER_SILVER); return gold,silver,copper; end --[[// general rpgo functions: item -- ////////////////////////////////////////////]] --[function] itemlink function rpgo_GetItemID(itemlink) local item,id,rid; if(itemlink) then _,_,item,id,rid=string.find(itemlink,"item:((%d+):%d+:(%d+):%d+)|"); end return item,id,rid; end --[function] itemlink function rpgo_GetItemInfo(itemlink) local c,l,i,n; if(itemlink) then _,_,c,l,i,n=string.find(itemlink,"|c(%x+)|H(item:(%d+:%d+:%d+:%d+))|h%[(.-)%]|h|r"); end return c,l,i,n; end --[function] tooltip iteminfo function rpgo_GetItemInfoTT(tooltipName) local nTT,cTT,r,g,b; if(tooltipName==nil) then tooltipName="rpgoCPtooltip"; end ttText=getglobal(tooltipName.."TextLeft1"); nTT=ttText:GetText(); if(nTT) then r,g,b=ttText:GetTextColor(); cTT=string.format("ff%02x%02x%02x",r*256,g*256,b*256); end return nTT,cTT; end function rpgo_StripColor(str) local function strippingHelper(word) return string.gsub(word,"|c%x%x%x%x%x%x%x%x(.-)|r","%1") end if(type(str)=="table") then for i=1,table.getn(str),1 do str[i]=strippingHelper(str[i]); end else str=strippingHelper(str); end return str; end --[[// general rpgo functions: tooltip -- ////////////////////////////////////////////]] --[function] tooltipName function rpgo_TooltipScan(tooltipName) if(tooltipName==nil) then tooltipName=rpgoCP_TOOLTIP; end tooltipFrame=getglobal(tooltipName); local ttTextScan={}; for idx=1,tooltipFrame:NumLines() do local ttTextBuff=nil; ttText=getglobal(tooltipName.."TextLeft"..idx); if(ttText and ttText:IsShown()) then ttTextBuff=ttText:GetText(); if (ttText) then ttTextBuff=string.gsub(ttTextBuff,"\n","
"); ttTextBuff=string.gsub(ttTextBuff,"\r",""); end end ttText=getglobal(tooltipName.."TextRight"..idx); if(ttText and ttText:IsShown()) then if (ttText) then ttTextBuff=ttTextBuff.."\t"..ttText:GetText(); end end if(ttTextBuff) then table.insert(ttTextScan,ttTextBuff); end end tooltipFrame:ClearLines(); if(rpgoCPpref["tooltipshtml"]) then return table.concat(ttTextScan,"
"); else return ttTextScan; end end --[[////////////////////////////////////////////// -- general rpgo functions (shared) -- ////////////////////////////////////////////]] --[function] str function rpgo_Str2Ary(str) local tab={n=0}; local function S2Ahelper(word) table.insert(tab,word) end if not string.find(string.gsub(str,"%w+",S2Ahelper),"%S") then return tab end end --[function] str function rpgo_Str2Abbr(str) local abbr=''; local function S2Ahelper(word) abbr=abbr..string.sub(word,1,1) end if not string.find(string.gsub(str,"%w+",S2Ahelper),"%S") then return abbr end end --[function] arg:key1,key2,val1,val2 function rpgo_Arg2Tab(...) local tab={}; local split=floor(arg.n/2); for i=1,split,1 do tab[arg[i]]=arg[i+split]; end return tab; end --[function] arg:arg1,arg2... function rpgo_Arg2Ary(...) local tab={}; for i=1,arg.n,1 do tab[i]=arg[i]; end return tab; end --[function] function rpgo_SetTooltip() GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT"); end --[function] pref function rpgo_LiteScan(pref) if(not pref) then return false; end if(pref) then local msg; if(UnitInRaid("player")) then msg="raid"; elseif(rpgo_IsInInstance()) then msg="instance"; end if(msg) then if(not rpgoCPstate["_litemsg"]) then rpgoCPstate["_litemsg"]=true; rpgo_VerboseMsg(rpgo_ColorizeTitle(rpgoCP_PROVIDER,rpgoCP_ABBR)..": scan skipped: character is in "..msg); end return 1; end end return nil; end --[function] function rpgo_IsInInstance() SetMapToCurrentZone(); a,b=GetPlayerMapPosition("player"); if(a==0 and b==0) then return 1; else return nil; end end --[function] msg function rpgo_VerboseMsg(msg) DEFAULT_CHAT_FRAME:AddMessage(msg); end --[function] pref function rpgo_ColorizePref(pref) if(pref) then return rpgo_ColorizeMsg(rpgoColorGreen,"on|r") else return rpgo_ColorizeMsg(rpgoColorRed,"off|r") end end --[function] helpline function rpgo_AssempleHelp(helpline) local msg; if(type(helpline)=="table") then msg=" |cff"..rpgoColorTitle..helpline[1].."|r "..helpline[2]; if(helpline[3]) then msg=msg.."\n "..helpline[3]; end else msg=helpline; end return msg; end --[function] structPref,structDefault function rpgo_InitPref(structPref,structDefault) for pref,val in structDefault do if(type(structDefault[pref])=="table") then if(not structPref[pref]) then structPref[pref]={}; end rpgo_InitPref(structPref[pref],structDefault[pref]); elseif(structPref[pref] == nil) then structPref[pref]=val; end end end --[function] structPref,structDefault function rpgo_TidyPref(structPref,structDefault) for pref,val in structPref do if(type(structDefault[pref])=="table") then rpgo_TidyPref(structPref[pref],structDefault[pref]); elseif(structDefault[pref] == nil) then structPref[pref]=nil; end end end --[function] structPref function rpgoCP_ConvertPrefSub(structPref,structPrefConv) local valNew,prefNew; for pref,val in structPref do prefNew=strlower(pref); if(type(structPref[pref])=="table") then if(not structPrefConv[pref]) then structPrefConv[pref]={}; end rpgoCP_ConvertPrefSub(structPref[pref],structPrefConv[pref]); structPrefConv[prefNew]=structPrefConv[pref]; structPrefConv[pref]=nil; else if(val==1) then valNew=true; elseif(val==0) then valNew=false; end structPrefConv[prefNew]=valNew; end end end --[function] provider,title function rpgo_ColorizeTitle(provider,title) if(provider and title) then return rpgo_ColorizeMsg(rpgoColorTitle,provider.."-"..title); end end --[function] color,msg function rpgo_ColorizeMsg(color,msg) if(color and msg) then return "|cff"..color..msg.."|r"; end end