HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Problems with loops?

06-14-2006, 02:40 AM#1
StRoNgFoE_2000
Hello everyone, in my wmw map I have a few triggers that keep track of the shrines when they are replaced, upgraded, or autoupgraded at 2000 income. I have all of the triggers using "for each integer A", and every once in awhile it gives me problems. Even though I know that all my shrines are being tracked correctly, sometimes the auto upgrade trigger will fire over and over and constantly replace the shrine after 2000 income, even though the trigger can only fire if shrine tracker is a certain type.

This trigger sets the shrines to a variable right at the start.
Trigger:
InitializeVariables
Collapse Events
Time - Elapsed game time is 0.20 seconds
Conditions
Collapse Actions
-------- ShrineTracker --------
Set ShrineTracker[1] = Shrine Level 1 0001 <gen>
Set ShrineTracker[2] = Shrine Level 1 0008 <gen>
Set ShrineTracker[3] = Shrine Level 1 0012 <gen>
Set ShrineTracker[4] = Shrine Level 1 0013 <gen>
Set ShrineTracker[5] = Shrine Level 1 0014 <gen>
Set ShrineTracker[6] = Shrine Level 1 0015 <gen>

This trigger replaces the shrines if superspeed is set, and remembers what it was.
Trigger:
SuperSpeedMode
Events
Conditions
Collapse Actions
Collapse For each (Integer A) from 1 to 6, do (Actions)
Collapse Loop - Actions
Set TempGroup = (Units in (Playable map area) owned by (Player((Integer A))))
Unit Group - Pick every unit in TempGroup and do (If ((Unit-type of (Picked unit)) Equal to Shrine Level 1) then do (Unit - Replace (Picked unit) with a SuperSpeed Shrine Lvl 1 using The new unit's max life and mana) else do (Do nothing))
Set ShrineTracker[(Integer A)] = (Last replaced unit)
Set TempGroup = (Units in (Playable map area))
Unit Group - Pick every unit in TempGroup and do (If ((Unit-type of (Picked unit)) Equal to Snow Man) then do (Unit - Replace (Picked unit) with a RF Snow Man using The new unit's max life and mana) else do (Do nothing))
Custom script: call DestroyGroup (udg_TempGroup)
For each (Integer A) from 1 to 6, do (Game - Display to (Player((Integer A))), at offset (0.00, 0.00) for 5.00 seconds the text: |c00ffff80S|r|c00ff...)
Trigger - Turn off AutoUpgradeShrine <gen>
Trigger - Turn on AutoUpgradeSuperSpeed <gen>

This trigger upgrades the shrines manually.
Trigger:
UpgradeSuperSpeed
Collapse Events
Unit - A unit Begins research
Collapse Conditions
(Researched tech-type) Equal to SuperSpeed Shrine Level 2
Collapse Actions
Wait 0.50 seconds
Unit - Replace (Triggering unit) with a SuperSpeed Shrine Lvl 2 using The new unit's max life and mana
Selection - Select (Last replaced unit) for (Triggering player)
Set ShrineTracker[(Player number of (Triggering player))] = (Last replaced unit)
Player - Add -1200 to (Triggering player) Current gold

This trigger auto upgrades the shrine.
Trigger:
AutoUpgradeSuperSpeed
Collapse Events
Time - Every 8.00 seconds of game time
Conditions
Collapse Actions
Collapse For each (Integer A) from 1 to 6, do (Actions)
Collapse Loop - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
(Unit-type of ShrineTracker[(Integer A)]) Equal to SuperSpeed Shrine Lvl 1
Income[(Integer A)] Greater than or equal to 2000
Collapse Then - Actions
Wait 0.50 seconds
Unit - Replace ShrineTracker[(Integer A)] with a SuperSpeed Shrine Lvl 2 using The new unit's default life and mana
Selection - Select (Last replaced unit) for (Player((Integer A)))
Set ShrineTracker[(Integer A)] = (Last replaced unit)
Game - Display to (Player((Integer A))), at offset (0.00, 0.00) the text: |c0000cdf9Your inco...
Else - Actions

I think the problem is either with the upgrade trigger, autoupgrade trigger, or there is a problem with using "for each integer A" or im not using it correctly. Any help will be appreciated.
06-14-2006, 03:19 AM#2
johnfn
Using For Loop Integer A with Waits is dangerous because Integer A is a global value meaning it can be overridden in other triggers. Change that to For Each (Variable) being a local variable and all should be well.
06-14-2006, 06:36 AM#3
Blade.dk
Eventually you can use the trick with local globals, and put a
Trigger:
Custom Script: local integer bj_forLoopAIndex

You can only use this bug on one variable per trigger, though. And it will cause problems if you use stuff like Pick Every Units In <Something> or Pick Every Player In <Something> in your trigger.
06-14-2006, 09:05 AM#4
StRoNgFoE_2000
ok i took the time and read vexorians post on local variables to understand them a little better found here. So, all I have to do is put this line of custom text at the start of the trigger, and refer to that integer instead of using integer A?

Trigger:
AutoUpgradeSuperSpeed
Collapse Events
Time - Every 8.00 seconds of game time
Conditions
Collapse Actions
Custom script: local integer udg_localinteger
Collapse For each (Integer localinteger) from 1 to 6, do (Actions)
Collapse Loop - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
(Unit-type of ShrineTracker[localinteger]) Equal to SuperSpeed Shrine Lvl 1
Income[localinteger] Greater than or equal to 2000
Collapse Then - Actions
Wait 0.50 seconds
Unit - Replace ShrineTracker[localinteger] with a SuperSpeed Shrine Lvl 2 using The new unit's default life and mana
Selection - Select (Last replaced unit) for (Player(localinteger))
Set ShrineTracker[localinteger] = (Last replaced unit)
Game - Display to (Player(localinteger)), at offset (0.00, 0.00) the text: |c0000cdf9Your inco...
Else - Actions

correct me if this is wrong.

Edit: Ok, in this case it is wrong. After reading a little more thoroughly about this subject and testing this failed trigger, I learned that locals cannot be used in the if/then/else actions. this creates a problem in the case i need the conditions to be checked every 8 seconds and match the player inside of the loop, but in this case, how can it be avoided? Should I just use a different global for each trigger that uses if/then/else instead? The above trigger crashed my game when it fired, but didn't when i removed the custom text.

And one last thing. The reason I use the wait command at all is because for some reason without that small delay the shrine sometimes did not get replaced. Using the wait fixed that but caused this problem.
05-09-2007, 10:29 PM#5
Euroset
hmm, i say you global idea. WAIT command in loop with "integer A" or "integer B" will make a bug if TWO or more loops runs at one time. Example: loop1 starts and when a=3 starts loop2. loop2 sets a=1 while loop1 is waiting. understand? A is global variable for all loops. if you want to run loops with wait action at one time, use local variables. you can use custom scrips for this idea.

Custom script: local integer a
Custom script: set a = 1
Custom script: loop
Custom script: exitwhen a > 20
Unit - Move air instantly to ((Position of land) offset by (((Distance between (Position of air) and (Position of land)) x 0.90) - 1.00) towards (Angle from (Position of land) to (Position of air)) degrees), facing ((Facing of land) + (((Facing of air) - (Facing of land)) x 0.80)) degrees
Wait 0.05 seconds
Custom script: set a = a + 1
Custom script: endloop