1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  4. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  5. The results are out! Check them out.
    Dismiss Notice
  6. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  7. The raddest synthwave tracks were chosen - Check out our Music Contest #12 - Results and congratulate the winners!
    Dismiss Notice
  8. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Trigger] Generating destructibles

Discussion in 'Triggers & Scripts' started by Strydhaizer, Aug 12, 2019.

  1. Strydhaizer

    Strydhaizer

    Joined:
    Feb 28, 2013
    Messages:
    1,480
    Resources:
    4
    Models:
    1
    Maps:
    1
    Template:
    2
    Resources:
    4
    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
     

    Attached Files:

    Last edited: Aug 12, 2019
  2. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,899
    Resources:
    1
    Spells:
    1
    Resources:
    1
    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.
     
  3. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,544
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    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.