NeuroToxin
New Member
- Reaction score
- 46
Hey, I've never actually had to use a parabola for ANYTHING. Quite literally. Recently, I made this attack spell, which uses souls, and I wanted to know, how to make it arc like
I have this, which works flawlessly, even at attack speeds such as 0.01, but I would like to know the parabola. I think I heard somewhere that you use the Sine function, but I personally have never needed to use it, so I've never learned.
EDIT: I believe its actually called a Bezier Curve.
EDIT: I believe its actually called a Bezier Curve.
JASS:
scope Steal initializer Init
globals
//The spell id of the spell, "Life Steal"
private constant integer SPELLID = 039;A002039;
//The dummy id of the dummy unit, attack dummy
private constant integer DUMID = 039;h001039;
//The boolean to use souls, note that souls are gathered from Soul Portal
private constant boolean USE_SOULS = true
//The interval for the timer
private constant real TINTERVAL = 0.03125
//The offset per TINTERVAL seconds.
private constant real OFFSET = 20
//The knockback when a bolt hits a unit.
private constant real KNOCKBACK = 40
endglobals
private constant function HPSTEAL takes integer lvl returns real
return .01 + (lvl * .01)
endfunction
globals
private hashtable ht = InitHashtable()
endglobals
private function MoveDamage takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit attacker = LoadUnitHandle( ht, GetHandleId(t), 0)
local unit target = LoadUnitHandle( ht, GetHandleId(t), 1)
local unit dummy = LoadUnitHandle( ht, GetHandleId(t), 2)
local boolean returning = LoadBoolean( ht, GetHandleId(t), 3)
local real tx = GetUnitX(target)
local real ty = GetUnitY(target)
local real dx = GetUnitX(dummy)
local real dy = GetUnitY(dummy)
local real distx = tx - dx
local real disty = dy - ty
local real tempreal = SquareRoot(distx * distx + disty * disty)
local real angle
local real offsetx
local real offsety
local real damage = HPSTEAL(GetUnitAbilityLevel(attacker, SPELLID))
local real cx = GetUnitX(attacker)
local real cy = GetUnitY(attacker)
local real dx1 = dx - cx
local real dy1 = dy - cy
local real casterdist = SquareRoot(dx1 * dx1 + dy1 * dy1)
local real lifestolen
if dummy == null then
call KillUnit(dummy)
call FlushChildHashtable( ht, GetHandleId(t))
call PauseTimer(t)
call DestroyTimer(t)
elseif tempreal >= 50 and returning == false then
set angle = Atan2(ty - dy, tx - dx)
set offsetx = dx + OFFSET * Cos(angle)
set offsety = dy + OFFSET * Sin(angle)
call SetUnitX( dummy, offsetx)
call SetUnitY( dummy, offsety)
call SetUnitFacing( dummy, bj_RADTODEG * angle)
elseif returning == false and tempreal <= 51 then
set angle = Atan2(ty - dy, tx - dx)
set offsetx = tx + KNOCKBACK * Cos(angle)
set offsety = ty + KNOCKBACK * Sin(angle)
call SetUnitX(target, offsetx)
call SetUnitY(target, offsety)
call SetWidgetLife( target, GetWidgetLife(target) - (GetWidgetLife(target) * damage))
set lifestolen = GetWidgetLife(target) * damage
call SaveReal( ht, GetHandleId(t), 4, lifestolen)
set returning = true
call SaveBoolean( ht, GetHandleId(t), 3, returning)
elseif returning == true and casterdist >= 50 then
set angle = Atan2(cy - dy, cx - dx)
set offsetx = dx + OFFSET * Cos(angle)
set offsety = dy + OFFSET * Sin(angle)
call SetUnitX( dummy, offsetx)
call SetUnitY( dummy, offsety)
call SetUnitFacing( dummy, bj_RADTODEG * angle)
else
set lifestolen = LoadReal( ht, GetHandleId(t), 4)
call SetWidgetLife( attacker, GetWidgetLife(attacker) + lifestolen)
call KillUnit(dummy)
call FlushChildHashtable( ht, GetHandleId(t))
call PauseTimer(t)
call DestroyTimer(t)
endif
set attacker = null
set target = null
set dummy = null
set t = null
endfunction
private function OnCast takes nothing returns boolean
local timer t
local integer i = GetUnitAbilityLevel(GetAttacker(), SPELLID)
local unit attacker
local unit target
local unit dummy
local real x
local real y
local boolean returning
if i > 0 then
if Count[GetUnitId(GetAttacker())] > 0 or USE_SOULS == false then
set t = CreateTimer()
set attacker = GetAttacker()
set target = GetTriggerUnit()
set x = GetUnitX(attacker)
set y = GetUnitY(attacker)
set returning = false
set dummy = CreateUnit( GetTriggerPlayer(), DUMID, x, y, GetRandomReal(0, 360))
call SaveUnitHandle( ht, GetHandleId(t), 0, attacker)
call SaveUnitHandle( ht, GetHandleId(t), 1, target)
call SaveUnitHandle( ht, GetHandleId(t), 2, dummy)
call SaveBoolean( ht, GetHandleId(t), 3, returning)
call TimerStart( t, TINTERVAL, true, function MoveDamage)
if USE_SOULS == true then
set Count[GetUnitId(attacker)] = Count[GetUnitId(attacker)] - 1
endif
set attacker = null
set t = null
set dummy = null
set target = null
endif
endif
return true
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerAddCondition( t, Condition( function OnCast) )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED)
endfunction
endscope