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. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. 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.

[Solved] Get Terrain at Point?

Discussion in 'Triggers & Scripts' started by Me_lo_dy, Oct 28, 2019.

  1. Me_lo_dy

    Me_lo_dy

    Joined:
    Mar 1, 2009
    Messages:
    12
    Resources:
    0
    Resources:
    0
    Hey, so I'm making a map and it involves items spawning on the ground, but I want it to spawn somewhere pathable.

    In short: How do I use JASS to check for terrain at a given point?

    I want a given item to only spawn on the ground if the terrain is, say, Dalaran - Grass. (I'm using this terrain because I've set... say, Dalaran - Trim Grass, under unpathable things like trees and doodads.) I have a trigger for the rest of the item spawning that's all fine and well, but this is the part of the trigger I want to troubleshoot:

    • Custom script: loop
    • Set L = (Random point in safe zone west <gen>)
    • Custom script: exitwhen //need to find terrain type here to check against preset variable 'dalaran_grass'
    • Custom script: endloop


    I know you can do a Terrain Type Comparison in the GUI editor which is the exact effect I'm looking for. I guess what I'm asking after is how to translate that into JASS, since as far as I know I have to keep "exitwhen" and the rest of the statement on the same line.

    EDIT:

    I used this guide by deathismyfriend to convert a trigger with only "If (Terrain type at (L)) equal to Dalaran - Grass" to JASS. I pulled what I think is what I need from that, so now my trigger looks like this:

    • Custom script: loop
    • Set L = (Random point in safe zone west <gen>)
    • Custom script: exitwhen exitwhen (GetTerrainTypeBJ(udg_L) == udg_dalaran_grass)
    • Custom script: endloop


    Note that (udg_dalaran_grass) is a global variable that's just Dalaran - Grass where it's easy to call upon. (This isn't the only trigger that's gonna need to look for Dalaran - Grass, so I figure I'm not legally culpable for this.)

    Am I right to use this, or is there a better/less stupid way?

    EDIT 2: Looks like it works. Items are generating and I noticed none of them generating on tiles that weren't Dalaran - Grass. I'll strike this edit out and bump the thread if I later on notice that they're generating on other terrain types. Until then, leaving this up for posterity because Google didn't help me how I wanted when I was originally trying to figure this out.
     
    Last edited: Oct 28, 2019
  2. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    3,056
    Resources:
    1
    Spells:
    1
    Resources:
    1
    You could use it without the BJ wrapper but otherwise that’s a fine way to do it.
     
  3. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,163
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    The gras might be under a bulding, at cliffs, under unreachable doodads, etc. It might be checking for gras alone does not suffice.
    But maybe there's no extra check needed, if it's specifically for spawning items. Actually, moving an item is already used as method to check if a point is walkable, or not. Check Walkability
     
  4. FeelsGoodMan

    FeelsGoodMan

    Joined:
    Dec 13, 2018
    Messages:
    574
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Code (Text):

    function TerrainChangeInRect takes rect r returns nothing
        local real minx = GetRectMinX(r)
        local real miny = GetRectMinY(r)
        local real maxx = GetRectMaxX(r)
        local real maxy = GetRectMaxY(r)
        local real x=minx
        local real y=maxy
        local integer TType
        loop
            exitwhen y<miny
            loop
                exitwhen x>maxx
                set TType = GetTerrainType(x, y)
                if TType == 'Ldrt' then // 'Ldrt' is the TerrainType-Id that should be found
                    call SetTerrainType(x, y, 'Jsqd', -1, 1, 0)
                    // 'Jsqd' ist the TerrainType-Id that will replace 'Ldrt
                elseif TType == 'Lgrd' then
                    // use more elseif's to add more terrain types that can be found in the rect and replace them with other ones
                    call SetTerrainType(x, y, 'Jsqd', -1, 1, 0)
                endif
                set x=x+128
            endloop
            set x=minx
            set y=y-128.0
            call TriggerSleepAction(0.01) // The wait could be needed to prevent a small lag and to make the terrain completely change if the rect is too big
        endloop
    endfunction
     

    • Events
      • Player - Player 1 (Red) types a chat message containing 2 as An exact match
    • Conditions
    • Actions
      • Custom script: call TerrainChangeInRect(gg_rct_Region_000)

    Instead of calling SetTerrainType you just create the appropriate item.

    I'm not sure if it will actually work as I don't know JASS but I know this effectively tracks terrain type and changes it out. If my theory is correct you should be able to just remove the functions that replaces the terrain and insert functions to create items instead.
     
  5. Me_lo_dy

    Me_lo_dy

    Joined:
    Mar 1, 2009
    Messages:
    12
    Resources:
    0
    Resources:
    0
    So... in other words, you're saying that this would be a valid way of doing it? Or am I mistaking what you're saying somehow?
    • Custom script: exitwhen (GetTerrainType == udg_dalaran_grass)


    The way I have it set is that I put Ashenvale - Leaves underneath all the trees, and Dalaran - Grass where it's pathable (in the area of the map where items should spawn). I basically don't want it to be on Dalaran - Dirt Cliff (where it could be halfway off the cliff and be hard-to-reach or unreachable) or on Ashenvale - Leaves (trees, exclusively). That said, that link is very fascinating, so thank you very much for linking it.

    This is a very interesting system as well. Honestly, all this in code makes it easy for me to just stick it in a New Custom Script instead of having to pick at individual Custom Script lines in an otherwise-purely-GUI trigger. I'll try this one out too and see which one I find good.

    Thank you, everyone who's responded so far!
     
  6. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    3,056
    Resources:
    1
    Spells:
    1
    Resources:
    1
    No. Usually functions that have BJ (Blizzard Jass) at the end are just unnecessary wrappers for non-bj functions. It is recommended not to call these functions as they are by definition less efficient than calling the function they wrap directly. In most instances this would never make a noticeable difference, and GUI uses all these BJs anyway, but it's best practice not to use them. An example of one of these is below, followed by the function you're using.
    Code (vJASS):
    //useless BJ
    function GetIssuedOrderIdBJ takes nothing returns integer
        return GetIssuedOrderId()
    endfunction

    //the function you used
    function GetTerrainTypeBJ takes location where returns integer
        return GetTerrainType(GetLocationX(where), GetLocationY(where))
    endfunction

    You can see that the second isn't a simple wrapper since it takes a location argument and the native takes coordinates. This means I was wrong that you can't simply replace it unless you instead randomize coordinates, but honestly that wouldn't be any noticeable performance difference for you and locations are easier to work with in GUI. Leave it as it is.