jp-ganis / JPS

Protected LUA DPS Addon
32 stars 46 forks source link

spell interrupting #393

Open ghost opened 10 years ago

ghost commented 10 years ago

Yeah, we got already some kind of issue. How we could implement a random interrupt delay? (I was asked yesterday if I use a kick addon since I interrupt often very fast as melee)

Thought about something like:

local interruptDelay = 0
local interruptDelaySpellUnit = ""
local interruptDelayTimestamp = GetTime()

function jps.kickDelayFinished(unit) min
    if jps.IsCasting(unit) then
        local castLeft, spellName = jps.CastTimeLeft(unit) or jps.ChannelTimeLeft(unit)
        if castLeft < 2 then return true end

        if GetTime() - interruptDelayTimestamp > 5 or  interruptDelaySpellUnit ~= spellName..unit then -- recalc delay value
            maxDelay = castLeft-2
            if(castLeft <= 2.5) then maxDelay = castLeft - 0.5 end
            minDelay = 0.5
            interruptDelay = Math.random(minDelay,maxDelay)
            interruptDelaySpellUnit = spellName..unit
            interruptDelayTimestamp = GetTime()
        end

        if interruptDelay <= castLeft and  interruptDelaySpellUnit == spellName..unit then
            interruptDelaySpellUnit = ""
            interruptDelay = 0
            return true
        end
        return false
    end
    if interruptDelaySpellUnit ~= "" then
        interruptDelaySpellUnit = ""
        interruptDelay = 0
    end
    return true
end

Usage:

 {"Kick" , 'jps.shouldKick("target") and jps.kickDelayFinished("target")'},
htordeux commented 10 years ago

there is already ain jps a fct jps.shouldKickLag(unit) that interrupts at the end of enemy cast

function jps.shouldKickLag(unit) if not jps.Interrupts then return false end if unit == nil then unit = "target" end local targetspell, , , , _, castendTime, , , unInterruptable = UnitCastingInfo(unit) local channelling, , , , _, chanelendTime, , notInterruptible = UnitChannelInfo(unit) if target_spell == L["Release Aberrations"] then return false end if cast_endTime == nil then cast_endTime = 0 end if chanel_endTime == nil then chanel_endTime = 0 end if target_spell and unInterruptable == false then if jps.CastTimeLeft(unit) < 1 then return true end elseif channelling and notInterruptible == false then if jps.ChannelTimeLeft(unit) < 1 then return true end end return false end

ghost commented 10 years ago

hmm but what if the player is currently casting/channeling and miss the interrupt time window ?

htordeux commented 10 years ago

perhaps something like this, now depends some casting spell needs to do not ne interrupted

function jps.shouldKickPlayerIsCasting(unit) local Kicktable = {"Kick" , 'false'} if not jps.IsCasting() and jps.shouldKickLag(unit) then Kicktable = {"Kick" , 'true'} if jps.IsCasting() and jps.shouldKickLag(unit) then SpellStopCasting() Kicktable = {"Kick" , 'true'} elseif jps.IsCasting() and jps.shouldKick(unit) then -- cast & channel if jps.CastTimeLeft() > jps.CastTimeLeft(unit) then SpellStopCasting() Kicktable = {"Kick" , 'true'} elseif jps.CastTimeLeft() > jps.ChannelTimeLeft(unit) then SpellStopCasting() Kicktable = {"Kick" , 'true'} elseif jps.ChannelTimeLeft() > jps.ChannelTimeLeft(unit) then SpellStopCasting() Kicktable = {"Kick" , 'true'} elseif jps.ChannelTimeLeft() > jps.CastTimeLeft(unit) then SpellStopCasting() Kicktable = {"Kick" , 'true'} end end return Kicktable end

ghost commented 10 years ago

hmmm sorry but the shouldKickLag function is more pvp use I think, in PVE you have some bosses which even cast/channel until interrupted or the cast duration is > 5-7 sec... and would this work for melees?

htordeux commented 10 years ago

Perhaps a fct below seems better

function jps.shouldKickCast(unit) local Kicktable = {"Kick" , 'false'} if jps.shouldKick(unit) then -- Target is casting or channeling local castLeftUnit = jps.CastTimeLeft(unit) + jps.ChannelTimeLeft(unit) -- 0 + 3 local castLeftPlayer = jps.CastTimeLeft() + jps.ChannelTimeLeft() -- 2 + 0 local GCD = 1 + jps.Lag if castLeftPlayer == 0 if castLeftUnit > GCD then Kicktable = {"Kick" , 'false'} else if castLeftUnit + GCD > castLeftPlayer then -- target is casting longer then player at least 1 sec Kicktable = {"Kick" , 'false'} elseif castLeftUnit + GCD < castLeftPlayer then -- target is casting shorter then player SpellStopCasting() Kicktable = {"Kick" , 'true'} end end end end return Kicktable end

kirk24788 commented 10 years ago

If you need a random number generator, mersenne twister is an option - here's a lua implementation: http://pastebin.com/D1th4Htw ... ;)

Haven't tested it but it should work fine...don't know how fast it is though...maybe use the cache funciton to cache this value...