• 🏆 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!

[Trigger] Base Capturing System - Efficency Improvement

Status
Not open for further replies.
Level 31
Joined
Apr 17, 2009
Messages
3,571
Hello Coding Experts :D

At the moment I'm working on a Base Capturing System.
It works like that:

If you enter a region at a circle of power, you have to stay 10 seconds inside this region to capture this base. The seconds are shown as floating text numbers.
If you successfully stay the 10 seconds, the colour of the circle becomes your team colour and the number of captured bases of your team gets increased by 1.

So I made following triggers, which work fine, do exactly what I want.


  • Capture Point01
    • Events
      • Unit - A unit enters NeutralBaseTop <gen>
    • Conditions
      • Or - Any (Conditions) are true
        • Conditons
          • And - All (Conditions) are true
            • Conditions
              • ((Owner of (Triggering unit)) is in Team1) Equal to True
              • Or - Any (Conditions) are true
                • Conditions
                  • CapturedBaseBelonging[1] Equal to 0
                  • CapturedBaseBelonging[1] Equal to 2
          • And - All (Conditions) are true
            • Conditons
              • ((Owner of (Triggering unit)) is in Team2) Equal to True
              • Or - Any (Conditions) are true
                • Condittions
                  • CapturedBaseBelonging[1] Equal to 0
                  • CapturedBaseBelonging[1] Equal to 1
    • Actions
      • Set CaptureTimeCounter[1] = 10
      • Set CapturingUnit[1] = (Entering unit)
      • Trigger - Turn on Capture Point Loop01 <gen>
      • Trigger - Turn off (This trigger)

Explanations:
CapturedBaseBelonging shows which Team owns this base.
0 = neutral, 1 = Team 1, 2 = Team 2.
CaptureTimeCounter is the time you need to stay in for capture it, here 10 seconds.


_________________________________________________________________________________________


  • Capture Base Loop01
    • Events
      • Time - Every 1.00 seconds of game time
    • Condtions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Condtions
          • CaptureTimeCounter[1] Not Equal to -1
        • 'THEN'-Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Conditons
              • (NeutralBaseTop <gen> contains CapturingUnit[1]) Equal to True
            • 'THEN'-Actions
              • Specialeffect- Destroy (Last created special effect)
              • Set TempPointCapture[1] = (Center of NeutralBaseTop <gen>)
              • Floating Text - Destroy CaptureFloatingText[1]
              • Floating Text - Create floating text that reads (String(CaptureTimeCounter[1])) at TempPointCapture[1] with Z offset 100.00, using font size 15.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
              • Set CaptureFloatingText[1] = (Last created floating text)
              • Floating Text - Zeigen CaptureFloatingText[1] for (All players)
              • Specialeffekt - Create a special effect at TempPointCapture[1] using Abilities\Spells\Items\AIre\AIreTarget.mdl
              • Set CaptureTimeCounter[1] = (CaptureTimeCounter[1] - 1)
              • Custom script: call RemoveLocation(udg_TempPointCapture[1])
            • 'ELSE'-Actions
              • Set CaptureTimeCounter[1] = 10
              • Trigger - Turn off (This trigger)
              • Specialeffekt - Destroy (Last created special effect)
        • 'ELSE'-Actions
          • Trigger - Turn off (This trigger)
          • Floating Text - Destroy CaptureFloatingText[1]
          • Unit - Change color of Circle of Power 0039 <gen> to (Color of (Owner of CapturingUnit[1]))
          • Trigger - Turn on Capture Point01 <gen>
          • -------- ///////////////////////////////////////////////////////////////// --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Condtions
              • ((Owner of CapturingUnit[1]) is in Team1) Equal to True
            • 'THEN'-Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • 'IF'-Conditions
                  • CapturedBaseBelonging[1] Equal to 2
                • 'THEN'-Actions
                  • Set CapturedBasesTeam2 = (CapturedBasesTeam2 - 1)
                • 'ELSE'-Actions
              • Set CapturedBasesTeam1 = (CapturedBasesTeam1 + 1)
              • Set CapturedBaseBelonging[1] = 1
            • 'ELSE'-Actions
              • -------- ///////////////////////////////////////////////////////////////// --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • 'IF'-Conditons
                  • CapturedBaseBelonging[1] Equal to 1
                • 'THEN'-Actions
                  • Set CapturedBasesTeam1 = (CapturedBasesTeam1 - 1)
                • 'ELSE'-Actions
              • Set CapturedBasesTeam2 = (CapturedBasesTeam2 + 1)
              • Set CapturedBaseBelonging[1] = 2



Yes, it works fine, but now I have to copy these triggers for every single base I want, which I think could be done more efficient and easier.
But I couldn't figure it out.
I thought about making every variable with an array.
Means for base 1 all variables have array 1
For base 2 all variables have array 2. And so on.

Here I need you help.
How can I make this triggers general and fitting for multiple bases?

Thanks for you time.
+rep for every useful answer.

chilla_killa
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
So basically you need a system to detect which rect was entered?

Try this. There a slightly larger rect for every rect that is entered. That's because Is unit in region check can fail even though Unit enters region triggers. The slightly larger rect is needed for that check to become true.

Looping through rects then gives the index of entered rect.

You could create a dummy unit, attach stuff to it and use it for the looping trigger, loop a unit group.

Or loop from 1 to number of bases.
 

Attachments

  • Enter_Region.w3x
    17.3 KB · Views: 42

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
You can get the X/Y of the entering unit. From this you could create a system which caches available rects at a certain area.

For example, a large map has 256*256 tile areas. I seriously doubt you have more than 1 base per tile area. As such you could reduce a units X/Y into a tile X and tile Y and use that as an index (like to a hashtable) which you store the region/rect which was entered or any other data you need. This has the advantage that it is directly efficent unlike the other way which uses the loop.

The loop method is perfectly fine though if you have low numbers of regions.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
8 is definitely a low enough value to avoid poor performance with looping. Remeber to use skip remaining actions so it doesn't loop after you've found the match.

You could also set bases that are more likely to be captured to low indexes.

But really, the check doesn't require much processing power at all :)
 
Level 31
Joined
Apr 17, 2009
Messages
3,571
Okay guys, I implemented it but I get an error at this line (the memory leak remover):

JASS:
call RemoveLocation(udg_TempPointCapture[index])

What shall I write instead of index???

____________________________________________________________________________________________________


EDIT:

Nevermind, I found it out. Stupid of me. index is a variable so I had to write:

JASS:
call RemoveLocation(udg_TempPointCapture[udg_index])


Everything seems to work as I want with some little flaws I can easily fix.
Thanks again for your help.
Especially Maker's posts were very helpful.
 
Level 31
Joined
Apr 17, 2009
Messages
3,571
Damn, it seems not to be MUI.
I can't capture two different bases at the same time.
It's because I have "Turn on" and "Turn off" the Loop Trigger.
Does someone have a clue how to make it MUI?

Here are the current triggers.
(Hope you get it in german)


  • Capturing Init
    • Ereignisse
      • Zeit - Elapsed game time is 0.00 seconds
    • Bedingungen
    • Aktionen
      • Set CapturedBasesTeam1 = 2
      • Set CapturedBasesTeam2 = 2
      • -------- //////////////////////////////////////////////////////////////// --------
      • Spielergruppe - Add Spieler 1 (Rot) to Team1
      • Spielergruppe - Add Spieler 2 (Blau) to Team1
      • Spielergruppe - Add Spieler 3 (Blaugrau) to Team1
      • Spielergruppe - Add Spieler 4 (Lila) to Team1
      • Spielergruppe - Add Spieler 5 (Gelb) to Team1
      • Spielergruppe - Add Spieler 6 (Orange) to Team2
      • Spielergruppe - Add Spieler 7 (Grün) to Team2
      • Spielergruppe - Add Spieler 8 (Rosa) to Team2
      • Spielergruppe - Add Spieler 9 (Grau) to Team2
      • Spielergruppe - Add Spieler 10 (Hellblau) to Team2
      • Spielergruppe - Add Spieler 11 (Dunkelgrün) to Team1
      • Spielergruppe - Add Spieler 12 (Braun) to Team2
      • -------- //////////////////////////////////////////////////////////////// --------
      • Set Region_Array_Enter[0] = NeutralBaseTop <gen>
      • Set Region_Array_Enter[1] = NeutralBaseBottom <gen>
      • Set Region_Array_Enter[2] = BaseLeftTop <gen>
      • Set Region_Array_Enter[3] = BaseLeftMiddle <gen>
      • Set Region_Array_Enter[4] = BaseLeftBottom <gen>
      • Set Region_Array_Enter[5] = BaseRightTop <gen>
      • Set Region_Array_Enter[6] = BaseRightMiddle <gen>
      • Set Region_Array_Enter[7] = BaseRightBottom <gen>
      • -------- //////////////////////////////////////////////////////////////// --------
      • Set Region_Array_Check[0] = NeutralBaseTopCheck <gen>
      • Set Region_Array_Check[1] = NeutralBaseBottomCheck <gen>
      • Set Region_Array_Check[2] = BaseLeftTopCheck <gen>
      • Set Region_Array_Check[3] = BaseLeftMiddleCheck <gen>
      • Set Region_Array_Check[4] = BaseLeftBottomCheck <gen>
      • Set Region_Array_Check[5] = BaseRightTopCheck <gen>
      • Set Region_Array_Check[6] = BaseRightMiddleCheck <gen>
      • Set Region_Array_Check[7] = BaseRightBottomCheck <gen>
      • -------- //////////////////////////////////////////////////////////////// --------
      • Set CircleOfPower[0] = Kreis der Macht 0039 <gen>
      • Set CircleOfPower[1] = Kreis der Macht 0038 <gen>
      • Set CircleOfPower[2] = Kreis der Macht 0145 <gen>
      • Set CircleOfPower[3] = Kreis der Macht 0037 <gen>
      • Set CircleOfPower[4] = Kreis der Macht 0084 <gen>
      • Set CircleOfPower[5] = Kreis der Macht 0146 <gen>
      • Set CircleOfPower[6] = Kreis der Macht 0040 <gen>
      • Set CircleOfPower[7] = Kreis der Macht 0147 <gen>
      • -------- //////////////////////////////////////////////////////////////// --------
      • For each (Integer loopA) from 0 to 7, do (Actions)
        • Schleifen - Aktionen
          • Auslöser - Add to Capturing Enter <gen> the event (Einheit - A unit enters Region_Array_Enter[loopA])



  • Capturing Enter
    • Ereignisse
    • Bedingungen
    • Aktionen
      • Set u1 = (Triggering unit)
      • For each (Integer loopA) from 0 to 7, do (Actions)
        • Schleifen - Aktionen
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Bedingungen
              • (Region_Array_Check[loopA] contains u1) Gleich True
            • 'THEN'-Aktionen
              • Set index = loopA
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • 'IF'-Bedingungen
                  • Or - Any (Conditions) are true
                    • Bedingungen
                      • And - All (Conditions) are true
                        • Bedingungen
                          • ((Owner of (Triggering unit)) is in Team1) Gleich True
                          • Or - Any (Conditions) are true
                            • Bedingungen
                              • CapturedBaseBelonging[index] Gleich 0
                              • CapturedBaseBelonging[index] Gleich 2
                      • And - All (Conditions) are true
                        • Bedingungen
                          • ((Owner of (Triggering unit)) is in Team2) Gleich True
                          • Or - Any (Conditions) are true
                            • Bedingungen
                              • CapturedBaseBelonging[index] Gleich 0
                              • CapturedBaseBelonging[index] Gleich 1
                • 'THEN'-Aktionen
                  • Set CaptureTimeCounter[index] = 10
                  • Set CapturingUnit[index] = u1
                  • Auslöser - Turn on Capture Point Loop <gen>
                  • Skip remaining actions
                • 'ELSE'-Aktionen
                  • Skip remaining actions
            • 'ELSE'-Aktionen
Is the loss of MUI located here?
Because I do
  • Set CapturingUnit[index] = u1



  • Capture Point Loop
    • Ereignisse
      • Zeit - Every 1.00 seconds of game time
    • Bedingungen
    • Aktionen
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • 'IF'-Bedingungen
          • CaptureTimeCounter[index] Ungleich -1
        • 'THEN'-Aktionen
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Bedingungen
              • (Region_Array_Check[index] contains CapturingUnit[index]) Gleich True
            • 'THEN'-Aktionen
              • Spezialeffekt - Destroy Capturing_SFX[index]
              • Set TempPointCapture[index] = (Center of Region_Array_Check[index])
              • Schwebender Text - Destroy CaptureFloatingText[index]
              • Schwebender Text - Create floating text that reads (String(CaptureTimeCounter[index])) at TempPointCapture[index] with Z offset 100.00, using font size 15.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
              • Set CaptureFloatingText[index] = (Last created floating text)
              • Schwebender Text - Zeigen CaptureFloatingText[index] for (All players)
              • Spezialeffekt - Create a special effect at TempPointCapture[index] using Abilities\Spells\Items\AIre\AIreTarget.mdl
              • Set Capturing_SFX[index] = (Last created special effect)
              • Set CaptureTimeCounter[index] = (CaptureTimeCounter[index] - 1)
              • Custom script: call RemoveLocation(udg_TempPointCapture[udg_index])
            • 'ELSE'-Aktionen
              • Set CaptureTimeCounter[index] = 10
              • Auslöser - Turn off (This trigger)
              • Spezialeffekt - Destroy Capturing_SFX[index]
        • 'ELSE'-Aktionen
          • Auslöser - Turn off (This trigger)
          • Schwebender Text - Destroy CaptureFloatingText[index]
          • Einheit - Change ownership of CircleOfPower[index] to (Owner of CapturingUnit[index]) and Farbe wechseln
          • -------- ///////////////////////////////////////////////////////////////// --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Bedingungen
              • ((Owner of CapturingUnit[index]) is in Team1) Gleich True
            • 'THEN'-Aktionen
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • 'IF'-Bedingungen
                  • CapturedBaseBelonging[index] Gleich 2
                • 'THEN'-Aktionen
                  • Set CapturedBasesTeam2 = (CapturedBasesTeam2 - 1)
                • 'ELSE'-Aktionen
              • Set CapturedBasesTeam1 = (CapturedBasesTeam1 + 1)
              • Set CapturedBaseBelonging[index] = 1
            • 'ELSE'-Aktionen
              • -------- ///////////////////////////////////////////////////////////////// --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • 'IF'-Bedingungen
                  • CapturedBaseBelonging[index] Gleich 1
                • 'THEN'-Aktionen
                  • Set CapturedBasesTeam1 = (CapturedBasesTeam1 - 1)
                • 'ELSE'-Aktionen
              • Set CapturedBasesTeam2 = (CapturedBasesTeam2 + 1)
              • Set CapturedBaseBelonging[index] = 2
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
You could create a variable the keeps up with how many bases are being captured. Begins being captured -> variable = variable +1, capturing ends -> variable = variable -1.

If the variable is 0 in the looping trigger, turn it off. Otherwise some capturing is going on, and the trigger should remain to be on.
 
Status
Not open for further replies.
Top