Results 1 to 7 of 7

Thread: [Confirmed] Spirit Breaker's Greater Bash knock-back isn't smooth

  1. #1
    Basic Member ThoAppelsin's Avatar
    Join Date
    Jan 2012
    Posts
    2,893

    [Confirmed] Spirit Breaker's Greater Bash knock-back isn't smooth

    It is constant 100 100 100 100 for all levels...
    It should be 143.1 152.04 158.01 162


    100s can be found in the abilities.txt data file as "knockback_distance" ("100 100 100 100")
    Also, here are two pictures that I captured while measuring the distance:
    picture1picture2 (lifestealers were knocked back with level 1-2-3-4 greater bashes from left to right) thanks to adrianlegg for teaching me this way of testing



    Now, for DotA...
    Well, the code is exceedingly well designed to make the knock-back movement all smooth. Therefore it is a little hard to explain:
    - a trigger moves the victim every 0.01 seconds
    - for the first 36 cycles, the victim gets moved 2 units per cycle
    - for the rest, that "2 units" get multiplied with 0.98 on each cycle, and the unit is moved for that amount
    -- for example; 2 * 0.98 = 1.96 units on the cycle 37, and 1.96 * 0.98 = 1,9208 on the next one (cycle 38) and so on...
    - the amount of the cycles are capped with 100 120 140 160 (80 + 20*lvl)

    Here I made this graph to show how far will the unit be pushed on every 1/100 seconds:
    link for the graph (click-hold on the graph to see coordinates of points)




    So, basically it starts of with a linear movement for some lesser time interval at the beginning, and then starts making a geometric movement for the rest of it, for the most of it.
    I will post the code extracts on the next post in case someone wonders, and wants to check/enjoy it themselves.



    Please, please rework the spell behaviour from scratch...
    It knocks back the units so fast that it almost blinks them. And when the distance gets increased to their proper values, it will look even more extreme.
    Setting the "knockback_duration" values to "1.0 1.2 1.4 1.6" may make it look more smooth and non-blink-like, but if the formula it uses is solely linear, please just change it.
    Make something so that it will look like Spirit Breaker pushes them with great force at first, and they get slowed down by ground/air friction or something like that.
    The formula used in DotA makes really sense on this aspect. It starts off fast, and slowly slows down.
    In Dota 2 it also prevents Spirit Breaker from being able to hit his victim a couple of more times while they are being pushed because of the lack of smoothness in the pushing behaviour...
    but the most important thing about this is that it looks horrible.
    Last edited by bu3ny; 11-30-2013 at 10:29 AM. Reason: Seperated fixed part

  2. #2
    Basic Member ThoAppelsin's Avatar
    Join Date
    Jan 2012
    Posts
    2,893
    Code:
    01  function Func3273 takes unit loc_unit01,unit loc_unit02,boolean loc_boolean01,boolean loc_boolean02 returns nothing
    02    local trigger loc_trigger01
    03    local integer loc_integer01
    04    local real loc_real01=Atan2(GetUnitY(loc_unit02)-GetUnitY(loc_unit01),GetUnitX(loc_unit02)-GetUnitX(loc_unit01))
    05    local integer loc_integer02=GetUnitAbilityLevel(loc_unit01,'A0G5')
    06    local unit loc_unit03
    07    if loc_boolean01 then
    08    endif
    09    if loc_integer02>0 then
    10      set loc_unit03=CreateUnit(GetOwningPlayer(loc_unit02),'e00E',GetUnitX(loc_unit02),GetUnitY(loc_unit02),0)
    11      call Func0181(loc_unit03,'A1WQ')
    12      call SetUnitAbilityLevel(loc_unit03,'A1WQ',loc_integer02)
    13      if IssueTargetOrder(loc_unit03,"thunderbolt",loc_unit02)then
    14        set loc_trigger01=CreateTrigger()
    15        set loc_integer01=GetHandleId(loc_trigger01)
    16        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl",loc_unit01,"weapon"))
    17        call SaveUnitHandle(hashtable001,(loc_integer01),(2),(loc_unit01))
    18        call SaveUnitHandle(hashtable001,(loc_integer01),(17),(loc_unit02))
    19        call SaveReal(hashtable001,(loc_integer01),(13),((loc_real01)*1.0))
    20        call SaveReal(hashtable001,(loc_integer01),(193),((2)*1.0))
    21        call SaveBoolean(hashtable001,(loc_integer01),(698),(loc_boolean02))
    22        call SaveInteger(hashtable001,(loc_integer01),(12),(80+20*loc_integer02))
    23        call TriggerRegisterUnitEvent(loc_trigger01,loc_unit02,EVENT_UNIT_DEATH)
    24        call TriggerRegisterTimerEvent(loc_trigger01,0.01,true)
    25        call TriggerAddCondition(loc_trigger01,Condition(function Func3272))
    26        call Func0109(loc_unit01,loc_unit02,1,GetUnitMoveSpeed(loc_unit01)*0.1*loc_integer02)
    27        call Func3271(loc_unit01)
    28      endif
    29      if loc_boolean02==false then
    30        call Func0044(loc_unit01,4276,1.5)
    31      endif
    32    endif
    33    set loc_trigger01=null
    34    set loc_unit01=null
    35    set loc_unit02=null
    36    set loc_unit03=null
    37  endfunction
    
    01  function Func3272 takes nothing returns boolean
    02    local trigger loc_trigger01=GetTriggeringTrigger()
    03    local integer loc_integer01=GetHandleId(loc_trigger01)
    04    local unit loc_unit01=(LoadUnitHandle(hashtable001,(loc_integer01),(17)))
    05    local unit loc_unit02=(LoadUnitHandle(hashtable001,(loc_integer01),(2)))
    06    local real loc_real01=(LoadReal(hashtable001,(loc_integer01),(13)))
    07    local real loc_real02=GetUnitX(loc_unit01)
    08    local real loc_real03=GetUnitY(loc_unit01)
    09    local integer loc_integer02=GetTriggerEvalCount(loc_trigger01)
    10    local real loc_real04=(LoadReal(hashtable001,(loc_integer01),(193)))
    11    local integer loc_integer03=(LoadInteger(hashtable001,(loc_integer01),(12)))
    12    if loc_integer02>35 then
    13      call SaveReal(hashtable001,(loc_integer01),(193),((loc_real04*0.98)*1.0))
    14    endif
    15    if GetTriggerEventId()==EVENT_UNIT_DEATH or loc_integer02>loc_integer03 then
    16      call FlushChildHashtable(hashtable001,(loc_integer01))
    17      call Func0035(loc_trigger01)
    18    else
    19      call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",loc_real02,loc_real03))
    20      call Func0170(loc_real02,loc_real03,150)
    21      set loc_real02=Func0120(loc_real02+loc_real04*Cos(loc_real01))
    22      set loc_real03=Func0122(loc_real03+loc_real04*Sin(loc_real01))
    23      if(IsPointInRegion(region006,((loc_real02)*1.0),((loc_real03)*1.0)))==false then
    24        call SetUnitX(loc_unit01,loc_real02)
    25        call SetUnitY(loc_unit01,loc_real03)
    26      endif
    27      if loc_integer02==1 and(LoadBoolean(hashtable001,(loc_integer01),(698)))==false then
    28        call IssueTargetOrder(loc_unit02,"attack",loc_unit01)
    29      endif
    30    endif
    31    set loc_trigger01=null
    32    set loc_unit01=null
    33    return false
    34  endfunction
    I have especially put them in this reversed order; begin with Func3273 and then Func3272 while reading
    - Atan2 is for measuring angle
    - A0G5 is the greater bash
    - e00E is a dummy, unimportant
    - A1WQ is the greater bash stun
    - Func0109 is a function that deals damage
    - region006 is a region that consists of a bunch of rectangles that are basically the inescapable terrain
    - Func0170 is a function that destroys trees
    - Func0120 and Func0122 are just to prevent things from being outside the map boundaries

    Example on how hashtables work:
    #17 from Func3273: call SaveUnitHandle(hashtable001,(loc_integer01),(2),(l oc_unit01))
    saves loc_unit01 (a UnitHandle) to (2) under (loc_integer01)

    These information should be enough for reading


    Code:
    	//=================================================================================================================
    	// Spirit Breaker: Greater Bash
    	//=================================================================================================================
    	"spirit_breaker_greater_bash"
    	{
    		// General
    		//-------------------------------------------------------------------------------------------------------------
    		"ID"							"5355"														// unique ID number for this ability.  Do not change this once established or it will invalidate collected stats.
    		"AbilityName"					"spirit_breaker_greater_bash"
    		"AbilityBehavior"				"DOTA_ABILITY_BEHAVIOR_PASSIVE"
    		"AbilityUnitDamageType"			"DAMAGE_TYPE_MAGICAL"
    
    		// Time		
    		//-------------------------------------------------------------------------------------------------------------
    		"AbilityCooldown"				"1.5 1.5 1.5 1.5"
    
    		// Stats
    		//-------------------------------------------------------------------------------------------------------------
    		"AbilityModifierSupportBonus"	"40"
    
    		// Special
    		//-------------------------------------------------------------------------------------------------------------
    		"AbilitySpecial"
    		{
    			"01"
    			{
    				"var_type"				"FIELD_INTEGER"
    				"chance_pct"			"17 17 17 17"
    			}
    			"02"
    			{
    				"var_type"				"FIELD_FLOAT"
    				"damage"				"10 20 30 40"
    			}
    			"03"
    			{
    				"var_type"				"FIELD_FLOAT"
    				"duration"				"1.0 1.2 1.4 1.6"
    			}
    			"04"
    			{
    				"var_type"				"FIELD_FLOAT"
    				"knockback_duration"	"0.5 0.5 0.5 0.5"
    			}
    			"05"
    			{
    				"var_type"				"FIELD_INTEGER"
    				"knockback_distance"	"100 100 100 100"
    			}
    			"06"
    			{
    				"var_type"				"FIELD_INTEGER"
    				"knockback_height"		"50 50 50 50"
    			}
    			"07"
    			{
    				"var_type"				"FIELD_INTEGER"
    				"bonus_movespeed_pct"	"15 15 15 15"
    			}
    			"08"
    			{
    				"var_type"				"FIELD_FLOAT"
    				"movespeed_duration"	"3.0 3.0 3.0 3.0"
    			}
    		}
    	}

  3. #3
    Basic Member
    Join Date
    Dec 2011
    Posts
    11,187
    added to sticky.
    Make sure to read the Forum Rules as well as the stickied Threads of the Forum Section you are posting in.

    Contributions i'd like to highlight:
    My Suggestion: Coaching System
    My Sticky: Intended Changes List
    My Challenge: Completely Fixed Hero Challenge: Skywrath Mage

  4. #4
    Basic Member hoveringmover's Avatar
    Join Date
    Feb 2013
    Posts
    2,509
    Ahem. Some people appear to be loving their win rates. http://dotabuff.com/heroes/winning http://dotabuff.com/heroes/played

  5. #5
    Basic Member igo95862's Avatar
    Join Date
    Aug 2012
    Posts
    3,142
    Distance was fixed
    "05"
    {
    "var_type" "FIELD_INTEGER"
    "knockback_distance" "143 152 158 162"

    But Acceleration is still incorect

  6. #6
    Basic Member Jan2011's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    17,357
    Quote Originally Posted by igo95862 View Post
    Distance was fixed
    "05"
    {
    "var_type" "FIELD_INTEGER"
    "knockback_distance" "143 152 158 162"

    But Acceleration is still incorect
    can you post that in the test client bug section so that it get fixed?
    If you find spelling errors, you are free to take them.

  7. #7
    Basic Member Jan2011's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    17,357
    bump still 1 element not fixed
    If you find spelling errors, you are free to take them.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •