HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Offsets Problem

04-20-2007, 09:44 AM#1
Tinki3
The unit "arrow" is created at the right location.

But it is instantly moved (probably after the first timer callback) near the bottom of my map, as soon as it is created...

Everything else seems to be working fine, apart from the arrow's "offsets".

If anyone could help me fix my trigger, I will appreciate it =)


Collapse JASS:
//-----------------------------------------------------------------------------------------------------------

constant function Timer_Delay takes nothing returns real
    return 0.03    //The timer's delay (+ to make slower, - to make faster)
endfunction

constant function Base_Offset takes nothing returns real
    return 15.0    //The offset in which the arrow is moved to after each timer interval (+ to make arrow move faster, - to make slower)
endfunction

constant function Damage_Base takes nothing returns real
    return 90.0    //The damage base for the spell/the lowest damage in which can be dealt to a unit
endfunction

constant function Arrow_Sensitivity takes nothing returns real
    return 200.0   //Area in which a unit can be hit by the arrow (+ to make more sensitive, - to make it harder to hit a unit)
endfunction

constant function Minimum_Stun_Range takes nothing returns real
    return 300.0   //The lowest range in which the lowest stun duration(Stun_Duration_Base) is acted upon a unit
endfunction

constant function Maximum_Range takes nothing returns real
    return 1200.0  //The max range in which the arrow can travel
endfunction

constant function Stun_Duration_Base takes nothing returns real
    return 0.5     //The stun duration base for the spell/the minimum time in which a target can be stunned for
endfunction

constant function Dummy_ID takes nothing returns integer
    return 'h001'  //The raw code for the arrow dummy unit
endfunction

constant function Arrow_SFX_1 takes nothing returns string
    return "Abilities\\Weapons\\GlaiveMissile\\GlaiveMissileTarget.mdl"  //Created when the arrow dies
endfunction

constant function Arrow_SFX_2 takes nothing returns string
    return "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"  //Created as the stun buff's animation
endfunction

//----------------------------------------------------------------------------------------------------------

function Arrow_Filter takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) != true 
and GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), 
GetOwningPlayer(GetHandleUnit(GetExpiredTimer(), "cast"))) == true
endfunction

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

function Unstun_Hit_Target takes nothing returns nothing
    local timer T = GetExpiredTimer()
    local unit p   = GetHandleUnit(T, "p")
    local effect e = GetHandleEffect(T, "e")

    call PauseUnit(p, false)
    call DestroyEffect(e)
    call PauseTimer(T)
    call DestroyTimer(T)
    call FlushHandleLocals(T)

    set T = null
    set p = null
    set e = null
endfunction

function Move_Arrow takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit cast     = GetHandleUnit(t, "cast")
    local unit arrow    = GetHandleUnit(t, "arrow")
    local real X1       = GetHandleReal(t, "X1")
    local real X2       = GetUnitX(arrow)
    local real Y1       = GetHandleReal(t, "Y1")
    local real Y2       = GetUnitY(arrow)
    local real a        = GetHandleReal(t, "a")
    local real offset   = GetHandleReal(t, "offset")
    local real polar_X  = X2 + offset * Cos(a * bj_DEGTORAD)
    local real polar_Y  = Y2 + offset * Sin(a * bj_DEGTORAD)
    local real distance = SquareRoot((X2-X1) * (X2-X1) + (Y2-Y1) * (Y2-Y1))
    local real damage   = GetUnitAbilityLevel(cast, 'A000') * Damage_Base()
    local real stun_dur = Stun_Duration_Base()    
    local boolexpr b = Condition(function Arrow_Filter)
    local group g = CreateGroup()
    local timer T
    local unit p
    local effect e
    local integer i

    if distance < Maximum_Range() then
        call SetUnitPosition(arrow, polar_X, polar_Y)
        call GroupEnumUnitsInRange(g, Arrow_Sensitivity(), X2, Y2, b)
        set i = CountUnitsInGroup(g)
        if i > 0 then
            set T = CreateTimer()
            set p = FirstOfGroup(g)
            call RemoveUnit(arrow)
            call UnitDamageTargetBJ(cast, p, damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL)
            call DestroyEffect(AddSpecialEffectTarget(Arrow_SFX_1(), p, "head"))
            call PauseUnit(p, true)
            set e = AddSpecialEffectTarget(Arrow_SFX_2(), p, "overhead")
            call SetHandleHandle(T, "p", p)
            call SetHandleHandle(T, "e", e)  
            if distance <= Minimum_Stun_Range() then
                call TimerStart(T, stun_dur , false, function Unstun_Hit_Target)
            else 
                call TimerStart(T, stun_dur * (distance/120), false, function Unstun_Hit_Target)
            endif          
            set p = null
            set e = null 
            set T = null
            call FlushHandleLocals(t)
            call PauseTimer(t)
            call DestroyTimer(t)    
        else
        endif
    else
        call RemoveUnit(arrow)
        call DestroyEffect(AddSpecialEffect(Arrow_SFX_1(), polar_X, polar_Y))
        call FlushHandleLocals(t)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    call SetHandleReal(t, "offset", GetHandleReal(t, "offset") + Base_Offset())
    
    call DestroyBoolExpr(b)
    call DestroyGroup(g)

    set t = null
    set cast = null
    set arrow = null
    set b = null
    set g = null
endfunction

function Elunes_Arrow_Actions takes nothing returns nothing
    local unit cast = GetTriggerUnit() 
    local location l = GetSpellTargetLoc()
    local real X1 = GetUnitX(cast)
    local real Y1 = GetUnitY(cast)
    local real X2 = GetLocationX(l)
    local real Y2 = GetLocationY(l)
    local real a  = bj_RADTODEG * Atan2(Y2-Y1,X2-X1)
    local unit arrow = CreateUnit(GetOwningPlayer(cast), Dummy_ID(), X1, Y1, a)
    local timer t = CreateTimer()

    call SetHandleHandle(t, "cast", cast)
    call SetHandleHandle(t, "arrow", arrow)
    call SetHandleReal(t, "X1", X1)
    call SetHandleReal(t, "Y1", Y1)
    call SetHandleReal(t, "a", a)    
    call SetHandleReal(t, "offset", 50)
    call TimerStart(t, Timer_Delay(), true, function Move_Arrow)

    call RemoveLocation(l)

    set cast = null
    set l = null
    set arrow = null
    set t = null    
endfunction

function InitTrig_Elunes_Arrow takes nothing returns nothing
    set gg_trg_Elunes_Arrow = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Elunes_Arrow, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Elunes_Arrow, Condition( function Elunes_Arrow_Conditions ) )
    call TriggerAddAction( gg_trg_Elunes_Arrow, function Elunes_Arrow_Actions )
endfunction
04-20-2007, 10:46 AM#2
Toink
Instead of using and setting the variable 'i' to CountUnitsInGroup() just use a unit variable, then use the 'set u = FirstOfGroup(<YourGroup>)' then use 'exitwhen u == null'

Anyways try checking your other triggers first. I haven't found any problems yet.
04-21-2007, 08:26 AM#3
Pyrogasm
What toink is referring to is replacing your ForGroup() calls with this general layout:
Collapse JASS:
loop
    set u = FirstOfGroup(u) //u being the unit variable and g being our group
    exitwhen u == null //So we can exit when the group is empty
    //Do some stuff with u
    GroupRemoveUnit(g, u) //Removing it from the group
endloop
Specifically, what Toink is saying is to replace the set i = CountUnitsInGroup(g) with something akin to this:
Collapse JASS:
local unit u
local group g2 = CreateGroup()
//...
call GroupAddGroup(g, g2)
loop
    set u = FirstOfGroup(u)
    exitwhen u == null 
    set i = i+1
    GroupRemoveUnit(g2, u)
endloop
call DestroyGroup(g2)
Of course, this is a bit more work, though.
04-21-2007, 11:04 AM#4
Thunder_Eye
Quote:
Originally Posted by Pyrogasm
Collapse JASS:
    set u = FirstOfGroup(u)
Corrected:
Collapse JASS:
    set u = FirstOfGroup(g2)