Undeclared variable problem

Exide

I am amazingly focused right now!
Reaction score
448
If I remember correctly you can use FirstOfGroup (FoG) to check a group within the same function:
http://wiki.thehelper.net/wc3/jass/common.j/Group_API#FirstOfGroup


Here's another pro tip on how to use ForGroup:
http://wiki.thehelper.net/wc3/jass/common.j/Group_API#boolexpr_as_callback


You've got an awful lot of BJs in your code.
As a JASSer you should know that BJs are the devil!
One of the reasons for converting from GUI to JASS is to get rid of the BJs, in order to improve your code.
(BJs are highlighted in red within the code tags.)
BJs usually call one (or more) extra functions.
The most common BJ is probably DoNothing() - which does nothing.
It will be easier for you to further optimize your code when you've figured out how to get rid of your BJs.

Here's an example of how to fix one of the BJs that you are using:

JASS:
function UnitApplyTimedLifeBJ takes real duration, integer buffId, unit whichUnit returns nothing
    call UnitApplyTimedLife(whichUnit, buffId, duration)
endfunction


JASS:
        call UnitApplyTimedLifeBJ( 3.50, 'BTLF', GetLastCreatedUnit() )


=

JASS:
    call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 3.5)


Note: GetLastCreatedUnit() is also a BJ. However, in a real code you should replace it with a local unit variable, so I leave it as it is.
 

killingdyl

Active Member
Reaction score
6
ok still beginner i am starting to get the hang of jass, but the FirstOfGroup is confusing me very!
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
With regard specifically to the issue of FirstOfGroup usage:

Groups in Warcraft 3 are just objects containing references to units. Within a group, though, the units are arranged in some order. The native function:
[ljass]native FirstOfGroup takes group whichGroup returns unit[/ljass]
Returns the 'first' unit in a group. If a group is empty, it returns null.

If you remove the first unit of the group from that group, the next unit in the group will then become the 'first' unit of the group, and the function [ljass]FirstOfGroup[/ljass] will then return that unit for that group. If you do this repeatedly, you can tell when all units from the group have been removed by checking when [ljass]FirstOfGroup(That_Group)==null[/ljass].

Using this knowledge, you can loop through a group and perform a set of actions on each unit in that group.


An example. Suppose that you have a group named 'somegroup' with units in it, and you want to pause each of those units. Suppose you also have a unit variable named 'someunit' that is free for use. Then, you could do:
JASS:

loop
set someunit = FirstOfGroup(somegroup)
exitwhen someunit == null
call PauseUnit(someunit,true)
call GroupRemoveUnit(somegroup,someunit)
endloop



Observe what happens in the loop.
-At the beginning of each iteration, someunit is assigned the 'first' unit of somegroup.
-If somegroup is empty, the unit is null, so the exitwhen statement causes the loop to exit. If somegroup is not empty, someunit holds a nonnull unit, and so this second line is ignored.
-someunit is paused.
-someunit is removed from somegroup. This way, for the next iteration, somegroup will have one unit emptied out and the next unit in somegroup will be assigned to someunit. The loop will then repeat for each unit in somegroup. When somegroup empties of units, someunit will be assigned a value of [ljass]null[/ljass] by [ljass]FirstOfGroup[/ljass], and the second line will cause the loop to be exited.

This process can be generalized to many situations.





As a final note, it should be pointed out that [ljass]ForGroup[/ljass] can almost always technically be used, and more efficiently, in situations where [ljass]FirstOfGroup[/ljass] loops pop up.
 

Lehona

New Member
Reaction score
12
And FirstOfGroup-loops get destroyed by so-called ghost-units which are references within a group to units which are already removed from the game. FirstOfGroup will return null for them, though the group isn't empty.
 

killingdyl

Active Member
Reaction score
6
And FirstOfGroup-loops get destroyed by so-called ghost-units which are references within a group to units which are already removed from the game. FirstOfGroup will return null for them, though the group isn't empty.

so do i need to do anything else to make it not leak or is it pretty much leakless?
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
Well, it works as anything else in JASS does with regard to leaks. In other words, in my example, you have a unit variable and a group floating about.

So:

With regard to the unit variable, if it is local, you want to make sure it holds a value of "null" at the end of the function. The unit variable will already inherintly be null at the end of the loop, though, so unless you reassign it this isn't a concern anyway.

The group is the same way. However, FirstOfGroup loops are usually done on groups being used instantaneously anyway (because of the safety concerns Lehona mentioned. There are ways to clean ghost units out of groups, but whatever. It's really just another advantage of ForGroup), so you might as well use some global group. This also makes it inherintly recycled, which is important with groups; you should never be creating and destroying groups all over the place, since they can be recycled.
 

uberfoop

~=Admiral Stukov=~
Reaction score
177
but if i used a global, wudnt it not be mui anymore???

Not if you're only using it instantaneously; then it would not collide with anything else.


I would suggest trying to understand thoroughly why non-mui things are non-mui.
 

killingdyl

Active Member
Reaction score
6
quick question is a global variable defined by the trigger editor the same as a variable defined using "globals" function tags?
i.e
JASS:
globals
variable
endglobals

and just "udg_variable"
 

cleeezzz

The Undead Ranger.
Reaction score
268
not really

if you define the global like that, you will not be able to use it in a GUI trigger. (also because it doesn't have udg_ in front of it, so its not a User Defined Global. aka, variable created in the GUI editor)

they may both be globals but jass defined "variable" is different from User created "variable"

i havent tested so i dont really know the effect of doing

(i think this is what you REALLY meant to ask)
JASS:
globals
  integer udg_variable
endglobals

(as THIS would be the same as GUI globals). however, since its not defined in the actual GUI variable editor, you will probably not be able to use the variable in the GUI triggers (in other words, you cant select the variable from the drop down list)

(but it would work in JASS/custom scripts.)

EDIT: ok through some preliminary tests, if you define udg_variable using JASS, AND in the gui variable editor (as variable), it will give a syntax error, because you are defining the global twice, which makes sense.

Bottom line is, you dont want to define udg_*name* variables in JASS, because you can't use them in GUI anyway. However if you want to stick with using GUI variable editor, by all means, keep using it, just dont define the variables in JASS.
 

killingdyl

Active Member
Reaction score
6
ok ill look into everything later but can someone combine these 2 functions, i cant figure out how to do it. is it even possible?

JASS:
function Trig_Elemental_Vortex_Func011Func001A takes nothing returns nothing
    if ( ( IsUnitType(GetEnumUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false ) and ( IsUnitAlly(GetEnumUnit(), GetOwningPlayer(GetTriggerUnit())) == false ) ) then
        if ( GetUnitTypeId(Dummy[(bj_forLoopAIndex)]) == 'h002' ) then
            call UnitDamageTargetBJ( GetTriggerUnit(), GetEnumUnit(), 100.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD )
            call AddSpecialEffectLocBJ( GetUnitLoc(GetEnumUnit()), "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" )
        else
            call UnitDamageTargetBJ( GetTriggerUnit(), GetEnumUnit(), 100.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE )
            call AddSpecialEffectLocBJ( GetUnitLoc(GetEnumUnit()), "Abilities\\Spells\\Human\\FlameStrike\\FlameStrike1.mdl" )
        endif
    else
        call DoNothing(  )
    endif
endfunction


and

JASS:
function Trig_Elemental_Vortex_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local location casterLoc = GetUnitLoc(GetTriggerUnit())
    local real Real = 0
    local location array LocOffset
    local unit array Dummy
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 8
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call CreateNUnitsAtLoc( 1, 'h003', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GetTriggerUnit()), bj_UNIT_FACING )
        set LocOffset[(bj_forLoopAIndex)] = PolarProjectionBJ(casterLoc, 700.00, Real)
        call IssuePointOrderLoc( GetLastCreatedUnit(), "move", LocOffset[bj_forLoopAIndex] )
        call UnitApplyTimedLife( GetLastCreatedUnit(), 'BTLF', 3.50 )
        set Dummy[(bj_forLoopAIndex)] = GetLastCreatedUnit()
        set Real = (Real + (360/8))
        set LocOffset[(bj_forLoopAIndex)] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    set Real = (360/16)
    set bj_forLoopAIndex = 9
    set bj_forLoopAIndexEnd = 16
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call CreateNUnitsAtLoc( 1, 'h002', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GetTriggerUnit()), bj_UNIT_FACING )
        set LocOffset[(bj_forLoopAIndex)] = PolarProjectionBJ(casterLoc, 500.00, Real)
        call IssuePointOrderLoc( GetLastCreatedUnit(), "move", LocOffset[bj_forLoopAIndex] )
        call UnitApplyTimedLife( GetLastCreatedUnit(), 'BTLF', 3.50 )
        set Dummy[(bj_forLoopAIndex)] = GetLastCreatedUnit()
        set Real = (Real + (360/8))
        set LocOffset[(bj_forLoopAIndex)] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call TriggerSleepAction( 3.45 )
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 16
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set bj_wantDestroyGroup = true
        call ForGroupBJ( GetUnitsInRangeOfLocAll(100.00, GetUnitLoc(Dummy[(bj_forLoopAIndex)])), function Trig_Elemental_Vortex_Func011Func001A )
        set Dummy[(bj_forLoopAIndex)] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    set casterLoc = null
endfunction


the first part has to go right here
JASS:
 call ForGroupBJ( GetUnitsInRangeOfLocAll(100.00, GetUnitLoc(Dummy[(bj_forLoopAIndex)])), function Trig_Elemental_Vortex_Func011Func001A )
 

Exide

I am amazingly focused right now!
Reaction score
448
Like I said before, I haven't coded anything in a long while, so this might not be correct.

JASS:
function Trig_Elemental_Vortex_Conditions takes nothing returns boolean
    return (GetSpellAbilityId() == 'A000')
endfunction

function Trig_Elemental_Vortex_Actions takes nothing returns nothing
    local unit array Dummy
    local unit caster = GetTriggerUnit()
    local player p = GetOwningPlayer(caster)
    local real x = GetUnitX(caster)
    local real y = GetUnitY(caster)
    local real xx
    local real yy
    local real Real = 0
    local integer i = 0
    local unit fog = null
    local group g = null

    loop
        exitwhen i > 7
        set Dummy<i> = CreateUnit(p, &#039;h003&#039;, x, y, 270)
        set xx = x + 700 * Cos(Real * bj_DEGTORAD)
        set yy = y + 700 * Sin(Real * bj_DEGTORAD)
        call UnitApplyTimedLife(Dummy<i>, &#039;BTLF&#039;, 3.5)
        call IssuePointOrder(Dummy<i>, &quot;move&quot;, xx, yy)
        set Real = (Real + (360/8))
        set i = i + 1
    endloop
    
    set Real = (360/16)

    loop
        exitwhen i &gt; 15
        set Dummy<i> = CreateUnit(p, &#039;h002&#039;, x, y, 270)
        set xx = x + 500 * Cos(Real * bj_DEGTORAD)
        set yy = y + 500 * Sin(Real * bj_DEGTORAD)        
        call UnitApplyTimedLife(Dummy<i>, &#039;BTLF&#039;, 3.5)
        call IssuePointOrder(Dummy<i>, &quot;move&quot;, xx, yy)
        set Real = (Real + (360/8))
        set i = i + 1
    endloop
    
    call TriggerSleepAction(3.45)   //This will probably cause trouble..

    loop
        exitwhen i &lt; 0
        set xx = GetUnitX(Dummy<i>)
        set yy = GetUnitY(Dummy<i>)
        call GroupEnumUnitsInRange(g, xx, yy, 50, null)

        loop
            set fog = FirstOfGroup(g)
            exitwhen fog == null

            if (IsUnitType(fog, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitAlly(fog, GetOwningPlayer(caster)) == false) then
                if (GetUnitTypeId(fog) == &#039;h002&#039;) then
                    call UnitDamageTarget(fog, caster, 100, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS)
                    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl&quot;, xx, yy))
                else
                    call UnitDamageTarget(fog, caster, 100, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS)
                    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Human\\FlameStrike\\FlameStrike1.mdl&quot;, xx, yy))
                endif
            endif

            call GroupRemoveUnit(g, fog)
        endloop
        
        set Dummy[(i)] = null
        set i = i - 1
    endloop
    
    call DestroyGroup(g)
    set caster = null
    set g = null
    set p = null           //I couldn&#039;t remember which had to be nulled and not, so I nulled them all. =)
endfunction

//===========================================================================
function InitTrig_Elemental_Vortex takes nothing returns nothing
    local trigger Elemental_Vortex = CreateTrigger()
    local integer i = 0
    
    loop
        exitwhen i == 16
        call TriggerRegisterPlayerUnitEvent(Elemental_Vortex, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set i = i + 1
    endloop
    
    call TriggerAddCondition( Elemental_Vortex, Condition( function Trig_Elemental_Vortex_Conditions ) )
    call TriggerAddAction( Elemental_Vortex, function Trig_Elemental_Vortex_Actions )
endfunction
</i></i></i></i></i></i></i></i>
 

Exide

I am amazingly focused right now!
Reaction score
448
That is just for adding the event.

Does the special effects show up?
 

tooltiperror

Super Moderator
Reaction score
231
Just use the spell casting event, no need to un-BJ it.
 

Exide

I am amazingly focused right now!
Reaction score
448
Just use the spell casting event, no need to un-BJ it.

It gives greater control over the event, though.
Like if there are max 4 players in the game he could change it to loop only 4 times. -No need to do it 16 times.
 

Exide

I am amazingly focused right now!
Reaction score
448
My bad.
I forgot to properly create the group.

It should be:
JASS:

    local group g = CreateGroup()


If I remember correctly..
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/
  • The Helper The Helper:
    Here is another comfort food favorite - Million Dollar Casserole - https://www.thehelper.net/threads/recipe-million-dollar-casserole.193614/

      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