Thread Tools Display Modes
01-18-12, 07:55 AM   #1
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Raid/dungeons event and data

Hello good people

I'm looking for two things related to raids/dungeons, which I couldn't find myself. Perhaps someone here will be able to assist me:

1. How do I know that a boss fight was ended, due to either boss kill or a wipe?
I can use INSTANCE_ENCOUNTER_ENGAGE_UNIT event for the boss fight start, but I coudn't find an event for boss fight end.

2. How can I know what is the current progress within the current raid/dungeon instance the player is doing? Meaning, how many bosses were killed out of the available bosses?

Thanks in advance!
  Reply With Quote
01-18-12, 07:57 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
1. At some point the same event will fire again; this is the event used by the default UI to determine when to show or hide the boss unit frames. However, most addons that care about boss encounters (eg. boss mods) do not use this event.

Instead, every time the player enters combat (PLAYER_REGEN_DISABLED), they scan the target of the player and all party/raid members. If anyone's target is classified as a worldboss (UnitClassification API) and is in combat (UnitAffectingCombat API), then a boss encounter has begun.

When a UNIT_DIED event occurs in the combat log (COMBAT_LOG_EVENT_UNFILTERED event), if it pertains to the boss, then the boss has been killed; you could also detect this occurrence by watching UNIT_HEALTH for the bossN unit(s). If all players in the group die before the boss dies, then a wipe has occurred.

2. See the GetInstanceLockTimeRemaining and GetInstanceLockTimeRemainingEncounter API documentation.
  Reply With Quote
01-19-12, 09:34 AM   #3
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Thank you for your answer!

So basically I should use COMBAT_LOG_EVENT_UNFILTERED, then:
1. if boss dies before all raid, then it's a kill.
2. if all raid players die before a boss, it's a wipe.

Is that what you meant?

Two more questions:
1. How do I handle a fight with more than one boss? Assuming I want a general code which will be compatible with all boss encounters.
2. Won't it be very CPU demanding to wait for "COMBAT_LOG_EVENT_UNFILTERED"?
  Reply With Quote
01-19-12, 07:13 PM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
If the boss dies at all, it's a kill. It doesn't matter if the whole raid is dead. Back in TBC, my guild's first Brutallus kill involved everyone dying with the boss at less than 1%, DoTs falling off before the paladin bubble expired and the paladin died, and then me (resto shaman) reincarnating and shooting a lightning bolt at the boss before he reset. It killed him, but he turned around and killed me while the lightning bolt was in the air, so technically the whole raid was dead before the boss died.

Otherwise, yes. I'd suggest taking a look at BigWigs. It's very modular, so all the boss encounter detection is in one file, and not much else is in that file, so it should be pretty easy to go through.

1. How do I handle a fight with more than one boss? Assuming I want a general code which will be compatible with all boss encounters.
Look at BigWigs for specifics, but I'd assume that you'd just make a table containing the NPC IDs for all of the bosses, start the encounter when any one of them was engaged, detect a wipe when all raid members died and at least one boss was still alive (I'd imagine you could easily detect when the boss reset by seeing when its health popped back up to 100% after all raid members died), and detect a kill when all bosses died.

2. Won't it be very CPU demanding to wait for "COMBAT_LOG_EVENT_UNFILTERED"?
1. You only register for the event after you detect that a boss has been engaged.

2. You can immediately discard any events that do not have the UNIT_DIED sub-event:

Code:
local f = CreateFrame("Frame")
f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
f:SetScript("OnEvent", function(self, event, timestamp, subevent, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, ...)
    if subevent ~= "UNIT_DIED" then return end
    -- do stuff here
end)
Additionally, when you detected a boss engagement, you would want to store the GUID of the boss(es), and use that to determine if the event was relevant:

Code:
local bossesAlive = {} -- Populate this with boss GUIDs when an encounter starts or a new boss spawns during an encounter.

local f = CreateFrame("Frame")
f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
f:SetScript("OnEvent", function(self, event, timestamp, subevent, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, ...)
    if subevent ~= "UNIT_DIED" then return end
    if bossesAlive[destGUID] then
        -- Boss mob that was alive
        bossesAlive[destGUID] = nil
   else
        -- Non-boss mob, or already dead
   end
end)
  Reply With Quote
01-19-12, 08:25 PM   #5
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Thank you for your thorough answer!
  Reply With Quote
01-22-12, 02:13 AM   #6
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
I'm sorry for the double post earlier, my bad.

I've checked the two functions GetInstanceLockTimeRemaining() and GetInstanceLockTimeRemainingEncounter(), and unfortunately they return valid result when a player is about to be saved to a partially done instance. If I just run them mid-raid, they return "0" for completed/dead bosses.

I thought of using GetSavedInstanceInfo, but this won't work for LFR or LFG instances.

If anyone knows a valid way to get current instance progress, I would be happy to get some help here.
  Reply With Quote
01-24-12, 06:04 AM   #7
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Bumping, in case someone can instruct me how to get current instance progress or direct me to another addon that does that.

Thanks
  Reply With Quote
01-24-12, 06:37 AM   #8
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
It seems that the LFR raid save information is received when LFG_LOCK_INFO_RECEIVED fires.

Then you can use these API to get more information:
Code:
local numEncounters, numCompleted = GetLFGDungeonNumEncounters(dungeonID)
Code:
local bossName, texture, isKilled = GetLFGDungeonEncounterInfo(dungeonID, index)
For example:
Code:
local d = 447 -- for example Dragon Soul part 1 (part 2 is 448)
for i = 1, GetLFGDungeonNumEncounters(d) do
  local bossName, _, isKilled = GetLFGDungeonEncounterInfo(dungeonID, i)
  print(bossName, isKilled and "is dead" or "is available")
end
The game uses the FrameXML function LFGRewardsFrameEncounterList_OnEnter from LFGFrame.lua to show the tooltip in the LFR frame to show what you are saved for, there is plenty of code in the LFG, LFD, LFR and RaidFinder lua files, it's handy to have the interface codes extracted somewhere for examples.
  Reply With Quote
01-24-12, 10:40 AM   #9
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
It doesn't work

This is my code:
Code:
dungeonID = GetPartyLFGID()
numBosses = GetLFGDungeonNumEncounters(dungeonID)
for i = 1, numBosses do
	self:Print(GetLFGDungeonEncounterInfo(dungeonID, i))
	if (select(3, GetLFGDungeonEncounterInfo(dungeonID, i))) then
		deadBosses = deadBosses + 1
	end			
end
I also tried the second field of GetLFGDungeonNumEncounters, which should be the number of completed encounters. But the results are always as if no boss was killed.
Number of bosses and bosses names look ok, though.
From looking at the code it looks like this data should be valid when a player is entering the instance and informed of the status. I just don't get why these functions don't always work.

I'm sure Blizzard hold this information somewhere, but I don't know how to get it. It's so frustrating.

Edit:
If I print GetLFGDungeonNumEncounters(416) (DS part one), I get the number of looted bosses. But this is not what I want, since a player can loot the LFR and do it all over again. I'm looking for the progress in the current instance. Meaning how many bosses are dead, regardless if the players is doing the LFR for the 1st of 5th time.

Last edited by Animor : 01-24-12 at 12:00 PM.
  Reply With Quote
01-24-12, 03:04 PM   #10
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Hmm, LFR is special... I don't think there is API to query this, only proper raid saves will provide information about killed bosses.
  Reply With Quote
01-24-12, 03:26 PM   #11
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Originally Posted by Vladinator View Post
Hmm, LFR is special... I don't think there is API to query this, only proper raid saves will provide information about killed bosses.
But I'm sure that somewhere in the code you can find the current LFG/LFR killed bosses status. I mean, the game uses it itself to handle those instances. For example, when a player joins an ongoing raid/dungeon, he gets the current progress status and can choose whether to enter or not. And if this info exists, then perhaps it's just a matter of digging it somehow. Which I didn't manage to do so far...
  Reply With Quote
01-24-12, 03:30 PM   #12
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
But that does not fire in LFR... only normal raids with save ids, and yes it triggers by an event and it will also contain the hyperlink for the savestate, containing flags for bosses downed and alive.

If you enter a raid save, INSTANCE_LOCK_WARNING fires and the static popup triggers INSTANCE_LOCK in StaticPopup.lua that shows bosses dead and alive.

It's just that since LFR don't have it's own lockout id like regular once, the game can't tell you because Blizz didn't make API for it, maybe I am wrong, maybe you can forge a link using some ID, need to look into it -but at glance, I have doubts.

Last edited by Vlad : 01-24-12 at 03:36 PM.
  Reply With Quote
01-24-12, 11:52 PM   #13
Talyrius
An Onyxian Warder
 
Talyrius's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 363
Try looking at WoW's UI source code.
  Reply With Quote
01-25-12, 12:52 AM   #14
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Originally Posted by ForeverTheGM View Post
Try looking at WoW's UI source code.
I did look there... and I've tried the functions there, but per my understanding they return valid data only when you enter an instance or search for available one. When I tried to use for example GetInstanceLockTimeRemainingEncounter during LFR/LFG, I got false for "isKilled", even though some of the bosses were dead at that time.
Perhaps I'm missing something there...?
  Reply With Quote
01-25-12, 06:48 AM   #15
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
I quote myself, weird. But yes, in the LFR and LFG you don't have your own save, thus you can't lookup what bosses are already dead when you join.

Originally Posted by Vladinator View Post
<snip> It's just that since LFR don't have it's own lockout id like regular once, the game can't tell you because Blizz didn't make API for it<snip>
The reason you can't track what bosses are dead in the looking for dungeon groups is the same reason you can't track what bosses are dead when you enter a 5 man dungeon, you do not have a save to parse and extract the information from.

The LFR API will only tell you what bosses you have already defeated and that you can not roll on their loot. It does not mean that the LFR you join have those bosses dead, if you like me run several LFR's to help friends and such, using these API functions would be inaccurate.

Last edited by Vlad : 01-25-12 at 07:01 AM.
  Reply With Quote
01-25-12, 09:54 AM   #16
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Vladinator, I think you might be wrong about it.
Before you enter a random dungeon (LFG) or an LFR raid, I think you get the info of defeated bosses in the popup message that let you enter the dungeon.
It's not the "about to be saved" message of standard dungeons/raids, it's just the info. If I remember correctly, it happens when u replace a player that left a dungeon after a boss was already defeated.

I'm not sure about it, thought. I will verify it later on, on the game itself. But this is what I remember. If you are right about it, then this whole thing might be a dead end for me...
  Reply With Quote
01-25-12, 11:10 AM   #17
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Ah, yes, if you get the queue popup that tells you what bosses are dead/alive before you accept or decline the invite, that you can use. But once inside the game won't tell you any longer.

That is a static popup I believe, using a instance hyperlink. One could parse the instance hyperlink data. Take a look in the StaticPopup related parts in the LFR, LFD and LFG lua files, also in the StaticPopup lua file itself.
  Reply With Quote
01-25-12, 03:57 PM   #18
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Ok, this is what I came with so far:
The static popup with number of defeated bosses appears for LFR and specific dungeons. However, for random dungeons the defeated bosses info is not shown on the static popup at all, so I guess there is no way to get this info.

The event is calles [COLOR="rgb(255, 140, 0)"]LFG_PROPOSAL_SHOW[/color], and the function to retrieve the data is GetLFGProposal().

I guess I can write a function to track boss encounters. But for random 5men I lack the initial number, so it won't be accurate. Very strange that blizz doesn't have such a trivial API...
  Reply With Quote
01-25-12, 07:13 PM   #19
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
From LFRFrame.lua

Code:
--this is used by the static popup for INSTANCE_LOCK_TIMER
function InstanceLock_OnEnter(self)
	GameTooltip:SetOwner(self:GetParent(), "ANCHOR_BOTTOM");
	if ( self.encountersComplete > 0 ) then
		GameTooltip:SetText(BOSSES);
		for i=1, self.encountersTotal do
			local bossName, texture, isKilled = GetInstanceLockTimeRemainingEncounter(i);
			if ( isKilled ) then
				GameTooltip:AddDoubleLine(bossName, BOSS_DEAD, RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b, RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b);
			else
				GameTooltip:AddDoubleLine(bossName, BOSS_ALIVE, GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b, GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b);
			end
		end
	else
		GameTooltip:SetText(ALL_BOSSES_ALIVE);
	end
	GameTooltip:Show();
end
They use GetInstanceLockTimeRemainingEncounter(index) to extract boss and if the boss is dead and such, for the popup for LFR that you mentioned earlier. Just wanted to tell you.
  Reply With Quote
01-26-12, 03:19 AM   #20
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
I've tried it. GetInstanceLockTimeRemainingEncounter is not the correct function, since it return "0" when the popup pops.
I think it's in LFRFrame.lua since it's legacy for the Raid Finder feature that was implemented in patch 3.3 or so. The raid finder was like a normal raid with save and locks. The LFR we have today doesn't have save or locks, u can repeat it as much as you want. The only thing that changes is the looted bosses info, and that info is extracted through GetLFGDungeonNumEncounters.

The correct function (I verified on the game), is GetLFGProposal

Last edited by Animor : 01-26-12 at 03:22 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Raid/dungeons event and data

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off