Merge pull request #70 from m4tjz/patch-1

@m4tjz 
Fix Spell Reflection Tracking
This commit is contained in:
Tercio Jose
2020-05-30 19:26:34 -03:00
committed by GitHub
+202 -36
View File
@@ -109,8 +109,43 @@
local ignore_actors = {}
--> spell containers for special cases
local monk_guard_talent = {} --guard talent for bm monks
--> holds transitory information about reflected spells
local reflected = {}
--> spell reflection
local reflection_damage = {} --self-inflicted damage
local reflection_debuffs = {} --self-inflicted debuffs
local reflection_events = {} --spell_missed reflected events
local reflection_auras = {} --active reflecting auras
local reflection_dispels = {} --active reflecting dispels
local reflection_spellid = {
--> we can track which spell caused the reflection
--> this is used to credit this aura as the one doing the damage
[23920] = true, --warrior spell reflection
[216890] = true, --warrior spell reflection (pvp talent)
[213915] = true, --warrior mass spell reflection
[212295] = true, --warlock nether ward
}
local reflection_dispelid = {
--> some dispels also reflect, and we can track them
[122783] = true, --monk diffuse magic
--[205604] = true, --demon hunter reverse magic
--> this last one is an odd one, like most dh spells is kindy buggy combatlog wise
--> for now it doesn't fire SPELL_DISPEL events even when dispelling stuff (thanks blizzard)
--> maybe someone can figure out something to track it... but for now it doesnt work
}
local reflection_ignore = {
--> common self-harm spells that we know weren't reflected
--> this list can be expanded
[111400] = true, --warlock burning rush
[124255] = true, --monk stagger
[196917] = true, --paladin light of the martyr
[217979] = true, --warlock health funnel
--> bugged spells
[315197] = true, --thing from beyond grand delusions
--> this corruption when reflected causes insane amounts of damage to the thing from beyond
--> anywhere from a few hundred thousand damage to over 50 millons
--> filtering it the best course of action as nobody should care about this damage
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
@@ -465,21 +500,47 @@
-- return
--end
--> this cast may have been spell reflected
if (who_serial == alvo_serial) then
local idx = who_serial
if (reflected[idx] and reflected[idx].serial and DetailsFramework:IsNearlyEqual(reflected[idx].time, time, 3.0)) then
--> the 'SPELL_MISSED' with type 'REFLECT' appeared first -> log the reflection
who_serial = reflected[idx].serial
who_name = reflected[idx].name
who_flags = reflected[idx].who_flags
reflected[idx] = nil
return parser:spell_dmg (token, time, who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags, alvo_flags2, spellid, spellname, spelltype, amount, -1, nil, nil, nil, nil, false, false, false, false)
------------------------------------------------------------------------------------------------
--> spell reflection
if (who_serial == alvo_serial and not reflection_ignore[spellid]) then
--> this spell could've been reflected, check it
if (reflection_events[who_serial] and reflection_events[who_serial][spellid] and time-reflection_events[who_serial][spellid].time > 3.5 and (not reflection_debuffs[who_serial] or (reflection_debuffs[who_serial] and not reflection_debuffs[who_serial][spellid]))) then
--> here we check if we have to filter old reflection data
--> we check for two conditions
--> the first is to see if this is an old reflection
--> if more than 3.5 seconds have past then we can say that it is old... but!
--> the second condition is to see if there is an active debuff with the same spellid
--> if there is one then we ignore the timer and skip this
--> this should be cleared afterwards somehow... don't know how...
reflection_events[who_serial][spellid] = nil
if (next(reflection_events[who_serial]) == nil) then
--> there should be some better way of handling this kind of filtering, any suggestion?
reflection_events[who_serial] = nil
end
end
local reflection = reflection_events[who_serial] and reflection_events[who_serial][spellid]
if (reflection) then
--> if we still have the reflection data then we conclude it was reflected
reflection_events[who_serial][spellid].time = time
--> extend the duration of the timer to catch the rare channelling spells
who_serial = reflection.who_serial
who_name = reflection.who_name
who_flags = reflection.who_flags
-- crediting the source of the reflection aura
spellid = reflection.spellid
spellname = reflection.spellname
spelltype = reflection.spelltype
--> data of the aura that caused the reflection
return parser:spell_dmg(token,time,who_serial,who_name,who_flags,alvo_serial,alvo_name,alvo_flags,alvo_flags2,spellid,spellname,spelltype,amount,-1,nil,nil,nil,nil,false,false,false,false)
else
--> otherwise log the amount for the 'SPELL_MISSED' event
reflected[idx] = {
--> saving information about this damage because it may occurred before a reflect event
reflection_damage[who_serial] = reflection_damage[who_serial] or {}
reflection_damage[who_serial][spellid] = {
amount = amount,
time = time
time = time,
}
end
end
@@ -1454,26 +1515,51 @@
end
--> It is non deterministic whether the 'SPELL_DAMAGE' or the 'SPELL_MISSED' log appears first. We handle both cases.
elseif (missType == "REFLECT") then
if (reflected[who_serial] and reflected[who_serial].amount > 0 and DetailsFramework:IsNearlyEqual(reflected[who_serial].time, time, 3.0)) then
--> 'SPELL_DAMAGE' was logged first -> log the reflect here
--> We cannot rely on amountMissed which is empty in the reflection case
local amount = reflected[who_serial].amount
reflected[who_serial] = nil
return parser:spell_dmg (token, time, alvo_serial, alvo_name, alvo_flags, who_serial, who_name, who_flags, nil, spellid, spellname, spelltype, amount, -1, nil, nil, nil, nil, false, false, false, false)
else
--> otherwise write out information used in the 'SPELL_DAMAGE' event
reflected[who_serial] = {
serial = alvo_serial,
name = alvo_name,
who_flags = alvo_flags,
time = time,
amount = 0
}
------------------------------------------------------------------------------------------------
--> spell reflection
elseif (missType == "REFLECT" and reflection_auras[alvo_serial]) then
--> a reflect event and we have the reflecting aura data
if (reflection_damage[who_serial] and reflection_damage[who_serial][spellid] and time-reflection_damage[who_serial][spellid].time > 3.5 and (not reflection_debuffs[who_serial] or (reflection_debuffs[who_serial] and not reflection_debuffs[who_serial][spellid]))) then
--> here we check if we have to filter old damage data
--> we check for two conditions
--> the first is to see if this is an old damage
--> if more than 3.5 seconds have past then we can say that it is old... but!
--> the second condition is to see if there is an active debuff with the same spellid
--> if there is one then we ignore the timer and skip this
--> this should be cleared afterwards somehow... don't know how...
reflection_damage[who_serial][spellid] = nil
if (next(reflection_damage[who_serial]) == nil) then
--> there should be some better way of handling this kind of filtering, any suggestion?
reflection_damage[who_serial] = nil
end
end
local damage = reflection_damage[who_serial] and reflection_damage[who_serial][spellid]
local reflection = reflection_auras[alvo_serial]
if (damage) then
--> damage ocurred first, so we have its data
amount = reflection_damage[who_serial][spellid].amount
alvo_serial = reflection.who_serial
alvo_name = reflection.who_name
alvo_flags = reflection.who_flags
spellid = reflection.spellid
spellname = reflection.spellname
spelltype = reflection.spelltype
--> crediting the source of the aura that caused the reflection
--> also saying that the damage came from the aura that reflected the spell
reflection_damage[who_serial][spellid] = nil
if next(reflection_damage[who_serial]) == nil then
--> this is so bad at clearing, there should be a better way of handling this
reflection_damage[who_serial] = nil
end
return parser:spell_dmg(token,time,alvo_serial,alvo_name,alvo_flags,who_serial,who_name,who_flags,nil,spellid,spellname,spelltype,amount,-1,nil,nil,nil,nil,false,false,false,false)
else
--> saving information about this reflect because it occurred before the damage event
reflection_events[who_serial] = reflection_events[who_serial] or {}
reflection_events[who_serial][spellid] = reflection
reflection_events[who_serial][spellid].time = time
end
else
--colocando aqui apenas pois ele confere o override dentro do damage
@@ -2001,6 +2087,22 @@
who_flags = 0xa48
who_serial = ""
end
------------------------------------------------------------------------------------------------
--> spell reflection
if (reflection_spellid[spellid]) then
--> this is a spell reflect aura
--> we save the info on who received this aura and from whom
--> this will be used to credit this spell as the one doing the damage
reflection_auras[alvo_serial] = {
who_serial = who_serial,
who_name = who_name,
who_flags = who_flags,
spellid = spellid,
spellname = spellname,
spelltype = spellschool,
}
end
------------------------------------------------------------------------------------------------
--> handle shields
@@ -2057,6 +2159,15 @@
who_serial, who_name, who_flags = "", enemyName, 0xa48
end
------------------------------------------------------------------------------------------------
--> spell reflection
if (who_serial == alvo_serial and not reflection_ignore[spellid]) then
--> self-inflicted debuff that could've been reflected
--> just saving it as a boolean to check for reflections
reflection_debuffs[who_serial] = reflection_debuffs[who_serial] or {}
reflection_debuffs[who_serial][spellid] = true
end
if (_in_combat) then
------------------------------------------------------------------------------------------------
@@ -2446,7 +2557,41 @@
local enemyName = GetSpellInfo(315161)
who_serial, who_name, who_flags = "", enemyName, 0xa48
end
------------------------------------------------------------------------------------------------
--> spell reflection
if (reflection_dispels[alvo_serial] and reflection_dispels[alvo_serial][spellid]) then
--> debuff was dispelled by a reflecting dispel and could've been reflected
--> save the data about whom dispelled who and the spell that was dispelled
local reflection = reflection_dispels[alvo_serial][spellid]
reflection_events[who_serial] = reflection_events[who_serial] or {}
reflection_events[who_serial][spellid] = {
who_serial = reflection.who_serial,
who_name = reflection.who_name,
who_flags = reflection.who_flags,
spellid = reflection.spellid,
spellname = reflection.spellname,
spelltype = reflection.spelltype,
time = time,
}
reflection_dispels[alvo_serial][spellid] = nil
if (next(reflection_dispels[alvo_serial]) == nil) then
--suggestion on how to make this better?
reflection_dispels[alvo_serial] = nil
end
end
------------------------------------------------------------------------------------------------
--> spell reflection
if (reflection_debuffs[who_serial] and reflection_debuffs[who_serial][spellid]) then
--> self-inflicted debuff was removed, so we just clear this data
reflection_debuffs[who_serial][spellid] = nil
if (next(reflection_debuffs[who_serial]) == nil) then
--> better way of doing this? accepting suggestions
reflection_debuffs[who_serial] = nil
end
end
if (_in_combat) then
------------------------------------------------------------------------------------------------
--> buff uptime
@@ -3367,6 +3512,22 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
este_jogador.dispell_spells = container_habilidades:NovoContainer (container_misc)
este_jogador.dispell_oque = {}
end
------------------------------------------------------------------------------------------------
--> spell reflection
if (reflection_dispelid[spellid]) then
--> this aura could've been reflected to the caster after the dispel
--> save data about whom was dispelled by who and what spell it was
reflection_dispels[alvo_serial] = reflection_dispels[alvo_serial] or {}
reflection_dispels[alvo_serial][extraSpellID] = {
who_serial = who_serial,
who_name = who_name,
who_flags = who_flags,
spellid = spellid,
spellname = spellname,
spelltype = spelltype,
}
end
------------------------------------------------------------------------------------------------
--> add amount
@@ -5207,7 +5368,12 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
_table_wipe (npcid_cache)
_table_wipe (ignore_death)
_table_wipe (reflected)
_table_wipe (reflection_damage)
_table_wipe (reflection_debuffs)
_table_wipe (reflection_events)
_table_wipe (reflection_auras)
_table_wipe (reflection_dispels)
damage_cache = setmetatable ({}, _detalhes.weaktable)
damage_cache_pets = setmetatable ({}, _detalhes.weaktable)