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

Small Code Snippets

Level 16
Joined
Aug 7, 2009
Messages
1,403
does the creator know that you can just put in \n and it will go to the next line o_O but its what i need and will work for now, thanks.

And did you know that DisplayTimedTextToPlayer is not the only native that uses strings, therefore you might need to break the lines manually? I, for example, found a similar library pretty useful multiple times already.
 
does the creator know that you can just put in \n and it will go to the next line o_O but its what i need and will work for now, thanks.

\n can cause odd problems for certain functions. For regular displaying of text, it works decently but can also shift the messages super far down if you do it enough. For multiboards, it just completely messes up the board and some text will overlap others, making it a mess. For texttags, you can quickly reach the character limit for texttags if you just use \n, and the \n adjustment moves the texttag a bit so the texttag requires position adjustments.

However, with the system you can just get the particular fragments and display them individually, such as in a separate game message, a separate multiboard row, or in a separate texttag placed beneath the previous line. It's practicality is a bit difficult to see at first, but a lot of map makers (especially if you use coded user interfaces) will encounter this problem. :)
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Can I used a small parabola function in here??

JASS:
function Parabola takes real h, real dr, real cdr returns real
    return (4 * h / dr ) * ( dr - cdr ) * ( cdr / dr )
endfunction

/* How to call the function?? Parabola(height,distance,counterdistance)

It just needs height , distance , and the current distance.

Simply: If you are setting the unit fly height use this

Height : 300
Distance Range: 500
Current Distance: 0.00
Speed Plus: 18.00

In the looping trigger 0.03 adds the Current Distance to the Speed like this:

set Current Dist = Current Dist + Speed = 18.00 and so on...
                                              ( 300 ) ( 500. )    ( 18.00 )
call SetUnitFlyHeight(udg_YOUR_UNIT,Parabola(height,distance,currentdistance),0)

Simplify like this: 4 * height divided by distance equals 2.4 finished at the first procedure now go to 2nd.
2.4 * (500 - 18.) equal to 1182 go to 3rd or last procedure
1182 * (18. / 500) equal to 42.
*/
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
Old thread is old. Made this just now.

JASS:
private function EnemyFilter takes nothing returns boolean
        return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), tempPlayer) and UnitAlive(GetFilterUnit())
    endfunction
    
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        local group g = CreateGroup()
        local unit u
        set tempPlayer = p
        call GroupEnumUnitsInRange(g, x, y, radius, Condition(function EnemyFilter))
        set u = FirstOfGroup(g)
        call DestroyGroup(g)
        set g = null
        if u == null then
            return false 
        endif
        set u = null
        return true 
    endfunction
 
Last edited:
Old thread is old. Made this just now.

JASS:
private function EnemyFilter takes nothing returns boolean
        return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), tempPlayer) and UnitAlive(GetFilterUnit())
    endfunction
    
    function IsEnemyInRangeOfLoc takes player p, real x, real y, real radius returns boolean
        local group g = CreateGroup()
        local unit u
        set tempPlayer = p
        call GroupEnumUnitsInRange(g, x, y, radius, Condition(function EnemyFilter))
        set u = FirstOfGroup(g)
        call DestroyGroup(g)
        set g = null
        if u == null then
            return false 
        endif
        set u = null
        return true 
    endfunction
I would rather call it IsEnemyInRangeXY

which reminds me

.
.
.
We don't have this kind of snippet! Goodjob!
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
I would change that:

JASS:
private function EnemyFilter takes nothing returns boolean
        return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), tempPlayer) and UnitAlive(GetFilterUnit())
    endfunction
    
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        set tempPlayer = p
        call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, radius, Condition(function EnemyFilter))
        return FirstOfGroup(bj_lastCreatedGroup) != null
    endfunction
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Now my turn:
JASS:
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        local unit FoG
        local group g = CreateGroup()
        call GroupEnumUnitsInRange(g, x, y, radius, null)
        
        loop
            set FoG = FirstOfGroup(g)
            exitwhen FoG == null
            call GroupRemoveUnit(g, FoG)
            
            if IsUnitEnemy(FoG, p) and UnitAlive(FoG) then
                call DestroyGroup(g)
                set g = null
                set FoG = null
                return true
            endif
        endloop
        call DestroyGroup(g)
        set g = null
        return false
    endfunction

You can also use a more optimized version that would result in this:
JASS:
    globals
        group ENEMYINRANGE_GROUP = CreateGroup()
    endglobals
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        local unit FoG
        call GroupEnumUnitsInRange(ENEMYINRANGE_GROUP, x, y, radius, null)
        
        loop
            set FoG = FirstOfGroup(ENEMYINRANGE_GROUP)
            exitwhen FoG == null
            call GroupRemoveUnit(ENEMYINRANGE_GROUP, FoG)
            
            if IsUnitEnemy(FoG, p) then
                call GroupClear(ENEMYINRANGE_GROUP)
                set FoG = null
                return true
            endif
        endloop
        return false
    endfunction

EDIT:
Now that we are talking about unit groups:
JASS:
function GroupEnumUnitsInCone takes group whichGroup, real x, real y, real radius, real direction, real angle returns group
    local unit FoG
    local group g = CreateGroup()
    local real x2
    local real y2
    local real difference
    
    call GroupEnumUnitsInRange(g, x, y, radius, null)
    loop
        set FoG = FirstOfGroup(g)
        exitwhen FoG == null
        
        set difference = DeNormalizeAngle(AngleBetweenCoordinates(x, y, GetWidgetX(FoG), GetWidgetY(FoG)) - direction)
        if difference > -angle and difference < angle then
            call GroupAddUnit(whichGroup, FoG)
        endif
        call GroupRemoveUnit(g,FoG)
    endloop
    
    call DestroyGroup(g)
    set g = null
    return whichGroup
endfunction

It uses some angle functions which I also wrote but might already exist:
JASS:
function NormalizeAngle takes real angle returns real
    loop
        if angle < 0 then
            set angle = angle + 360
        elseif angle >= 360 then
            set angle = angle - 360
        else
            return angle
        endif
    endloop
    return 0.
endfunction

function DeNormalizeAngle takes real angle returns real
    loop
        if angle <= -180 then
            set angle = angle + 360
        elseif angle > 180 then
            set angle = angle - 360
        else
            return angle
        endif
    endloop
    return 0.
endfunction

function AngleBetweenCoordinates takes real x1, real y1, real x2, real y2 returns real
    return bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
endfunction

Because of the return, you can even do this:
local group g = GroupEnumUnitsInCone(CreateGroup(), X, Y, RADIUS, DIRECTION, ANGLE)
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
What trickery is this? Would you really? :D

I would change that:

JASS:
private function EnemyFilter takes nothing returns boolean
        return IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), tempPlayer) and UnitAlive(GetFilterUnit())
    endfunction
    
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        set tempPlayer = p
        call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, radius, Condition(function EnemyFilter))
        return FirstOfGroup(bj_lastCreatedGroup) != null
    endfunction
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
If you want no global variables:

JASS:
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        local unit u
        call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, radius, null)
        loop
            set u = FirstOfGroup(bj_lastCreatedGroup)
            exitwhen u == null
            call GroupRemoveUnit(bj_lastCreatedGroup, u)
            
            if IsUnitEnemy(u, p) and UnitAlive(u) then
                set u = null
                return true
            endif
        endloop
        return false
    endfunction

GroupEnum... already clears the group so the clear action is wasteful. Also, bj_lastCreatedGroup never gets destroyed so you save from having to create a new one.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
If you want no global variables:

JASS:
    function IsEnemyInRangeXY takes player p, real x, real y, real radius returns boolean
        local unit u
        call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, radius, null)
        loop
            set u = FirstOfGroup(bj_lastCreatedGroup)
            exitwhen u == null
            call GroupRemoveUnit(bj_lastCreatedGroup, u)
            
            if IsUnitEnemy(u, p) and UnitAlive(u) then
                set u = null
                return true
            endif
        endloop
        return false
    endfunction

GroupEnum... already clears the group so the clear action is wasteful. Also, bj_lastCreatedGroup never gets destroyed so you save from having to create a new one.

(you have to create a group first)
If I make a group and you overwrite that bj_lastCreatedGroup, then I hate you because you destroy my GUI scripts.

set bj_lastCreatedGroup = CreateGroup() when you start function
call DestroyGroup(bj_lastCreatedGroup) when you end the function (also in the return)
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
do you also use
JASS:
bj_lastCreatedUnit or bj_lastReplacedUnit
instead of local units?

I used bj_lastCreatedUnit in MissileRecycler.

May cause conflicts, when using it over a whole map script ...
but in general you can do so.

The only time that MIGHT not work is in recursive scenarios, such as TriggerRegisterEnterRegion using the boolexpr attached, or using hooks or something of the like. Basically you'd be hard-pressed to find a scenario where it would cause any issues whatsoever.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Not perferct, but worth considering.
You may add more globals to store settings per player like fog status, etc
Replaces CinematicModeExBJ.

JASS:
library Cinematic initializer Init 
// Improved version of CinematicModeExBJ
//

    globals
        private boolean array allowCinematicSkip// Per player.
        private integer PlayersInCineMode = 0
        private force InCineMode          = CreateForce()
    endglobals
    
    function IsPlayerInCineMode takes player whichPlayer returns boolean
        return IsPlayerInForce(whichPlayer, InCineMode)
    endfunction
    
    private function RemoveFromCineForce takes nothing returns nothing
        local player picked = GetEnumPlayer()
        
        set allowCinematicSkip[GetPlayerId(picked)] = false
        if IsPlayerInForce(picked, InCineMode) then
            call ForceRemovePlayer(InCineMode, picked)
            set PlayersInCineMode = PlayersInCineMode - 1
            
            // Perform local code 
            if (GetLocalPlayer() == picked) then
                // Use only local code (no net traffic) within this block to avoid desyncs.
                call ShowInterface(true, bj_cineFadeContinueDuration)
                call EnableUserControl(true)
                call EnableOcclusion(true)
                call VolumeGroupReset()
                call EndThematicMusic()
                call FogMaskEnable(true)
                call FogEnable(true)
                //call CameraSetSmoothingFactor(0)
            endif
            
        endif
        if (PlayersInCineMode == 0) and IsTriggerEnabled(bj_cineSceneBeingSkipped) then
            call DisableTrigger(bj_cineSceneBeingSkipped)
        endif
        set picked = null
    endfunction
    
    private function AddToCineForce takes nothing returns nothing
        local player picked = GetEnumPlayer()
        
        if (bj_rescueChangeColorUnit) then
            set allowCinematicSkip[GetPlayerId(picked)] = true
            if not (IsTriggerEnabled(bj_cineSceneBeingSkipped)) then
                call EnableTrigger(bj_cineSceneBeingSkipped)
            endif
        endif
        if not IsPlayerInForce(picked, InCineMode) then
            call ForceAddPlayer(InCineMode, picked)
            set PlayersInCineMode = PlayersInCineMode + 1
        endif
        set picked = null
    endfunction
    
    function CinematicMode takes boolean cineMode, force forForce, real interfaceFadeTime, boolean allowCineSkip, boolean disableFog returns nothing
        if (cineMode) then
            // Scrap game speed and random seed.
            // Leave less important settings global
            //
            // global boolean with low potential usage.
            set bj_rescueChangeColorUnit = allowCineSkip
            call ForForce(forForce, function AddToCineForce)
            if IsPlayerInForce(GetLocalPlayer(), forForce) then
                call ShowInterface(false, interfaceFadeTime)
                call EnableUserControl(false)
                call EnableOcclusion(false)
                if (disableFog) then
                    call FogEnable(false)
                    call FogMaskEnable(false)
                endif
            
            endif
            
            // Perform global changes
            call EnableWorldFogBoundary(false)
            //call EnableDawnDusk(false)

        else
            set bj_cineModeAlreadyIn = false
            set bj_cineFadeContinueDuration = interfaceFadeTime
            call ForForce(forForce, function RemoveFromCineForce)

            // Perform global changes
            call EnableWorldFogBoundary(true)
            //call EnableDawnDusk(bj_cineModePriorDawnDusk)
    
        endif
    
    endfunction
    
    // May use a global for interface fade time.
    private function OnEndCinematic takes nothing returns boolean
        local integer id = GetPlayerId(GetTriggerPlayer())
        if (allowCinematicSkip[id]) then 
            if (GetLocalPlayer() == Player(id)) then
                call EndCinematicScene()
            endif
            call CinematicModee(false, bj_FORCE_PLAYER[id], bj_CINEMODE_INTERFACEFADE, false, false) 
        endif
        return false
    endfunction
    
    // Register ESC event.
    private function Init takes nothing returns nothing
        local integer index          = 0
        local player p  
        set bj_cineSceneBeingSkipped = CreateTrigger()
        loop
            set p = Player(index)
            if (GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING) and (GetPlayerController(p) == MAP_CONTROL_USER) then
                call TriggerRegisterPlayerEvent(bj_cineSceneBeingSkipped, p, EVENT_PLAYER_END_CINEMATIC)
            endif
            set index = index + 1
            exitwhen index == 12
        endloop
        call TriggerAddCondition(bj_cineSceneBeingSkipped, Condition(function OnEndCinematic))
        call DisableTrigger(bj_cineSceneBeingSkipped)
    endfunction

endlibrary
 
JASS:
//Checks whether a point is clockwise to another point/vector
function IsPointClockwise takes real x1, real x2, real y1, real y2 returns boolean
    return -x1*y2 + y1*x2 > 0.
endfunction
    
//c = center, s = start, e = end
function IsPointInSector takes real px, real py, real cx, real cy, real sx, real sy, real ex, real ey, real range returns boolean
    set px = px - cx
    set py = py - cy
    return (not isClockwise(sx, px, sy, py)) and isClockwise(ex, px, ey, py) and (px*px) + (py*py) <= range*range
endfunction

This checks whether a point is within 2 point that are projected from a central point, given also the radius.

I used this snippet in my flocking system so that I won't use any Angles for flying projection.

the function originally uses vectors instead of coordinates.

[edit]
I forgot to note that this doesn't work on angles > 180, so if you want to check something lying on angles that has values greater than 180, you will have to do an inverse check.
 
This one also can belongs here (I'm sure PurgeandFire remembers this quite well) : http://www.hiveworkshop.com/forums/...ls-279/fixing-smartcamerapanbj-desync-243334/
Since practically, it handles SmartCameraPanBJ in a MUCH better way. I don't own the script, so credits go to PurgeandFire.

I'm referring to the main script in the first post.

EDIT :
I guess this one needs a snippet of VJass as well.
Wish hooks doesn't use the original native and override it COMPLETELY.

EDIT 2 :
This fixing Blizzard with better scripts posts reminds me of a Pastebin from Malhorne's VM with me.
Pastebin
 
Level 13
Joined
Nov 7, 2014
Messages
571
MathRound - floor, ceil, round, nearest, nearest_floor, nearest_ceil, round_places

JASS:
library MathRound

function floor takes real r returns integer
    local integer i = R2I(r)

    if r == i then
        return i
    endif

    if r > 0 then
        return i
    else // if r < 0 then
        return i - 1
    endif
endfunction

function ceil takes real r returns integer
    local integer i = R2I(r)

    if r == i then
        return i
    endif

    if r > 0 then
        return i + 1
    else // if r < 0 then
        return i
    endif
endfunction

function round takes real r returns integer
    if r > 0 then
        return R2I(r + 0.5)
    else // if r < 0 then
        return R2I(r - 0.5)
    endif
endfunction

function nearest_floor takes real r, real n returns real
    return floor(r / n) * n
endfunction

function nearest_ceil takes real r, real n returns real
    return ceil(r / n) * n
endfunction

function nearest takes real r, real n returns real
    return round(r / n) * n
endfunction

function round_places takes real r, real places returns real
    local real ten_pow_places = Pow(10, places)
    return round(r * ten_pow_places) / ten_pow_places
endfunction

endlibrary

Demo:

JASS:
    local real array round_values
    local real array nearest_values
    local integer i

    set round_values[0] = -0.6
    set round_values[1] = -0.5
    set round_values[2] = -0.4
    set round_values[3] = 0.0
    set round_values[4] = 0.4
    set round_values[5] = 0.5
    set round_values[6] = 0.6

    set i = 0
    loop
        exitwhen i >= 7
        call BJDebugMsg("floor(" + R2S(round_values[i]) + ") = " + R2S(floor(round_values[i])))
        set i = i + 1
    endloop
    // output:
    // floor(-0.6) = -1
    // floor(-0.5) = -1
    // floor(-0.4) = -1
    // floor(0) = 0
    // floor(0.4) = 0
    // floor(0.5) = 0
    // floor(0.6) = 0

    set i = 0
    loop
        exitwhen i >= 7
        call BJDebugMsg("ceil(" + R2S(round_values[i]) + ") = " + R2S(ceil(round_values[i])))
        set i = i + 1
    endloop
    // output:
    // ceil(-0.6) = 0
    // ceil(-0.5) = 0
    // ceil(-0.4) = 0
    // ceil(0) = 0
    // ceil(0.4) = 1
    // ceil(0.5) = 1
    // ceil(0.6) = 1

    set i = 0
    loop
        exitwhen i >= 7
        call BJDebugMsg("round(" + R2S(round_values[i]) + ") = " + R2S(round(round_values[i])))
        set i = i + 1
    endloop
    // output:
    // round(-0.6) = -1
    // round(-0.5) = -1
    // round(-0.4) = 0
    // round(0) = 0
    // round(0.4) = 0
    // round(0.5) = 1
    // round(0.6) = 1


    set nearest_values[0] = -25
    set nearest_values[1] = -24
    set nearest_values[2] = 24
    set nearest_values[3] = 25

    set i = 0
    loop
        exitwhen i >= 4
        call BJDebugMsg("nearest_floor(" + R2S(nearest_values[i]) + ", 10) = " + R2S(nearest_floor(nearest_values[i], 10)))
        set i = i + 1
    endloop
    // output
    // nearest_floor(-25, 10) = -30
    // nearest_floor(-24, 10) = -30
    // nearest_floor(24, 10) = 20
    // nearest_floor(25, 10) = 20

    set i = 0
    loop
        exitwhen i >= 4
        call BJDebugMsg("nearest_ceil(" + R2S(nearest_values[i]) + ", 10) = " + R2S(nearest_ceil(nearest_values[i], 10)))
        set i = i + 1
    endloop
    // output:
    // nearest_ceil(-25, 10) = -20
    // nearest_ceil(-24, 10) = -20
    // nearest_ceil(24, 10) = 30
    // nearest_ceil(25, 10) = 30

    set i = 0
    loop
        exitwhen i >= 4
        call BJDebugMsg("nearest(" + R2S(nearest_values[i]) + ", 10) = " + R2S(nearest(nearest_values[i], 10)))
        set i = i + 1
    endloop
    // output:
    // nearest(-25, 10) = -30
    // nearest(-24, 10) = -20
    // nearest(24, 10) = 20
    // nearest(25, 10) = 30

    set i = 5
    loop
        exitwhen i < 0
        call BJDebugMsg("round_places(3.14159, " + I2S(i) + ") = " + R2SW(round_places(bj_PI, i), 1, 5))
        set i = i - 1
    endloop
    // output:
    // 3.14159
    // 3.1416
    // 3.142
    // 3.14
    // 3.1
    // 3
 
Last edited:
Level 13
Joined
Nov 7, 2014
Messages
571
JASS:
function floor takes real r returns real
    return I2R(R2I(r))
endfunction

That's truncation, i.e rounding towards 0, flooring is rounding towards -∞

floor(-0.4) => -1, not 0

JASS:
function ceil takes real r returns real
    return floor(r) + 1
end/*function*/

That doesn't compile..., even if it did it would be wrong.

ceil(1) => 1, not 2
 
JASS:
function floor takes real r returns real
    return I2R(R2I(r))
endfunction

That's truncation, i.e rounding towards 0, flooring is rounding towards -∞

floor(-0.4) => -1, not 0

JASS:
function ceil takes real r returns real
    return floor(r) + 1
end/*function*/

That doesn't compile..., even if it did it would be wrong.

ceil(1) => 1, not 2

sorry about the error, too much Lua. anyways, i forgot that it doesn't support negatives, thank you.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
In 7 years of modding WarCraft 3, I've never needed any of these, sans truncation and rounding.

Rounding can be simplified:

JASS:
function RoundReal takes real r returns integer
    if r > 0.00 then
        return R2I(r + 0.50)
    endif
    return R2I(r - 0.50)
endfunction

FunctionNamesLikeThis not_like_this if you want to stick to intuitive syntax.
 
Level 13
Joined
Nov 7, 2014
Messages
571
Rounding can be simplified:
Yes, agree.

FunctionNamesLikeThis not_like_this if you want to stick to intuitive syntax.

There probably is some merit in using different casing for function names and global/local variables (although local variables overshadow globals)
because they "live" in the same namespace and collisions can happen (rarely in my experience), but in my opinion PascalCase (and camelCase)
identifiers are in fact harder to read (I would prefer if kebab-case-was-valid =), but it's not so the next "best" thing seems to be underscore_case),
so the little you get in the reduction of function names with local variable names collisions, you seem lose a lot more in readability, but that's just me maybe.
 
Level 3
Joined
Oct 17, 2013
Messages
29
--> RandomPointInRect

JASS:
function RandomRectX takes rect r returns real
    local real minX = GetRectMinX(r)
    local real maxX = GetRectMaxX(r)
    return GetRandomReal(minX,maxX)
endfunction
function RandomRectY takes rect r returns real
    local real minY = GetRectMinY(r)
    local real maxY = GetRectMaxY(r)
    return GetRandomReal(minY,maxY)
endfunction
:fp: Perfect for shortening your codes
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
How? You could directly do.

GetRandomReal(GetRectMinX(r), GetRectMaxX(r))
Except that produces procedural coupling. You are basically duplicating that code everywhere you want a random X/Y inside a rect.

Something like GetRandomXInRect(r) and GetRandomYInRect(r) looks neater and keeps with the WC3 style of GetRandomLocInRect(r).

JASS:
function GetRandomXInRect takes rect whichRect returns real
    return GetRandomReal(GetRectMinX(whichRect), GetRectMaxX(whichRect))
endfunction

function GetRandomYInRect takes rect whichRect returns real
    return GetRandomReal(GetRectMinY(whichRect), GetRectMaxY(whichRect))
endfunction
I would use it if I had to get a random position from inside a rect at more than 1 place in the code.
 

Ardenian

A

Ardenian

JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    if IsUnitType(u,ConvertUnitType(14)) then
        if GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0 then
            return true
        endif
    else
        if GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0 then
            return true
        endif
    endif
    return false
endfunction

Returns a boolean if a unit is under construction.
Tested it with default buildings and works like a charm.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    if IsUnitType(u,ConvertUnitType(14)) then
        if GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0 then
            return true
        endif
    else
        if GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0 then
            return true
        endif
    endif
    return false
endfunction

Gives a boolean if a unit is under construction.
Tested it with default buildings.

This is a bit nerdy but it can be improved.
JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    if IsUnitType(u,ConvertUnitType(14)) then
        return GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0 
    else
        return GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0
    endif
endfunction

Anyway what is ConvertUnitType(14)? If there is a constant for it then better to use it.
 

Ardenian

A

Ardenian

Thanks, this is the best solution then:
JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    if IsUnitType(u,UNIT_TYPE_UNDEAD) then
        return GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0
    else
        return GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0
    endif
endfunction
 
JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    if IsUnitType(u,ConvertUnitType(14)) then
        if GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0 then
            return true
        endif
    else
        if GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0 then
            return true
        endif
    endif
    return false
endfunction

Gives a boolean if a unit is under construction.
Tested it with default buildings.

JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    if IsUnitType(u,ConvertUnitType(14)) then
        return GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0
    endif
    return GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0
endfunction

btw, your current solution raises an error :)
 

Ardenian

A

Ardenian

Thanks, haven't thought of that.

You might want to give me some more details on the error.
It worked fine for me.
 
Top