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

[JASS] Convert to jass

Status
Not open for further replies.
Level 19
Joined
Oct 29, 2007
Messages
1,184
As I've learned about jass I figured that GUI has crappy performance. That's why I want to change some of the triggers in my map to jass. I need help converting this trigger:

  • Grass
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • Custom script: local integer a
      • Custom script: set a = 1000
      • Custom script: set udg_tmp_region = Rect ( 0, 0, 0, 0 )
      • For each (Integer tmp_integer) from 1 to 4, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Life of Player[tmp_integer]) Not equal to 0.00
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • detect_up[tmp_integer] Equal to 1
                • Then - Actions
                  • Set tmp_loc2 = (Position of Player[tmp_integer])
                  • Set tmp_loc = (tmp_loc2 offset by 800.00 towards (Facing of Player[tmp_integer]) degrees)
                  • Custom script: call RemoveLocation(udg_tmp_loc2)
                • Else - Actions
                  • Set tmp_loc = (Position of Player[tmp_integer])
              • Custom script: call SetRect ( udg_tmp_region, GetLocationX(udg_tmp_loc) - (a * 0.5), GetLocationY(udg_tmp_loc) - (a * 0.5), GetLocationX(udg_tmp_loc) + (a * 0.5), GetLocationY(udg_tmp_loc) + (a * 0.5) )
              • Set tmp_group[1] = (Units in tmp_region matching ((Unit-type of (Matching unit)) Equal to Grass))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in tmp_group[1]) Less than 16
                • Then - Actions
                  • For each (Integer A) from 1 to (16 - (Number of units in tmp_group[1])), do (Actions)
                    • Loop - Actions
                      • Set tmp_loc2 = (Random point in tmp_region)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain type at tmp_loc2) Equal to Village Fall - Short Grass
                        • Then - Actions
                          • Unit - Create 1 Grass for Player 5 (Yellow) at tmp_loc2 facing (Random angle) degrees
                          • Set tmp_real = (Random real number between 90.00 and 120.00)
                          • Animation - Change (Last created unit)'s size to (tmp_real%, tmp_real%, tmp_real%) of its original size
                          • Animation - Change (Last created unit)'s animation speed to 0.00% of its original speed
                        • Else - Actions
                  • Custom script: call RemoveLocation(udg_tmp_loc)
                • Else - Actions
              • Custom script: call RemoveLocation(udg_tmp_loc2)
              • Custom script: call DestroyGroup(udg_tmp_group[1])
            • Else - Actions
      • Custom script: call RemoveRect ( udg_tmp_region )
I was up late last night and struggled with getting it right, but I couldn't...

Here's what I made:

JASS:
function Trig_Create_Grass_Condition takes nothing returns boolean
    return ( GetUnitTypeId(GetFilterUnit()) == 'h005' )
endfunction

function Trig_Create_Grass_Actions takes nothing returns nothing
    
    local group g
    local integer a = 1000
    local integer i = 1
    local rect r
    local real n
    local real x
    local real x1
    local real y
    local real y1
    
    loop
        if (GetUnitState(udg_Player[i], UNIT_STATE_LIFE) != 0) then
            if (udg_detect_up[i] == 1) then
                set x1 = GetUnitX(udg_Player[i])
                set y1 = GetUnitY(udg_Player[i])
                set x = x + 800 * Cos(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
                set y = y + 800 * Sin(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
            else
                set x = GetUnitX(udg_Player[i])
                set y = GetUnitY(udg_Player[i])
            endif
            call SetRect ( r, x - (a * 0.5), y - (a * 0.5), x + (a * 0.5), y + (a * 0.5) )
            call GroupEnumUnitsInRect(g, r, Condition(function Trig_Create_Grass_Condition))
                if (CountUnitsInGroup(g) < 16) then
                    loop
                    set x = GetRandomReal(GetRectMinX(r),GetRectMaxX(r))
                    set y = GetRandomReal(GetRectMinY(r),GetRectMaxY(r))
                    call CreateUnitAtLoc(Player(4), 'h005', Location(x, y), GetRandomInt(0, 360))
                    set n = GetRandomReal(0.9, 1.1)
                    call SetUnitScale(GetEnumUnit(), n, n, n)
                    if (CountUnitsInGroup(g) == 16) then
                        exitwhen true
                    endif
                    endloop
                endif
            call RemoveRect(r)
        endif
        set i = i + 1
        if (i == 4) then
        exitwhen true
        endif
        set i = i + 1
    endloop
endfunction

//===========================================================================
function InitTrig_Create_Grass takes nothing returns nothing
    set gg_trg_Create_Grass = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Create_Grass, 0.04 )
    call TriggerAddAction( gg_trg_Create_Grass, function Trig_Create_Grass_Actions )
endfunction

Can someone please look at this and correct the script? The script should create grass around the player if the number of grass is less than 16. Also I would like to know how to get rid of those BJ's, CountUnitsInGroup. I give +rep to people who help me.
 
Level 28
Joined
Mar 25, 2008
Messages
2,955
function list says:
JASS:
function CountUnitsInGroup takes group g returns integer
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    set bj_groupCountUnits = 0
    call ForGroup(g, function CountUnitsInGroupEnum)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(g)
    endif
    return bj_groupCountUnits
endfunction
and
JASS:
function CountUnitsInGroupEnum takes nothing returns nothing
    set bj_groupCountUnits = bj_groupCountUnits + 1
endfunction

Also, define your globals as locals and call CreateUnit(Player(4), 'h005', x, y, GetRandomReal(0.00, 360.00)) gets you rid of the location
 
Level 19
Joined
Oct 29, 2007
Messages
1,184
@ Squiggy: Do you mean like this?

JASS:
local unit u
//blabla
set local unit u = udg_Player[i]
//use "u" instead of "udg_Player[i]" ?

@Pharao_

a) Is to check whether udg_Player is alive or not.

b) Grass isn't triggering unit. : <
 
Level 19
Joined
Oct 29, 2007
Messages
1,184
I've made changes, but still nothing happens. : / No units are created. What's wrong with the code?

JASS:
function Trig_Create_Grass_Condition takes nothing returns boolean
    return( GetUnitTypeId(GetEnumUnit()) == 'h005' )
endfunction

function Trig_Create_Grass_Actions takes nothing returns nothing
    
    local group g
    local integer a = 1000
    local integer i = 1
    local integer j
    local rect r
    local real n
    local real x
    local real x1
    local real y
    local real y1
    local unit u
    
    loop
        set u = udg_Player[i]
        if (GetUnitState(u, UNIT_STATE_LIFE) > 0) then
            if (udg_detect_up[i] == 1) then
                set x1 = GetUnitX(u)
                set y1 = GetUnitY(u)
                set x = x + 800 * Cos(GetUnitFacing(u) * bj_DEGTORAD)
                set y = y + 800 * Sin(GetUnitFacing(u) * bj_DEGTORAD)
            else
                set x = GetUnitX(u)
                set y = GetUnitY(u)
            endif
            call SetRect ( r, x - (a * 0.5), y - (a * 0.5), x + (a * 0.5), y + (a * 0.5) )
            set g = GetUnitsInRectMatching(r, Condition(function Trig_Create_Grass_Condition))
            set j = CountUnitsInGroup(g)
                if (j < 16) then
                    loop
                    set x = GetRandomReal(GetRectMinX(r),GetRectMaxX(r))
                    set y = GetRandomReal(GetRectMinY(r),GetRectMaxY(r))
                    call CreateUnitAtLoc(Player(4), 'h005', Location(x, y), GetRandomInt(0, 360))
                    set n = GetRandomReal(0.9, 1.1)
                    call SetUnitScale(GetEnumUnit(), n, n, n)
                    set j = j + 1
                    if (j == 16) then
                        exitwhen true
                    endif
                    endloop
                endif
            call RemoveRect(r)
        endif
        if (i == 4) then
        exitwhen true
        endif
        set i = i + 1
    endloop
endfunction

//===========================================================================
function InitTrig_Create_Grass takes nothing returns nothing
    set gg_trg_Create_Grass = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Create_Grass, 0.04 )
    call TriggerAddAction( gg_trg_Create_Grass, function Trig_Create_Grass_Actions )
endfunction
 
Code cleaned, optimized and (I think) fixed.
JASS:
function Trig_Create_Grass_Condition takes nothing returns boolean
    return GetUnitTypeId(GetEnumUnit()) == 'h005'
endfunction

function Trig_Create_Grass_Actions takes nothing returns nothing
    local integer i = 0

    local real x
    local real y
    
    local rect r = Rect(0, 0, 0, 0)
    local boolexpr conds = Condition(function Trig_Create_Grass_Condition)
    local group g = CreateGroup()
    local unit u
    local integer j
    
    local integer real = 500.00
    local real n

    loop
        set i = i + 1
        exitwhen i > 4
        
        if (GetUnitState(u, UNIT_STATE_LIFE) > 0) then
        
            if (udg_detect_up[i] == 1) then
                set x = GetUnitX(udg_Player[i]) + 800 * Cos(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
                set y = GetUnitY(udg_Player[i]) + 800 * Sin(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
            else
                set x = GetUnitX(udg_Player[i])
                set y = GetUnitY(udg_Player[i])
            endif
            
            call SetRect ( r, x - a, y - a, x + a, y + a )
            call GroupEnumUnitsInRect(g, r, conds)
            
            set j = 0
            
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                
                set j = j + 1
                call GroupRemoveUnit(g, u)
            endloop
            
            loop
                exitwhen j >= 16
                
                set x = GetRandomReal(GetRectMinX(r),GetRectMaxX(r))
                set y = GetRandomReal(GetRectMinY(r),GetRectMaxY(r))
                set u = CreateUnit(Player(4), 'h005', x, y, GetRandomInt(0, 360))
                set n = GetRandomReal(0.9, 1.1)
                call SetUnitScale(u, n, n, n)
                
                set j = j + 1
            endloop
            
        endif
    endloop
    
    call DestroyBoolExpr(conds)
    call RemoveRect(r)
    call DestroyGroup(g)
    
    set conds = null
    set r = null
    set g = null
    
    set u = null
endfunction

//===========================================================================
function InitTrig_Create_Grass takes nothing returns nothing
    set gg_trg_Create_Grass = CreateTrigger( )
    call TriggerRegisterTimerEvent( gg_trg_Create_Grass, 0.04, true )
    call TriggerAddAction( gg_trg_Create_Grass, function Trig_Create_Grass_Actions )
endfunction
 
Last edited:
Level 19
Joined
Oct 29, 2007
Messages
1,184
Here it is:

JASS:
function Trig_Create_Grass_Condition takes nothing returns boolean
    return GetUnitTypeId(GetEnumUnit()) == 'h005'
endfunction

function Trig_Create_Grass_Actions takes nothing returns nothing
    
    local integer i = 0
    local real x
    local real y
    local rect r = Rect(0, 0, 0, 0)
    local boolexpr conds = Condition(function Trig_Create_Grass_Condition)
    local group g = CreateGroup()
    local unit u
    local integer j
    local real a = 500.00
    local real n
    
    call BJDebugMsg("1")
    
    loop
        call BJDebugMsg("2")
        set i = i + 1
        exitwhen i > 4
        if (GetUnitState(udg_Player[i], UNIT_STATE_LIFE) > 0) then
            if (udg_detect_up[i] == 1) then
                set x = GetUnitX(udg_Player[i]) + 800 * Cos(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
                set y = GetUnitY(udg_Player[i]) + 800 * Sin(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
                call BJDebugMsg("3")
            else
                set x = GetUnitX(udg_Player[i])
                set y = GetUnitY(udg_Player[i])
                call BJDebugMsg("4")
            endif
            call BJDebugMsg("5")
            call SetRect ( r, x - a, y - a, x + a, y + a )
            call GroupEnumUnitsInRect(g, r, conds)
            set j = 0
            loop
                call BJDebugMsg("6")
                set u = FirstOfGroup(g)
                exitwhen u == null
                set j = j + 1
                call GroupRemoveUnit(g, u)
            endloop
            loop
                call BJDebugMsg("7")
                exitwhen j == 16
                set x = GetRandomReal(GetRectMinX(r),GetRectMaxX(r))
                set y = GetRandomReal(GetRectMinY(r),GetRectMaxY(r))
                set u = CreateUnit(Player(4), 'h005', x, y, GetRandomInt(0, 360))
                set n = GetRandomReal(0.9, 1.1)
                call SetUnitScale(u, n, n, n)
                set j = j + 1
            endloop
        endif
    endloop
    call DestroyBoolExpr(conds)
    call RemoveRect(r)
    call DestroyGroup(g)
    set conds = null
    set r = null
    set g = null
    set u = null
endfunction

//===========================================================================

function InitTrig_Create_Grass takes nothing returns nothing
    set gg_trg_Create_Grass = CreateTrigger( )
    call TriggerRegisterTimerEvent( gg_trg_Create_Grass, 0.04, true )
    call TriggerAddAction( gg_trg_Create_Grass, function Trig_Create_Grass_Actions )
endfunction
 
Level 11
Joined
Apr 6, 2008
Messages
760
whats up with this local local real a = 500.00?

seriously i don't get it, just use the number of a constant global?

try scope/library with a initailizer and a timer instead of a perodic event

JASS:
scope NAME initializer init

globals
    private timer Time = CreateTimer()
endglobals

private function Callback takes nothing returns nothing
   //Do Stuff
endfunction

private function init takes nothing returns nothing
    call TimerStart(Time,'Interval',true,function Callback)
endfunction

endscope

And if u dont have newgen GET IT! :p
 
Ok, code should be fixed now, I think the problem was you used GetEnumUnit() wen you should have used GetFilterUnit() in the enumeration filter.

JASS:
function Trig_Create_Grass_Condition takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == 'h005'
endfunction

function Trig_Create_Grass_Actions takes nothing returns nothing

    local integer i = 0
    local real x
    local real y
    local rect r = Rect(0, 0, 0, 0)
    local boolexpr conds = Condition(function Trig_Create_Grass_Condition)
    local group g = CreateGroup()
    local unit u
    local integer j
    local real a = 500.00
    local real n

    call BJDebugMsg("1")

    loop
        call BJDebugMsg("2")
        set i = i + 1
        exitwhen i > 4
        if (GetUnitState(udg_Player[i], UNIT_STATE_LIFE) > 0) then
            if (udg_detect_up[i] == 1) then
                set x = GetUnitX(udg_Player[i]) + 800 * Cos(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
                set y = GetUnitY(udg_Player[i]) + 800 * Sin(GetUnitFacing(udg_Player[i]) * bj_DEGTORAD)
                call BJDebugMsg("3")
            else
                set x = GetUnitX(udg_Player[i])
                set y = GetUnitY(udg_Player[i])
                call BJDebugMsg("4")
            endif
            call BJDebugMsg("5")
            call SetRect ( r, x - a, y - a, x + a, y + a )
            call GroupEnumUnitsInRect(g, r, conds)
            set j = 0
            loop
                call BJDebugMsg("6")
                set u = FirstOfGroup(g)
                exitwhen u == null
                set j = j + 1
                call GroupRemoveUnit(g, u)
            endloop
            loop
                call BJDebugMsg("7")
                exitwhen j == 16
                set x = GetRandomReal(GetRectMinX(r),GetRectMaxX(r))
                set y = GetRandomReal(GetRectMinY(r),GetRectMaxY(r))
                set u = CreateUnit(Player(4), 'h005', x, y, GetRandomInt(0, 360))
                set n = GetRandomReal(0.9, 1.1)
                call SetUnitScale(u, n, n, n)
                set j = j + 1
            endloop
        endif
endloop
    call DestroyBoolExpr(conds)
    call RemoveRect(r)
    call DestroyGroup(g)
    set conds = null
    set r = null
    set g = null
    set u = null
endfunction

//===========================================================================

function InitTrig_Create_Grass takes nothing returns nothing
    set gg_trg_Create_Grass = CreateTrigger( )
    call TriggerRegisterTimerEvent( gg_trg_Create_Grass, 0.04, true )
    call TriggerAddAction( gg_trg_Create_Grass, function Trig_Create_Grass_Actions )
endfunction
 
Level 8
Joined
Aug 4, 2006
Messages
357
when a live unit's hp goes below .405, it dies, and its hp is set to 0. if its hp is anything above this, even .406, it will not die yet.

however, once a unit dies, its hp can still be changed through triggers. while it is bad practice to change a dead's unit hp, it is possible. if the dead unit's hp is increased above .405 through triggers, it does not revive the unit, but will result in conditions thinking that the unit is now alive.

so, the best and only accurate way to check if a unit is dead is the following:
JASS:
function IsUnitDead takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_DEAD)
endfunction
 
Level 8
Joined
Aug 4, 2006
Messages
357
Element of Water said:
And if a dead unit's hp is changed by triggers, then your map is bugged.
Why should changing a dead unit's hp bug your map? What if there were some use for it that we haven't discovered?

Okay, let's assume you weren't trying to change a dead unit's hp. Which map do you think would be less bugged: one that uses your function or one that uses my function? Which map would be easier to debug? Wouldn't you rather use a function that returns EXACTLY what you want it to rather than a function that only returns the right value if everything else works right?

Element of Water said:
It's the fastest way of doing it.
It is? Have you tested it? Anyway, the speed difference would never be noticeable.

By the way, this argument inspired me to submit this function to the Jass section: http://www.hiveworkshop.com/forums/submissions-414/isunitdead-135811/
 
Status
Not open for further replies.
Top