Announcement

Collapse

Forum Rules

  • No flaming or derogatory remarks, directly or through insinuation.
  • No discussion, sharing or referencing illegal software such as hacks, keygen, cracks and pirated software.
  • No offensive contents, including but not limited to, racism, gore or pornography.
  • No excessive spam/meme, i.e. copious one liners in a short period of time, typing with all caps or posting meme responses (text/image).
  • No trolling, including but not limited to, flame incitation, user provocation or false information distribution.
  • No link spamming or signature advertisements for content not specific to Dota 2.
  • No Dota 2 key requests, sell, trade etc.
  • You may not create multiple accounts for any purpose, including ban evasion, unless expressly permitted by a moderator.

  • Please search before posting. One thread per issue. Do not create another thread if there is an existing one already.
  • Before posting anything, make sure you check out all sticky threads (e.g., this). Do not create new threads about closed ones.
  • It is extremely important that you post in correct forum section.

  • Balance discussion only in Misc.
  • All art related (such as hero model) feedbacks go to Art Feedback Forum.
  • All matchmaking feedback should go here: Matchmaking Feedback
  • All report/low priority issues should go here: Commend/Report/Ban Feedback
  • No specific workshop item feedback. These should go to workshop page of that item.
  • When posting in non-bugs section (such as this), use [Bugs], [Discussion] or [Suggestion] prefix in your thread name.



In case you object some action by a moderator, please contact him directly through PM and explain your concerns politely. If you are still unable to resolve the issue, contact an administrator. Do not drag these issues in public.



All rules are meant to augment common sense, please use them when not conflicted with aforementioned policies.
See more
See less

[Intended?] Slark's Essence Shift lacks an Attack Speed threshold check

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [Intended?] Slark's Essence Shift lacks an Attack Speed threshold check

    Slark is able to shift essence with an Attack Speed lower than 50
    he shouldn't be able to shift essence when his Attack Speed is below 50


    One may call this as an intended change, but I would say no and defend otherwise.
    I may provide a jass explanation for this if requested

  • #2
    I considered this an intended change, i do hope it stays the way it is now.

    Comment


    • #3
      Surely this was protection to stop him essence shifting when he kept failing attacks at low attack speed? This doesn't happen anymore and works when the attack lands instead so surely this is a fix? But I'd love to hear your reasoning.

      And reading your playdota thread this is the EXACT reason it doesn't work in dota 1... This isn't an issue in dota 2, and it can be checked properly, just like all the other on-attack modifiers... So... Yeah... Why the hell isn't this intended?
      Last edited by Wyn-Ryder; 04-05-2013, 06:31 PM.
      Comprehensive Damage Reduction & Amplifications Dota 2 Guide

      Comment


      • #4
        Being reluctant with intended changes is alright but in this case I don't see the point in copying a dota 1 workaround for a problem that is nonexistent in dota 2, am I missing something here?

        Comment


        • #5
          No such thing

          Essence Shift in DotA takes its effect after passing through numereous checks.
          I will try to explain it simple but complete, without making it sound too complicated; and I will add the full function chain for the Essence Shift at the end of this post:

          1 - Leveling up this skill A1HR (Essence Shift) activates everything
          2 - ATTACKED event triggers the next function
          3 - Check if the attacker has the ability A1HR over level zero and is Slark
          4 - Check if the attacked unit is a hero and not a structure and not Roshan and an enemy of the attacker
          5 - Check if the triggered cooldown is off the cooldown
          6 - Put the triggered cooldown on cooldown (0.45 - 0.05*lvl)
          7 - Either DAMAGED event, or the 1 sec countdown timer triggers the next function
          8 - If the trigger was the DAMAGED event and the damage source was the Slark; disable the trigger, and shift essence after 0.01 second
          8 - If the trigger was the 1 sec countdown timer, disable the trigger


          Wow, went better than I thought. I think this is really simple now. It only needs these two extra info:
          ATTACKED event: it is when an attacker begins its attacking animation against the ATTACKED unit, the t = 0
          DAMAGED event: it is when a unit receives a damage, the t = attackPoint(oftheAttacker)


          If a Slark fails to land the attack he started; Essence Shift simply won't shift anything, not because of the timer, but because of the DAMAGED event is not fulfilled.
          Whether there be a timer or not, Slark may not shift essence until he starts an ATTACK, and then deals DAMAGE to the target.

          The timer effectively prevents Slark from shifting essence if it takes him longer than 1 second for him to fulfill DAMAGED event after breaching the ATTACKED event.
          Slark has the attack point 0.5. With -50 IAS, his attack point increases to 1 sec. -50 IAS and anything lower than that makes him unable to shift essence.


          Setting that timer to be anything higher than 2.5 would allow Slark to shift essence at any IAS, yet it is set to 1, which achieves almost nothing else than an IAS threshold.
          Promised JASS:


          Code:
          function Func3542 takes nothing returns boolean
            local trigger loc_trigger01=GetTriggeringTrigger()
            local integer loc_integer01=GetHandleId(loc_trigger01)
            local unit loc_unit01=(LoadUnitHandle(hashtable001,(loc_integer01),(2)))
            local unit loc_unit02=GetDyingUnit()
            if GetOwningPlayer(GetKillingUnit())==GetOwningPlayer(loc_unit01)and IsUnitType(loc_unit02,UNIT_TYPE_HERO)==true and IsUnitIllusion(loc_unit02)==false then
            endif
            set loc_trigger01=null
            set loc_unit01=null
            set loc_unit02=null
            return false
          endfunction
          
          function Func3543 takes nothing returns boolean
            local trigger loc_trigger01=GetTriggeringTrigger()
            local integer loc_integer01=GetHandleId(loc_trigger01)
            local unit loc_unit01=(LoadUnitHandle(hashtable001,(loc_integer01),(2)))
            local unit loc_unit02=(LoadUnitHandle(hashtable001,(loc_integer01),(17)))
            local integer loc_integer02=(LoadInteger(hashtable001,(loc_integer01),(422)))
            local integer loc_integer03=(LoadInteger(hashtable001,(loc_integer01),(423)))
            local integer loc_integer04=(LoadInteger(hashtable001,(loc_integer01),(424)))
            if GetTriggerEventId()==EVENT_UNIT_DEATH then
              if(LoadBoolean(hashtable001,(loc_integer01),(276)))==false and GetTriggerUnit()==loc_unit01 then
                call SaveBoolean(hashtable001,(loc_integer01),(276),(true))
                call SetHeroAgi(loc_unit01,GetHeroAgi(loc_unit01,false)-loc_integer02-loc_integer03-loc_integer04,true)
              elseif(LoadBoolean(hashtable001,(loc_integer01),(277)))==false and GetTriggerUnit()==loc_unit02 then
                call SaveBoolean(hashtable001,(loc_integer01),(277),(true))
                call SetHeroAgi(loc_unit02,GetHeroAgi(loc_unit02,false)+loc_integer02,true)
                call SetHeroStr(loc_unit02,GetHeroStr(loc_unit02,false)+loc_integer03,true)
                call SetHeroInt(loc_unit02,GetHeroInt(loc_unit02,false)+loc_integer04,true)
              endif
            else
              if(LoadBoolean(hashtable001,(loc_integer01),(276)))==false then
                call SaveBoolean(hashtable001,(loc_integer01),(276),(true))
                call SetHeroAgi(loc_unit01,GetHeroAgi(loc_unit01,false)-loc_integer02-loc_integer03-loc_integer04,true)
              endif
              if(LoadBoolean(hashtable001,(loc_integer01),(277)))==false then
                call SaveBoolean(hashtable001,(loc_integer01),(277),(true))
                call SetHeroAgi(loc_unit02,GetHeroAgi(loc_unit02,false)+loc_integer02,true)
                call SetHeroStr(loc_unit02,GetHeroStr(loc_unit02,false)+loc_integer03,true)
                call SetHeroInt(loc_unit02,GetHeroInt(loc_unit02,false)+loc_integer04,true)
              endif
              call FlushChildHashtable(hashtable001,(loc_integer01))
              call Func0035(loc_trigger01)
            endif
            set loc_trigger01=null
            set loc_unit01=null
            set loc_unit02=null
            return false
          endfunction
          
          function Func3544 takes unit loc_unit01,unit loc_unit02 returns nothing
            local integer loc_integer01=GetUnitAbilityLevel(loc_unit01,'A1HR')
            local integer loc_integer02=Func0045(loc_unit02)
            local trigger loc_trigger01=CreateTrigger()
            local integer loc_integer03=GetHandleId(loc_trigger01)
            local integer loc_integer04
            local integer loc_integer05
            local integer loc_integer06
            local real loc_real01
            if loc_integer02==2 then
              set loc_integer04=IMinBJ(GetHeroAgi(loc_unit02,false)-1,1)
              set loc_integer05=IMinBJ(GetHeroStr(loc_unit02,false)-1,1)
              set loc_integer06=IMinBJ(GetHeroInt(loc_unit02,false)-1,1)
            elseif loc_integer02==3 then
              set loc_integer04=IMinBJ(GetHeroAgi(loc_unit02,false)-1,1)
              set loc_integer05=IMinBJ(GetHeroStr(loc_unit02,false)-1,1)
              set loc_integer06=IMinBJ(GetHeroInt(loc_unit02,false)-1,1)
            elseif loc_integer02==1 then
              set loc_integer04=IMinBJ(GetHeroAgi(loc_unit02,false)-1,1)
              set loc_integer05=IMinBJ(GetHeroStr(loc_unit02,false)-1,1)
              set loc_integer06=IMinBJ(GetHeroInt(loc_unit02,false)-1,1)
            endif
            call SetHeroAgi(loc_unit01,GetHeroAgi(loc_unit01,false)+loc_integer04+loc_integer06+loc_integer05,true)
            call SetHeroAgi(loc_unit02,GetHeroAgi(loc_unit02,false)-loc_integer04,true)
            call SetHeroStr(loc_unit02,GetHeroStr(loc_unit02,false)-loc_integer05,true)
            call SetHeroInt(loc_unit02,GetHeroInt(loc_unit02,false)-loc_integer06,true)
            call SaveInteger(hashtable001,(loc_integer03),(422),(loc_integer04))
            call SaveInteger(hashtable001,(loc_integer03),(424),(loc_integer06))
            call SaveInteger(hashtable001,(loc_integer03),(423),(loc_integer05))
            call SaveUnitHandle(hashtable001,(loc_integer03),(2),(loc_unit01))
            call SaveUnitHandle(hashtable001,(loc_integer03),(17),(loc_unit02))
            call SaveBoolean(hashtable001,(loc_integer03),(276),(false))
            call SaveBoolean(hashtable001,(loc_integer03),(277),(false))
            if loc_integer01==1 then
              set loc_real01=15
            elseif loc_integer01==2 then
              set loc_real01=30
            elseif loc_integer01==3 then
              set loc_real01=60
            elseif loc_integer01==4 then
              set loc_real01=120
            endif
            call TriggerRegisterTimerEvent(loc_trigger01,loc_real01,false)
            call TriggerRegisterUnitEvent(loc_trigger01,loc_unit01,EVENT_UNIT_DEATH)
            call TriggerRegisterUnitEvent(loc_trigger01,loc_unit02,EVENT_UNIT_DEATH)
            call TriggerAddCondition(loc_trigger01,Condition(function Func3543))
            set loc_trigger01=null
          endfunction
          
          function Func3545 takes nothing returns boolean
            local trigger loc_trigger01=GetTriggeringTrigger()
            local integer loc_integer01=GetHandleId(loc_trigger01)
            local unit loc_unit01=(LoadUnitHandle(hashtable001,(loc_integer01),(2)))
            local unit loc_unit02=(LoadUnitHandle(hashtable001,(loc_integer01),(17)))
            if GetTriggerEventId()!=EVENT_UNIT_DEATH then
              call Func3544(loc_unit01,loc_unit02)
            endif
            call FlushChildHashtable(hashtable001,(loc_integer01))
            call Func0035(loc_trigger01)
            set loc_trigger01=null
            set loc_unit01=null
            set loc_unit02=null
            return false
          endfunction
          
          function Func3546 takes nothing returns boolean
            local trigger loc_trigger01=GetTriggeringTrigger()
            local integer loc_integer01=GetHandleId(loc_trigger01)
            local integer loc_integer02=(LoadInteger(hashtable001,(loc_integer01),(30)))
            local unit loc_unit01=Func0022(loc_integer02)
            local unit loc_unit02=(LoadUnitHandle(hashtable001,(loc_integer01),(2)))
            if GetTriggerEventId()==EVENT_UNIT_DAMAGED then
              if GetEventDamageSource()==loc_unit02 then
                call DisableTrigger(loc_trigger01)
                call Func0021(loc_integer02)
                call FlushChildHashtable(hashtable001,(loc_integer01))
                call Func0035(loc_trigger01)
                set loc_trigger01=CreateTrigger()
                set loc_integer01=GetHandleId(loc_trigger01)
                call TriggerRegisterTimerEvent(loc_trigger01,0.01,false)
                call TriggerAddCondition(loc_trigger01,Condition(function Func3545))
                call TriggerRegisterUnitEvent(loc_trigger01,loc_unit02,EVENT_UNIT_DEATH)
                call TriggerRegisterUnitEvent(loc_trigger01,loc_unit01,EVENT_UNIT_DEATH)
                call SaveUnitHandle(hashtable001,(loc_integer01),(2),(loc_unit02))
                call SaveUnitHandle(hashtable001,(loc_integer01),(17),(loc_unit01))
              endif
            else
              call Func0021(loc_integer02)
              call FlushChildHashtable(hashtable001,(loc_integer01))
              call Func0035(loc_trigger01)
            endif
            set loc_trigger01=null
            set loc_unit02=null
            set loc_unit01=null
            return false
          endfunction
          
          function Func3547 takes nothing returns nothing
            local trigger loc_trigger01=CreateTrigger()
            local unit loc_unit01=GetTriggerUnit()
            local unit loc_unit02=GetAttacker()
            local integer loc_integer01=GetHandleId(loc_trigger01)
            call TriggerRegisterUnitEvent(loc_trigger01,loc_unit01,EVENT_UNIT_DAMAGED)
            call TriggerRegisterTimerEvent(loc_trigger01,1,false)
            call TriggerAddCondition(loc_trigger01,Condition(function Func3546))
            call SaveInteger(hashtable001,(loc_integer01),(30),(Func0024(loc_unit01)))
            call SaveUnitHandle(hashtable001,(loc_integer01),(2),(loc_unit02))
            set loc_unit01=null
            set loc_unit02=null
            set loc_trigger01=null
          endfunction
          
          function Func3548 takes nothing returns nothing
            local unit loc_unit01=GetAttacker()
            if((LoadInteger(hashtable001,(GetHandleId((loc_unit01))),((4274))))==1)==false then
              call Func0044(loc_unit01,4274,0.45-GetUnitAbilityLevel(GetAttacker(),'A1HR')*0.05)
              call Func3547()
            endif
          endfunction
          
          function Func3549 takes nothing returns boolean
            if GetUnitAbilityLevel(GetAttacker(),'A1HR')>0 and IsUnitType(GetTriggerUnit(),UNIT_TYPE_HERO)==true and IsUnitType(GetTriggerUnit(),UNIT_TYPE_STRUCTURE)==false and GetAttacker()==(LoadUnitHandle(hashtable001,(GetHandleId(GetTriggeringTrigger())),(14)))and GetUnitTypeId(GetTriggerUnit())!='n00L' and IsUnitEnemy(GetTriggerUnit(),GetOwningPlayer(GetAttacker()))then
              call Func3548()
            endif
            return false
          endfunction
          
          function Func3550 takes nothing returns nothing
            local trigger loc_trigger01=CreateTrigger()
            local integer loc_integer01
            call Func0166(loc_trigger01,EVENT_PLAYER_UNIT_ATTACKED)
            call TriggerAddCondition(loc_trigger01,Condition(function Func3549))
            call SaveUnitHandle(hashtable001,(GetHandleId(loc_trigger01)),(14),(GetTriggerUnit()))
            set loc_trigger01=CreateTrigger()
            set loc_integer01=GetHandleId(loc_trigger01)
            call Func0166(loc_trigger01,EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(loc_trigger01,Condition(function Func3542))
            call SaveUnitHandle(hashtable001,(loc_integer01),(2),(GetTriggerUnit()))
            set loc_trigger01=null
          endfunction
          
          function Func3551 takes nothing returns boolean
            if GetLearnedSkill()=='A1HR' and IsUnitIllusion(GetTriggerUnit())==false and GetUnitAbilityLevel(GetTriggerUnit(),'A1HR')==1 then
              call Func3550()
            endif
            return false
          endfunction
          
          function Func3552 takes nothing returns nothing
            local trigger loc_trigger01=CreateTrigger()
            call Func0166(loc_trigger01,EVENT_PLAYER_HERO_SKILL)
            call TriggerAddCondition(loc_trigger01,Condition(function Func3551))
            set loc_trigger01=null
          endfunction

          Comment


          • #6
            So basically. It's just there for the reason I pointed out in #3. Obsolete piece of code now.
            Comprehensive Damage Reduction & Amplifications Dota 2 Guide

            Comment


            • #7
              There is no point in post #3

              Comment


              • #8
                This is really obsolete indeed.
                I mean the way it used to work is if he had begun an attack in the past second, he could trigger the Essence Shift effect with -anything-. Dark Pact, Pounce, Radiance, whatever.

                This is really the same as Riki's backstab and god knows how many other abilities that were smooth lined due to WC3 limitations in regards to on-hit events requiring awkward work arounds.

                Comment


                • #9
                  If it is true that Slark needs to deal damage for Essence Shift to work in DOTA 2, then this seemingly minor bug is going to potentially turn into a very big bug when Abaddon comes out, don't you think? And how about now with Omniknight? Or is this something that is mostly going to be relevant when Slark is missing a Monkey King Bar and can't hit his targets due to Evasion or Curse? I personally haven't noticed any issues with this, but I can keep my eyes open.
                  Last edited by hoveringmover; 04-05-2013, 07:59 PM.
                  I will mercilessly add to my ignore list anyone that makes an incredibly annoying signature.

                  Comment


                  • #10
                    Originally posted by hoveringmover View Post
                    If it is true that Slark needs to deal damage for Essence Shift to work in DOTA 2, then this seemingly minor bug is going to potentially turn into a very big bug when Abaddon comes out, don't you think? And how about now with Omniknight? Or is this something that is mostly going to be relevant when Slark is missing a Monkey King Bar and can't hit his targets due to Evasion or Curse?
                    Essence Shift doesn't trigger on missed attacks.
                    Triggered healing spells still trigger on-damage effects, as they take damage before they are healed back, so it's no different.

                    Comment


                    • #11
                      Originally posted by Arxos View Post
                      This is really obsolete indeed.
                      I mean the way it used to work is if he had begun an attack in the past second, he could trigger the Essence Shift effect with -anything-. Dark Pact, Pounce, Radiance, whatever.

                      This is really the same as Riki's backstab and god knows how many other abilities that were smooth lined due to WC3 limitations in regards to on-hit events requiring awkward work arounds.

                      Not even in the same direction...

                      Look, the thing I am asking for is not that "Slark is unable to shift essence by beginning to attack, and at the same time the Dark Pact starts exploding, and then Slark is able to shift essence before damaging the target" or something like that...
                      The thing I am asking for is that this thing effectively was preventing Slark from being able to shift essence in case his IAS drops down to -80 ~ -50. It is almost impossible without an Enchantress being in the play.

                      We have the stupid cooldown, which does literally nothing at all here in Dota 2...
                      This thing really does something, only when Enchantress is against the Slark, but it still does, I don't know why it shouldn't here

                      Comment


                      • #12
                        Did I read the title wrong? Well, the ability now has a cooldown, isn't that sufficient to substitute for the 'missing' "Attack Speed threshold"?
                        I will mercilessly add to my ignore list anyone that makes an incredibly annoying signature.

                        Comment


                        • #13
                          Originally posted by hoveringmover View Post
                          Did I read the title wrong? Well, the ability now has a cooldown, isn't that sufficient to substitute for the 'missing' "Attack Speed threshold"?
                          It always had a cooldown. You're completely missing the point. Read this thread again from the beginning.

                          Originally posted by ThoAppelsin View Post
                          Not even in the same direction...

                          Look, the thing I am asking for is not that "Slark is unable to shift essence by beginning to attack, and at the same time the Dark Pact starts exploding, and then Slark is able to shift essence before damaging the target" or something like that...
                          The thing I am asking for is that this thing effectively was preventing Slark from being able to shift essence in case his IAS drops down to -80 ~ -50. It is almost impossible without an Enchantress being in the play.

                          We have the stupid cooldown, which does literally nothing at all here in Dota 2...
                          This thing really does something, only when Enchantress is against the Slark, but it still does, I don't know why it shouldn't here
                          I knew you were referring to that, but really the stealing via Dark Pact is actually more major than that. Quite frankly in cases where he can't finish his attack animation or perhaps interrupts it in favor of something else it can play a role. Not just against a single hero in a single (fairly rare, really) case.
                          However, to me this really passes the boundary of silly mechanics to include in Dota 2. I imagine all it'll do is get us a false bug report every 2-4 weeks on people being confused about this.

                          You're not in the wrong to report this, but I can't help but call intended.

                          Comment


                          • #14
                            Thanks Arxos I really appreciate that, I liked the read of your post.
                            I really do not report everything, I have been seeing countless tiny differences while reading the code and these reports are just some remarkable picks out of them. At first I thought like maybe I should not report this one too, but then I thought about what would happen against Enchantress. She can drop the IAS by 110 at level 7, where Slark has like ~30 agi or something. 30 - 110 = -80 IAS
                            Say that Slark has the PT -80 + 30 = -50 IAS

                            And if Slark does not have anything more like branches or band, and he is a couple of levels behind, then he better just not shift essence from the Enchantress for being that so weak at that stage. That's what I've thought. This thing would affect only this case, and I could not see why this would be bad. That's why I've reported this one, and I still think the way I was thinking at the beginning.


                            As I've said on the very first post, one may call this intended, but I would just support otherwise.
                            No need to run down with "silly w3 mechanic" on this one, because it's not. The thing about being able to shift essence with Dark Pact is silly, and that is not what I'm talking about.

                            Comment


                            • #15
                              Its not just in cases where Untouchable is invovled, but also purges. A purge would reduce IAS by 100 in the first update interval. It should also be easily achieved via some other less powerful slows like Viper strike or Liquid Fire, if its like in your case where the slark is terribly behind.

                              That being said, I do agree with the others that it is an intended change (or even an oversight that doesn't warrant porting). While this is only valid in extreme cornercases, you could also argue that because of that, its not something very important to port. In addition, since you've recently gone through a lot of the dota map's jass, I think you may realise just how inefficient or even contradictory Ice's code can get. Sometimes even good code may look like genius, but may well be bits of insanity....ahem.

                              I won't list or move this just yet, we can have more discussion since its not a big impact.
                              Always read and follow the forum rules. If you need help from a moderator, use the report button ()
                              Before posting new bugs:
                              -Check the Known Bugs List and search the forum for an existing report.
                              -Make sure its a bug (test in WC3 Dota, visit playdota guides and adv. mech, etc). If you're still not sure, post in Mechanics and Gameplay Bug Brainstorming instead.
                              -Read the Bug Posting Guidelines on how to report a bug properly.

                              Comment

                              Working...
                              X