Learning vjass: need help on code

Vassilev

New Member
Reaction score
39
What my spell is supposed to do:
Group Units around target location and cause a random effect every 0.50 to 1 second for as long as the spell duration i.e ( count * GetUnitAbilityLevel() )

Pretty simple actually, I just don't know how to make it MUI >.<"

EDIT: AND make the count = count - 1 run every second, not every 0.50 to 1 second

JASS:
scope FieldOfChaos initializer Init

globals
private integer count
endglobals

function Timer takes nothing returns nothing
set count = GetUnitAbilityLevel(GetTriggerUnit(), &#039;A05N&#039;) * 5
call TriggerSleepAction(1.00)

loop
exitwhen count == 0

set count = count - 1
call TriggerSleepAction(1.00)
endloop
endfunction

function GroupFilter takes nothing returns boolean
return GetWidgetLife( GetFilterUnit() ) &gt; 0.405 and IsUnitType( GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

function Cond takes nothing returns boolean
return GetSpellAbilityId() == &#039;A05N&#039;
endfunction


function Act takes nothing returns nothing
local integer i
local location l = GetSpellTargetLoc()
local real x = GetLocationX(l)
local real y = GetLocationY(l)
local unit c = GetTriggerUnit()
local unit d 
local group g = CreateGroup()
local unit temp

call Timer()
loop
set count = count - 1
call BJDebugMsg( I2S(count))
exitwhen count == 0
call GroupEnumUnitsInRange( g, x, y, 250, null) 
set temp = GroupPickRandomUnit(g)
if temp != null then
set i = GetRandomInt(1, 6)
set d = CreateUnit( Player(15), Dummy(), x + GetRandomReal( -150, 150) ,  y + GetRandomReal( -150, 150) , 0)
call SetUnitFlyHeight( d, 300, 900)
call UnitAddAbility(d, udg_FieldOfChaosSpells2<i>)
call IssueTargetOrder( d, udg_FieldOfChaosStrings2<i>, temp)
call UnitApplyTimedLife( d, &#039;BTLF&#039;, 1)
call GroupRemoveUnit(g, temp)
call GroupClear(g)
endif
call TriggerSleepAction( GetRandomReal(0.50, 1.)) 

endloop
set i = 0
call RemoveLocation(l)
set l = null
set c = null
set d = null
call DestroyGroup(g)
set g = null
set temp = null


endfunction


function Init takes nothing returns nothing
local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition( t, Condition( function Cond) )
    call TriggerAddAction(t,function Act)

endfunction


endscope</i></i>


Ok... so.. the problem is... how do i make my global "private integer count" MUI? Does it have to be private or public or just "integer count" ?

Also, when the Timer() function is called, the trigger waits for "count" to reach 0 before proceeding to the unitgroup loop... Bleh... Im clueless :p How do I do this properly?

Do I need to use an attachment system?



Any help will be appreciated much, thx ^^
 

saw792

Is known to say things. That is all.
Reaction score
280
Use timers and an attachment system.

(Note: I have barely read your code, just skimmed over it. There is probably a better way to achieve what you want, so I will leave that to other posters for now).
 

Vassilev

New Member
Reaction score
39
OOps, i pasted the old code, that's not the problem..

so any1 out there who can explain or more rather help me make this spell?
 

Faust

You can change this now in User CP.
Reaction score
123
JASS:
function GroupFilter takes nothing returns boolean
return GetWidgetLife( GetFilterUnit() ) &gt; 0.405 and IsUnitType( GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction


The first part is, the unit is alive... but then you have == false, means it only targets dead units
Switch that > to a <


Handler functions don't like waits. Nor do casual loops. You should work with an attachment system (I recommend ABC)

And also make your functions private

You also set count = count - 1 at 2 places o_O
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
Timers, Triggers and Groups library.

JASS:
//! textmacro Recycle takes LIBRARY, NAME, TYPE, CREATEHOW, RELEASEHOW, AMOUNT
    library $LIBRARY$ initializer Init requires HandleVars
    
        scope ReadMe
            //**************************
            //* $LIBRARY$
            //* ¯¯¯¯¯¯¯¯
            //* Author  : Themis@Azeroth, StealthOfKing@Azeroth, Vexorian.
            //* URL     : <a href="http://www.clanbom.net" target="_blank" class="link link--external" rel="nofollow ugc noopener">www.clanbom.net</a>
            //* Credits : Not required, though appreciated.
            //* 
            //* This Recycle Textmaro creates a recycle type $TYPE$.
            //* This script is originally made by Vexorian, updated by StealthOfKing and textmacro&#039;ed by Themis.
            //* It creates a Timers, Groups and a Triggers library which allow you to recycle the types.
            //* It allowes us to save memory and store and get struct data&#039;s in the timers, groups, triggers.
            //* 
            //****************************************************************************************************************
        endscope
    
        globals
            private constant integer MAX_HANDLES = $AMOUNT$

            private $TYPE$ array $TYPE$s
            private integer array data
            private integer index = 0
            private integer offset
        endglobals

        private function h2i takes handle h returns integer
            return h
            return 0
        endfunction

        function Get$NAME$Data takes $TYPE$ h returns integer
            return data[h2i( h ) - offset]
        endfunction
        function Set$NAME$Data takes $TYPE$ h, integer i returns nothing
            set data[h2i( h ) - offset] = i
        endfunction

        function New$NAME$ takes nothing returns $TYPE$
            if index == 0 then
                debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;$NAME$ stack if full.&quot;)
                return null
            endif
            set index = index - 1
            return $TYPE$s[index]
        endfunction
        function Release$NAME$ takes $TYPE$ h returns nothing
            if h != null then
                call $RELEASEHOW$(h)
                set $TYPE$s[index] = h
                set index = index + 1
            endif
        endfunction

        private function Init takes nothing returns nothing
            set $TYPE$s[0] = $CREATEHOW$()
            set offset     = h2i( $TYPE$s[0] )
            loop
                exitwhen index == MAX_HANDLES
                set $TYPE$s[index] = $CREATEHOW$()
                set index = index + 1
            endloop
        endfunction
    endlibrary
//! endtextmacro
    
//  runtextmacro Recycle( &quot;LibName&quot;, &quot;FuncName&quot;, &quot;VarType&quot;, &quot;CreateHow&quot;, &quot;ReleaseHow&quot;, &quot;HandleAmount&quot; )

//! runtextmacro Recycle( &quot;Timers&quot;, &quot;Timer&quot;, &quot;timer&quot;, &quot;CreateTimer&quot;, &quot;PauseTimer&quot;, &quot;30&quot; )
//! runtextmacro Recycle( &quot;Groups&quot;, &quot;Group&quot;, &quot;group&quot;, &quot;CreateGroup&quot;, &quot;GroupClear&quot;, &quot;30&quot; )
//! runtextmacro Recycle( &quot;Triggers&quot;, &quot;Trigger&quot;, &quot;trigger&quot;, &quot;CreateTrigger&quot;, &quot;ResetTrigger&quot;, &quot;30&quot; )


Your MUI code, though not tested.
JASS:
scope FieldOfChaos initializer Init 

    globals
        private constant integer DUMMY = &#039;dumy&#039;
    endglobals
    
    private struct tempdata
        integer count
        
        // Add aditional values you want to use in another function.
    endstruct
    
    private function TimerCallback takes nothing returns nothing
        local tempdata d = GetTimerData( GetExpiredTimer() )
        
        if d.count == 0 then
            call DestroyTimer( GetExpiredTimer() )
        endif
        
        set d.count = d.count - 1
    endfunction

    function GroupFilter takes nothing returns boolean
        return GetWidgetLife( GetFilterUnit() ) &gt; 0.405 and IsUnitType( GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
    endfunction

    function TriggerCondition takes nothing returns boolean
        return GetSpellAbilityId() == &#039;A05N&#039;
    endfunction


    function TriggerAction takes nothing returns nothing
        local tempdata td = tempdata.create()
        local integer   i
        local location  l = GetSpellTargetLoc()
        local real      x = GetLocationX(l)
        local real      y = GetLocationY(l)
        local unit      c = GetTriggerUnit()
        local unit      d 
        local group     g = CreateGroup()
        local unit   temp
        local timer     t = CreateTimer()
        
        set td.count = GetUnitAbilityLevel( c, &#039;A05N&#039; ) * 5
        
        call SetTimerData( t, td )
        call TimerStart( t, 1., true, function TimerCallback )
        
        loop
            exitwhen td.count == 0
            
            call GroupEnumUnitsInRange( g, x, y, 250, null) 
            set temp = GroupPickRandomUnit(g)
            
            if temp != null then
                set i = GetRandomInt(1, 6)
                set d = CreateUnit( Player(15), DUMMY, x + GetRandomReal( -150, 150) ,  y + GetRandomReal( -150, 150) , 0)
                
                call SetUnitFlyHeight( d, 300, 900)
                
                // Commented it because I do not have the 2 globals.
                
                //call UnitAddAbility(d, udg_FieldOfChaosSpells2<i>)
                //call IssueTargetOrder( d, udg_FieldOfChaosStrings2<i>, temp)
                
                call UnitApplyTimedLife( d, &#039;BTLF&#039;, 1)
                call GroupClear(g)
            endif
            call TriggerSleepAction( GetRandomReal(0.50, 1.)) 
        endloop
        
        call RemoveLocation(l)
        call DestroyGroup(g)

        set l    = null
        set c    = null
        set d    = null
        set g    = null
        set temp = null
        set t    = null
    endfunction


    function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition( t, Condition( function TriggerCondition) )
        call TriggerAddAction(t,function TriggerAction)

        set t = null
    endfunction

endscope</i></i>
 

Viikuna

No Marlo no game.
Reaction score
265
You dont have to null local trigger t in Init function, because you are never going to destroy that trigger. ( If you do your spell wont work, so dont do it. )
 

Vassilev

New Member
Reaction score
39
Faust

The first part is, the unit is alive... but then you have == false, means it only targets dead units
Switch that > to a <

You are wrong, it works perfectly fine.

Themis,

Thank you ! it works perfectly fine... I didn't know timers could run concurrently within triggers ! I'm using kattana's local vars attachment system though... May I know why your system has dollar signs in it? ( $NAME$) does it have significant value or is it only for naming purposes.

Here's the final code btw (of course its not finished as I have more things to add to it later but it serves its purpose as intended for now)

JASS:
scope FieldOfChaos initializer Init

private struct data
integer count
endstruct

private function GroupFilter takes nothing returns boolean
return GetWidgetLife( GetFilterUnit() ) &gt; 0.405 and IsUnitType( GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == false
endfunction

private function Cond takes nothing returns boolean
return GetSpellAbilityId() == &#039;A05N&#039;
endfunction

private function Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local data d = GetHandleInt(t, &quot;counter&quot;)
if d.count != 0 then
set d.count = d.count - 1
 else
call DestroyTimer(t)
endif

endfunction



private function Act takes nothing returns nothing
local data d = data.create()
local timer t = CreateTimer()
local boolexpr b = Condition( function GroupFilter )
local integer i
local location l = GetSpellTargetLoc()
local real x = GetLocationX(l)
local real y = GetLocationY(l)
local unit c = GetTriggerUnit()
local unit du 
local group g = CreateGroup()
local unit temp
local integer chance
set d.count = GetUnitAbilityLevel(c, &#039;A05N&#039;) * 5
call SetHandleInt( t, &quot;counter&quot;, d)
call TimerStart( t, 1.00, true, function Timer )
loop
   
exitwhen d.count == 0
    call GroupEnumUnitsInRange( g, x, y, 250, b) 
loop
    set temp = FirstOfGroup(g)
exitwhen temp == null
    set chance = GetRandomInt(1, 3)
if chance &lt;= 2 then
    call GroupRemoveUnit(g, temp)
else
    set i = GetRandomInt(1, 6)
    set du = CreateUnit( Player(15), Dummy(), x + GetRandomReal( -150, 150) ,  y + GetRandomReal( -150, 150) , 0)
    call SetUnitFlyHeight( du, 300, 900)
    call UnitAddAbility(du, udg_FieldOfChaosSpells2<i>)
    call IssueTargetOrder( du, udg_FieldOfChaosStrings2<i>, temp)
    call UnitApplyTimedLife( du, &#039;BTLF&#039;, 1)
    call GroupRemoveUnit(g, temp)
endif
endloop

call TriggerSleepAction( GetRandomReal(0.50, 1.)) 

endloop
call DestroyBoolExpr(b)
set b = null
set i = 0
call RemoveLocation(l)
set l = null
set c = null
set du = null
call DestroyGroup(g)
set g = null
set temp = null
set t = null

endfunction


private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition( t, Condition( function Cond) )
    call TriggerAddAction(t,function Act)

endfunction


endscope

</i></i>
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top