• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Trigger] Terrain-detect triggers request

Status
Not open for further replies.
Level 3
Joined
Jun 13, 2008
Messages
59
[REQUEST]

I need a terrain detect trigger for my map. It should work like this:

When a unit walks into water-terrain, his health will gradually drop. While on Lava terrain, it will gain speed and attack bonus.

And the trigger should not depend on regions.


Jass will be good, but GUI will be better.


[DETAILS]
Generic Informations
Map Size : Huge ( 192 x 192 )

Speed+Attack Bonus
Lava tiles : Little circle on the center of the map and done through triggered-skill
# of Units affected : 3-15

Health Penalty
Water tiles : Bending rivers (making region trigger useless)
# of Units on the map : 12-225
# of Players : 12



[RAINBOW]All helps and suggestions are appreciated[/RAINBOW]:thumbs_up:
 
Last edited:
Level 28
Joined
Mar 25, 2008
Messages
2,955
Put regions all over the water areas and include them in that trigger
  • Events
    • Time - Every x seconds of the game
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every Unit in (Playable map area) and do:
    • If / Then / Else - multiple actions
      • If - Conditions
        • Or, multiple Conditions
          • (Picked Unit) is in region 1 equal to true
          • (Picked Unit) is in region 2 equal to true
          • (Picked Unit) is in region 3 equal to true
          • (Picked Unit) is in region 4 equal to true
          • (Picked Unit) is in region ... equal to true
      • Then - Actions
        • Unit - Set Life of (Picked Unit) to ((Life of (Picked Unit) - x)
      • Else - Actions
Next,
  • Events
    • Time - Every x seconds of the game
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every Unit in (Playable map area) and do:
      • Set temppoint = Position of (Picked Unit)
      • If / Then / Else - multiple actions
        • If - Conditions
          • Terrain type at temppoint equal to *lava*
        • Then - Actions
          • Unit - Create 1 dummy at temppoint for (Owner of (Picked Unit)) facing default building degrees degrees
          • Unit - Add a 3 seconds standard expiration timer to (last created unit)
          • Unit - Add *the speed ability* to (last created unit)
          • Unit - Order (last created unit) to *speed ability* (Picked Unit)
        • Else - Actions
      • Custom script: call RemoveLocation (udg_temppoint)
 
Level 6
Joined
Sep 5, 2007
Messages
264
And the trigger should not depend on regions.
@Squiggy: I'm not picking here, but your answer depends on regions.

@zipeater1990: You'd have to use unit picking. No matter what way you approach this, if there are a fair few units on the map or you want the damage to occur fairly often, then performance issues WILL arise. I'm sure that there'd be a way to do it quickly, I just can't think of it right now.
 
Level 3
Joined
Jun 13, 2008
Messages
59
Put regions all over the water areas and include them in that trigger
  • Events
    • Time - Every x seconds of the game
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every Unit in (Playable map area) and do:
    • If / Then / Else - multiple actions
      • If - Conditions
        • Or, multiple Conditions
          • (Picked Unit) is in region 1 equal to true
          • (Picked Unit) is in region 2 equal to true
          • (Picked Unit) is in region 3 equal to true
          • (Picked Unit) is in region 4 equal to true
          • (Picked Unit) is in region ... equal to true
      • Then - Actions
        • Unit - Set Life of (Picked Unit) to ((Life of (Picked Unit) - x)
      • Else - Actions
Next,
  • Events
    • Time - Every x seconds of the game
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every Unit in (Playable map area) and do:
      • Set temppoint = Position of (Picked Unit)
      • If / Then / Else - multiple actions
        • If - Conditions
          • Terrain type at temppoint equal to *lava*
        • Then - Actions
          • Unit - Create 1 dummy at temppoint for (Owner of (Picked Unit)) facing default building degrees degrees
          • Unit - Add a 3 seconds standard expiration timer to (last created unit)
          • Unit - Add *the speed ability* to (last created unit)
          • Unit - Order (last created unit) to *speed ability* (Picked Unit)
        • Else - Actions
      • Custom script: call RemoveLocation (udg_temppoint)

Well, thank you for paying attention for my request. It is a good trigger, yet it still depends on region.I'm making a HUGE map with lots of bending rivers that made region-triggerring will be pretty hard. I appreciate it though.

@Squiggy: I'm not picking here, but your answer depends on regions.

@zipeater1990: You'd have to use unit picking. No matter what way you approach this, if there are a fair few units on the map or you want the damage to occur fairly often, then performance issues WILL arise. I'm sure that there'd be a way to do it quickly, I just can't think of it right now.

Sorry, i didn't get into the specific details, Lord_BoNes. There will be about 3 units affected by this trigger, or a maximum of 15 units. I tried the unit picking but still found no clue. I even used a dummy unit with 0 collision with permanent immolation ALL OVER the rivers, but it didn't turn out quite good. Any solution?
 
Level 6
Joined
Sep 5, 2007
Messages
264
I take it that by "lava" you mean the terrain-tile...

What you could do is (JASS solution):
Pick your units, use "ForGroup" to scan through the group, using this function:
JASS:
function ScanGroup takes nothing returns nothing
    local unit enum = GetEnumUnit()
    local real x = GetUnitX(enum)
    local real y = GetUnitY(enum)

    local boolean path_amphib = IsTerrainPathable(x,y, PATHING_TYPE_AMPHIBIOUSPATHING)
    local boolean path_walk = IsTerrainPathable(x,y, PATHING_TYPE_WALKABILITY)
    local integer terrain_id = GetTerrainType(x,y)

    // Water check
    if (path_amphib == true and path_walk != true) then
        <do water actions here>
    elseif (terrain_id == <id of lava tile>) then
        <do lava actions here>
    endif

    set enum = null
endfunction
 
Level 3
Joined
Jun 13, 2008
Messages
59
Solution granted. Any other GUI solution?

I take it that by "lava" you mean the terrain-tile...

What you could do is (JASS solution):
Pick your units, use "ForGroup" to scan through the group, using this function:
JASS:
function ScanGroup takes nothing returns nothing
    local unit enum = GetEnumUnit()
    local real x = GetUnitX(enum)
    local real y = GetUnitY(enum)

    local boolean path_amphib = IsTerrainPathable(x,y, PATHING_TYPE_AMPHIBIOUSPATHING)
    local boolean path_walk = IsTerrainPathable(x,y, PATHING_TYPE_WALKABILITY)
    local integer terrain_id = GetTerrainType(x,y)

    // Water check
    if (path_amphib == true and path_walk != true) then
        <do water actions here>
    elseif (terrain_id == <id of lava tile>) then
        <do lava actions here>
    endif

    set enum = null
endfunction

Sorry for the long absent. My computer got knocked down.


Thx Lord_BoNes, for your system! Rep is on the way!:grin: Haha. But still, I'm waiting for GUI solutions. Yeah, I'll use this system too, but I'm looking forward for a GUI user-friendly map so anyone can learn and develop my map further, Thanks anyway...:infl_thumbs_up:
 
Level 3
Joined
Jun 13, 2008
Messages
59
I would check every 0.5 seconds. It would'nt lag great deal.

Really? Haven't tried it on multi player games yet, but I'll try it soon. Maybe beta test it here if I've completed the codes.

To check for Water in GUI you could try a condition like:

  • (Terrain pathing at TempPoint of type Floatability is off) Equal to False

Nice... but actually, I'm already thought about this, and it's timer-dependent. Thanks though!
 
Level 8
Joined
May 21, 2008
Messages
218
Gui trigger probably wont cause lagg but I'll make an optimized Jass Trigger for ya to.

  • Terrain Kill
    • Events
      • Time - Every 0.35 seconds of game time
    • Conditions
    • Actions
      • Set temp_group = (Units in (Playable map area))
      • Unit Group - Pick every unit in temp_group and do (Actions)
        • Loop - Actions
          • Set temp_point = (Position of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Summer - Grass
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Summer - Dark Grass
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Fall - Dirt
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Fall - Grassy Dirt
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
Jass optimized to natives.

JASS:
function Trig_Terrain_Kill_Func002Func002C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Lgrs' ) ) then //Terrain type Lgrs
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002Func003C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Lgrd' ) ) then //Terrain type Lgrd
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002Func004C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Fdrt' ) ) then //ect...
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002Func005C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Fdrg' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002A takes nothing returns nothing //filter chooser
    set udg_temp_point = GetUnitLoc(GetEnumUnit())
    if ( Trig_Terrain_Kill_Func002Func002C() ) then
        // Your actions
    else
    endif
    if ( Trig_Terrain_Kill_Func002Func003C() ) then
        // Your actions
    else
    endif
    if ( Trig_Terrain_Kill_Func002Func004C() ) then
        // Your actions
    else
    endif
    if ( Trig_Terrain_Kill_Func002Func005C() ) then
        // Your actions
    else
    endif
endfunction

function Trig_Terrain_Kill_Actions takes nothing returns nothing //picks units, assigns fiter
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
    call ForGroup( udg_temp_group, function Trig_Terrain_Kill_Func002A )
endfunction

//===========================================================================
function InitTrig_Terrain_Kill takes nothing returns nothing
    set gg_trg_Terrain_Kill = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Terrain_Kill, 0.35, true )
    call TriggerAddAction( gg_trg_Terrain_Kill, function Trig_Terrain_Kill_Actions )
endfunction

Did not use locals and did not test trigger. Gui one works for sure, Jass not so sure. I'm newbie to jass.
 
Level 6
Joined
Sep 5, 2007
Messages
264
@Zypher: I optimised it...
JASS:
function Func_True takes nothing returns boolean
    return true
endfunction
function Filter_AlwaysTrue takes nothing returns boolexpr
    return Filter(function Func_True)
endfunction

function Trig_Terrain_Kill_Actions takes nothing returns nothing //picks units, assigns fiter
    local group g = CreateGroup()

    local unit enum
    local real x
    local real y
    local integer terrain_type

    local boolexpr filter = Filter_AlwaysTrue() 
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, filter)
    call DestroyBoolExpr(filter)

    loop
        set enum = FirstOfGroup(g)
        exitwhen (enum == null)

        set x = GetUnitX(enum)
        set y = GetUnitY(enum)
        set terrain_type = GetTerrainType(x, y)

        if (terrain_type == 'Lgrs') then
            // Lordaeron Summer Grass
        elseif (terrain_type == 'Lgrd') then
            // Lordaeron Summer Dark Grass
        elseif (terrain_type == 'Fdrt') then
            // Lordaeron Fall Dirt
        elseif (terrain_type == 'Fdrg') then
            // Lordaeron Fall Grassy Dirt
        endif

        call GroupRemoveUnit(g, enum)
    endloop

    call DestroyGroup(g)
    set g = null
endfunction

//===========================================================================
function InitTrig_Terrain_Kill takes nothing returns nothing
    set gg_trg_Terrain_Kill = CreateTrigger()
    call TriggerRegisterTimerEvent(gg_trg_Terrain_Kill, 0.35, true)
    call TriggerAddAction(gg_trg_Terrain_Kill, function Trig_Terrain_Kill_Actions)
endfunction

You were leaking a location and a group on each execution.
JASS:
// This location
set udg_temp_point = GetUnitLoc(GetEnumUnit())

// And this group
local group g = CreateGroup()
You're meant to "destroy" those things after they are finished with...
JASS:
call DestroyGroup(g)
set g = null
I'm not sure if the "set g = null" is necessary, but I see it as making sure that it's gone. :thumbs_up:
 
Level 3
Joined
Jun 13, 2008
Messages
59
W00t? JASS!

Gui trigger probably wont cause lagg but I'll make an optimized Jass Trigger for ya to.

  • Terrain Kill
    • Events
      • Time - Every 0.35 seconds of game time
    • Conditions
    • Actions
      • Set temp_group = (Units in (Playable map area))
      • Unit Group - Pick every unit in temp_group and do (Actions)
        • Loop - Actions
          • Set temp_point = (Position of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Summer - Grass
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Summer - Dark Grass
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Fall - Dirt
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain type at temp_point) Equal to Lordaeron Fall - Grassy Dirt
            • Then - Actions
              • -------- Your actions --------
            • Else - Actions
Jass optimized to natives.

JASS:
function Trig_Terrain_Kill_Func002Func002C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Lgrs' ) ) then //Terrain type Lgrs
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002Func003C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Lgrd' ) ) then //Terrain type Lgrd
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002Func004C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Fdrt' ) ) then //ect...
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002Func005C takes nothing returns boolean
    if ( not (  GetTerrainType(GetLocationX(udg_temp_point), GetLocationY(udg_temp_point)) == 'Fdrg' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Terrain_Kill_Func002A takes nothing returns nothing //filter chooser
    set udg_temp_point = GetUnitLoc(GetEnumUnit())
    if ( Trig_Terrain_Kill_Func002Func002C() ) then
        // Your actions
    else
    endif
    if ( Trig_Terrain_Kill_Func002Func003C() ) then
        // Your actions
    else
    endif
    if ( Trig_Terrain_Kill_Func002Func004C() ) then
        // Your actions
    else
    endif
    if ( Trig_Terrain_Kill_Func002Func005C() ) then
        // Your actions
    else
    endif
endfunction

function Trig_Terrain_Kill_Actions takes nothing returns nothing //picks units, assigns fiter
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, null)
    call ForGroup( udg_temp_group, function Trig_Terrain_Kill_Func002A )
endfunction

//===========================================================================
function InitTrig_Terrain_Kill takes nothing returns nothing
    set gg_trg_Terrain_Kill = CreateTrigger(  )
    call TriggerRegisterTimerEvent( gg_trg_Terrain_Kill, 0.35, true )
    call TriggerAddAction( gg_trg_Terrain_Kill, function Trig_Terrain_Kill_Actions )
endfunction

Did not use locals and did not test trigger. Gui one works for sure, Jass not so sure. I'm newbie to jass.

@Zypher: I optimised it...
JASS:
function Func_True takes nothing returns boolean
    return true
endfunction
function Filter_AlwaysTrue takes nothing returns boolexpr
    return Filter(function Func_True)
endfunction

function Trig_Terrain_Kill_Actions takes nothing returns nothing //picks units, assigns fiter
    local group g = CreateGroup()

    local unit enum
    local real x
    local real y
    local integer terrain_type

    local boolexpr filter = Filter_AlwaysTrue() 
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, filter)
    call DestroyBoolExpr(filter)

    loop
        set enum = FirstOfGroup(g)
        exitwhen (enum == null)

        set x = GetUnitX(enum)
        set y = GetUnitY(enum)
        set terrain_type = GetTerrainType(x, y)

        if (terrain_type == 'Lgrs') then
            // Lordaeron Summer Grass
        elseif (terrain_type == 'Lgrd') then
            // Lordaeron Summer Dark Grass
        elseif (terrain_type == 'Fdrt') then
            // Lordaeron Fall Dirt
        elseif (terrain_type == 'Fdrg') then
            // Lordaeron Fall Grassy Dirt
        endif

        call GroupRemoveUnit(g, enum)
    endloop

    call DestroyGroup(g)
    set g = null
endfunction

//===========================================================================
function InitTrig_Terrain_Kill takes nothing returns nothing
    set gg_trg_Terrain_Kill = CreateTrigger()
    call TriggerRegisterTimerEvent(gg_trg_Terrain_Kill, 0.35, true)
    call TriggerAddAction(gg_trg_Terrain_Kill, function Trig_Terrain_Kill_Actions)
endfunction

You were leaking a location and a group on each execution.
JASS:
// This location
set udg_temp_point = GetUnitLoc(GetEnumUnit())

// And this group
local group g = CreateGroup()
You're meant to "destroy" those things after they are finished with...
JASS:
call DestroyGroup(g)
set g = null
I'm not sure if the "set g = null" is necessary, but I see it as making sure that it's gone. :thumbs_up:

Thank you for replying my request. I'm grateful for that, really I am.
But, My JASS skill is -100! The plain text is blurring my EYES! Haha. It's not that bad, but I'm sure a n00b at JASS. Mind to comment your JASS? (I mean, where to put my variables and that sort of things)
 
Status
Not open for further replies.
Top