diff --git a/API Custom Displays.txt b/API Custom Displays.txt index e7d0b2fa..815fdb9e 100644 --- a/API Custom Displays.txt +++ b/API Custom Displays.txt @@ -1,25 +1,25 @@ - -A custom display is made with 4 scripts: +Cstom Display is a special display where users can set their own rules on searching for what show in the window. +There is 4 scripts which compose the display: Required: -Search - this is the main script, it's responsible to build a list of players to be show in the window. +Search - this is the main script, it's responsible to build a list of actors to show in the window. Optional: -Tooltip - it run when the user hover over a bar. +Tooltip - it runs when the user hover over a bar. Total - runs when showing the bar, and helps format the total done. Percent - also runs when showing the bar, it formats the percentage amount. Search Code: -- The script receives 3 parameters: *Combat, *Container and *Instance. +- The script receives 3 parameters: *Combat, *CustomContainer and *Instance. *Combat - is the reference for the selected combat shown in the window (the one selected on segments menu). -*Container - is the place where the display mantain stored the results, Details! get the content inside the container and use to update the window. -*Instance - is the reference of the window where the custom display is being shown. +*CustomContainer - is the place where the display mantain stored the results, Details! get the content inside the container and use to update the window. +*Instance - is the reference of the window where the custom display is shown. - Also, the script must return three values: total made by all players, the amount of the top player and the amount of players found by the script. -- The search script basicaly begins getting these three parameters and declaring our three return values: +- The search script basically begins getting these three parameters and declaring our three return values: -local combat, instance_container, instance = ... +local Combat, CustomContainer, Instance = ... local total, top, amount = 0, 0, 0 - Then, we build our search for wherever we want to show, here we are building an example for Damage Done by Pets and Guardians. @@ -43,20 +43,20 @@ if (petOwner:IsPlayer()) then local petDamage = actor.total end -- The next step is add the pet owner into the Container: +- The next step is add the pet owner into the CustomContainer: -Container:AddValue (petOwner, petDamage) +CustomContainer:AddValue (petOwner, petDamage) - And in the and, we need to get the total, top and amount values. This is generally calculated inside our loop above, but just calling the API for the result is more handy: -total, top = Container:GetTotalAndHighestValue() -amount = Container:GetNumActors() +total, top = CustomContainer:GetTotalAndHighestValue() +amount = CustomContainer:GetNumActors() return total, top, amount The finished script looks like this: -local Combat, Container, Instance = ... +local Combat, CustomContainer, Instance = ... local total, top, amount = 0, 0, 0 local damage_container = Combat:GetActorList( DETAILS_ATTRIBUTE_DAMAGE ) @@ -65,13 +65,13 @@ for i, actor in ipairs( damage_container ) do local petOwner = actor.owner if (petOwner:IsPlayer()) then local petDamage = actor.total - Container:AddValue( petOwner, petDamage ) + CustomContainer:AddValue( petOwner, petDamage ) end end end -total, top = Container:GetTotalAndHighestValue() -amount = Container:GetNumActors() +total, top = CustomContainer:GetTotalAndHighestValue() +amount = CustomContainer:GetNumActors() return total, top, amount @@ -131,4 +131,43 @@ Total Code and Percent Code: local value, top, total, combat, instance = ... local result = floor (value) -return total \ No newline at end of file +return total + + +Custom Container Object: +======================================= + +A custom container is primarily used when building custom displays. +Is used to hold values for any kind of actor in Details! and also any other table as long as it has a ".name" or ".id" key. + +value = is a number indicating the actor's score, the container doesn't know what kind of actor it is holding, if is a damage actor, energy, a spell, so, it is just nominated 'value'. + +container:GetValue ( actor ) +returns the current value for the requested actor. + +container:AddValue ( actor, amountToAdd, checkTop, nameComplement ) +actor is any actor object or any other table containing a member "name" or "id", e.g. {name = "Jeff"} {id = 186451} +amountToAdd is the amount to add to this actor on the container. +checkTop is for some special cases when the top value needs to be calculated immediately. +nameComplement is a string to add on the end of the actor's name, for instance, in cases where the actor is a spell and its name is generated by the container. +returns the current value for the actor. + +container:SetValue (actor, amount, nameComplement) +actor is any actor object or any other table containing a member "name" or "id", e.g. {name = "Jeff"} {id = 186451} +amount is the amount to set to this actor on the container. +nameComplement is a string to add on the end of the actor's name, for instance, in cases where the actor is a spell and its name is generated by the container. + +container:HasActor (actor) +return true if the container holds a reference for 'actor'. + +container:GetNumActors() +returns the amount of actors present inside the container. + +container:GetTotalAndHighestValue() +return 'total' and 'top' values. +total is the total of value of all actors together. +top is the amount of value of the actor with more value. + +container:WipeCustomActorContainer() +removes all data from a custom container. +this is automatically performed when the search script runs. \ No newline at end of file diff --git a/API.txt b/API.txt index 2f8e565e..bd30320d 100644 --- a/API.txt +++ b/API.txt @@ -3,6 +3,8 @@ It still is incomplete, we are working on. This is a diagram showing the structure: http://i.imgur.com/vyTjpFh.png + + Attributes: ======================================= All these keys are globals: @@ -40,15 +42,42 @@ DETAILS_SUBATTRIBUTE_DCOOLDOWN = 6 DETAILS_SUBATTRIBUTE_BUFFUPTIME = 7 DETAILS_SUBATTRIBUTE_DEBUFFUPTIME = 8 + + TL;DR ======================================= -A history segment container is the higher table in the hierarchy, it holds combat objects. -Current and overall combat objects are directly attached to the core. When a combat finishes, it detach and is sent to history container. -A Combat Object has 4 tables: damage on index 1, healing on index 2, energy on index 3, misc on index 4. -Those tables are called 'containers', these containers holds 'Actor Objects'. -Actor Objects hold a target table and a spell table. -Each player will have 4 tables, one for each attribute, e.g. 1 for store its damage, another for the healing done. -Actor Objects also has specific members for each attribute, see below. +Details! has three main objects: Combat, Container and Actor: + +"Combat" holds containers, when a fight is gone, the "Current Combat" is placed inside the History Segment. +"Container" holds Actors. +"Actor" has members telling what the player or npc has made in the combat. + +"Combat" has 4 indexes: [1] holds the Damage Container [2] Healing [3] Energy [4] Misc. +These indexes are called "Attributes" + +"Actor" has different data depending on which container the actor are, for instance, if is a Damage Actor, it will have members like damage_taken, friendly fire, +if is a Healing Actor, it will have members for overheal, absorbs etc. +Actors also have tables for spells and targets. +An Actor only is created inside a container when it performs an action which fits the container, for instance, if the player didn't restored any energy/mana/rage, etc, +it won't have an actor inside the Energy Container. + +"History Segment" is a table, it holds combat objects of previous combats. + +========== +| COMBAT | = { [1] = {DAMAGE CONTAINER}, [2] = {HEAL CONTAINER}, [3] = {ENERGY CONTAINER}, [4] = {MISC CONTAINER} } +========== + +============ +| CONTAINER | = { ACTORS } +============ + +========== +| ACTOR | = {attribute_keys, spells = {}, targets = {}} +========== +attribute keys are the members which holds all the totals made by the actor (see more below). +spells = {spellid = {SPELL}} targets = {["targetname"] = amount} + + Getting Details! Object: ======================================= @@ -56,35 +85,54 @@ Just get the global 'Details', for instance: local details = _G.Details + +Important Functions: +======================================= +Details:Format (number, formatString) +if formatString is nil, Format uses current format chosen on details options panel. + +Details:GetActorsOnDamageCache() +only usable while in combat, it returns a numeric table with all damage actors in the group (combatlog flag matching 0x00000007). +this table can be freely sorted. + +Details:GetActorsOnHealingCache() +only usable while in combat, it returns a numeric table with all healing actors in the group (combatlog flag matching 0x00000007). +this table can be freely sorted. + +*For out of combat, energy and misc containers or get all actors even pets, enemies etc, you may use Container:SortByKey(key) and Container:ListActors(). + + + Getting a Combat Object: ======================================= - combat = Details:GetCurrentCombat() returns the current combat object. combat = Details:GetCombat (combat) returns the requested combat object. if 'combat' is omitted, returns the current combat. -combat can be a number: -1 for overall, 0 for current and > 0 for past segments. +combat can be a number: -1 for overall, 0 for current and > 0 for past segments (1, 2, 3, ...). combat also can be a string "overall" or "current". history_segment_container = Details:GetCombatSegments() returns the numeric table containing all past segments. + + Gettings an Actor: ======================================= - -local actor = Details:GetActor (combat = "current", attribute = 1, actorname = playername) +local actor = Details:GetActor (combat = "current", attribute = DETAILS_ATTRIBUTE_DAMAGE, actorname = Details.playername) returns the actor for the requested combat, attribute and actor name. -if all parameters are omitted, returns the damage actor object of the player for the current combat. +if some parameter are omitted, it uses the default value which are current combat, damage container and the name of the player character. + + Combat Object: ======================================= - A Combat object is a table with 4 numerical indexes holding: damage, healing, energy and misc containers. function for combat objects: -actor = combat ( attribute, character_name ) +actor = combat:GetActor ( attribute, character_name ) or actor = combat ( attribute, character_name ) returns an actor object characterList = combat:GetActorList ( attribute ) @@ -129,6 +177,9 @@ returns the unique ID number for the combat. container = combat:GetContainer ( attribute ) returns the container table for the requested attribute. +roster = combat:GetRoster() +returns a hash table with player names preset in the raid group at the start of the combat. + chartData = combat:GetTimeData ( chart_data_name ) returns the table containing the data for create a chart. @@ -165,57 +216,90 @@ returns all the four actor objects for the requested combat and actor. combat must be a combat object. + Container Object: ======================================= A container is used to store actors, each combat have four containers, one for each attribute. +There is spell containers which holds the spells used by actors, spell containers are more limited and have only few functions. + +ipairs() = container:ListActors() +returns a iterated table of actors inside the container. +Usage: 'for index, actor in container:ListActors() do' +Note: if the container is a spell container, returns pairs() instead: 'for spellid, spelltable in container:ListActors() do' + +actor = container:GetActor (character_name) +returns the actor, for spell container use the spellid instead. + +container:GetSpell (spellid) +unique for spell container. +e.g. actor.spells:GetSpell (spellid) +return the spelltable for the requested spellid. amount = container:GetAmount (actorName [, key = "total"]) -returns the amount of the requested member key, is key is not passed, "total" is used. +returns the amount of the requested member key, if key is not passed, "total" is used. + +container:SortByKey (keyname) +sort the actor container placing in descending order actors with bigger amounts on their 'keyname'. +*only works for actor container + +sourceName = container:GetSpellSource (spellid) +return the name of the first actor found inside the container which used a spell with the desired spellid. +note: this is important for multi-language auras/displays where you doesn't want to hardcode the npc name. +*only works for actor container total = container:GetTotal (key = "total") returns the total amount of all actors inside the container, if key is omitted, "total" is used. +*only works for actor container total = container:GetTotalOnRaid (key = "total", combat) similar to GetTotal, but only counts the total of raid members. - -ipairs_list = container:ListActors() -returns a iterated table of actors inside the container. -Usage: 'for index, actor in container:ListActors() do' +combat is the combat object owner of this container. +*only works for actor container Actor Object: ======================================= Holds keys, spells and targets of a character. +Actor can be anything, player, npc, pet, boss, enemy, etc. name = actor:name() returns the actor's name. +class = actor:class() +returns the actor class. + +guid = actor:guid() +returns the GUID for this actor. + +flag = actor:flag() +returns the combatlog flag for the actor. + displayName = actor:GetDisplayName() returns the name shown on the player bar, can suffer modifications from realm name removed, nicknames, etc. name = actor:GetOnlyName() returns only the actor name, remove realm or owner names. -class = actor:class() -returns the actor class. - activity = actor:Tempo() returns the activity time for the actor. -isGroupMember = actor:IsGroupPlayer() -return true if the actor is a player and member of the raid group. - isPlayer = actor:IsPlayer() return true if the actor is a player. +isGroupMember = actor:IsGroupPlayer() +return true if the actor is a player and member of the raid group. + IsneutralOrEnemy = actor:IsNeutralOrEnemy() return true if the actor is a neutral of an enemy. isEnemy = actor:IsEnemy() return true if the actor is a enemy. +isPet = actor:IsPetOrGuardian() +return true if the actor is a pet or guardian + list = actor:GetSpellList() returns a hash table with spellid, spelltable. @@ -231,6 +315,15 @@ returns the class color. texture, left, right, top, bottom = actor:GetClassIcon() returns the icon texture path and the texture's texcoords. + + +Spell and Target Tables: +======================================= +Target and Spells are simple tables and has different member names and keys for each attribute. +See below how each one is named on each attribute. + + + Keys for Damage Actors: ======================================= @@ -243,16 +336,49 @@ actor.start_time = time when this actor started to apply damage. actor.end_time = time when the actor stopped with damage. actor.friendlyfire_total = amount of friendlyfire. -containers: +tables: actor.targets = hash table of targets: {[targetName] = amount}. actor.damage_from = hash table of actors which applied damage to this actor: {[aggresorName] = true}. actor.pets = numeric table of GUIDs of pets summoned by this actor. actor.friendlyfire = hash table of friendly fire targets: {[targetName] = table {total = 0, spells = hash table: {[spellId] = amount}}} -actor.spells = hash table with spells used to apply damage: {[spellId] = spellTable}. +actor.spells = spell container. + +spell: +spell.total = total of damage by this spell. +spell.counter = how many hits this spell made. +spell.id = spellid + +spell.successful_casted = how many times this spell has been casted successfully (only for enemies). + - players has its own spell cast counter inside Misc Container with the member "spell_cast". + - the reason os this is spell_cast holds all spells regardless of its attribute (can hold healing/damage/energy/misc). + +spell.m_amt = multistrike hits. +spell.m_dmg = multistrike damage. +spell.m_crit = multistrike critical hits. +spell.n_min = minimal damage made on a normal hit. +spell.n_max = max damage made on a normal hit. +spell.n_amt = amount of normal hits. +spell.n_dmg = total amount made doing only normal hits. +spell.c_min = minimal damage made on a critical hit. +spell.c_max = max damage made on a critical hit. +spell.c_amt = how many times this spell got a critical hit (doesn't count critical by multistrike). +spell.c_dmg = total amount made doing only normal hits. +spell.g_amt = how many glancing blows this spell has. +spell.g_dmg = total damage made by glancing blows. +spell.r_amt = total of times this spell got resisted by the target. +spell.r_dmg = amount of damage made when it got resisted. +spell.b_amt = amount of times this spell got blocked by the enemy. +spell.b_dmg = damage made when the spell got blocked. +spell.a_amt = amount of times this spell got absorbed. +spell.a_dmg = total damage while absorbed. + +spell.targets = hash table containing {["targetname"] = total damage done by this spell on this target} Getting Dps: -For activity time: actor.total / actor:Tempo() -For effective time: actor.total / combat:GetCombatTime() +For activity time: DPS = actor.total / actor:Tempo() +For effective time: DPS = actor.total / combat:GetCombatTime() + + Keys for Healing Actors: ======================================= @@ -269,8 +395,8 @@ actor.last_event = when the last event for this actor occured. actor.start_time = time when this actor started to apply heals. actor.end_time = time when the actor stopped with healing. -containers: -actor.spells = hash table with spells used to apply heals: {[spellId] = spellTable}. +tables: +actor.spells = spell container. actor.targets = hash table of targets: {[targetName] = amount}. actor.targets_overheal = hash table of overhealed targets: {[targetName] = amount}. actor.targets_absorbs = hash table of shield absorbs: {[targetName] = amount}. @@ -278,6 +404,36 @@ actor.healing_from = hash table of actors which applied healing to this actor: { actor.pets = numeric table of GUIDs of pets summoned by this actor. actor.heal_enemy = spells used to heal the enemy: {[spellid] = amount healed} +spell: +spell.total = total healing made by this spell. +spell.counter = how many times this spell healed something. +spell.id = spellid. + +spell.totalabsorb = only for shields, tells how much damage this spell prevented. +spell.absorbed = is how many healing has been absorbed by some external mechanic like Befouled on Fel Lord Zakuun encounter. +spell.overheal = amount of overheal made by this spell. +spell.m_amt = multistrike hits. +spell.m_healed = multistrike healed. +spell.m_crit = multistrike critical hits. +spell.n_min = minimal heal made on a normal hit. +spell.n_max = max heal made on a normal hit. +spell.n_amt = amount of normal hits. +spell.n_curado = total amount made doing only normal hits (weird name I know). +spell.c_min = minimal heal made on a critical hit. +spell.c_max = max heal made on a critical hit. +spell.c_amt = how many times this spell got a critical hit (doesn't count critical by multistrike). +spell.c_curado = total amount made doing only normal hits. + +spell.targets = hash table containing {["targetname"] = total healing done by this spell on this target} +spell.targets_overheal = hash table containing {["targetname"] = total overhealing by this spell on this target} +spell.targets_absorbs = hash table containing {["targetname"] = total absorbs by shields (damage prevented) done by this spell on this target} + +Getting Hps: +For activity time: HPS = actor.total / actor:Tempo() +For effective time: HPS = actor.total / combat:GetCombatTime() + + + Keys for Energy Actors: ======================================= @@ -288,55 +444,300 @@ actor.resource_type = type of the resource used by the actor. actor.pets = numeric table of GUIDs of pets summoned by this actor. actor.targets = hash table of targets: {[targetName] = amount}. -actor.spells = hash table with spells used to generate energy: {[spellId] = spellTable}. +actor.spells = spell container. + +spell: +total = total energy restored by this spell. +counter = how many times this spell restored energy. +id = spellid + +targets = hash table containing {["targetname"] = total energy produced towards this target} + + Keys for Misc Actors: ======================================= -these members and container may not be present on all actors, depends if the actor performed the action. +these members and tables may not be present on all actors, depends what the actor performs during the combat, these tables are created on the fly by the parser. -cc_done = amount of crowd control done. -cc_done_targets = cc done targets {[targetName] = amount}. -cc_done_spells = spells used to make the cc. +- Crowd Control Done: +actor.cc_done = amount of crowd control done. +actor.cc_done_targets = hash table with target names and amount {[targetName] = amount}. +actor.cc_done_spells = spell container. -interrupt = amount of interrupts. -interrupt_targets = target which was its spell interrupted {[targetName] = amount}. -interrupt_spells = spells used to interrupt. -interrompeu_oque = spells interrupted. +spell: +spell.counter = amount of times this spell has been used to perform a crowd control. +spell.targets = hash table containing {["targetname"] = total of times this spell made a CC on this target} -buff_uptime = seconds of all buff uptime. -buff_uptime_targets = -buff_uptime_spells = -debuff_uptime = -debuff_uptime_targets = {[targetName] = amount}. -debuff_uptime_spells = +- Interrupts: +actor.interrupt = total amount of interrupts. +actor.interrupt_targets = hash table with target names and amount {[targetName] = amount}. +actor.interrupt_spells = spell container. +actor.interrompeu_oque = hash table which tells what this actor interrupted {[spell interrupted spellid] = amount} -cooldowns_defensive = amount of defensive cooldowns used. -cooldowns_defensive_targets = in which player the cooldown was used. -cooldowns_defensive_spells = spells used. +spell: +spell.counter = amount of interrupts performed by this spell. +spell.interrompeu_oque = hash table talling what this spell interrupted {[spell interrupted spellid] = amount} +spell.targets = hash table containing {["castername"] = total of times this spell interrupted something from this caster} -ress = amount of resses. -ress_targets = {[targetName] = amount}. -ress_spells = -dispell = amount of dispells done. -dispell_targets = {[targetName] = amount}. -dispell_spells = -dispell_oque = +- Aura Uptime: +actor.buff_uptime = seconds of all buffs uptime. +actor.buff_uptime_spells = spell container. +actor.debuff_uptime = seconds of all debuffs uptime. +actor.debuff_uptime_spells = spell container. + +spell: +spell.id = spellid +spell.uptime = uptime amount in seconds. + + +- Cooldowns: +actor.cooldowns_defensive = amount of defensive cooldowns used by this actor. +actor.cooldowns_defensive_targets = in which player the cooldown was been used {[targetName] = amount}. +actor.cooldowns_defensive_spells = spell container. + +spell: +spell.id = spellid +spell.counter = how many times the player used this cooldown. +spell.targets = hash table with {["targetname"] = amount} + + +- Ress +actor.ress = amount of ress performed by this actor. +actor.ress_targets = which actors got ressed by this actor {["targetname"] = amount} +actor.ress_spells = spell container. + +spell: +spell.ress = amount of resses made by this spell. +spell.targets = hash table containing player names resurrected by this spell {["playername"] = amount} + + +- Dispel (members has 2 "L" instead of 1) +actor.dispell = amount of dispels done. +actor.dispell_targets = hash table telling who got dispel from this actor {[targetName] = amount}. +actor.dispell_spells = spell container. +actor.dispell_oque = hash table with the ids of the spells dispelled by this actor {[spellid of the spell dispelled] = amount} + +spell: +spell.dispell = amount of dispels by this spell. +spell.dispell_oque = hash table with {[spellid of the spell dispelled]} = amount +spell.targets = hash table with target names dispelled {["targetname"] = amount} + + +- CC Break +actor.cc_break = amount of times the actor broke a crowd control. +actor.cc_break_targets = hash table containing who this actor broke the CC {[targetName] = amount}. +actor.cc_break_spells = spell container. +actor.cc_break_oque = hash table with spells broken {[CC spell id] = amount} + +spell: +spell.cc_break = amount of CC broken by this spell. +spell.cc_break_oque = hash table with {[CC spellid] = amount} +spell.targets = hash table with {["targetname"] = amount}. -cc_break = -cc_break_targets = {[targetName] = amount}. -cc_break_spells = -cc_break_oque = Other API Calls: ======================================= +Details:GetSourceFromNpcId (npcId) +return the npc name for the specific npcId. +this is a expensive function, once you get a valid result, store the npc name somewhere. + +bestResult, encounterTable = Details.storage:GetBestFromPlayer (encounterDiff, encounterId, playerRole, playerName) +query the storage for the best result of the player on the encounter. +encounterDiff = raid difficult ID (15 for heroic, 16 for mythic). +encounterId = may be found on "id" member getting combat:GetBossInfo(). +playerRole = "DAMAGER" or "HEALER", tanks are considered "DAMAGER". +playerName = name of the player to query (with server name if the player is from another realm). +bestResult = integer, best damage or healing done on the boss made by the player. +encounterTable = {["date"] = formated time() ["time"] = time() ["elapsed"] = combat time ["guild"] = guild name ["damage"] = all damage players ["healing"] = all healers} + +heal_or_damage_done = Details.storage:GetPlayerData (encounterDiff, encounterId, playerName) +query the storage for previous ecounter data for the player. +returns a numeric table with the damage or healing done by the player on all encounters found. +encounterDiff = raid difficult ID (15 for heroic, 16 for mythic). +encounterId = may be found on "id" member getting combat:GetBossInfo(). +playerName = name of the player to query (with server name if the player is from another realm). + +itemLevel = Details.ilevel:GetIlvl (guid) +returns a table with {name = "actor name", ilvl = itemLevel, time = time() when the item level was gotten}. +return NIL if no data for the player is avaliable yet. + +talentsTable = Details:GetTalents (guid) +if available, returns a table with 7 indexes with the talentId selected for each tree {talentId, talentId, talentId, talentId, talentId, talentId, talentId}. +use with GetTalentInfoByID() + +spec = Details:GetSpec (guid) +if available, return the spec id of the actor, use with GetSpecializationInfoByID() + Details:SetDeathLogLimit (limit) Set the amount of lines to store on death log. +npcId = Details:GetNpcIdFromGuid (guid) +Extract the npcId from the actor guid. +Examples: +======================================= --- + +1) Get the player damage, heal, dps and hps: + +local combat = Details:GetCurrentCombat() +local damageActor = combat:GetActor (DETAILS_ATTRIBUTE_DAMAGE, UnitName ("player")) +local healingActor = combat:GetActor (DETAILS_ATTRIBUTE_HEAL, UnitName ("player")) +or +local damageActor = Details:GetActor ("current", DETAILS_ATTRIBUTE_DAMAGE, Details.playername) +local healingActor = Details:GetActor ("current", DETAILS_ATTRIBUTE_HEAL, Details.playername) + +local totalDamage, totalHeal = damageActor.total, healingActor.total + +local effectiveDps, effectiveHps = totalDamage / combat:GetCombatTime(), totalHeal / combat:GetCombatTime() +local activeDps, activeHps = totalDamage / damageActor:Tempo(), totalHeal / healingActor:Tempo() + + +2) Get a list of all overhealing: + +-- get the combat, here we want the current combat: +local combat = Details:GetCurrentCombat() + +-- as we want all players, we get here the container which stores all healing actors: +local healingContainer = combat:GetContainer (DETAILS_ATTRIBUTE_HEAL) + +-- sort the container with the key "totalover" - we got this key from "Keys for Healing Actors": +healingContainer:SortByKey ("totalover") + +-- now just iterate among the actors: +local actorsFound = 0 +for i, actor in healingContainer:ListActors() do + + -- inside the container has all entities which made any heal during the combat, here we check if the actor is a player for our group. + if (actor:IsGroupPlayer()) then + actorsFound = actorsFound + 1 + end +end + + +3) Damage done to an add called "Grand Corruptor U'rogg": + +local combat = Details:GetCurrentCombat() +local damageContainer = combat:GetContainer (DETAILS_ATTRIBUTE_DAMAGE) +local targetName = "Grand Corruptor U'rogg" + +there is two ways for do this: + +1 - with an external table: + + local actorsAmount = {} + for i, actor in damageContainer:ListActors() do + local amount = actor.targets [targetName] + if (amount and amount >= 1) then + tinsert (actorsAmount, {name = actor:name(), total = amount}) + end + end + + table.sort (actorsAmount, function (a,b) return a.total > b.total end) + +2 - replacing the member "custom" on the actor: + + for i, actor in damageContainer:ListActors() do + if (actor:IsGroupPlayer()) then + local amount = actor.targets [targetName] + if (amount and amount >= 1) then + actor.custom = amount + else + actor.custom = 0 + end + else + actor.custom = 0 + end + end + + damageContainer:SortByKey ("custom") + + local actorsDamagedTheTarget = 0 + for i, actor in damageContainer:ListActors() do + actorsDamagedTheTarget = actorsDamagedTheTarget + 1 + end + + +4) Get everyone who took damage from an ability: + +local combat = Details:GetCurrentCombat() +local damageContainer = combat:GetContainer (DETAILS_ATTRIBUTE_DAMAGE) + +local targetSpell = 183449 --Felfire Volley from hellfire assault encounter +local sourceNpc = "Gorebound Felcaster" +--in cases of multi-language auras or displays, we doesn't want to hardcode the npc name. +sourceNpc = damageContainer:GetSpellSource (targetSpell) + +--reset the custom member on all actors: +for i, actor in damageContainer:ListActors() do + actor.custom = 0 +end + +local source = damageContainer:GetActor (sourceNpc) +local felfireVolleySpell = source:GetSpell (targetSpell) +if (felfireVolleySpell) then + for playerName, amount in pairs (felfireVolleySpell.targets) do + --players who took damage from this ability + --now this result may be placed on a external table or .custom may also be used + local targetActor = damageContainer:GetActor (playerName) + targetActor.custom = amount + end +end + +damageContainer:SortByKey ("custom") + + +5) Get damage taken by an enemy + +local combat = Details:GetCurrentCombat() +local damageContainer = combat:GetContainer (DETAILS_ATTRIBUTE_DAMAGE) + +--get the npc name for multi-language auras or displays. +local npcName = Details:GetSourceFromNpcId (90409) -- "Gorebound Felcaster" +if (not npcName) then + npcName = Details:GetSourceFromNpcId (93931) -- "Gorebound Felcaster" +end +--once we get a valid npcName, we need to cache the name since GetSourceFromNpcId is an expensive call. +aura_env.npcName = npcName -- for weakauras +Details.cache_npc_ids [93931] = npcName --for details! +Details.cache_npc_ids [90409] = npcName --for details! + +-- here, there is two ways: + +1 - iterage among all actor and get their .targets [npcName]. + + for i, actor in damageContainer:ListActors() do + local amount = actor.targets [npcName] + if (amount and amount >= 1) then + player.custom = amount + else + player.custom = 0 + end + end + + damageContainer:SortByKey ("custom") + + +2 - get the npc actor and its damage_from table. + + local actor = damageContainer:GetActor (npcName) + if (actor) then + --reset the custom member on all actors: + for i, actor in damageContainer:ListActors() do + actor.custom = 0 + end + for playerName, _ in pairs (actor.damage_from) do + local player = damageContainer:GetActor (playerName) + if (player:IsPlayer()) then --we only want players. pets always has their damage merged on its owner damage. + player.custom = actor.targets [npcName] + end + end + + damageContainer:SortByKey ("custom") + end diff --git a/boot.lua b/boot.lua index 5d04a62f..45db0cac 100644 --- a/boot.lua +++ b/boot.lua @@ -3,8 +3,8 @@ _ = nil _detalhes = LibStub("AceAddon-3.0"):NewAddon("_detalhes", "AceTimer-3.0", "AceComm-3.0", "AceSerializer-3.0", "NickTag-1.0") - _detalhes.build_counter = 2005 --it's 2005 for release - _detalhes.userversion = "v4.0.3a" + _detalhes.build_counter = 2009 --it's 2009 for release + _detalhes.userversion = "v4.0.4" _detalhes.realversion = 75 --core version _detalhes.version = _detalhes.userversion .. " (core " .. _detalhes.realversion .. ")" Details = _detalhes @@ -22,7 +22,8 @@ do --[[ |cFFFFFF00v4.0.3a (|cFFFFCC00Set 29, 2015|r|cFFFFFF00)|r:\n\n -|cFFFFFF00-|r Fix for an error on Damage Taken By Spell display.\n\n +|cFFFFFF00-|r Added slash command '/details api'.\n\n +|cFFFFFF00-|r Major update on our .txt about the API, these files are on the root folder of details! at WoW/Interface/AddOns/Details.\n\n --]] -- @@ -79,6 +80,7 @@ do --> cache de grupo _detalhes.cache_damage_group = {} _detalhes.cache_healing_group = {} + _detalhes.cache_npc_ids = {} --> cache de specs _detalhes.cached_specs = {} _detalhes.cached_talents = {} diff --git a/classes/classe_combate.lua b/classes/classe_combate.lua index 1047ba3d..8354ef4e 100644 --- a/classes/classe_combate.lua +++ b/classes/classe_combate.lua @@ -62,6 +62,10 @@ return self [attribute] end + function combate:GetRoster() + return self.raid_roster + end + function combate:InstanceType() return _rawget (self, "instance_type") end @@ -118,6 +122,14 @@ return self [container]._ActorTable end + function combate:GetActor (container, name) + local index = self [container] and self [container]._NameIndexTable [name] + if (index) then + return self [container]._ActorTable [index] + end + return nil + end + --return the combat time in seconds function combate:GetFormatedCombatTime() local time = self:GetCombatTime() diff --git a/classes/classe_custom.lua b/classes/classe_custom.lua index 8f8b1058..ff38b34e 100644 --- a/classes/classe_custom.lua +++ b/classes/classe_custom.lua @@ -789,7 +789,9 @@ spellname = "" end actor.nome = spellname + actor.name = spellname actor.classe = actor.spellschool + actor.class = actor.spellschool class = actor.spellschool local index = self._NameIndexTable [actor.nome] @@ -799,6 +801,9 @@ else class = actor.classe or actor.class + if (not class or class == "UNKNOWN") then + class = "UNKNOW" + end if (class == "UNKNOW") then --> try once again class = _detalhes:GetClass (actor.nome or actor.name) diff --git a/classes/container_combatentes.lua b/classes/container_combatentes.lua index 67f9f02f..6c9a1d3f 100644 --- a/classes/container_combatentes.lua +++ b/classes/container_combatentes.lua @@ -60,6 +60,23 @@ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --> api functions + function container_combatentes:GetActor (actorName) + local index = self._NameIndexTable [actorName] + if (index) then + return self._ActorTable [index] + end + end + + function container_combatentes:GetSpellSource (spellid) + local t = self._ActorTable + print ("getting the source", spellid, #t) + for i = 1, #t do + if (t[i].spells._ActorTable [spellid]) then + return t[i].nome + end + end + end + function container_combatentes:GetAmount (actorName, key) key = key or "total" local index = self._NameIndexTable [actorName] @@ -514,6 +531,18 @@ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --> core + + --_detalhes:AddToNpcIdCache (novo_objeto) + function _detalhes:AddToNpcIdCache (actor) + if (flag and serial) then + if (_bit_band (flag, REACTION_HOSTILE) ~= 0 and _bit_band (flag, OBJECT_TYPE_NPC) ~= 0 and _bit_band (flag, OBJECT_TYPE_PETGUARDIAN) == 0) then + local npc_id = _detalhes:GetNpcIdFromGuid (serial) + if (npc_id) then + _detalhes.cache_npc_ids [npc_id] = nome + end + end + end + end function _detalhes:UpdateContainerCombatentes() container_pets = _detalhes.tabela_pets.pets @@ -563,10 +592,11 @@ local bykey local sort = function (t1, t2) - return t1 [bykey] > t2 [bykey] + return (t1 [bykey] or 0) > (t2 [bykey] or 0) end function container_combatentes:SortByKey (key) + assert (type (key) == "string", "Container:SortByKey() expects a keyname on parameter 1.") bykey = key _table_sort (self._ActorTable, sort) self:remapear() diff --git a/classes/container_habilidades.lua b/classes/container_habilidades.lua index 44521cd0..5477cc6d 100644 --- a/classes/container_habilidades.lua +++ b/classes/container_habilidades.lua @@ -47,6 +47,17 @@ local _ function container_habilidades:GetSpell (id) return self._ActorTable [id] end + + function container_habilidades:GetAmount (id, key) + local spell = self._ActorTable [id] + if (spell) then + return spell [key] + end + end + + function container_habilidades:ListActors() + return _pairs (self._ActorTable) + end function container_habilidades:PegaHabilidade (id, criar, token, cria_shadow) diff --git a/core/gears.lua b/core/gears.lua index 331f48f8..99796aa0 100644 --- a/core/gears.lua +++ b/core/gears.lua @@ -1452,4 +1452,12 @@ function _detalhes.ilevel:GetInOrder() table.sort (order, _detalhes.Sort2) return order +end + +function _detalhes:GetTalents (guid) + return _detalhes.cached_talents [guid] +end + +function _detalhes:GetSpec (guid) + return _detalhes.cached_specs [guid] end \ No newline at end of file diff --git a/core/util.lua b/core/util.lua index a74ea715..9e8fb755 100644 --- a/core/util.lua +++ b/core/util.lua @@ -50,6 +50,19 @@ end return 0 end + + function _detalhes:GetSourceFromNpcId (npcId) + for index, container in ipairs (_detalhes.tabela_vigente) do + if (index <= 4) then + local t = container._ActorTable + for i = 1, #t do + if (_detalhes:GetNpcIdFromGuid (t[i].serial) == npcId) then + return t[i].nome + end + end + end + end + end --> get the fractional number representing the alphabetical letter function _detalhes:GetOrderNumber (who_name) @@ -155,6 +168,21 @@ return _detalhes.ToKFunctions [_detalhes.ps_abbreviation] end + function _detalhes:Format (n, custom) + n = _math_floor (n) + if (custom) then + if (n > 999999) then + return _string_format (custom, n/1000000) .. "M" + elseif (n > 999) then + return _string_format (custom, (n/1000)) + else + return n + end + else + return _detalhes.ToKFunctions [_detalhes.ps_abbreviation] (nil, n) + end + end + _detalhes.ToKFunctions = {_detalhes.NoToK, _detalhes.ToK, _detalhes.ToK2, _detalhes.ToK0, _detalhes.ToKMin, _detalhes.ToK2Min, _detalhes.ToK0Min, _detalhes.comma_value} _detalhes.string = {} diff --git a/core/windows.lua b/core/windows.lua index fcfb8649..d807488c 100644 --- a/core/windows.lua +++ b/core/windows.lua @@ -3179,6 +3179,619 @@ end + + -- ~API + + function _detalhes.OpenAPI() + if (not DetailsAPIPanel) then + + local topics_text = { +[[ +Attribute Indexes: +DETAILS_ATTRIBUTE_DAMAGE = 1 +DETAILS_ATTRIBUTE_HEAL = 2 +DETAILS_ATTRIBUTE_ENERGY = 3 +DETAILS_ATTRIBUTE_MISC = 4 +]], +[[ +Combat Object: +actor = combat:GetActor ( attribute, character_name ) or actor = combat ( attribute, character_name ) +returns an actor object + +characterList = combat:GetActorList ( attribute ) +returns a numeric table with all actors of the specific attribute, contains players, npcs, pets, etc. + +combatName = combat:GetCombatName ( try_to_find ) +returns the segment name, e.g. "Trainning Dummy", if try_to_find is true, it searches the combat for a enemy name. + +bossInfo = combat:GetBossInfo() +returns the table containing informations about the boss encounter. +table members: name, zone, mapid, diff, diff_string, id, ej_instance_id, killed, index + +battlegroudInfo = combat:GetPvPInfo() +returns the table containing infos about the battlegroud: +table members: name, mapid + +arenaInfo = combat:GetArenaInfo() +returns the table containing infos about the arena: +table members: name, mapid, zone + +time = combat:GetCombatTime() +returns the length of the combat in seconds, if the combat is in progress, returns the current elapsed time. + +minutes, seconds = GetFormatedCombatTime() +returns the combat time formated with minutes and seconds. + +startDate, endDate = combat:GetDate() +returns the start and end date as %H:%M:%S. + +isTrash = combat:IsTrash() +returns true if the combat is a trash segment. + +encounterDiff = combat:GetDifficulty() +returns the difficulty number of the raid encounter. + +deaths = combat:GetDeaths() +returns a numeric table containing the deaths, table is ordered by first death to last death. + +combatNumber = combat:GetCombatNumber() +returns the unique ID number for the combat. + +container = combat:GetContainer ( attribute ) +returns the container table for the requested attribute. + +roster = combat:GetRoster() +returns a hash table with player names preset in the raid group at the start of the combat. + +chartData = combat:GetTimeData ( chart_data_name ) +returns the table containing the data for create a chart. + +start_at = GetStartTime() +returns the GetTime() of when the combat started. + +ended_at = GetEndTime() +returns the GetTime() of when the combat ended. + +DETAILS_TOTALS_ONLYGROUP = true + +total = combat:GetTotal ( attribute, subAttribute [, onlyGroup] ) +returns the total of the requested attribute. +]], +[[ +ipairs() = container:ListActors() +returns a iterated table of actors inside the container. +Usage: 'for index, actor in container:ListActors() do' +Note: if the container is a spell container, returns pairs() instead: 'for spellid, spelltable in container:ListActors() do' + +actor = container:GetActor (character_name) +returns the actor, for spell container use the spellid instead. + +container:GetSpell (spellid) +unique for spell container. +e.g. actor.spells:GetSpell (spellid) +return the spelltable for the requested spellid. + +amount = container:GetAmount (actorName [, key = "total"]) +returns the amount of the requested member key, if key is not passed, "total" is used. + +container:SortByKey (keyname) +sort the actor container placing in descending order actors with bigger amounts on their 'keyname'. +*only works for actor container + +sourceName = container:GetSpellSource (spellid) +return the name of the first actor found inside the container which used a spell with the desired spellid. +note: this is important for multi-language auras/displays where you doesn't want to hardcode the npc name. +*only works for actor container + +total = container:GetTotal (key = "total") +returns the total amount of all actors inside the container, if key is omitted, "total" is used. +*only works for actor container + +total = container:GetTotalOnRaid (key = "total", combat) +similar to GetTotal, but only counts the total of raid members. +combat is the combat object owner of this container. +*only works for actor container +]], +[[ +name = actor:name() +returns the actor's name. + +class = actor:class() +returns the actor class. + +guid = actor:guid() +returns the GUID for this actor. + +flag = actor:flag() +returns the combatlog flag for the actor. + +displayName = actor:GetDisplayName() +returns the name shown on the player bar, can suffer modifications from realm name removed, nicknames, etc. + +name = actor:GetOnlyName() +returns only the actor name, remove realm or owner names. + +activity = actor:Tempo() +returns the activity time for the actor. + +isPlayer = actor:IsPlayer() +return true if the actor is a player. + +isGroupMember = actor:IsGroupPlayer() +return true if the actor is a player and member of the raid group. + +IsneutralOrEnemy = actor:IsNeutralOrEnemy() +return true if the actor is a neutral of an enemy. + +isEnemy = actor:IsEnemy() +return true if the actor is a enemy. + +isPet = actor:IsPetOrGuardian() +return true if the actor is a pet or guardian + +list = actor:GetSpellList() +returns a hash table with spellid, spelltable. + +spell = actor:GetSpell (spellid) +returns a spell table of requested spell id. + +r, g, b = actor:GetBarColor() +returns the color which the player bar will be painted on the window, it respects owner, arena team, enemy, monster. + +r, g, b = Details:GetClassColor() +returns the class color. + +texture, left, right, top, bottom = actor:GetClassIcon() +returns the icon texture path and the texture's texcoords. +]], +[[ +members: +actor.total = total of damage done. +actor.total_without_pet = without pet. +actor.damage_taken = total of damage taken. +actor.last_event = when the last event for this actor occured. +actor.start_time = time when this actor started to apply damage. +actor.end_time = time when the actor stopped with damage. +actor.friendlyfire_total = amount of friendlyfire. + +tables: +actor.targets = hash table of targets: {[targetName] = amount}. +actor.damage_from = hash table of actors which applied damage to this actor: {[aggresorName] = true}. +actor.pets = numeric table of GUIDs of pets summoned by this actor. +actor.friendlyfire = hash table of friendly fire targets: {[targetName] = table {total = 0, spells = hash table: {[spellId] = amount}}} +actor.spells = spell container. + +spell: +spell.total = total of damage by this spell. +spell.counter = how many hits this spell made. +spell.id = spellid + +spell.successful_casted = how many times this spell has been casted successfully (only for enemies). +- players has its own spell cast counter inside Misc Container with the member "spell_cast". +- the reason os this is spell_cast holds all spells regardless of its attribute (can hold healing/damage/energy/misc). + +spell.m_amt = multistrike hits. +spell.m_dmg = multistrike damage. +spell.m_crit = multistrike critical hits. +spell.n_min = minimal damage made on a normal hit. +spell.n_max = max damage made on a normal hit. +spell.n_amt = amount of normal hits. +spell.n_dmg = total amount made doing only normal hits. +spell.c_min = minimal damage made on a critical hit. +spell.c_max = max damage made on a critical hit. +spell.c_amt = how many times this spell got a critical hit (doesn't count critical by multistrike). +spell.c_dmg = total amount made doing only normal hits. +spell.g_amt = how many glancing blows this spell has. +spell.g_dmg = total damage made by glancing blows. +spell.r_amt = total of times this spell got resisted by the target. +spell.r_dmg = amount of damage made when it got resisted. +spell.b_amt = amount of times this spell got blocked by the enemy. +spell.b_dmg = damage made when the spell got blocked. +spell.a_amt = amount of times this spell got absorbed. +spell.a_dmg = total damage while absorbed. + +spell.targets = hash table containing {["targetname"] = total damage done by this spell on this target} + +Getting Dps: +For activity time: DPS = actor.total / actor:Tempo() +For effective time: DPS = actor.total / combat:GetCombatTime() +]], +[[ +members: +actor.total = total of healing done. +actor.totalover = total of overheal. +actor.totalabsorb = total of absorbs. +actor.total_without_pet = total without count the healing done from pets. +actor.totalover_without_pet = overheal without pets. +actor.heal_enemy_amt = how much this actor healing an enemy actor. +actor.healing_taken = total of received healing. +actor.last_event = when the last event for this actor occured. +actor.start_time = time when this actor started to apply heals. +actor.end_time = time when the actor stopped with healing. + +tables: +actor.spells = spell container. +actor.targets = hash table of targets: {[targetName] = amount}. +actor.targets_overheal = hash table of overhealed targets: {[targetName] = amount}. +actor.targets_absorbs = hash table of shield absorbs: {[targetName] = amount}. +actor.healing_from = hash table of actors which applied healing to this actor: {[healerName] = true}. +actor.pets = numeric table of GUIDs of pets summoned by this actor. +actor.heal_enemy = spells used to heal the enemy: {[spellid] = amount healed} + +spell: +spell.total = total healing made by this spell. +spell.counter = how many times this spell healed something. +spell.id = spellid. + +spell.totalabsorb = only for shields, tells how much damage this spell prevented. +spell.absorbed = is how many healing has been absorbed by some external mechanic like Befouled on Fel Lord Zakuun encounter. +spell.overheal = amount of overheal made by this spell. +spell.m_amt = multistrike hits. +spell.m_healed = multistrike healed. +spell.m_crit = multistrike critical hits. +spell.n_min = minimal heal made on a normal hit. +spell.n_max = max heal made on a normal hit. +spell.n_amt = amount of normal hits. +spell.n_curado = total amount made doing only normal hits (weird name I know). +spell.c_min = minimal heal made on a critical hit. +spell.c_max = max heal made on a critical hit. +spell.c_amt = how many times this spell got a critical hit (doesn't count critical by multistrike). +spell.c_curado = total amount made doing only normal hits. + +spell.targets = hash table containing {["targetname"] = total healing done by this spell on this target} +spell.targets_overheal = hash table containing {["targetname"] = total overhealing by this spell on this target} +spell.targets_absorbs = hash table containing {["targetname"] = total absorbs by shields (damage prevented) done by this spell on this target} + +Getting Hps: +For activity time: HPS = actor.total / actor:Tempo() +For effective time: HPS = actor.total / combat:GetCombatTime() +]], +[[ +actor.total = total of energy generated. +actor.received = total of energy received. +actor.resource = total of resource generated. +actor.resource_type = type of the resource used by the actor. + +actor.pets = numeric table of GUIDs of pets summoned by this actor. +actor.targets = hash table of targets: {[targetName] = amount}. +actor.spells = spell container. + +spell: +total = total energy restored by this spell. +counter = how many times this spell restored energy. +id = spellid + +targets = hash table containing {["targetname"] = total energy produced towards this target} +]], +[[ +these members and tables may not be present on all actors, depends what the actor performs during the combat, these tables are created on the fly by the parser. + +- Crowd Control Done: +actor.cc_done = amount of crowd control done. +actor.cc_done_targets = hash table with target names and amount {[targetName] = amount}. +actor.cc_done_spells = spell container. + +spell: +spell.counter = amount of times this spell has been used to perform a crowd control. +spell.targets = hash table containing {["targetname"] = total of times this spell made a CC on this target} + + +- Interrupts: +actor.interrupt = total amount of interrupts. +actor.interrupt_targets = hash table with target names and amount {[targetName] = amount}. +actor.interrupt_spells = spell container. +actor.interrompeu_oque = hash table which tells what this actor interrupted {[spell interrupted spellid] = amount} + +spell: +spell.counter = amount of interrupts performed by this spell. +spell.interrompeu_oque = hash table talling what this spell interrupted {[spell interrupted spellid] = amount} +spell.targets = hash table containing {["castername"] = total of times this spell interrupted something from this caster} + + +- Aura Uptime: +actor.buff_uptime = seconds of all buffs uptime. +actor.buff_uptime_spells = spell container. +actor.debuff_uptime = seconds of all debuffs uptime. +actor.debuff_uptime_spells = spell container. + +spell: +spell.id = spellid +spell.uptime = uptime amount in seconds. + + +- Cooldowns: +actor.cooldowns_defensive = amount of defensive cooldowns used by this actor. +actor.cooldowns_defensive_targets = in which player the cooldown was been used {[targetName] = amount}. +actor.cooldowns_defensive_spells = spell container. + +spell: +spell.id = spellid +spell.counter = how many times the player used this cooldown. +spell.targets = hash table with {["targetname"] = amount} + + +- Ress +actor.ress = amount of ress performed by this actor. +actor.ress_targets = which actors got ressed by this actor {["targetname"] = amount} +actor.ress_spells = spell container. + +spell: +spell.ress = amount of resses made by this spell. +spell.targets = hash table containing player names resurrected by this spell {["playername"] = amount} + + +- Dispel (members has 2 "L" instead of 1) +actor.dispell = amount of dispels done. +actor.dispell_targets = hash table telling who got dispel from this actor {[targetName] = amount}. +actor.dispell_spells = spell container. +actor.dispell_oque = hash table with the ids of the spells dispelled by this actor {[spellid of the spell dispelled] = amount} + +spell: +spell.dispell = amount of dispels by this spell. +spell.dispell_oque = hash table with {[spellid of the spell dispelled]} = amount +spell.targets = hash table with target names dispelled {["targetname"] = amount} + + +- CC Break +actor.cc_break = amount of times the actor broke a crowd control. +actor.cc_break_targets = hash table containing who this actor broke the CC {[targetName] = amount}. +actor.cc_break_spells = spell container. +actor.cc_break_oque = hash table with spells broken {[CC spell id] = amount} + +spell: +spell.cc_break = amount of CC broken by this spell. +spell.cc_break_oque = hash table with {[CC spellid] = amount} +spell.targets = hash table with {["targetname"] = amount}. +]], +[[ +Details:GetSourceFromNpcId (npcId) +return the npc name for the specific npcId. +this is a expensive function, once you get a valid result, store the npc name somewhere. + +bestResult, encounterTable = Details.storage:GetBestFromPlayer (encounterDiff, encounterId, playerRole, playerName) +query the storage for the best result of the player on the encounter. +encounterDiff = raid difficult ID (15 for heroic, 16 for mythic). +encounterId = may be found on "id" member getting combat:GetBossInfo(). +playerRole = "DAMAGER" or "HEALER", tanks are considered "DAMAGER". +playerName = name of the player to query (with server name if the player is from another realm). +bestResult = integer, best damage or healing done on the boss made by the player. +encounterTable = {["date"] = formated time() ["time"] = time() ["elapsed"] = combat time ["guild"] = guild name ["damage"] = all damage players ["healing"] = all healers} + +heal_or_damage_done = Details.storage:GetPlayerData (encounterDiff, encounterId, playerName) +query the storage for previous ecounter data for the player. +returns a numeric table with the damage or healing done by the player on all encounters found. +encounterDiff = raid difficult ID (15 for heroic, 16 for mythic). +encounterId = may be found on "id" member getting combat:GetBossInfo(). +playerName = name of the player to query (with server name if the player is from another realm). + +itemLevel = Details.ilevel:GetIlvl (guid) +returns a table with {name = "actor name", ilvl = itemLevel, time = time() when the item level was gotten}. +return NIL if no data for the player is avaliable yet. + +talentsTable = Details:GetTalents (guid) +if available, returns a table with 7 indexes with the talentId selected for each tree {talentId, talentId, talentId, talentId, talentId, talentId, talentId}. +use with GetTalentInfoByID() + +spec = Details:GetSpec (guid) +if available, return the spec id of the actor, use with GetSpecializationInfoByID() + +Details:SetDeathLogLimit (limit) +Set the amount of lines to store on death log. + +npcId = Details:GetNpcIdFromGuid (guid) +Extract the npcId from the actor guid. +]], --custom displays +[[ +Cstom Display is a special display where users can set their own rules on searching for what show in the window. +There is 4 scripts which compose the display: + +Required: +Search - this is the main script, it's responsible to build a list of actors to show in the window. + +Optional: +Tooltip - it runs when the user hover over a bar. +Total - runs when showing the bar, and helps format the total done. +Percent - also runs when showing the bar, it formats the percentage amount. + + +Search Code: +- The script receives 3 parameters: *Combat, *CustomContainer and *Instance. +*Combat - is the reference for the selected combat shown in the window (the one selected on segments menu). +*CustomContainer - is the place where the display mantain stored the results, Details! get the content inside the container and use to update the window. +*Instance - is the reference of the window where the custom display is shown. + +- Also, the script must return three values: total made by all players, the amount of the top player and the amount of players found by the script. +- The search script basically begins getting these three parameters and declaring our three return values: + +local Combat, CustomContainer, Instance = ... +local total, top, amount = 0, 0, 0 + +- Then, we build our search for wherever we want to show, here we are building an example for Damage Done by Pets and Guardians. +- So, as we are working with damage, we want to get a list of Actors from the Damage Container of the combat and iterate it with ipairs: + +local damage_container = combat:GetActorList( DETAILS_ATTRIBUTE_DAMAGE ) +for i, actor in ipairs( damage_container ) do + --do stuff +end + +- Actor, can be anything, a monster, player, boss, etc, so, we need to check if actor is a pet: + +if (actor:IsPetOrGuardian()) then + --do stuff +end + +- Now we found a pet, we need to get the damage done and find who is the owner of this pet, after that, we also need to check if the owner is a player: + +local petOwner = actor.owner +if (petOwner:IsPlayer()) then + local petDamage = actor.total +end + +- The next step is add the pet owner into the CustomContainer: + +CustomContainer:AddValue (petOwner, petDamage) + +- And in the and, we need to get the total, top and amount values. This is generally calculated inside our loop above, but just calling the API for the result is more handy: + +total, top = CustomContainer:GetTotalAndHighestValue() +amount = CustomContainer:GetNumActors() +return total, top, amount + + +The finished script looks like this: + +local Combat, CustomContainer, Instance = ... +local total, top, amount = 0, 0, 0 + +local damage_container = Combat:GetActorList( DETAILS_ATTRIBUTE_DAMAGE ) +for i, actor in ipairs( damage_container ) do + if (actor:IsPetOrGuardian()) then + local petOwner = actor.owner + if (petOwner:IsPlayer()) then + local petDamage = actor.total + CustomContainer:AddValue( petOwner, petDamage ) + end + end +end + +total, top = CustomContainer:GetTotalAndHighestValue() +amount = CustomContainer:GetNumActors() + +return total, top, amount + + +Tooltip Code: +- The script receives 3 parameters: *Actor, *Combat and *Instance. This script has no return value. +*Actor - in our case, actor is the petOwner. + +local Actor, Combat, Instance = ... +local Format = Details:GetCurrentToKFunction() + +- What we want where is show all pets the player used in the combat and how much damage each one made. +- The member .pets gives us a table with pet names that belongs to the actor. + +local actorPets = Actor.pets + +- Next move is iterate this table and get the pet actor from the combat. +- In Details! always use ">= 1" not "> 0", also when not using our format functions, use at least floor() + +for i, petName in ipairs( actorPets ) do + local petActor = Combat( DETAILS_ATTRIBUTE_DAMAGE, petName) + if (petActor and petActor.total >= 1) then + --do stuff + end +end + +- With the pet in hands, what we have to do now is add this pet to our tooltip. +- Details! uses 'GameCooltip' which is slight different than 'GameTooltip': + +GameCooltip:AddLine( petName, Format( nil, petActor.total ) ) +Details:AddTooltipBackgroundStatusbar() + + +The finished script looks like this: + +local Actor, Combat, Instance = ... +local Format = Details:GetCurrentToKFunction() + +local actorPets = Actor.pets + +for i, petName in ipairs( actorPets ) do + local petActor = Combat( DETAILS_ATTRIBUTE_DAMAGE, petName) + if (petActor and petActor.total >= 1) then + GameCooltip:AddLine( petName, Format( nil, petActor.total ) ) + Details:AddTooltipBackgroundStatusbar() + end +end + + + +Total Code and Percent Code: +- Details! build the total and the percent automatically, these scripts are for special cases where you want to show something different, e.g. convert total into seconds/minutes. +- Both scripts receives 5 parameters, three are new to us: +*Value - the total made by this actor. +*Top - the value made by the rank 1 actor. +*Total - the total made by all actors. + +local value, top, total, combat, instance = ... +local result = floor (value) +return total +]], --custom container +[[ +Custom Container Object: +A custom container is primarily used when building custom displays. +Is used to hold values for any kind of actor in Details! and also any other table as long as it has a ".name" or ".id" key. + +value = is a number indicating the actor's score, the container doesn't know what kind of actor it is holding, if is a damage actor, energy, a spell, so, it is just nominated 'value'. + +container:GetValue ( actor ) +returns the current value for the requested actor. + +container:AddValue ( actor, amountToAdd, checkTop, nameComplement ) +actor is any actor object or any other table containing a member "name" or "id", e.g. {name = "Jeff"} {id = 186451} +amountToAdd is the amount to add to this actor on the container. +checkTop is for some special cases when the top value needs to be calculated immediately. +nameComplement is a string to add on the end of the actor's name, for instance, in cases where the actor is a spell and its name is generated by the container. +returns the current value for the actor. + +container:SetValue (actor, amount, nameComplement) +actor is any actor object or any other table containing a member "name" or "id", e.g. {name = "Jeff"} {id = 186451} +amount is the amount to set to this actor on the container. +nameComplement is a string to add on the end of the actor's name, for instance, in cases where the actor is a spell and its name is generated by the container. + +container:HasActor (actor) +return true if the container holds a reference for 'actor'. + +container:GetNumActors() +returns the amount of actors present inside the container. + +container:GetTotalAndHighestValue() +return 'total' and 'top' values. +total is the total of value of all actors together. +top is the amount of value of the actor with more value. + +container:WipeCustomActorContainer() +removes all data from a custom container. +this is automatically performed when the search script runs. +]] +} + local f = gump:CreateSimplePanel (UIParent, 700, 480, "Details! API", "DetailsAPIPanel") + + local text_box = gump:NewSpecialLuaEditorEntry (f, 520, 430, "text", "$parentTextEntry", true) + text_box:SetPoint ("topleft", f, "topleft", 170, -40) + local file, size, flags = text_box.editbox:GetFont() + text_box.editbox:SetFont (file, 12, flags) + + local topics = { + "Attributes List", + "Object: Combat", + "Object: Container", + "Object: Actor", + "Keys for Damage Actor", + "Keys for Healing Actor", + "Keys for Energy Actor", + "Keys for Misc Actor", + "General Functions", + "Custom Displays", + "Object: Custom Container", + } + + local select_topic = function (self, button, topic) + text_box:SetText (topics_text [topic]) + end + + for i = 1, #topics do + local title = topics [i] + local button = gump:CreateButton (f, select_topic, 80, 16, title, i) + button:SetPoint ("topleft", f, "topleft", 5, (-i*20)-40) + button:SetIcon ([[Interface\Buttons\UI-GuildButton-PublicNote-Up]], nil, nil, nil, nil, nil, nil, 2) + end + + end + + DetailsAPIPanel:Show() + end + --old versions dialog --[[ --print ("Last Version:", _detalhes_database.last_version, "Last Interval Version:", _detalhes_database.last_realversion) diff --git a/functions/classes.lua b/functions/classes.lua index 04470bac..e818f5ec 100644 --- a/functions/classes.lua +++ b/functions/classes.lua @@ -100,17 +100,14 @@ do CONTAINER_ENEMYDEBUFFTARGET_CLASS = 11 } - function _detalhes:name (actor) - return self.nome or actor.nome - end function _detalhes:Name (actor) - return self.nome or actor.nome + return self.nome or actor and actor.nome end function _detalhes:GetName (actor) - return self.nome or actor.nome + return self.nome or actor and actor.nome end function _detalhes:GetDisplayName (actor) - return self.displayName or actor.displayName + return self.displayName or actor and actor.displayName end function _detalhes:GetOnlyName (string) if (string) then @@ -128,10 +125,16 @@ do end end function _detalhes:Class (actor) - return self.classe or actor.classe + return self.classe or actor and actor.classe end - function _detalhes:class (actor) - return self.classe or actor.classe + function _detalhes:GetActorClass (actor) + return self.classe or actor and actor.classe + end + function _detalhes:GetGUID (actor) + return self.serial or actor and actor.serial + end + function _detalhes:GetFlag (actor) + return self.flag_original or actor and actor.flag_original end function _detalhes:GetActorSpells() return self.spells._ActorTable @@ -139,4 +142,11 @@ do function _detalhes:GetSpell (spellid) return self.spells._ActorTable [spellid] end + + --> inherits to all actors without placing it on _detalhes namespace. + _detalhes.container_combatentes.guid = _detalhes.GetGUID + _detalhes.container_combatentes.name = _detalhes.GetName + _detalhes.container_combatentes.class = _detalhes.GetActorClass + _detalhes.container_combatentes.flag = _detalhes.GetFlag + end diff --git a/functions/slash.lua b/functions/slash.lua index 9acfdfe7..d61542f0 100644 --- a/functions/slash.lua +++ b/functions/slash.lua @@ -18,7 +18,9 @@ function SlashCmdList.DETAILS (msg, editbox) command = string.lower (command) if (command == Loc ["STRING_SLASH_WIPE"] or command == "wipe") then - _detalhes:CallWipe (true) + + elseif (command == "api") then + _detalhes.OpenAPI() elseif (command == Loc ["STRING_SLASH_NEW"] or command == "new") then _detalhes:CriarInstancia (nil, true) @@ -1111,6 +1113,7 @@ function SlashCmdList.DETAILS (msg, editbox) print ("|cffffaeae/details|r |cffffff33" .. Loc ["STRING_SLASH_ENABLE"] .. " " .. Loc ["STRING_SLASH_DISABLE"] .. "|r: " .. Loc ["STRING_SLASH_CAPTURE_DESC"]) print ("|cffffaeae/details|r |cffffff33" .. Loc ["STRING_SLASH_RESET"] .. "|r: " .. Loc ["STRING_SLASH_RESET_DESC"]) print ("|cffffaeae/details|r |cffffff33" .. Loc ["STRING_SLASH_OPTIONS"] .. "|r|cfffcffb0 <" .. Loc ["STRING_WINDOW_NUMBER"] .. ">|r: " .. Loc ["STRING_SLASH_OPTIONS_DESC"]) + print ("|cffffaeae/details|r |cffffff33" .. "API" .. "|r: " .. Loc ["STRING_SLASH_API_DESC"]) print ("|cffffaeae/details|r |cffffff33" .. Loc ["STRING_SLASH_CHANGES"] .. "|r: " .. Loc ["STRING_SLASH_CHANGES_DESC"]) print ("|cffffaeae/details|r |cffffff33" .. Loc ["STRING_SLASH_WIPECONFIG"] .. "|r: " .. Loc ["STRING_SLASH_WIPECONFIG_DESC"]) diff --git a/gumps/janela_custom.lua b/gumps/janela_custom.lua index 70081ef4..feb5454b 100644 --- a/gumps/janela_custom.lua +++ b/gumps/janela_custom.lua @@ -174,14 +174,18 @@ DetailsCustomPanel.code1_default = [[ --get the parameters passed - local combat, instance_container, instance = ... + local Combat, CustomContainer, Instance = ... --declade the values to return local total, top, amount = 0, 0, 0 --do the loop - + --CustomContainer:AddValue (actor, actor.value) --loop end + --if not managed inside the loop, get the values of total, top and amount + total, top = Container:GetTotalAndHighestValue() + amount = Container:GetNumActors() + --return the values return total, top, amount ]] @@ -1768,8 +1772,10 @@ font_size2:SetPoint ("left", font_size1, "right", -4, 2) local apply1 = gump:NewButton (code_editor, nil, "$parentApply", "applybutton", 8, 10, apply_code, nil, nil, nil, "apply") apply1:SetPoint ("left", font_size2, "right", -4, 1) + + local open_API = gump:NewButton (code_editor, nil, "$parentOpenAPI", "openAPIbutton", 8, 10, _detalhes.OpenAPI, nil, nil, nil, "Open Details! API") + open_API:SetPoint ("left", apply1, "right", -4, -1) - --code_editor:SetWidth (650) --> select damage DetailsCustomPanelAttributeMenu1:Click() diff --git a/gumps/switch.lua b/gumps/switch.lua index 5f3d4e65..c5448861 100644 --- a/gumps/switch.lua +++ b/gumps/switch.lua @@ -1103,10 +1103,12 @@ function _detalhes.switch:Update() if (name == Loc ["STRING_SWITCH_CLICKME"]) then --button.button2.texto:SetTextColor (.3, .3, .3, 1) button:SetAlpha (0.3) + button.textureNormal:SetDesaturated (true) button.button2.texto:SetPoint ("left", button, "right", 5, -1) else --button.button2.texto:SetTextColor (.8, .8, .8, 1) button:SetAlpha (1) + button.textureNormal:SetDesaturated (false) button.button2.texto:SetPoint ("left", button, "right", 3, -1) end