• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Help, there is somewhere a bug.

Status
Not open for further replies.
Level 21
Joined
Aug 9, 2006
Messages
2,384
This Spell works, but the movement works much too fast, and when i reduce the speed value to around 1 or 2 wc3 crashes.

The Spell should make the target slowly floating towards the caster.

JASS:
scope GravityDrain

public struct Data
    unit caster
    unit target
    real distancebetween = 0
    real distancemax = 0
    real facing = 0
    real x = 0
    real y = 0
    real x1 = 0
    real y1 = 0
    real x2 = 0
    real y2 = 0
    real speed = 600*0.03
endstruct

globals
    Data array Ar
    integer Total = 0
    timer t = CreateTimer()
endglobals

function Trig_Gravity_Drain_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A001'
endfunction

function Trig_Gravity_Pull_Loop takes nothing returns nothing
    local Data kd
    local integer i = 0
    loop        
        exitwhen i >= Total        
        set kd = Ar[i]
        if GetUnitCurrentOrder(kd.caster) != String2OrderIdBJ("charm") or kd.distancebetween >= kd.distancemax then
            //call IssueImmediateOrder(kd.caster, "stop")
            call BJDebugMsg("LOL")
            call SetUnitFlyHeight(kd.target,0, 80)
            set Ar[i] = Ar[Total - 1]            
            set Total = Total - 1
            call kd.destroy()
        else
            call BJDebugMsg("LOL1")
            set kd.distancebetween = kd.distancebetween + kd.speed
            set kd.x2 = kd.x1 + kd.distancebetween * Cos(kd.facing * bj_DEGTORAD)
            set kd.y2 = kd.y1 + kd.distancebetween * Sin(kd.facing * bj_DEGTORAD)
            call SetUnitXY(kd.target, kd.x2, kd.y2)
        endif
    endloop
    if Total == 0 then
        call PauseTimer(t)
    endif
endfunction

function Trig_Gravity_Drain_Actions takes nothing returns nothing
    local Data kd = Data.create()
    set kd.caster = GetTriggerUnit()
    set kd.target = GetSpellTargetUnit()
    set kd.x = GetUnitX(kd.caster)
    set kd.x1 = GetUnitX(kd.target)
    set kd.y = GetUnitY(kd.caster)
    set kd.y1 = GetUnitY(kd.target)
    set kd.distancemax = SquareRoot((kd.x - kd.x1) * (kd.x - kd.x1) + (kd.y - kd.y1) * (kd.y - kd.y1))
    set kd.facing = Atan2(kd.y - kd.y1, kd.x - kd.x1) + (180*bj_DEGTORAD)
    call UnitAddAbility( kd.target, 'Amrf' )
    call UnitRemoveAbility( kd.target, 'Amrf' )
    call SetUnitFlyHeight(kd.target, 80, 360)
    call TriggerSleepAction(0.25)
    if Total == 0 then
        call TimerStart(t, 0.03, true, function Trig_Gravity_Pull_Loop)
    endif
    set Total = Total + 1
    set Ar[Total-1] = kd
endfunction

//===========================================================================
function InitTrig_GravityDrain takes nothing returns nothing
    local integer index = 0
    set gg_trg_GravityDrain = CreateTrigger(  )
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_GravityDrain, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_GravityDrain, Condition( function Trig_Gravity_Drain_Conditions ) )
    call TriggerAddAction( gg_trg_GravityDrain, function Trig_Gravity_Drain_Actions )
endfunction

endscope
 
Last edited:
Level 5
Joined
Oct 27, 2007
Messages
158
This Spell works, but the movement works much too fast, and when i reduce the speed value to around 1 or 2 wc3 crashes.

The Spell should make the target slowly floating towards the caster.

JASS:
scope GravityDrain

public struct Data
    unit caster
    unit target
    real distancebetween = 0
    real distancemax = 0
    real facing = 0
    real x = 0
    real y = 0
    real x1 = 0
    real y1 = 0
    real x2 = 0
    real y2 = 0
    real speed = 600*0.03
endstruct

globals
    Data array Ar
    integer Total = 0
    timer t = CreateTimer()
endglobals

function Trig_Gravity_Drain_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A001'
endfunction

function Trig_Gravity_Pull_Loop takes nothing returns nothing
    local Data kd
    local integer i = 0
    loop        
        exitwhen i >= Total        
        set kd = Ar[i]
        if GetUnitCurrentOrder(kd.caster) != String2OrderIdBJ("charm") or kd.distancebetween >= kd.distancemax then
            //call IssueImmediateOrder(kd.caster, "stop")
            call BJDebugMsg("LOL")
            call SetUnitFlyHeight(kd.target,0, 80)
            set Ar[i] = Ar[Total - 1]
            set Total = Total - 1
            call kd.destroy()
        else
            call BJDebugMsg("LOL1")
            set kd.distancebetween = kd.distancebetween + kd.speed
            set kd.x2 = kd.x1 + kd.distancebetween * Cos(kd.facing * bj_DEGTORAD)
            set kd.y2 = kd.y1 + kd.distancebetween * Sin(kd.facing * bj_DEGTORAD)
            call SetUnitXY(kd.target, kd.x2, kd.y2)
        endif
    endloop
    if Total == 0 then
        call PauseTimer(t)
    endif
endfunction

function Trig_Gravity_Drain_Actions takes nothing returns nothing
    local Data kd = Data.create()
    set kd.caster = GetTriggerUnit()
    set kd.target = GetSpellTargetUnit()
    set kd.x = GetUnitX(kd.caster)
    set kd.x1 = GetUnitX(kd.target)
    set kd.y = GetUnitY(kd.caster)
    set kd.y1 = GetUnitY(kd.target)
    set kd.distancemax = SquareRoot((kd.x - kd.x1) * (kd.x - kd.x1) + (kd.y - kd.y1) * (kd.y - kd.y1))
    set kd.facing = Atan2(kd.y - kd.y1, kd.x - kd.x1) + (180*bj_DEGTORAD)
    call UnitAddAbility( kd.target, 'Amrf' )
    call UnitRemoveAbility( kd.target, 'Amrf' )
    call SetUnitFlyHeight(kd.target, 80, 360)
    call TriggerSleepAction(0.25)
    if Total == 0 then
        call TimerStart(t, 0.03, true, function Trig_Gravity_Pull_Loop)
    endif
    set Total = Total + 1 // Bad programming habit. Callback could retrieve an uninitialized pointer.
    set Ar[Total-1] = kd
endfunction

//===========================================================================
function InitTrig_GravityDrain takes nothing returns nothing
    local integer index = 0
    set gg_trg_GravityDrain = CreateTrigger(  )
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_GravityDrain, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_GravityDrain, Condition( function Trig_Gravity_Drain_Conditions ) )
    call TriggerAddAction( gg_trg_GravityDrain, function Trig_Gravity_Drain_Actions )
endfunction

endscope

I commented a possible problem. You increase the element index, before placing a new instance struct into it. Best is to store the element and then increase the index.

Another problem occurs with your callback. The loop will not exit before all spell instances are finished. As you noticed with high speeds the spells get done quick and there is no visible problem. However when you turn down the speed, it will become a problem. The loop will take too much processing time. Combine that with the possible uninitialized pointer and WC3 will most likely crash.
 
Status
Not open for further replies.
Top