HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Help

02-15-2007, 03:11 AM#1
Feroc1ty
Well erm im making a spell and there is an error that i cant find :o

Collapse JASS:
function Trig_spell_spell takes nothing returns nothing
    local real r = I2R(GetUnitUserData(GetLastCreatedUnit())) / 2
    if r == 0 then
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
        call RemoveUnit( GetLastCreatedUnit())
        return
    endif
    call SetUnitX( GetLastCreatedUnit(), (GetUnitX(GetTriggerUnit()) + r * Cos(GetUnitFacing(GetLastCreatedUnit()) * bj_DEGTORAD)))
    call SetUnitY( GetLastCreatedUnit(), (GetUnitY(GetTriggerUnit()) + r * Sin(GetUnitFacing(GetLastCreatedUnit()) * bj_DEGTORAD)))
    call SetUnitUserData( GetLastCreatedUnit(), R2I(r) - 1 )
    call SetUnitFacing( GetLastCreatedUnit(), GetUnitFacing(GetLastCreatedUnit()) + 1 )
endfunction

function Trig_spell_Conditions takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        return true
    endif
    return false
endfunction

function Trig_spell_Actions takes nothing returns nothing
    local location l = Location(GetRectCenterX(bj_mapInitialPlayableArea), GetRectCenterY(bj_mapInitialPlayableArea))
    local timer t = CreateTimer()
    call CreateUnitAtLocSaveLast(GetOwningPlayer(GetTriggerUnit()), 'h000', l, 0)
    call SetUnitUserData( GetLastCreatedUnit(), 800 )
    call TimerStart(t, 0.03, true, function Trig_spell_spell)
    call RemoveLocation(l)
    set l = null
endfunction

//===========================================================================
function InitTrig_spell takes nothing returns nothing
    set gg_trg_spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_spell, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_spell, Condition( function Trig_spell_Conditions ) )
    call TriggerAddAction( gg_trg_spell, function Trig_spell_Actions)
endfunction

The unit creates, the dummy unit who is created circles around the middle where he was created, not where the triggering unit is for some reason. I've no idea why it does that. The coordinates are obviously set to triggering unit + distance ( r )
02-15-2007, 03:22 AM#2
wantok
You are using GetLastCreatedUnit() and GetTriggerUnit() in your timer callback function. Those units aren't passed to that function. You need to attach them to the timer using handle variables, or set them to global variables, or use some other method to store them.
02-15-2007, 03:59 AM#3
Pyrogasm
He's right.

Also, that code is inefficient; here it is optimized and with globals. Handles would require a bit more work.
Collapse JASS:
function Trig_spell_spell takes nothing returns nothing
    local unit u = udg_My_Moving_Unit //In case it changes
    local unit u2 = udg_My_Casting_Unit //In case it changes
    local real r = I2R(GetUnitUserData(u)) / 2

    if r == 0 then
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
        call RemoveUnit(u)
        return
    endif
    call SetUnitX( u, (GetUnitX(u2) + r * Cos(GetUnitFacing(u) * bj_DEGTORAD)) )
    call SetUnitY( u, (GetUnitY(u2) + r * Sin(GetUnitFacing(u) * bj_DEGTORAD)) )
    call SetUnitUserData( u, R2I(r) - 1 )
    call SetUnitFacing(u, (GetUnitFacing(u) + 1))

    set u = null
    set u2 = null
endfunction

function Trig_spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Trig_spell_Actions takes nothing returns nothing
    local real x = GetRectCenterX(GetPlayableMapRect()) //Maybe this isn't what you're looking for...
    local real y = GetRectCenterY(GetPlayableMapRect())
    local timer t = CreateTimer()

    set udg_My_Casting_Unit = GetTriggerUnit()
    set udg_My_Moving_Unit = CreateUnit(GetOwningPlayer(udg_My_Casting_Unit), 'h000', l, 0)
    call SetUnitUserData( udg_My_Moving_Unit, 800 )
    call TimerStart(t, 0.03, true, function Trig_spell_spell)

    //This might leak a Timer, though I'm not sure if it's a handle (I don't think it is)
endfunction

//===========================================================================
function InitTrig_spell takes nothing returns nothing
    set gg_trg_spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_spell, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_spell, Condition( function Trig_spell_Conditions ) )
    call TriggerAddAction( gg_trg_spell, function Trig_spell_Actions)
endfunction

Just throwing another idea out there: wouldn't this be possible with a loop?

EDIT: Oh... minimum wait time on TriggerSleepAction() ><
02-15-2007, 04:05 AM#4
wantok
You could also do it this way using structs and a global timer.

Collapse JASS:
globals
    spelldata array spelldata_ar
    integer spelldata_total = 0
    timer spell_timer = CreateTimer()
endglobals

struct spelldata
    unit caster
    unit new
endstruct

function Trig_spell_spell takes nothing returns nothing
    local spelldata dat
    local real r
    local integer i=0
    
    loop
        exitwhen i == spelldata_total
        set dat = spelldata_ar[i]
        set r = I2R(GetUnitUserData(dat.new))/2
        if r ==0 then
            call RemoveUnit(dat.new)
            set spelldata_ar[i] = spelldata_ar[spelldata_total-1]
            set spelldata_total = spelldata_total -1
            call dat.destroy()
            set i = i -1
            
           
        else
            call SetUnitX(dat.new, (GetUnitX(dat.caster) + r * Cos(GetUnitFacing(dat.new) * bj_DEGTORAD)))
            call SetUnitY(dat.new, (GetUnitY(dat.caster) + r * Sin(GetUnitFacing(dat.new) * bj_DEGTORAD)))
            call SetUnitUserData(dat.new, R2I(r) -1)
            call SetUnitFacing(dat.new, GetUnitFacing(dat.new) + 1)
        endif
        set i = i + 1
    endloop
    if spelldata_total == 0 then
        call PauseTimer(spell_timer)
    endif
endfunction

function Trig_spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000' 
endfunction

function Trig_spell_Actions takes nothing returns nothing
    local spelldata dat = spelldata.Create()
    local location l = Location(GetRectCenterX(bj_mapInitialPlayableArea), GetRectCenterY(bj_mapInitialPlayableArea))
    
    if spelldata_total == 0 then
        call TimerStart(spell_timer, .03, TRUE, function Trig_spell_spell)
    endif
    
    set dat.new = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'h000', l, 0)
    set dat.caster = GetTriggerUnit()
    
    call SetUnitUserData(dat.new, 800 )
    
    set spelldata_ar[spelldata_total] = dat
    set spelldata_total = spelldata_total+1
    
    call RemoveLocation(l)
    set l = null
endfunction

//===========================================================================
function InitTrig_spell takes nothing returns nothing
    set gg_trg_spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_spell, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_spell, Condition( function Trig_spell_Conditions ) )
    call TriggerAddAction( gg_trg_spell, function Trig_spell_Actions)
endfunction
02-15-2007, 10:32 PM#5
Feroc1ty
I do not want to use a global, is there any way i can do this without using CSCACHE, and globals?

EDIT: Last credit unit works perfectly, it moves the unit and it does it the right angle, its just triggering unit i guess.
02-16-2007, 01:37 AM#6
Pyrogasm
If you were to do it without globals and CScache, it would not be MUI.

Is this just an effect, or is it an actual spell?
02-16-2007, 03:29 AM#7
Feroc1ty
its a spell, and you mean quite the opposite. If i used globals or cscache it would be not be mui, othervise it is. its same as telling me that if i used locals it would not be mui.
02-16-2007, 03:51 AM#8
wantok
It is impossible to use only locals for this spell, you need some way to let the timer callback function know what units to manipulate.

Globals may or may not let your spell be MUI. It depends on how you use them. CScache will definitely make it MUI.

The code I posted above allows for MUI. If you don't like structs you can implement the same thing using unit arrays instead.
02-16-2007, 05:41 AM#9
Feroc1ty
The thing is i do not know what structs are. Do you require any extra scripts or globals for them? how do they work, link me to a tutorial if thats needed.
02-16-2007, 05:53 AM#10
Pyrogasm
vJass for spell makers (Moving from handle vars to structs)

That should help you out.