RCLootCouncil

RCLootCouncil

23M Downloads

Autopass when saved or didn't tag the boss

SafeteeWoW opened this issue ยท 25 comments

commented

By comparing the raid lockout before the encounter and after the encounter, whether or not the player is eligible for the loot can be known.

GetMasterLootCandidate is another way to check this, but this occasionally changes when a raider leaves instance and is still eligible for the loot, at least when I tested it in Patch 7.3 (before 7.3.5) I have never done any loot tests since 7.3.5, because I can no longer master loot in old dungeons.

  1. If the player is not locked to the boss and is locked to the boss after it is dead, the player is eligible for the loot, respond to ML normally.
  2. If the player was locked to the boss before the instance, autopass by sending "SAVED" to the ML.
  3. If the player wasn't locked after the encounter, autopass by sending "OUT" to the ML.
  4. We only do the above check when the item is BoP.
    5.Out of instance response will be deprecated after the full implementation of this feature.

Such information can be gathered from the following API:
GetSavedInstanceInfo, GetNumSavedInstances, GetSavedInstanceEncounterInfo
RequestRaidInfo RequestLFDPlayerLockInfo

For more reference, read FrameXML/RaidFrame.lua and the addon SavedInstances

There are several challenges for this feature:

  1. (a)Award Later list should maintain the boss which the item belongs to, otherwise this does not work if ML awards many items later, or (b) we hardcode the boss-item relationship. This is probably a better bug-free version. I think there is already an addon which has implemented this feature, and it's not hard for me to dump this information from the Encounter Journal, just need some disk space to store such information in the source code. ~~~Also needs to generate a table to translate between Encounter Journal id and ENCOUNTER_START/ENCOUNTER_END id, which possibly can be done by parsing DBM/BigWigs source code?~~~ (Probably not needed)
  2. The recent saved instance information should be recorded in the SV for every raider, so the autopass by lockout can be sent correctly if ML does award later.
  3. There could be a delay between the boss kill and the registration of lockout. The duration of the delay should be tested by experiment. If the session is started immediately after the end of encounter, we can delay the response by several seconds to solve this problem.
  4. Privacy issue. DBM can fetch all lockout information from raiders too, but raider won't send this information unless confirm by clicking the dialog. Therefore, RCLootCouncil never sends all lockout infomation. It only sends information for the most recent encounter. Since most of the time, ML can know the lockout information by reading the master loot list anyway, it is not a privacy leaking.

Why this feature:

  1. In the guild gold run, conveniently check who has the lockout. My guild offers less gold for ppl without fresh lockout, I check this through Master Loot List, which is most likely correct, but it is not convenient. (Another suggestion, If the raider does not have RC installed, and he is not in the Master Loot list, mark the response as ineligible for the loot?)
  2. For general heroic guild ML/PL run, it is convenient, as often several people doesn't have the fresh lockout.
commented

This is something I'd definitely want to do as well.

Doing as you mention and checking the lock status will provide the most info, but I still think it's an good idea to check GetMasterLootCandidate as it's a requirement for people to be on there for the addon to automatically give out the loot.
Kinda related is the issue of trying to award something to someone with full bags - an indicator of this would be really helpful.

As for the challenges:

  1. Imo the less hardcoding the better, and it isn't really needed in this case.
  2. Yes.
  3. I don't believe this will be a problem, but of course that would need some testing. I'd refrain from delaying sessions, and there's several ways around it. Check GetMasterLootCandidate list is one way of avoiding it, and secondly, if the player isn't locked before the kill and gets an ENCOUNTER_END event with a kill, I think it's save to assume they are eligible for loot.
  4. I wouldn't worry too much about that - it's practically available on the armory for everyone to see anyway.

And yes, if for any reason any candidate is ineligible, they should be marked as such, preferably with an explanation why. If we're checking the ML list, then people without the addon will get caught there, but otherwise I don't think it's worth the time creating special use cases for people without the addon.

commented

I did suggest to check GetMasterLootCandidate a while ago, but the idea was rejected by you.
See #62
The reason is that ML list can change each time when the ML opens the loot, if the raider leaves the instance before the loot is opened. Thus the ML list is not accurate. The other problem is that GetMasterLootCandidate does not work if the loot method is not master.

  1. I don't know if ENCOUNTER_END fires if a player is locked just outside of the boss fight zone the entire fight. I don't know if ENCOUNTER_END fires only when the player joins the fight. It is very likely to fire when the player keep afking and never tags the boss and ineligible for the loot (Happened in my guild when ppl controlling 3 characters in a heroic boss fight and forget to tag the boss for one character). Test needed.
commented

I rejected the idea of sending all candidates with every loottable, and that "ineligble" in it self wasn't enough info. I agreed with the concept, and with this idea you got something I like.

If a raider leaves the instance, he can't receive the loot automatically anyway, and should be marked as "Not in Raid" (or similar). Obviously we can't use it for non ML raids, for which the other methods will have to do.

I'm not 100% sure about the ENCOUNTER_END either, but I imagine it only fires if you participate. I won't be raiding the next week or so, but I can skip a boss on my next clear to check it.

commented

GetMasterLootCandidate should be used as a fallback method if the raider does not send the lockout information, (old RC version, no RC installed, etc). ML will broadcast group members not in the ML list after some given timeout.

For the ENCOUNTER_END, I think it fires regardless if you participate in the fight or not, as long as you are not too far away from the boss. I guess if at least one INSTANCE_ENCOUNTER_ENGAGE_UNIT fires between ENCOUNTER_START and ENCOUNTER_END, then we can know the player joins the boss fight. Test this when you have time. Test needed(LFR or old dungeon are a good places to test), as I am not 100% sure the meaning of INSTANCE_ENCOUNTER_ENGAGE_UNIT. (I am guessing, probably wrong) The other possible way is that we can check the threat between the player/pet and boss1-5 during the encounter (2nd return of UnitDetailedThreatSituation is not nil = on threat list). I do believe all player will receive the kill credit if and only if on the threat list. Anyway, I don't think ENCOUNTER_END tells whether ppl participate the fight or not. Check what event fires and whether you are on the threat list next time when your raid team is resetting bloodlust and you choose not to tag the boss to not reset your bloodlust. Of course, I still prefer to check the raid lockout if you can confirm that the lockout status always updates immediately after a kill.

Another small suggestion:
"Not in Raid" should be determined by the API EJ_GetCurrentInstance(), which returns an instance id that tells the ML whether the raider is in the SAME instance, which is more precise than the currently used GetNumGroupMembers() >= 8 and not IsInInstance()

commented

Did a quick test with a starter account in the group outside the instance. INSTANCE_ENCOUNTER_ENGAGE_UNIT seems to fire whenever you enter an instance, after ENCOUNTER_START and way after ENCOUNTER_END. It also sends no arguments with the event.
image
The starter account outside received no events indicating any kind of combat occured, except for some UNIT_ power, aura of the one inside.

Next, I tried a raid (Magtheridon's Lair 25 to be precise). This time I had no INSTANCE_ENCOUNTER_ENGAGE_UNIT when entering the raid. ENCOUNTER_START fired immediately when engaging the adds in front of him (as expected), but INSTANCE_ENCOUNTER_ENGAGE_UNIT only fired just before the boss became targetable (still without arguments):
image
It fired again well after ENCOUNTER_END, just before PLAYER_REGEN_ENABLED:
image
The one outside still didn't get anything.

Furthermore I found that GetSavedInstanceInfo() is not immediately updated, but relies on an UPDATE_INSTANCE_INFO before returning correct results. It will query the server for it when called though, and it's pretty much available immediately afterwards.

In conclusion
While this was no where near a real raid test, I think a few things are clear:

  1. INSTANCE_ENCOUNTER_ENGAGE_UNIT is inconsistent to its name. While it could probably be used if thrown between encounter start/end, we would still rely on the encounter event for the encounter id.
  2. People outside the instance doesn't receive any boss related events. This might be because I wasn't in a raid group, but I somewhat doubt it.
  3. GetSavedInstanceInfo() and GetSavedInstanceEncounterInfo() is very likely to be useable, but relies on localized boss names for comparisons.
  4. BOSS_KILL seems to be useful.

I still need to see what happens in a real raid, and when inside without participating in the kill. That won't be until next week though.

As for the "Not in Raid", I agree. Also, I'd like to know what the difference from EJ_GetCurrentInstance() and the instance(Map)ID from GetInstanceInfo() is, or rather which is best. I'm a bit concerned about the different wings in say Antorus.

commented
  1. UnitDetailedThreatSituation is sth should be tested. I guess to be on the threat table or not determine whether you have joined the fight.
  2. If ppl doesn't receive any boss related events, it's even easier for us to deal with it.
  3. GetSavedInstanceEncounterInfo() relies on the localized boss name, which I believe is the boss name in ENCOUNTER_START
  4. BOSS_KILL useful? test needed.
  5. When ENCOUNTER_END, we can do RequestRaidInfo immediately to request UPDATE_INSTANCE_INFO event.
  6. You can convert the id returned from EJ_GetCurrentInstance to map id by EJ_GetInstanceInfo([instanceID]), or even easier, call EJ_GetInstanceInfo without argument to get the map id of the current instance, which is probably the same as the map id returned by GetInstanceInfo().

What I really want to do is to determine whether the raid member is in the same instance, so the ML can get better information whether the loot can be distributed or not. I now have a better way, compare the zone name returned by GetRaidRosterInfo. If the return value is not equal to GetInstanceInfo(the instance map name) and any of _G["DUNGEON_FLOOR_" .. strupper(GetMapInfo() or "") .. NUM](NUM is a number, starting from 1 until the table is nil. This is the sub zone name of the instances used in the blizzard map frame. _G["DUNGEON_FLOOR_ARGUSRAID0"], for example), then not in the same instance. Test needed.

Antorus, the Burning Throne
Light's Breach
Gaze of the Legion
Halls of the Boundless Reach
Elunaria
Elarian Sanctuary
The Exhaust
The Burning Throne
Chamber of Anguish
The World Soul
Seat of the Pantheon
Upper Deck
Lower Deck

If a player in the Antorus raid instance, but you found that the Zone name returned by GetRaidRosterInfo is not any of the above strings, then I will need to make some fixes to my method.

commented
  1. I would very much like to avoid UnitDetailedThreatSituation. Partly to avoid doing stuff in combat, but mostly: when do you call it? There's no guarantee a player is on the treat table after any amount of time, and which parameters do you give it for someone not even close to the boss? I agree it could potentially do the job, I'd just prefer basically any other way.
  2. Indeed.
  3. I can't remember. I just don't like relying on localized stuff, and since we would need to compare it with the ML's result, then it potentially won't work.
  4. Yeah, but it seems to fire when you kill a boss, i.e. are participating.
  5. Yep.
  6. The reason I asked is because the two are not the same. I know GetInstanceInfo()'s "instanceMapID" (named such by the wiki's - different from mapID) is the same throughout different wings of the instance - it's the one used in the history to determine which instance an item was awarded from. This leads me to believe EJ_GetInstanceInfo() returns a wing specific id or maybe even an EJ specific id.
    I'm not entirely sure if people always needs to be in the same wing to receive items (I've seen it work with different wings, and I've also seen it fail, although it might have been for another reason). If they only need to be in the same raid, then GetInstanceInfo() does the trick.

Also, the wiki states EJ_GetCurrentInstance() returns info about the currently viewed instance - this makes it useless without a parameter, as users could easily change the viewed instance.

commented
  1. It's not a problem to compare with ML, because the boss index number is non-localized. In the game, we can share a saved instance chat link to others, but it does not have localization problem, because that chat link use a binary number to store the encounter lockout info. The only time when we need to compare localized boss name is when we want to know whether the current player is eligible for the loot of the most recent boss, because I don't find a API to get the boss index of the last encounter (Boss index in the lockout is not always the same as that in the EncounterJournal).
  2. I now believe BOSS_KILL is very likely to be useful. In blizzard code, BOSS_KILL is used in FrameXML/LevelUpDisplay.lua, which shows boss defeat banner and sound when the boss is dead. I have never seen or heard those when I didn't join the fight.
  3. EJ_GetCurrentInstance returns the instance of the current location, irrelevant to the instance being viewed in EJ and this function returns the same id for all wings in the same instance.
commented

I believe GetSavedInstanceEncounterInfo() uses the same boss order for all localizations. Though the boss name returned by that function is localized, it is exactly the same as the boss name returned by ENCOUNTER_START ENCOUNTER_END BOSS_KILL (For the Eonar encounter, those use the name "The Defense of Eonar" and the journal uses the name "Eonar the Life-Binder". Another example is the Opera Hall encounter in Return to Karazhan. The 3 possible encounters share the same encounter id and the boss name "Opera Hall" and the lockout boss name also uses "Opera Hall"). I don't think localization will cause much trouble. Btw, I use the addon EventTracker, which is much better than "/etrace"

commented

If you have time, can you print select(7, GetRaidRosterInfo(the index of you)) every 1s, next time when you do Antorus? I want to make sure exactly what could be the possible returned zone values while inside Antorus. I want to use this API to give ML more information why the loot distribution fails.

If ML is inside an instance IsInInstance(), raider is in the same instance if the 1st return value of any of the following is the same as that of the ML:

  1. GetZoneText()
  2. GetInstanceInfo()
  3. G["DUNGEON_FLOOR" .. strupper(GetMapInfo() or "") .. NUM] for any NUM

I did a test in a heroic Antorus with all bosses dead. Zone text of GetRaidRosterInfo always returns "Antorus, the Burning Throne" for me, for every location inside Antorus. However, I am very sure while in the Eonar encounter area, it returned "Elunaria" sometime ago. It could be a bug that fixed recently, or it only returns that when Eonar boss is alive. So I need more test result when you progress the entire raid normally. I personally stop raiding in this expansion after mythic Antorus progression.

commented

Your tests agrees with mine and what I expected. I'll sit out the first boss in my raid tonight to fully confirm it.

I don't expect GetZoneText() to be useful. First off, I think it returns the name of any subzone you're in (i.e. wings in antorus), and secondly the return is most likely localized.

I'll run the following during my raid tonight:

local function executeTimer()
	for i = 1, GetNumGroupMembers() do
		local name, _,_,_,_,_, zone, _,_,_, ml = GetRaidRosterInfo(i)
		if ml then
			tinsert(RCLootCouncil.db.global.testLog, date("%X", time()) .." - "..name..": "..zone)
		elseif RCLootCouncil:UnitIsUnit(name, "player") then
			local iname, _, _, _, _, _, _, instanceMapID = GetInstanceInfo()
			tinsert(RCLootCouncil.db.global.testLog, date("%X", time()) .." - "..name..": "..zone.." | GetZoneText():"..(GetZoneText() or "")..
			" | InstanceName: "..(iname or "").." | InstanceMapID "..(instanceMapID or ""))
		end
	end
	RCLootCouncil:ScheduleTimer(executeTimer, 60)
end
executeTimer()

Recoding it every second seems a bit excessive, so I bumped it to 1 min.

commented

I did a test in the Ragefire Chasm dungeon with 2 characters. My lvl110 main (A) and a lvl10 starter account (B)

  1. B enters the dungeon and stands next to the entrance and A goes and kills the 1st boss. ENCOUNTER_START ENCOUNTER_END fires for B, but BOSS_KILL not fired. B is NOT eligible for the boss loot.
  2. A initiates the boss fight. B autoattacks the boss to join the fight, A makes the killing blow. ENCOUNTER_START ENCOUNTER_END BOSS_KILL fires for B and B is eligible for the loot.

Now I think BOSS_KILL can be used to determine whether the player has participated the encounter.

commented
  1. GetZoneText returns the zone text "Antorus, the Burning Throne", while GetSubZoneText returns the subzone. I don't think LFR wings in Antorus are ever used as zone text.
  2. The reason why I use both GetInstanceInfo and GetZoneText is that I am not sure which one GetRaidRosterInfo returns. Besides, G["DUNGEON_FLOOR" .. strupper(GetMapInfo() or "") .. NUM]. It is not a bad thing to check those if I am not sure. GetRaidRosterInfo does not always return the same result inside the instance one month ago. Waiting for your test result.
  3. Every second seems a bit excessive, but 1min seems too long. I want to know the zone return of GetRaidRosterInfo everywhere inside the raid instance, not limited to the boss fight area.
  4. All those zone stuffs I mentioned are localized. However, they are always in our localization. GetRaidRosterInfo returns zone in our localization, regardless the localization of the player we are querying. Therefore, those zone texts are comparable, as long as they are compared locally. We only need to worry about the localization issue when the zone text is transmitted to another computer. But in this case, ML just needs to call these API on his computer without needing to send or receive any more addon comm from the raiders. Thus, no worry about the localization issues.
commented

Can you check GetRaidRosterInfo every frame and record only when there is a change?

commented

My script

local z = nil
RCLootCouncil.db.global.testLog = RCLootCouncil.db.global.testLog or {}
local function executeTimer()
    for i = 1, GetNumGroupMembers() do
        local name, _, _, _, _, _, zone, _, _, _, ml = GetRaidRosterInfo(i)
        if RCLootCouncil:UnitIsUnit(name, "player") and z ~= zone then
            z = zone
            local iname, _, _, _, _, _, _, instanceMapID = GetInstanceInfo()
            tinsert(RCLootCouncil.db.global.testLog, date("%X", time()) .. " - " .. name .. ": " .. zone .. " | GetZoneText():" .. (GetZoneText() or "") ..
            " | InstanceName: " .. (iname or "") .. " | InstanceMapID " .. (instanceMapID or ""))
            print(zone)
        end
    end
    RCLootCouncil:ScheduleTimer(executeTimer, 0)
end
executeTimer()
commented

I did some tests in LFR wing2. I found that GetInstanceInfo returns the same instance name and instance id (1712), regardless of the location inside the instance and the LFR wing. GetRaidRosterInfo always return "Antorus, the Burning Throne" inside the instance for all my testing till now

Then I sit outside of the 1st boss (Garoth) in LFR wing1. I stand above the encounter playspace and not jump down the entire fight. The distance between me and the boss is roughly 100 yards. I got a very interesting result under a very poor internet connection.

  1. BOSS_KILL NOT fired. ENCOUNTER_END fired.
  2. I can NOT loot the boss.
  3. I AM saved to the 1st boss.
  4. I CAN bonus loot.
    This could be caused by poor internet connection that I disconnected once mid-fight. I'll retest on another character when I get time.
commented

For some reason my post from yesterday didn't stick, so here I go again...

Log from raid. Barrow is the ML, Potdisc is me.

The zone name from GetRaidRosterInfo is inconsistent. For Garothi, it reports "Edge of Discord" at 19:55:14 and 19:56:14, even though he stayed there until we killed it (and he finished looting) at 20:05:06.

Btw, I did exactly the same as you, with the same result (expect for the looting part due to ML). This is what I expected though. I didn't check if I got saved until later (~5 bosses in), and I was saved. However, I believe that's because one gets saved to the same instance lock as the leader, which is different from loot lock. I'll see if I can get time to do a pug to check.

Another example, "20:37:14 - Barrow: Den of the Devourers" - this was after we killed high command, about 30s after he finished looting, so he probably ran past it there (your script would have been good there) - but why didn't it report that name when we were actually fighting Felhounds from 20:09:56 to 20:13:47?

Also, interestingly enough, I dc'd just before we started Eonar (20:58:14), and did some /reloads afterwards, hence the jump in the log. After the dc, I was dead at the top of the stairs. I still got BOSS_KILL and loot - presumably because I was attacked by something and/or inside the boss area. On Garothi I was hit by several abilities even though I was outside the area, but that didn't "tag" me for the boss. Also, all Barrows "Elarian Sanctuary" reports coincides with the kill at 21:06:14, session ending at 21:08:25, followed by a 5 min break. Maybe GetRaidRosterInfo doesn't update properly in combat?

GetZoneText() returned "Elunaria" once seemingly random (although I was there at the time), but otherwise always returned "Antorus ...". This one off makes it unreliable imo.

Finally, the last entry is really weird. After killing Argus, we started looting at 22:59:20 (and I was there before the ML). I went to Dalaran afterwards, and had a PLAYER_ENTERING_WORLD at 23:02:09, i.e. I was still at the ship at 23:00:01 and 23:01:01. It seems to me I "switched" places internally between the GetRaidRosterInfo and GetInstanceInfo calls.

In conclusion
GetRaidRosterInfo is seemingly unreliable for determining if one is in the same instance as the ML. I'll use your script next raid to log all the changes though.
I've always known GetInstanceInfo to be reliable, and imo the best way to determine if one is in the same instance as the ML is to include the mapID in the lootTable.

Remaining issues
I'm not certain whether GetSavedInstanceInfo, GetNumSavedInstances and GetSavedInstanceEncounterInfo tells if you're able to receive loot from a boss, or merely if you're "saved" to it. Afaik there has been a difference between the two for a long time.

commented

Hi, I found an actual and precise API to determine the instance location of group members.
WHY DIDN'T I KNOW THIS BEFORE?
posY, posX, posZ, instanceID = UnitPosition("unit") Gamepedia link
The 4th return value of this API returns the current instance id of the unit. This API returns the 4th return value regardless of the location of the current player and the one being queried. (First three return values can be nil when the person being queried is in the restricted area (raid/dungeon/bg/arena)
The result of 4th return value:

1712 // Inside Antorus instance,
1669 // Any location on Argus (Antoran Waste/Mac'Aree/Krokuun)
1220 // Dalaran
389 // Inside Ragefire Chasm dungeon
1 // Ogrimmar, outside Ragefire dungeon

Thus, we can simply do the additional check in RCLootCouncilML:CanGiveLoot

if not IsInInstance() then
   return false, "ml_not_in_instance" // ML leaves the instance during a RC session?
end
if select(4, UnitPosition(winner)) ~= select(4, UnitPosition("player")) then
  return false, "not_in_instance"
end
// We don't run GetMasterLootCandidate if above fails. 
// Then if we run GetMasterLootCandidate and it timeouts, 
// the only possible reason is inventory full

My current test shows that this function returns accurate and consistent instance id and its value is updated in real time.

Other suggesions:

  1. Send the raider an automated message when ML attempts to give him the item, but fails because the raider is not in the instance or inventory is full
  2. Add visual indication in the voting frame to show the ML if the raider is in the instance. For example, show NAME(Out of instance) in the name column if not in the instance. Update the voting frame on every GROUP_ROSTER_UPDATE. I think this is a very convenient feature.
    1. If the current player is in an instance, mark raiders as out of instance if the 4th return of UnitPosition is different with the current player.
    2. If the current player is not in an instance, mark raiders as out of instance if the 1st return of UnitPosition is NOT nil. (First 3 returns of UnitPosition are nil if the unit is in an instance)
commented

I found a new way to check the eligibility of the loot. Research it if you are interested.

  1. guid1, quant1, guid2, quant2, ... = GetLootSourceInfo(lootSlot) gamepedia link

  2. canLoot, inRange = CanLootUnit(unitGUID) no gamepedia link, see usage in Addons\Blizzard_Tutorial\Blizzard_TutorialLogic.lua

I haven't tested in game, but the idea is to send the loot source GUID with the loot table.
If the raider fails CanLootUnit, autopass

Send one GUID for each item is very costly, but the new serializer done by me will help, as duplicate strings are only serialized in plain text once.

Potential issues:

  1. When does CanLootUnit return a valid result after a reload?
    CanLootUnit returns the correct result immediately after reload when the corpse is next to me.
  2. Does CanLootUnit return a valid result when the corpse is very far way or in the different subzone of the instance compared to the current player?
    Return nil if the corpse is not in the same instance. Not sure what happens if far away but in the same instance.
  3. After the corpse has been fully looted by ML or looted by myself in peronsalloot, CanLootUnit no longer return true.
    Thus, the result(true/false) of CanLootUnit of all sourceGUID of all recent looted items or recent loot table items should be stored in SV.
  4. I am very curious if COMBAT_LOG_EVENT_UNFILTERED record the GUID of the chests after Eonar/Argus encounter.
    Did a quick test on the behavior of loot chest on Hymdall in Hall of Valor. The GUID of the loot chest looks like "GameObject-0-3023-1477-329-258968-000036D88C". CanLootUnit always returns nil for that GUID. COMBAT_LOG_EVENT_UNFILTERED does NOT track that. BOSS_KILL still fires even if the boss is actually not killed in this encounter.

Seems boss whose loot dropped as chest cannot be tracked using this method. So I think BOSS_KILL is still the better way to track it?

I'm not certain whether GetSavedInstanceInfo, GetNumSavedInstances and GetSavedInstanceEncounterInfo tells if you're able to receive loot from a boss, or merely if you're "saved" to it. Afaik there has been a difference between the two for a long time.

I don't think Blizzard stores separate information whether the user has looted the boss before and whether the user has saved to the boss. It does not make sense to store both. I don't think it's possible to be eligible for the loot if the player is saved to the encounter when it starts.
Though I didn't actually loot LFR Garothi, I was saved to Garothi and the Raid Finder frame also shows I have "Already Looted" Garothi. Today I rekilled LFR Garothi and I can NOT loot the boss. I saw the bonus roll popup again, but this is normal, as bonus roll does not require loot eligibility.
It is sad to lose both lockout and the one loot attempt at the same time. I think this is just a Blizzard bug that happens in some rare cases.

commented

Idea to implement the autopass:
To make this simple, let's first implement this feature only in direct mode (Master Loot), not considering award later or personalloot. Not going to store anything in SV and not going to make it work perfectly (but never false autopass) when raider reloads between RC session and encounter ends.
All of the time recorded is the value returned by GetServerTime(). This is an epoch time of the server synchronized across the game client, irrelevant to the local computer time and irrelevant to the server time zone.

  1. When PLAYER_LOGIN, store the login time
  2. When ENCOUNTER_END WITH A KILL, store the time and stores the encounter lockout status and reset the variable of BOSS_KILL
  3. When BOSS_KILL, record this in a variable.
  4. When ML starts a RC session, send the time of the most recent ENCOUNTER_END(with a kill) and its encounter id with the loot table. Raider autopasses if ALL of the following is true.
    1. The raider logins earlier than the time of loot table. (Ensure no false autopass)
    2. If the raider's most recent ENCOUNTER_END(with a kill) time or encounter id does not closely match the loot table time --> Raider is not in the instance during the encounter, autopass. Otherwise, If the raider has no BOSS_KILL ---> Raider didn't tag the boss, autopass. Otherwise, if the raider was saved at the time of the most recent ENCOUNTER_END(with a kill) ---> Raider was saved, autopass.

I am emphasizing to only do stuff on ENCOUNTER_END WITH A KILL because otherwise bloodlust reset will pollute the data.
Btw, this autopass should not be turned off in the user option.

commented

Not in instance

There's really two sides to this:

1. Player is outside the instance during a kill
He won't get any BOSS_KILL event (probably not even ENCOUNTER_START/END). He should silently send NOTINRAID response to all items just as now. The check for this should be updated though.

2. Player leaves the instance before item is awarded.
Thus he can't receive any loot directly. There's two ways of dealing with this.

  1. The ML can check the winner's zone just before awarding (UnitPosition seems like the best candidate so far) and report it/use that as a fail message.
  2. Dynamically check players' positions, either locally at the ML/council side, or by sending a small message every time one changes zone. This could be incorporated in the name (as suggested in #158), but I don't really like that as that column is pretty much full already, and adding "Out of instance" makes it hard to see the name. I'd much prefer to add the message to the response, or even replace the response entirely with "Out of instance". Another option is to create some sort of overlay/marker to indicate something's wrong.

Send the raider an automated message when ML attempts to give him the item, but fails because the raider is not in the instance or inventory is full.

Yes - but it should probably be togglable just in case some people prefer not to have automated messages.

Add visual indication ...

Mentioned above. Are you certain GROUP_ROSTER_UPDATE fires when someone leaves the instance? I seem to remember it doesn't.


CanLootUnit
Sounds promising. Would need testing for range of course. It removes the need to check for instance locks when it's usable, but if it doesn't work for chests, then it's probably not worth it. You would also only need send the GUID once for each kill, as it should be the same for all items.

BOSS_KILL still fires even if the boss is actually not killed in this encounter.

That's to be expected. A "kill" merely means "you won the encounter" - doesn't matter if the boss actually dies in a lore perspective.


Raid lockouts

I don't have any real proof, but I'm pretty sure there's a difference. For example, in the beginning of Antorus before completing the skip quest, we had some people kill up to and including Coven in a pug group. They would be the first to enter the raid, so that we used their lockout. All the first bosses are down in the raid, and once we killed Aggramar, the rest of us got saved to their lockout. This did not mean, however, that we couldn't get loot of the first bosses, it just ment the bosses were dead, and the instance reflected that.

Autopasses

First off ENCOUNTER_END WITH A KILL == BOSS_KILL. We probably don't even need ENCOUNTER_END for this.

Secondly, do we really need the time?

  1. Store BOSS_KILL when fired (in SV in case of a /reload before session start).
  2. ML starts session, sends encounterID in the lootTable.
    1. Raider's BOSS_KILL matches the encounterID from lootTable -> proceed as normal.
    2. No BOSS_KILL he's either outside or didn't tag. If he's outside, that should be caught with the "is in instance" check mentioned above, i.e. -> "NOTINRAID" response. If he didn't tag, it means no BOSS_KILL but select(4, UnitPosition(ML)) == select(4, UnitPosition("player")) -> No tag response.
    3. Raider was saved at pull (probably just check at ENCOUNTER_START) and has BOSS_KILL -> saved response.

Time doesn't seem to be required.

I am emphasizing to only do stuff on ENCOUNTER_END WITH A KILL because otherwise bloodlust reset will pollute the data.

I.e. only do stuff on BOSS_KILL. But it doesn't really matter too much, as we would need to receive a lootTable before we use the data anyway. We do need to make a special case for sessions that does not involve a boss - but we could just use encounterID = 0 or something like that.

Btw, this autopass should not be turned off in the user option.

Yes. I also don't like to call this "autopass" - it's more like auto responses, which I labeled "Status texts" in the filtering menus.

commented

I found a method to convert instance id to its localized string:
Tooltip parsing: instancelock::ID
For example, tooltip parsing instancelock::1712 Shows
"UNKNOWN's Antorus, the Burning Throne Instance Lock"
parse this against format(INSTANCE_LOCK_SS, UNKNOWNOBJECT) will do the trick

commented

First off, ENCOUNTER_END with a kill (Last argument returned by ENCOUNTER_END is 1) is not equal to BOSS_KILL.
If a player afks inside the instance, he will see ENCOUNTER_END with a kill, but no BOSS_KILL.

My solution is a little bit more comprehensive that it gives the correct response if the raider without touching the boss hearthstones or enters the instance immediately after encounter ends, before RC session starts.

commented

btw, a good Sublime package for WoW addon:
https://packagecontrol.io/packages/WoWDevelopment

commented

I use Atom, but thanks anyway.