HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Trigger Variables and Their Scope

08-30-2002, 04:55 PM#1
Guest
I would like to be thoroughly educated in the use of variables,
and their scope. If you can answer my questions or point me to a
link which does I would be most appreciative. I've read several
tutorials out there, including the ones linked to by DrunkOldMan on the battle.net map forum. While they tell you what a variable is, they don't cover scope.

I've now got my "trainable peasant" thing working like this:

/==============================

Event:

Player 1 unit is loaded into a transport

/==============================

Conditions:

Unit is of type Rohirrim Worker AND transporting unit is of type Rohirrim Barracks

/==============================

Actions:

If Player 1 gold is < SpearmanCost display text "Not enough gold to train!" and skip remaining actions

Display text triggering unit name + " begins training in a " + transporting unit name

Subtract SpearmanCost from Player 1 gold

loop 1 to SpearmanWait

Wait 0.5

If triggering unit is not being transported by transporting unit add SpearmanCost to Player 1 gold and display text triggering unit name + " abandons training!" and skip remaining actions

endloop

Replace triggering unit with Rohirrim Spearman using old unit's relative mana and health

/==============================

And before you get on to me about using triggering unit instead of transported unit, it's working fine. Well, sort of. :) Plus the
above is all in custom text but it's easier to read the way I wrote
it.

I do another one like the above except for entering a Manor (accepts gold and builds more workers) to convert Rohirrim Spearmen back to Rohirrim Workers, refunding the SpearmanCost.

See, I build 2 barracks. Then I make two groups of 12 Rohirrim Workers. I gather all 24 around the 2 barracks, then I rapid fire make them all enter until they're all converted into Spearmen. SpearmanWait is 10 right now (5 seconds), so it takes 5 seconds per 4 Workers. Or it's supposed to.

The thing is, and I played with this only a little so I might be off in my observations, if I put one Worker in and wait until he's almost done and then put some more Workers in...some of the Workers come out sooner than their 5 seconds, like at the same time as the first guy. But get this: all 24 Workers get converted to Spearmen, and all 24 Spearmen are converted back to Workers (in the Manor) just fine with no loss of gold even after I do it over and over and over and over (i.e., thoroughly tested this part, heh heh).

So try and explain to me how the use of triggering unit is going to fail the way I'm using it when it is obviously working, at least as far as the unit replacement and gold modification is concerned.

I mean, I've got up to 8 of these triggers going at once (4 per barracks), and it never indicates anybody abandons their training (like you would think it would if it somehow got confused who the triggering unit was and thought that the first guy out was the triggering unit for the 3rd guy in, 3 seconds later). It doesn't "lose" or "gain" gold. After converting all Spearmen back to Workers I've got exactly how much I started with, every time (over and over and over).

But the thing with some of the later guys coming out at the same time as the first guy in is bothering me. If anyone could shed some light on this, I would be a happy camper. I didn't fiddle too much with this, but plan on testing more later. (NOTE: see below for some thoughts on this)

So what does all this have to do with the scope of variables? Well, DrunkOldMan told me in a post on the battle net map forum that I shouldn't/couldn't use triggering unit like I did and implied that it was global and not local to each trigger. Well, this is seemingly not the case since each trigger is somehow keeping track of it's own triggering unit all the way through to the end of the trigger.

What that does imply is that each trigger has a local copy of triggering unit, and transporting unit as well, and probably all of the other event variables that we use.

Can anyone verify this stuff? Does each trigger maintain a local copy of the event vars like triggering unit, transporting unit, entering unit, etc? If not, why is my trigger working? I can understand vars like last created changing while a trigger is working, and of course your own vars that you've created changing if multiple triggers are accessing them. But by golly if it doesn't seem that some of them (again, triggering, transporting, etc.) are definitely local.

And finally, I haven't tried this yet but can you make local vars in custom text?

EDIT:

I think I just figured out why some units come out later than others. It almost seems like something that would happen if the loop variable wasn't local to each trigger, but global. In other words, if unit #1 went in and the loop var started at 1 and incremented up to 5 (out of 10) and then unit #2 entered in, the loop var would be set back to 1...but incremented TWICE per iteration. Unit #3 came in say 2 iterations later, the loop var would again be on 5 (1+2+2) and then reset to 1, but now it would be incremented THREE per iteration. Finally, unit #4 comes in 1 interation later at loop var of 4, reset to 1, but now incremented FOUR times per iteration. It would only take 3 more iterations and then all four triggers would be finished resulting in all four units coming out at the same time! Also, total iterations would be...10!!! Ok, I just made up the above times the units entered but you get the idea. Anyway, that is probably what is happening. It explains why the all come out together, or extremely close together, even when they enter seconds apart at least. Thank you Ninquenor. Heh heh. *pat self on back* To save myself from looking like a total idiot, if anyone can contradict me and tell me what is REALLY happening I'd be more than appreciative. :)

Thanks a ton for any help you may be able to give me on this stuff.

Take care.
08-30-2002, 05:16 PM#2
Mr.123
Integer A and Integer B are global. You can even call another trigger within a for loop and grab those values if you want. To get local variables, switch to custom text and write 'local <type> <name>' where <type> = integer, real, etc and <name> is the name of the variable.

I don't know if WE supports scope in the truest sense of the word. I never tried declaring a variable inside a for loop and tried to access it outside of the loop.
08-30-2002, 06:52 PM#3
SuperIKI
Your text is too long and I'm too lazy to read. But here's some info:

Variables do have a scope.
Globals well are global.
Locals can only be defined at the top of a function and they last for the entire function.
@123: So you cannot create a local variable 'in a for loop'.
You can create a local with the keyword 'local'.

And for the local copies for each trigger: I don't think the trigger has many local copies of variables. That'd use lots of memory keeping track of all those stuff. Maybe some copies will be made. Especially GetTriggeringTrigger() works fine for me. But normally you must make your local copy by yourself.
Look at blizzard.j: Some variables are defined there and they are definitely global:
Code:
    // Last X'd vars
    unit               bj_lastCreatedUnit          = null
    item               bj_lastCreatedItem          = null
    item               bj_lastRemovedItem          = null
    unit               bj_lastHauntedGoldMine      = null
    destructable       bj_lastCreatedDestructable  = null
    group              bj_lastCreatedGroup         = CreateGroup()
    fogmodifier        bj_lastCreatedFogModifier   = null
    effect             bj_lastCreatedEffect        = null
    weathereffect      bj_lastCreatedWeatherEffect = null
    quest              bj_lastCreatedQuest         = null
    questitem          bj_lastCreatedQuestItem     = null
    defeatcondition    bj_lastCreatedDefeatCondition = null
    timer              bj_lastStartedTimer         = CreateTimer()
    timerdialog        bj_lastCreatedTimerDialog   = null
    leaderboard        bj_lastCreatedLeaderboard   = null
    sound              bj_lastPlayedSound          = null
    string             bj_lastPlayedMusic          = ""
    real               bj_lastTransmissionDuration = 0
    gamecache          bj_lastCreatedGameCache     = null
    unit               bj_lastLoadedUnit           = null
    button             bj_lastCreatedButton        = null
    unit               bj_lastReplacedUnit         = null
08-30-2002, 07:12 PM#4
Guest
Quote:
Originally posted by SuperIKI
Your text is too long and I'm too lazy to read.
Sloth! Heh.

Quote:
And for the local copies for each trigger: I don't think the trigger has many local copies of variables. That'd use lots of memory keeping track of all those stuff.
??? A handful of bytes per variable is lots of memory? S'pose we're talking a 256 byte string even. Say 1,000 of those strings are being stored at any given moment. That's only 250 Kb!

Quote:
Look at blizzard.j: Some variables are defined there and they are definitely global:
Yeah, the "last" variables make sense as being global. As soon as you need to you can make a local copy anyways, according to what you and others have told me.

Thanks for the input!

Care.
08-30-2002, 08:06 PM#5
SuperIKI
I think, I can keep the signature: I don't use a horse! :D

And for the memory: You're right, it wouldn't need much memory. But in fact the variables are not stored in this little piece of memory they would use. Sad fact. :(

BTW you're right: You can always make your own local copy of global variables as I told you.