HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Trig functions help

03-22-2007, 08:05 PM#1
Joker
Im pretty new to trig funcs and i was trying to make a knockback function with it, but i failed pretty bad. Dunno whats wrong though. It moves that unit though, just to a wierd place.

Collapse JASS:

function H2I takes handle h returns integer
    return h
    return 0
endfunction

function LocalVars takes nothing returns gamecache
    return InitGameCache("jasslocalvars.w3v")
endfunction

function SetHandleHandle takes handle subject, string name, handle value returns nothing
    if value==null then
        call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreInteger(LocalVars(), I2S(H2I(subject)), name, H2I(value))
    endif
endfunction

function SetHandleReal takes handle subject, string name, real value returns nothing
    if value==0 then
        call FlushStoredReal(LocalVars(), I2S(H2I(subject)), name)
    else
        call StoreReal(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function GetHandleUnit takes handle subject, string name returns unit
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction

function GetHandleReal takes handle subject, string name returns real
    return GetStoredReal(LocalVars(), I2S(H2I(subject)), name)
endfunction

function FlushHandleLocals takes handle subject returns nothing
    call FlushStoredMission(LocalVars(), I2S(H2I(subject)) )
endfunction



function KnockBackFunction2_Core takes timer t returns nothing //This is not the function you type in!
    local unit target = GetHandleUnit( t, "target" )
    local real tx = GetHandleReal( t, "x" )
    local real ty = GetHandleReal( t, "y" )
    local real angle = GetHandleReal( t, "angle" )
    local real count = GetHandleReal( t, "count" )
    local real duration = GetHandleReal( t, "duration" ) 
    
    if count < duration then
           
        call SetUnitPosition( target, tx + 15 * angle, ty + 15 * angle ) 

    else
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushHandleLocals(t)
    endif

    call SetHandleReal( t, "count", GetHandleReal( t, "count" ) + 0.02 )
    set target = null
endfunction

function KnockBackFunction2 takes nothing returns nothing
    call KnockBackFunction2_Core( GetExpiredTimer() )
endfunction
              
function KnockBackFunction takes timer t,unit caster, unit target, real duration returns nothing
    local real tx = GetUnitX(target)
    local real ty = GetUnitY(target)
    local real cx = GetUnitX(caster)
    local real cy = GetUnitX(caster)
    local real angle = bj_RADTODEG * Atan2( ty - cy, tx - cx )
    
    call SetHandleHandle( t, "target", target )
    call SetHandleReal( t, "count", 0.02 )
    call SetHandleReal( t, "y", ty )
    call SetHandleReal( t, "x", tx )
    call SetHandleReal( t, "angle", angle )
    call SetHandleReal( t, "duration", duration )
    call TimerStart( t, 0.02, true, function KnockBackFunction2 )
endfunction
03-22-2007, 08:10 PM#2
Vexorian
You don't really need trig functions for a knockback function, you could just use them once to get initial speeds and then deaccelerate the speed by scaled substraction and whatever until speeds are 0.

Collapse JASS:
    if count < duration then
           
        call SetUnitPosition( target, tx + 15 * angle, ty + 15 * angle ) 

    else


Maybe you want something like this:?
Collapse JASS:
    if count < duration then
           
        call SetUnitPosition( target, tx + count*15 * Cos(angle), ty + cout*15 * Sin(angle) ) 

    else
03-22-2007, 08:32 PM#3
grim001
uh yeah how exactly did you expect it to go in the right direction when you're just multiplying the x and y by the angle... that doesn't even make sense for a guess

what you want are these formulas:
newx = x + Cos(angle*bj_DEGTORAD)*distance
newy = y + Sin(angle*bj_DEGTORAD)*distance

(notice that if you remove to RADTODEG from your angle calc you can remove the DEGTORAD from these, just keep in radians)

Now instead of using this at every step you should calculate the final target x and the final target y when the spell is initially cast. Then divide the x and y by the number of steps, and that's the amount to move it by each step on each axis.
03-22-2007, 08:48 PM#4
Joker
i had these:
newx = x + Cos(angle*bj_DEGTORAD)*distance
newy = y + Sin(angle*bj_DEGTORAD)*distance

but then, if the caster or the target arent facing each other, then this doesnt work
03-22-2007, 10:29 PM#5
grim001
uhh i think you completely lack understanding of what that formula is for

the angle that you calculate using the angle formula goes into that formula where it says "angle"
03-22-2007, 11:05 PM#6
Joker
could you give me a example of that Atan2 then? Like i said earlier, im still pretty new to trigomonetry
03-23-2007, 01:38 AM#7
grim001
but you already calculated angle in your example
03-23-2007, 07:51 PM#8
Joker
Then why does the trigger not work properly? Vex's dont work right either
03-25-2007, 11:10 PM#9
Joker
ok heres other attempt on atan and it doesnt work at all (no movement of any kind) i see the debug msgs though
Collapse JASS:
function Trig_Gravity_Ward_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetEnteringUnit()) == 'ohwd'
endfunction

function Trig_Gravity_Ward_Effect_Conditions takes nothing returns boolean
    return GetUnitState( GetFilterUnit(), UNIT_STATE_LIFE ) > 0.405 and IsUnitEnemy( GetFilterUnit(), GetOwningPlayer(GetHandleUnit( GetExpiredTimer(), "e" ))) == true
endfunction

function Trig_Gravity_Ward_Effect_Core takes timer t returns nothing
    local unit e = GetHandleUnit( t, "e" )
    local real ex = GetUnitX(e)
    local real ey = GetUnitY(e)
    local group g = CreateGroup()
    local boolexpr b = Condition( function Trig_Gravity_Ward_Effect_Conditions )
    local unit f = null
    local real fx
    local real fy
    local real angle

    
    if GetUnitState( e, UNIT_STATE_LIFE ) > 0.405 then 
call BJDebugMsg("as")
        call GroupEnumUnitsInRange( g, ex, ey, 260, b )
        
        loop
            set f = FirstOfGroup(g)
            set fx = GetUnitX(f)
            set fy = GetUnitY(f)
            set angle = Atan2( fy - ey, fx - ex )
            exitwhen GetUnitState( e, UNIT_STATE_LIFE ) > 0.405 
            call SetUnitPosition( f, fx - 5 * Cos(angle), fx - 5 * Sin(angle) )
        endloop 
        
    else
call BJDebugMsg("ass")
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushHandleLocals(t)
    endif
    
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set e = null
    set g = null
    set b = null
    set f = null
endfunction   

function Trig_Gravity_Ward_Effect takes nothing returns nothing
    call Trig_Gravity_Ward_Effect_Core( GetExpiredTimer() )
endfunction

function Trig_Gravity_Ward_Actions_Core takes unit e, timer t returns nothing
    call SetHandleHandle( t, "e", e )
    call TimerStart( t, 0.03, true, function Trig_Gravity_Ward_Effect )
endfunction

function Trig_Gravity_Ward_Actions takes nothing returns nothing
    call Trig_Gravity_Ward_Actions_Core( GetEnteringUnit(), CreateTimer() )
endfunction

//===========================================================================
function InitTrig_Gravity_Ward takes nothing returns nothing
    local region r = CreateRegion()
    set gg_trg_Gravity_Ward = CreateTrigger(  )
    
    call RegionAddRect( r, bj_mapInitialPlayableArea )
    call TriggerRegisterEnterRegion( gg_trg_Gravity_Ward, r, null )
    call TriggerAddCondition( gg_trg_Gravity_Ward, Condition( function Trig_Gravity_Ward_Conditions ) )
    call TriggerAddAction( gg_trg_Gravity_Ward, function Trig_Gravity_Ward_Actions )
    
    set r = null
endfunction