• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Things That Leak

Level 12
Joined
Mar 23, 2008
Messages
942
Sounds don't leak if you do not locally create them. You can use a global one and just use StartSound or something?

If you create a local one, you can destroy it and you will still be able to play that sound, you just have to create it again.

Or I'm wrong?
Yes, you are wrong xD
I have a global sound, when I play it locally and and destroy it, I cannot play it again.
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
I was talking about the sounds that are made by CreateSound... something something.

You shouldn't destroy global sounds, why would you want to do that? You should just stop the sound and start it again from the beginning when you need to.
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
They don't leak if you play them via StartSound function.

Need_O2 said:
Btw if sounds leak whats that KillSoundWhenDone for ?

Sorry, didn't see this. KillSoundWhenDone destroys the sound when it ends, you use it only for sounds that are manually created in the game, and that is via CreateSound function(s).

Why I have this feeling that with an enormous certainty I'm telling the wrong thing? Support me, people, anyone.
 
Level 12
Joined
Aug 20, 2007
Messages
866
Yeah I finally got a handle on sounds, good old JASScraft :D

Ok, yeah when you create the normal global variable, you do not need to destroy the sound, because it is one single sound handle/object that is used everytime you call it

If you are using purely JASS, then you will probably be creating local variables, setting each one to a brand new sound variable, using it, and then you must destroy it

Normally - One Sound Used 500 times - One Object that should not be destroyed

JASS - 500 Sounds Used 1 Time Each - 500 Objects that should each be destroyed with the KillSoundWhenDone() function
 
Last edited:
Level 19
Joined
Aug 24, 2007
Messages
2,888
They don't leak if you play them via StartSound function.



Sorry, didn't see this. KillSoundWhenDone destroys the sound when it ends, you use it only for sounds that are manually created in the game, and that is via CreateSound function(s).

I love you
 
Sounds are kind of like triggers. You don't have to destroy them each time and recreate them, you simply start them over and over again. When generated globals are created by using "Use as Sound" in the sound editor, it is automatically created and able to be used as an argument for sound functions.

They do "technically" leak, as you are creating a handle but it is one of those minimal leaks. Since the sound is already a global sound, you don't need to destroy it. Only when using "Create Sound" should you actually destroy it when not needed. Unless, it again, is a global sound.

Let me give you guys some info about "Sounds".

Sounds, are sounds that you hear in game. :p Well, there are different ways to create sounds:
JASS:
native CreateSound                  takes string fileName, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate, string eaxSetting returns sound
native CreateSoundFilenameWithLabel takes string fileName, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate, string SLKEntryName returns sound
native CreateSoundFromLabel         takes string soundLabel, boolean looping, boolean is3D, boolean stopwhenoutofrange, integer fadeInRate, integer fadeOutRate returns sound
- fileName - This is the path in which the file is located. The extension must be ".wav" and it does use double-backslashes. Example:
JASS:
"Abilities\\Spells\\Undead\\DeathPact\\DeathPactTargetBirth1.wav"
- looping - This means if you want it to be looping. When using a sound in the sound editor, double-clicking it will have this as an option to checkmark or not. This too is a value in the sound editor for a certain sound's options.

- is3D - This is if you want the sound to be 3D. This means that it has to be positioned and will fade in volume as you move away from the point.

- stopwhenoutofrange - This is like a 3D sound, but instead of fading, I think this will completely stop it. This too is a value in the sound editor for a certain sound's options.

- fadeIn/OutRate - How quickly it fades in/out. The higher the input, the faster. The default is instant.

- eaxSetting - (I think) This is the "effect" of the sound. It is a special effect to the sound, but note that this is only compatible with certain sound cards. You use the suffix "EAX" and replace it with something like "Default", or "Combat", etc.. Doesn't make too much of a difference on some stuff though. For a simple null value (yes, the sound will still work), just use simple double quotes. --> ""

I'm not positive of this though. As they would simply use volume groups instead of strings for values.

- SLKEntryName
- I'm not sure. I think this enters it into a SLK file.

- soundLabel - Not sure either. :p I think after entering the SLK entry name, I think you can use that SLK entry name to retrieve it.

That is how you create sounds.

Generally, when playing sounds more than once you can usually just simply use a global sound since it won't affect the game much.

Now let's take a look at some of the setting sounds... This will allow you to manipulate sounds easily.
JASS:
native SetSoundChannel              takes sound soundHandle, integer channel returns nothing
native SetSoundConeAngles           takes sound soundHandle, real inside, real outside, integer outsideVolume returns nothing
native SetSoundConeOrientation      takes sound soundHandle, real x, real y, real z returns nothing
native SetSoundDistanceCutoff       takes sound soundHandle, real cutoff returns nothing
native SetSoundDistances            takes sound soundHandle, real minDist, real maxDist returns nothing
native SetSoundDuration             takes sound soundHandle, integer duration returns nothing
native SetSoundParamsFromLabel      takes sound soundHandle, string soundLabel returns nothing
native SetSoundPitch                takes sound soundHandle, real pitch returns nothing
native SetSoundPlayPosition         takes sound soundHandle, integer millisecs returns nothing
native SetSoundPosition             takes sound soundHandle, real x, real y, real z returns nothing
native SetSoundVelocity             takes sound soundHandle, real x, real y, real z returns nothing
native SetSoundVolume               takes sound soundHandle, integer volume returns nothing
These are kind of advanced, out of my league in some ways. But I'll do my best at guessing. :p

Note that most or a lot of these are for 3D sounds. If you do not have that option checked, it might not work properly. Creating it via JASS, you need to make sure that the argument for the "is3D" parameter is set to true.

- SetSoundChannel - I think this refers to the "Channel" selection bar that is in the sound's options. I'm not sure what the identifiers (they have integer identifiers) are. But I kind of doubt it serves that purpose, a more practical purpose would be setting the actual sound channel number. If you double click a .wav (not MP3, they will probably have the encoding method in place of where the sound channel number should be) and look at the Format text. It will name the extension (WAV), then the max kilohertz of the sound, then the bit rate if it is .mp3, otherwise the sample rate for .wav, and finally the number of channels. (google it if you don't know what it is)

- SetSoundConeAngles - This is a pretty advanced sound thing. (I think) this is actual literal sound cones. When the sound cone has no sound orientation, it will simply have the same amplitude at all angles of the sound. (It won't differentiate as the angles change within the cone) I think "inside" refers to the inside cone, and "outside" refers to the outer cone.

The cone is like a flashlight, it will have a cone towards that angle I believe. I haven't really tested this out nor have I tested how it works, but I hope to soon. I'm not sure how the reals work, but I think they are set in hundredths of decibels (logarithmic unit used to measure magnitude of a physical quantity)...

When it has an orientation, it will transition and be louder as it gets towards the middle of the sound cone (the highest point, or whatever you'd like to call it) and then it will transition out as you get near the ends of the cone. If the specified angle was 270, it would be highest (loudest) at 270 and be less loud as it changes the angle.

The outside volume I believe is the amount of sound projected outside of the cone. Remember that this value is 1-127, it doesn't use Percents unless you use PercentToInt() conversion or any other manual conversion.

- SetSoundConeOrientation - If the above stuff are true, then it should determine whether throughout the cone it will be same or transition as you go towards the center (the highest point).

I'm not sure what the parameters are for, though.

- SetSoundDistanceCutoff - This simply will set the distance in which the sound will fade out. Default of 3D sounds vary. Usually when it isn't 3D, the default (grayed out) is 3,000. But for certain sounds such as sound sets, they can be as high as 100,000 or for some small sounds, it might be as low as 1,200.

- SetSoundDistances - I think this refers to the min and max distances. Min distances are the sound level at the minimum distance that the sound can be heard. Max distances are the sound level at the maximum distance that the sound can be heard.

- SetSoundDuration - This sets the duration of the sound. I haven't tested if this works. It might cutoff the end, or it might even speed it up to fit the time, but that can be done by setting a sound's pitch values.

- SetSoundParamsFromLabel - I don't know. My guess is that it can label a sound handle.

- SetSoundPitch - Increasing this will speed up the track/sound.

- SetSoundPlayPosition - This can be used to offset sounds. In SetSoundOffsetBJ, the new offset value will actually use a R2I conversion and be multiplied by 1000, so if your new offset was something like 6.2, it would be R2I(6.2*1,000)... So 6.2*1000 would simply be 6,200... Then you wouldn't really need a conversion.

- SetSoundVelocity - Like texttag velocity, I'm guessing this is the rate of change of position along a straight line.

- SetSoundVolume - This sets the volume of a sound. Like many others, it uses 127 instead of 0-100 or 0-255 or whatever you would expect.

Now we will move on to KillSoundWhenDone:
JASS:
native KillSoundWhenDone            takes sound soundHandle returns nothing
This is a misleading function. People think it will simply just null it or make it not leak or some other variation, but it literally kills it. It destroys it, it demolishes it, so you can't play it again unless you recreate it. If you demolish a building, you can't use their stuff of course unless you rebuild it.

This is leads to a lot of problems by users. This will globally destroy it when it is done and it won't be back until you create it again. Though, there are a lot of bugs and it might not remove leaks.... So it is preferred to use a global sound. The only thing is, it might be better (Imo) to use global blocks and create it because:

1 - You get to control the name of the global
2 - You can control the creation properties
3 - It uses less lines and function executions than blizzard's creation... Unless you really want to label it...
4 - There might be some weird problems of locally creating it and problems with memory and leaks from using KillSoundWhenDone().

There is also this, to prevent KillSoundWhenDone from killing it before it even finishes or something like that:
http://wc3jass.com/viewtopic.php?t=2775

Now I will go over MIDI sounds and retrieving certain options:
JASS:
native CreateMIDISound              takes string soundLabel, integer fadeInRate, integer fadeOutRate returns sound
native GetSoundIsLoading            takes sound soundHandle returns boolean
native GetSoundDuration             takes sound soundHandle returns integer
native GetSoundFileDuration         takes string musicFileName returns integer
native GetSoundIsPlaying            takes sound soundHandle returns boolean
- CreateMIDISound - MIDI sounds are sounds with the extension .midi. .MIDI stands for Musical Instrument Digital Interface. These are used in a few maps because they are much lower in file size than .mp3 and .wav. The only downside is that you need a lot of implementation to get .MIDIs to work, and they might be lower quality. This creates a MIDI sound, I don't understand the purpose if wc3 uses all (or at least mostly) .wavs, but I think there might be some .MIDIs in wc3, but I don't know. :p

- GetSoundIsLoading - This probably just checks if a sound is loading. (no sh*t)

- GetSoundDuration - Retrieves the duration of a sound. Except it retrieves the number in microseconds I think... (If the sound was 1.635 seconds, it would display "1635" if you use I2S(GetSoundDuration(soundHandle))... To make it use regular seconds, just use I2R(GetSoundDuration(...))*0.001... If you want it to display only a portion of it, then you can use Substring functions.

- GetSoundFileDuration - Same as GetSoundDuration(), but uses the sound file instead of a sound handle.

- GetSoundIsPlaying - Returns if a sound is playing. Tested and it works fine. (At least for returning true)

Now, there is also one function to avoid and that is PlaySound(). This will use "KillSoundWhenDone"... So try to use StartSound() instead. PlaySoundBJ() is fine though and uses a good method, for once....

Hopefully, this will help you understand SOUNDS!!!!

EDIT: Woah!!! I feel like Pyrogasm!
(Probably not entirely)

I RESERVE DIBS ON MAKING A TUTORIAL OUT OF THIS! (jk, but please don't make a tutorial before me, it will tear my heart... It took me like two days to write this. :sad:)
 
Last edited:
Level 13
Joined
Nov 22, 2006
Messages
1,260
Thank you so much!! That is basically all the info on sounds summed up! You have no idea how grateful we are for this (or maybe you do). You should write a tutorial, you seem to know all about sounds (people usually know only a part of them).
 
Level 12
Joined
Aug 20, 2007
Messages
866
I do very much appreciate it, although that is quite a bit of guesswork, not exactly what I was looking for ><

But, nonetheless, it will help anybody who has no idea about sound to at least start using them
(if I didn't have JASScraft, I wouldn't be able to see that when global sounds are set, where their filenames come from, as well as a few other parameters, exporting scripts is so helpful)
 
But, nonetheless, it will help anybody who has no idea about sound to at least start using them
(if I didn't have JASScraft, I wouldn't be able to see that when global sounds are set, where their filenames come from, as well as a few other parameters, exporting scripts is so helpful)

Yeah... You can just click, "Use as sound" in the sound editor, make a syntax error and check the InitSound function or w/e that blizzard uses. Then you can delete the sound and whala... You have the label,filepath, and other parameters.

:p
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
It's voila, not whala, you........... stupidhead :)

Yeah, some of it is just guessing, but not pointless guessing Herman. Too bad no one knows what those things are for sure and there is no way to find that out.

Sounds probably suck the most, there are many bugs and misunderstandings related to them.
 
There are ways to test them, the only thing I don't know are some values to input... Like, if I put in a certain value, and it doesn't work, I might just assume it doesn't work because I input the wrong value Yeah.

These non-auto-assumable stuff kind of give headaches. Not like they will be hugely useful though...

It isn't an everyday problem when someone asks how to create a sound cone. :)

>It's voila, not whala, you(I use entirely too many periods)(I use entirely too many periods)... stupidhead :)

Yeah, I was in a rush. =( *cry*
 
Last edited:
Level 12
Joined
Aug 20, 2007
Messages
866
I can't see your signature
You guys are both stupidheads for using entirely too many periods x)
Voila is an instrument that I quit playing in 6th grade, whala works just fine if not better

Yeah I can't stand all the little bugs you can get in JASS

Atm I am working on a fairly complex system for producing projectiles that can follow an angled quadratic path, but the system uses both the HandleVars system and a customized version of Pandamime's HSAS

I keep getting all these bugs that just do not line up, and there is 10000x places they could be ><

Mostly the bugs are to do with the collision effect + condition, and the endeffect + condition, but FUCK it is annoying me

Sorry, almost completely offtopic, but I NEEDED TO LET IT OUT!
 
Level 12
Joined
Aug 18, 2006
Messages
1,193
okay, this leaks 4 Points, right? (i know how to fix leaks, this is just something i have thought about)
  • Unit - Move UNIT instantly to ((Position of UNIT) offset by 500 towards (Angle between (Position of UNIT) and (Position of UNIT2)))
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Yes positions do leak ... it not something new.
But I think it leaks 3 points as Position of Unit is called twice.
And if you want to make something leaky have some imagination. That line could have been a lot longer ;)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
It leaks four points:
  • the first position of UNIT
  • the second position of UNIT
  • the position of UNIT2
  • the point created with the polar offset
Wow, four leaks in a single line, not bad at all..... I wonder if there's a leak making contest :p
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
This is interesting :D
When calling the same position twice is that 2 leaks or one leak. Do you have to clear both or one. So I think this is one leak :p
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Leak checkers are stupid, you'll never learn anything by using those.

When calling the same position twice is that 2 leaks or one leak. Do you have to clear both or one. So I think this is one leak :p

Nope, it leaks every single time you call Position of (Unit). You can't clear both.... do you even know how to clean leaks? You store the Position of (Unit) in a variable, then use that variable, after that destroy it with JASS. You can't get to that location of you don't store it in a variable.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
And you store only 3 positions
* the first position of UNIT
* the position of UNIT2
* the point created with the polar offset
... in variables than clear them.
WE will do the same: will store 3 points, will use them, then forget to clear them. That is why I say it leaks 3 points
 
Level 12
Joined
Aug 20, 2007
Messages
866
Do code (handles?) leak?

I know numbers + strings do not, but I created code as a handle, and then converted it to an integer to be stored and then re-used using

function GetCode takes integer i returns code
return i
return null
endfunction


function, I can use the reference integer as many times as I'd like, because the code doesn't need to be destroyed/removed???

(please say they do not leak)
 
does this trigger leak?

  • Attack Treant
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Attack Treant
    • Actions
      • Set Temppos = ((Position of (Triggering unit)) offset by 100.00 towards (Facing of (Triggering unit)) degrees)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units in Damage <gen> matching (((Owner of (Matching unit)) Equal to (Owner of (Triggering unit))) and ((Unit-type of (Matching unit)) Equal to Treant Damage))) and do (Actions)
        • Loop - Actions
          • Unit - Move (Picked unit) instantly to Temppos
          • Set Damagepos = (Position of (Picked unit))
          • Set Damage[(Player number of (Triggering player))] = (Picked unit)
          • Unit - Create 1 Call Back Treant for (Owner of (Triggering unit)) at Damagepos facing Default building facing degrees
          • Unit - Order (Last created unit) to Special Rexxar - Battle Roar
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within 100.00 of Damagepos matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True)) and do (Actions)
            • Loop - Actions
              • Unit - Order Damage[(Player number of (Triggering player))] to Attack (Picked unit)
      • Set Damage[(Player number of (Triggering player))] = No unit
      • Set attackingunit = No unit
      • Custom script: call RemoveLocation(udg_Damagepos)
      • Custom script: call RemoveLocation(udg_Temppos)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Do code (handles?) leak?

Codes do not leak and they don't need to be nullified. Afaik they aren't handles, they are basic types like reals, integers, strings or booleans.

Just_Spectating, yes, in this line:

  • Set Temppos = ((Position of (Triggering unit)) offset by 100.00 towards (Facing of (Triggering unit)) degrees)
Position of Triggering unit leaks. You have to do like this:

  • Set TrigPos = (Position of (Triggering unit))
  • Set Temppos = TrigPos offset by 100.00 towards (Facing of (Triggering unit)) degrees)
Also, in that Pick every unit line, you have to destroy Damagepos inside the loop, because many locations are created and you're just destroying the last one. So you should do like this:

  • Unit Group - Pick every unit in (Units in Damage <gen> matching (((Owner of (Matching unit)) Equal to (Owner of (Triggering unit))) and ((Unit-type of (Matching unit)) Equal to Treant Damage))) and do (Actions)
    • Loop - Actions
      • Unit - Move (Picked unit) instantly to Temppos
      • Set Damagepos = (Position of (Picked unit))
      • Set Damage[(Player number of (Triggering player))] = (Picked unit)
      • Unit - Create 1 Call Back Treant for (Owner of (Triggering unit)) at Damagepos facing Default building facing degrees
      • Unit - Order (Last created unit) to Special Rexxar - Battle Roar
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 100.00 of Damagepos matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Order Damage[(Player number of (Triggering player))] to Attack (Picked unit)
      • Custom script: call RemoveLocation(udg_Damagepos)
So the final code would look like this:

  • Attack Treant
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Attack Treant
    • Actions
      • Set TrigPos = (Position of (Triggering unit))
      • Set Temppos = TrigPos offset by 100.00 towards (Facing of (Triggering unit)) degrees)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units in Damage <gen> matching (((Owner of (Matching unit)) Equal to (Owner of (Triggering unit))) and ((Unit-type of (Matching unit)) Equal to Treant Damage))) and do (Actions)
        • Loop - Actions
          • Unit - Move (Picked unit) instantly to Temppos
          • Set Damagepos = (Position of (Picked unit))
          • Set Damage[(Player number of (Triggering player))] = (Picked unit)
          • Unit - Create 1 Call Back Treant for (Owner of (Triggering unit)) at Damagepos facing Default building facing degrees
          • Unit - Order (Last created unit) to Special Rexxar - Battle Roar
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within 100.00 of Damagepos matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True)) and do (Actions)
            • Loop - Actions
              • Unit - Order Damage[(Player number of (Triggering player))] to Attack (Picked unit)
            • Custom script: call RemoveLocation(udg_Damagepos)
      • Set Damage[(Player number of (Triggering player))] = No unit
      • Set attackingunit = No unit
      • Custom script: call RemoveLocation(udg_Trigpos)
      • Custom script: call RemoveLocation(udg_Temppos)
 
Level 12
Joined
Aug 18, 2006
Messages
1,193
  • Attack Treant
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Attack Treant
    • Actions
      • Set TrigPos = (Position of (Triggering unit))
      • Set Temppos = TrigPos offset by 100.00 towards (Facing of (Triggering unit)) degrees)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units in Damage <gen> matching (((Owner of (Matching unit)) Equal to (Owner of (Triggering unit))) and ((Unit-type of (Matching unit)) Equal to Treant Damage))) and do (Actions)
        • Loop - Actions
          • Unit - Move (Picked unit) instantly to Temppos
          • Set Damagepos = (Position of (Picked unit))
          • Set Damage[(Player number of (Triggering player))] = (Picked unit)
          • Unit - Create 1 Call Back Treant for (Owner of (Triggering unit)) at Damagepos facing Default building facing degrees
          • Unit - Order (Last created unit) to Special Rexxar - Battle Roar
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within 100.00 of Damagepos matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True)) and do (Actions)
            • Loop - Actions
              • Unit - Order Damage[(Player number of (Triggering player))] to Attack (Picked unit)
            • Custom script: call RemoveLocation(udg_Damagepos)
      • Set Damage[(Player number of (Triggering player))] = No unit
      • Set attackingunit = No unit
      • Custom script: call RemoveLocation(udg_Trigpos)
      • Custom script: call RemoveLocation(udg_Temppos)
isnt this one leaking aswell? its using Damagepos twice

oh, and you only need 1 "set bj_wantDestroyGroup = true i think, becouse its a setting within the trigger :p

and this trigger isnt really working anyway, since there is no (Triggering player) since its reffering to a "Player" event, just incase you forgot :)

EDIT : I just checked the first post, and some mod should fix the part about the Special Effects

it leaks a Location :p
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
You can use Damagepos as many times you want because you're using the same locaton, you aren't creating a new one, you just have to null it at the end.

oh, and you only need 1 "set bj_wantDestroyGroup = true i think, becouse its a setting within the trigger :p

I thought of that too, but I wasn't sure, are you sure?

EDIT : I just checked the first post, and some mod should fix the part about the Special Effects

it leaks a Location :p

Crap, you're right.
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
I'm sure you need to set it twice, because this is what Pick every unit looks in JASS:

JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction

You see? It sets bj_wantDestroyGroup to false even before the actual ForGroup actions, so during the execution bj_wantDestroyGroup is already false, so if you want another group loop inside the first one, you need to set it to true again.
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Er, yeah, how do you code if you're not using unit groups Razorbrain? I can hardly imagine coding without using Pick every unit in group action. But I guess you have your own ways...

And stop spamming Need or at least try to sound like you're saying something useful, it's for your own good (I somehow always get away with it, bwahahahaha :p).

A tip to all you GUI users, always try to store everything (mostly event responses) in variables and then use those variables instead. It's inefficient if you use triggering unit like 10 times in a single spell, sometimes if there are too many, it can cause lags (in combination with other inefficiencies in GUI).

You see, Need? I said something useful (or at least it sounded that way) and now mods can't do me shit.
 
Level 8
Joined
Nov 29, 2007
Messages
371
I have a question [shock, horror].
Does "loop integer A" leak?
example:
  • Do Multiple ActionsFor each (Integer A) from 6 to 20, do (Actions)
    • Loop - Actions
      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Triggering unit) Equal to (==) r_unit[(Integer A)]
        • Then - Actions
          • Set r_tier3var[(Integer A)] = (r_tier3var[(Integer A)] + 0.05)
        • Else - Actions
Thanks in advance

EDIT: The GUI looks strange because JNGP uses slightly different wording and misses out spaces sometimes.
 
Level 8
Joined
Nov 29, 2007
Messages
371
JNGP World Editor.
In the modified WE some of the syntax is different [for instance Equal to now has its JASS code in brackets next to it.
I just read somewhere that using loops was inefficient or something, if that's not true then that saves me a lot of grunt work.

Thanks, +rep
 
Level 11
Joined
Aug 25, 2006
Messages
971
Using loops is not inefficient. However a ForGroup isn't exactly amazingly fast... Besides in GUI, inefficiency is not half as significant as removing the dozens of leaks caused by the different functions.
 
Top