HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Grapple Hook Ability, Need Some Help

03-25-2007, 11:39 PM#1
herbyhancok
Hi, just started picking up on JASS a couple days ago. For the most part I've been able to stumble through things so far. I found Blade.DK's stomp move tutorial pretty helpful, and I used it as a foundation for a skill I wanted to make. Grapple, when a location is targeted, it's supposed to gradually move the targeting unit to the targeted location.

WE keeps giving me the message "Type Mismatch in Assignment" for the first line containing the variable dur. Sorry for any sloppyness etc. I'm still trying to figure my way around. Thanks for any help.

Collapse JASS:
function Trig_Rope_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

function Rope_Move takes nothing returns nothing
    local string s = I2S(H2I(GetExpiredTimer()))
    local gamecache gc = udg_gcRope
    local real x = GetStoredReal(gc, s, "x")
    local real y = GetStoredReal(gc, s, "y")
    local real xc = GetStoredReal(gc, s, "xc")
    local real yc = GetStoredReal(gc, s, "yc")
    local unit c = I2H(GetStoredInteger(gc, s, "caster"))
    local real dur = GetStoredReal(gc, s, "dur")+0.05
    local real a
    if dur < 1.0 then
        loop
            call SetUnitPosition(c, x+20*Cos(a), y+20*Sin(a))
            exitwhen (x, y) == (xc, yc)
            set a = Atan2(yc-y, xc-x)
        endloop
        call StoreReal(gc, s, "dur", dur)
    else
        call FlushStoredMission(gc, s)
        call DestroyTimer(GetExpiredTimer())
    endif
    set gc = null
endfunction

function Trig_Rope_Actions takes nothing returns nothing
    local unit c = GetTriggerUnit() 
    local location tl = GetSpellTargetLoc()
    local location lc = PolarProjectionBJ(GetUnitLoc(c), 30, AngleBetweenPoints(GetUnitLoc(c), tl))
    local real x = GetUnitX(c)
    local real y = GetUnitY(c)
    local real xc = GetLocationX(lc)
    local real yc = GetLocationY(lc)
    local boolexpr b = Condition(function Rope_Filter)
    local gamecache gc = udg_gcRope
    local timer t = CreateTimer()
    local string s = I2S(H2I(t))
    call AddLightningLoc( "LEAS", GetUnitLoc(c), tl )
    set lightning light = GetLastCreatedLightningBJ()
    call StoreInteger(gc, s, "level", i)
    call StoreInteger(gc, s, "caster", H2I(c))
    call StoreReal(gc, s, "x", x)
    call StoreReal(gc, s, "y", y)
    call StoreReal(gc, s, "xc", xc)
    call StoreReal(gc, s, "yc", yc)
    call TimerStart(t, .05, true, function Rope_Move)
    set c = null
    call DestroyBoolExpr(b)
    set b = null
    call DestroyLightningBJ(light)
    set gc = null
    set t = null
    set tl = null
    set lc = null
endfunction


//===========================================================================
function InitTrig_Rope takes nothing returns nothing
    set gg_trg_Rope = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rope, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Rope, Condition( function Trig_Rope_Conditions ) )
    call TriggerAddAction( gg_trg_Rope, function Trig_Rope_Actions )
endfunction
03-25-2007, 11:44 PM#2
Alevice
Actually the mismatch has to do with the line before dur. Don't you love the jass compiler?

Collapse JASS:
function Rope_Move takes nothing returns nothing
    local string s = I2S(H2I(GetExpiredTimer()))
    local gamecache gc = udg_gcRope
    local real x = GetStoredReal(gc, s, "x")
    local real y = GetStoredReal(gc, s, "y")
    local real xc = GetStoredReal(gc, s, "xc")
    local real yc = GetStoredReal(gc, s, "yc")
    local unit c = I2H(GetStoredInteger(gc, s, "caster"))
    local real dur = GetStoredReal(gc, s, "dur")+0.05
    local real a

The problem lies in that you can't assign a handle to a unit. For that, you have to create an Integer2Unit function, ie:

Collapse JASS:
function Int2Unit takes integer i returns unit
return i
return null
endfunction
03-26-2007, 12:03 AM#3
herbyhancok
Thanks. I'm still a bit confused as to how WE goes about w/ handles. I figured I did that correctly since units were a subfamily. So, should I also change the below to U2I and creat a corresponding function?


Collapse JASS:
function Trig_Rope_Actions takes nothing returns nothing
    local unit c = GetTriggerUnit() 
    local location tl = GetSpellTargetLoc()
    local location lc = PolarProjectionBJ(GetUnitLoc(c), 30, AngleBetweenPoints(GetUnitLoc(c), tl))
    local real x = GetUnitX(c)
    local real y = GetUnitY(c)
    local real xc = GetLocationX(lc)
    local real yc = GetLocationY(lc)
    local boolexpr b = Condition(function Rope_Filter)
    local gamecache gc = udg_gcRope
    local timer t = CreateTimer()
    local string s = I2S(H2I(t))
    call AddLightningLoc( "LEAS", GetUnitLoc(c), tl )
    set lightning light = GetLastCreatedLightningBJ()
    call StoreInteger(gc, s, "level", i)
    call StoreInteger(gc, s, "caster", H2I(c))
    call StoreReal(gc, s, "x", x)
    call StoreReal(gc, s, "y", y)
    call StoreReal(gc, s, "xc", xc)
    call StoreReal(gc, s, "yc", yc)
    call TimerStart(t, .05, true, function Rope_Move)
    set c = null
    call DestroyBoolExpr(b)
    set b = null
    call DestroyLightningBJ(light)
    set gc = null
    set t = null
    set tl = null
    set lc = null
endfunction
03-26-2007, 12:10 AM#4
Vexorian
Collapse JASS:
    call AddLightningLoc( "LEAS", GetUnitLoc(c), tl )
    set lightning light = GetLastCreatedLightningBJ()
    call StoreInteger(gc, s, "level", i)

Must be a compile error
03-26-2007, 02:28 AM#5
herbyhancok
Ok, I managed to clean up a good bit of that. I forgot to disable pathing on the caster which was important. Now my only hang up is that my exit condition for the loop is incorrect. How do I set up the exitwhen line to work, so that it executes when the casting unit "c" is at the spell target points "xc, yc"?

This is the new code:

Collapse JASS:
function Trig_Rope_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

function Rope_Move takes nothing returns nothing
    local string s = I2S(H2I(GetExpiredTimer()))
    local gamecache gc = udg_gcRope
    local real x = GetStoredReal(gc, s, "x")
    local real y = GetStoredReal(gc, s, "y")
    local real xc = GetStoredReal(gc, s, "xc")
    local real yc = GetStoredReal(gc, s, "yc")
    local unit c = I2U(GetStoredInteger(gc, s, "caster"))
    local real dur = GetStoredReal(gc, s, "dur")+0.05
    if dur < 1.0 then
        loop 
            call SetUnitPosition(c, x+xc/10, y+yc/10)
            set x = GetUnitX(c)
            set y = GetUnitY(c)
            exitwhen GetUnitLoc(c) == (xc, yc)
        endloop
        call StoreReal(gc, s, "dur", dur)
    else
        call FlushStoredMission(gc, s)
        call DestroyTimer(GetExpiredTimer())
    endif
    set gc = null
endfunction

function Trig_Rope_Actions takes nothing returns nothing
    local unit c = GetTriggerUnit() 
    local location tl = GetSpellTargetLoc()
    local location lc = PolarProjectionBJ(GetUnitLoc(c), 30, AngleBetweenPoints(GetUnitLoc(c), tl))
    local real x = GetUnitX(c)
    local real y = GetUnitY(c)
    local real xc = GetLocationX(lc)
    local real yc = GetLocationY(lc)
    local gamecache gc = udg_gcRope
    local timer t = CreateTimer()
    local string s = I2S(H2I(t))
    local lightning lg
    call SetUnitPathing( c, false )
    call AddLightningLoc( "LEAS", GetUnitLoc(c), tl )
    call StoreInteger(gc, s, "caster", H2I(c))
    call StoreReal(gc, s, "x", x)
    call StoreReal(gc, s, "y", y)
    call StoreReal(gc, s, "xc", xc)
    call StoreReal(gc, s, "yc", yc)
    call TimerStart(t, .05, true, function Rope_Move)
    call SetUnitPathing( c, true )
    set c = null
    call DestroyLightning(GetLastCreatedLightningBJ())
    set gc = null
    set t = null
    set tl = null
    set lc = null
    set lg = null
endfunction


//===========================================================================
function InitTrig_Rope takes nothing returns nothing
    set gg_trg_Rope = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rope, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Rope, Condition( function Trig_Rope_Conditions ) )
    call TriggerAddAction( gg_trg_Rope, function Trig_Rope_Actions )
endfunction
03-26-2007, 07:50 PM#6
Anopob
Are you sure that by dividing by 10 (from the 1st line in the loop) will get the targeted unit to c? (caster)
03-27-2007, 04:04 AM#7
herbyhancok
It doesn't. My math skills are terrbile. But I have it up and running correctly now. I just need to finish implementing the lightning effects correctly.
03-27-2007, 10:13 AM#8
Fireeye
Don't forget to pause the timer before destroying it, as much as i know there can occour bugs when destroy it without pausing.
03-28-2007, 04:10 AM#9
herbyhancok
Thanks. Wasn't aware.
03-30-2007, 04:11 AM#10
herbyhancok
I'm still hung up on this skill. Below is what the latest form looks like. It moves the unit correctly, but it doesn't accomplish 2 things that I want it to. For some reason it doesn't turn off the caster's pathing and the lightning doesn't get properly declared/destroyed. Some help please, this is frustrating.

Collapse JASS:
function Trig_Rope_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

function Rope_Move takes nothing returns nothing
    local string s = I2S(H2I(GetExpiredTimer()))
    local gamecache gc = udg_gcRope
    local real x = GetStoredReal(gc, s, "x")
    local real y = GetStoredReal(gc, s, "y")
    local real z = GetStoredReal(gc, s, "z")
    local real dist = GetStoredReal(gc, s, "dist")
    local unit c = I2U(GetStoredInteger(gc, s, "caster"))
    local integer count = GetStoredInteger(gc, s, "count")
    local integer count2 = GetStoredInteger(gc, s, "count2")
    local real ux
    local real uy
    local real a
    if count < 10 then
        loop
            exitwhen count < count2
            set ux = GetUnitX(c)
            set uy = GetUnitY(c)
            set a = Atan2(uy-y, ux-x)
            call SetUnitPosition(c, ux-(dist/10)*Cos(a), uy-(dist/10)*Sin(a))
            set count2 = count + 1
        endloop
        set count = count2
        call StoreInteger(gc, s, "count", count)
        call StoreInteger(gc, s, "count2", count2)
    else
        call FlushStoredMission(gc, s)
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
    endif
    set gc = null
endfunction

function Trig_Rope_Actions takes nothing returns nothing
    local unit c = GetTriggerUnit()
    local location tl = GetSpellTargetLoc() 
    local real x = GetLocationX(GetSpellTargetLoc())
    local real y = GetLocationY(GetSpellTargetLoc())
    local real z = GetLocationZ(GetSpellTargetLoc())
    local real cx = GetUnitX(c)
    local real cy = GetUnitY(c)
    local real cz = GetUnitFlyHeight(c)
    local real dx = cx - x
    local real dy = cy - y
    local real dist = SquareRoot(dx * dx + dy * dy)
    local integer count = 0
    local integer count2 = 0 
    local gamecache gc = udg_gcRope
    local timer t = CreateTimer()
    local string s = I2S(H2I(t))
    local lightning lg
    call AddLightningEx( "LEAS", true, cx, cy, cz, x, y, z)
    set lg = GetLastCreatedLightningBJ()
    call SetUnitPathing(c, false)
    call StoreInteger(gc, s, "caster", H2I(c))
    call StoreReal(gc, s, "x", x)
    call StoreReal(gc, s, "y", y)
    call StoreReal(gc, s, "z", z)
    call StoreReal(gc, s, "dist", dist)
    call StoreInteger(gc, s, "count", count)
    call StoreInteger(gc, s, "count2", count2)   
    call TimerStart(t, .05, true, function Rope_Move)
    call SetUnitPathing(c, true)
    call DestroyLightningBJ(lg)
    set c = null
    set tl = null
    set s = null
    set gc = null
    set t = null
    set lg = null
endfunction


//===========================================================================
function InitTrig_Rope takes nothing returns nothing
    set gg_trg_Rope = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rope, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Rope, Condition( function Trig_Rope_Conditions ) )
    call TriggerAddAction( gg_trg_Rope, function Trig_Rope_Actions )
endfunction
03-30-2007, 05:24 AM#11
The__Prophet
well for the lightning, set the variable directly. Example:
Collapse JASS:
    local lightning lg = AddLightningEx( "LEAS", true, cx, cy, cz, x, y, z)

Other than that, I'm not quite sure what problem I'm looking for.
03-30-2007, 07:50 AM#12
herbyhancok
Thanks alot. That little bit of information helped a lot. It's running pretty much perfectly now. The final build looks something like this for anyone interested for w/e reason:

Collapse JASS:
function Trig_Rope_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

function Rope_Move takes nothing returns nothing
    local string s = I2S(H2I(GetExpiredTimer()))
    local gamecache gc = udg_gcRope
    local real x = GetStoredReal(gc, s, "x")
    local real y = GetStoredReal(gc, s, "y")
    local real z = GetStoredReal(gc, s, "z")
    local real dist = GetStoredReal(gc, s, "dist")
    local real cx
    local real cy
    local real cz
    local real a
    local unit c = I2U(GetStoredInteger(gc, s, "caster"))
    local integer count = GetStoredInteger(gc, s, "count")
    local integer count2 = GetStoredInteger(gc, s, "count2")
    local lightning lg = I2L(GetStoredInteger(gc, s, "lg"))
    if count < 10 then
        loop
            exitwhen count < count2
            set cx = GetUnitX(c)
            set cy = GetUnitY(c)
            set cz = GetUnitFlyHeight(c)
            set a = Atan2(cy-y, cx-x)
            call SetUnitPosition(c, cx-(dist/10)*Cos(a), cy-(dist/10)*Sin(a))
            call MoveLightningEx(lg, true, cx, cy, cz, x, y, z)
            set count2 = count + 1
        endloop
        set count = count2
        call StoreInteger(gc, s, "count", count)
        call StoreInteger(gc, s, "count2", count2)
    else
        call FlushStoredMission(gc, s)
        call SetUnitPathing(c, true)
        call DestroyLightning(lg)
        set lg = null
        set c = null
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
    endif
    set gc = null
endfunction

function Trig_Rope_Actions takes nothing returns nothing
    local unit c = GetTriggerUnit()
    local location cl = GetUnitLoc(c)
    local location tl = GetSpellTargetLoc() 
    local real x = GetLocationX(GetSpellTargetLoc())
    local real y = GetLocationY(GetSpellTargetLoc())
    local real z = GetLocationZ(GetSpellTargetLoc())
    local real cx = GetUnitX(c)
    local real cy = GetUnitY(c)
    local real cz = GetUnitFlyHeight(c)
    local real dx = cx - x
    local real dy = cy - y
    local real dist = SquareRoot(dx * dx + dy * dy)
    local integer count = 0
    local integer count2 = 0 
    local gamecache gc = udg_gcRope
    local timer t = CreateTimer()
    local string s = I2S(H2I(t))
    local lightning lg = AddLightningEx( "LEAS", true, cx, cy, cz, x, y, z)
    call SetUnitPathing(c, false)
    call StoreInteger(gc, s, "caster", H2I(c))
    call StoreInteger(gc, s, "lg", H2I(lg))
    call StoreReal(gc, s, "x", x)
    call StoreReal(gc, s, "y", y)
    call StoreReal(gc, s, "z", z)
    call StoreReal(gc, s, "dist", dist)
    call StoreInteger(gc, s, "count", count)
    call StoreInteger(gc, s, "count2", count2)   
    call TimerStart(t, .05, true, function Rope_Move)
    set c = null
    set cl = null
    set tl = null
    set s = null
    set gc = null
    set t = null
    set lg = null
endfunction


//===========================================================================
function InitTrig_Rope takes nothing returns nothing
    set gg_trg_Rope = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rope, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Rope, Condition( function Trig_Rope_Conditions ) )
    call TriggerAddAction( gg_trg_Rope, function Trig_Rope_Actions )
endfunction