• 🏆 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] Generating destructibles

Status
Not open for further replies.
Hello, I made this trigger for my map, I just want to consult to you guys if it is actually good or it can be optimized abit more.

I saved the points of the destructibles at the array so that the destructible will not spawn at the same spot.

  • Dev Arena Detect
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
      • Unit - A unit enters Arena Detect Player <gen>
    • Conditions
    • Actions
      • -------- --------
      • -------- Debug --------
      • Game - Display to (All players) the text: Randomized
      • -------- --------
      • -------- Setup --------
      • Set Arena_DesCountMax = 20
      • Set Arena_DesCountCurrent = 0
      • Set Arena_SimilarPointCheck = False
      • -------- --------
      • -------- Clear the area --------
      • Destructible - Pick every destructible in Arena Detect Player <gen> and do (Actions)
        • Loop - Actions
          • Destructible - Remove (Picked destructible)
      • -------- --------
      • -------- Clear the points --------
      • For each (Integer A) from 1 to Arena_DesCountMax, do (Actions)
        • Loop - Actions
          • Set Arena_DesPointArraySaved[(Integer A)] = (Point(0.00, 0.00))
      • -------- --------
      • -------- Generate Objects --------
      • Trigger - Run Dev Arena Generate <gen> (ignoring conditions)
  • Dev Arena Generate
    • Events
    • Conditions
    • Actions
      • -------- --------
      • -------- Check if objects is below or equal the max --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Arena_DesCountCurrent Less than or equal to Arena_DesCountMax
        • Then - Actions
          • -------- --------
          • -------- Check if the point is already taken --------
          • Set Arena_DesPoint = (Random point in Arena Spawn Doods <gen>)
          • For each (Integer A) from 1 to Arena_DesCountMax, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • (X of Arena_DesPointArraySaved[(Integer A)]) Equal to (X of Arena_DesPoint)
                      • (Y of Arena_DesPointArraySaved[(Integer A)]) Equal to (Y of Arena_DesPoint)
                • Then - Actions
                  • Set Arena_SimilarPointCheck = True
                • Else - Actions
                  • Do nothing
          • -------- --------
          • -------- Rerun trigger without increment if point already exists, otherwise generate objects --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Arena_SimilarPointCheck Equal to True
            • Then - Actions
              • -------- --------
              • -------- Debug --------
              • Game - Display to (All players) the text: Same Point
              • -------- --------
              • -------- Run again --------
              • Trigger - Run (This trigger) (ignoring conditions)
            • Else - Actions
              • -------- --------
              • -------- Debug --------
              • Game - Display to (All players) the text: Generated
              • -------- --------
              • -------- Randomize object models --------
              • Set Arena_DesRandomDes = (Random integer number between 1 and 2)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Arena_DesRandomDes Equal to 1
                • Then - Actions
                  • Destructible - Create a #B02_ArenaBarrel at Arena_DesPoint facing (Random angle) with scale 3.00 and variation 0
                • Else - Actions
                  • Destructible - Create a #B02_ArenaBarrel2 at Arena_DesPoint facing (Random angle) with scale 3.00 and variation 0
              • -------- --------
              • -------- Save the point as taken --------
              • Set Arena_DesPointArraySaved[Arena_DesCountCurrent] = (Point((X of (Position of (Last created destructible))), (Y of (Position of (Last created destructible)))))
              • -------- --------
              • -------- Increment --------
              • Set Arena_DesCountCurrent = (Arena_DesCountCurrent + 1)
              • -------- --------
              • -------- Run again --------
              • Trigger - Run (This trigger) (ignoring conditions)
        • Else - Actions
          • Custom script: call RemoveLocation(udg_Arena_DesPoint)
          • Set Arena_DesCountCurrent = 0
          • For each (Integer A) from 1 to Arena_DesCountMax, do (Actions)
            • Loop - Actions
              • Custom script: call RemoveLocation(udg_Arena_DesPointArraySaved[udg_Arena_DesCountCurrent])
          • Set Arena_DesCountCurrent = 0

Edit: Actually it still doesn't work, destructible/s still spawn/s on top of another destructible (see attachment). I'll try to fix it, brb :D
 

Attachments

  • WC3ScrnShot_081219_103436_01.png
    WC3ScrnShot_081219_103436_01.png
    2.1 MB · Views: 34
Last edited:
Level 38
Joined
Feb 27, 2007
Messages
4,951
  1. You are not setting Arena_SimilarPointCheck = false before the trigger runs so even if it did work once it detected a 'same point' once it would never be able to spawn another destructible and would threadcrash.
  2. The way you are attempting to clear the point array is ridiculous and is causing you to leak 2x as many locations. Just RemoveLocation() on each of the points; trying to get the X/Y values of a null point just returns 0 anyway.
  3. This method will almost never actually work because the odds of randomizing the exact same point are astronomically slim. Points are not (integer, integer) they are (real, real). Remember how in school you learned that the real number line is a continuum so there are an infinite number of real values between 1.000 and 1.001? Same logic applies here, with the caveat that there is some minimum real value wc3 can work with, so it's not technically infinite. What you will randomize are points that are close to each other but are not exactly the same, which your method would never pick up. For example: (32.005, 951.20013) vs (32.110, 950.000).
There are 2 ways to resolve 3 above and actually get randomized destructibles that aren't too close to each other.
  1. Save the location of all placed destructibles in an array as you've done. Generate a new point, and then check the distance from that point to all placed destructible locations. If any distance is < some min threshold, throw out the point and generate a new one.

  2. Subdivide your arena into a grid of possible destructible spawn locations. Eyeballing your screenshot I'd say a 21x14 (X-by-Y) grid would probably give approximately the spacing you have present there. Pre-generate these 21*14=294 points and save them into a 2D array where [X][Y] = [X*14 + Y]. Make another parallel boolean array that checks if that location has a destructible placed in it. When you want to place a destructible, randomize rX between 1 and 21, rY between 1 and 14, and then check the [rX][rY] = [rX*14 + rY] index of the boolean array to see if it's used. If so, randomize again. If not, make the destructible at the location in the point array and set the boolean array = true so you know there's one there already.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
There are likely standard and well tested algorithms that can do what you are after doing. I would suggest googling for those to avoid trying to reinvent the wheel.

When creating a destructable you can check if there are any nearby destructables before creation and if so abort. This is useful if you do not care how many spawn and just want them to appear randomly.
 
Status
Not open for further replies.
Top