Small Code Snippets

Level 17
Joined
Apr 27, 2008
Messages
2,453
Guys, let's do one line then :

JASS:
function IsBuildingUnderConstruction takes unit u returns boolean
    return IsUnitType(u,UNIT_TYPE_UNDEAD) and (GetUnitAbilityLevel(u,'Abgs')!= 0 or GetUnitAbilityLevel(u,'Abgl')!= 0) or GetUnitAbilityLevel(u,'Abds')!= 0 or GetUnitAbilityLevel(u,'Abdl')!= 0
endfunction
But will this work only for default human and undead structures ?
What about custom ones and the other races like night elves ?
 
@Aniki We moved your math functions to the small code snippets thread. Since the merging is done by date, your post ended up on the previous page here:
Small Code Snippets

If possible, could you provide a brief comment on the functions/function list? :) It probably isn't necessary for ceil/floor, but it would be helpful for the "nearest" functions.
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
To check if a unit is invulnerable:

JASS:
library InvulnerabilityChecker

    function CheckInvulnerability takes unit u returns boolean
        local real origHP = GetWidgetLife(u)
        local real origMP = GetUnitState(u, UNIT_STATE_MANA)
        local boolean check
        call UnitDamageTarget(u, u, 0.01, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
        set check = GetWidgetLife(u) == origHP and GetUnitState(u, UNIT_STATE_MANA) == origMP
        call SetWidgetLife(u, origHP)
        call SetUnitState(u, UNIT_STATE_MANA, origMP)
        return check
    endfunction

endlibrary

False positives from mana shields are accounted for.
 
Last edited:
Level 13
Joined
Nov 7, 2014
Messages
570
JASS:
if newHP != origHP then
           set check = false
       endif
       if newMP != origMP then
           set check = false
       endif

-->
JASS:
if newHP != origHP or newMP != origMP then
           set check = false
       endif

-->
JASS:
set check = newHp == origHP and newMP == origMP

@AGD note that currently the function will report ethereal units as invulnerable, you need to change the attack type to ATTACK_TYPE_NORMAL, currently it's ATTACK_TYPE_CHAOS.
 
Last edited:
Level 19
Joined
Aug 13, 2013
Messages
1,680
^ Or

Does it really need to include the mana for checking? And is this tested for accuracy? Will it always return false if the unit suddenly have hp or mp regeneration?
( You are checking the life state changes btw so it affects the unit that have regen )
 
Last edited:

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Okay, the neccessary changes were made. Thanks for pointing the errors btw.

@jakeZinc These evaluations are done at a very tiny fraction of a second. And the unitstate regeneration happens at a much greater time interval. Btw, the mana evaluation is included to make sure units with mana shield dont register a false positive.
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Counted Random Units Iteration

JASS:
library RandomIteration

    globals
        private group tempGroup = CreateGroup()
        private integer unitCount = 0
    endglobals

    private function EnumUnits takes nothing returns boolean
        call GroupAddUnit(tempGroup, GetFilterUnit())
        set unitCount = unitCount + 1
        return false
    endfunction

    function EnumRandomUnitsInRangeCounted takes group g, real x, real y, real radius, integer limit returns nothing
        local real chance
        local unit u
        call GroupEnumUnitsInRange(g, x, y, radius, Filter(function EnumUnits))
        set chance = I2R(limit)/I2R(unitCount)
        loop
            set u = FirstOfGroup(tempGroup)
            exitwhen u == null or limit == 0
            call GroupRemoveUnit(tempGroup, u)
            if GetRandomReal(0, 1) <= chance then
                call GroupAddUnit(g, u)
                set limit = limit - 1
            endif
        endloop
    endfunction

endlibrary
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Why?
Just why?

function FilterRandomUnitsCounted takes group g, integer count returns group (optional)
(Remove units from the given group and return the group.)

I mean, if I wanted to get the units from a rect, or filter them first by something else, or even if I already have an existing group that has units.
In any of those cases, your function is pretty much useless. So you have to separate the two functionalities,
1 pick units in range
2 filter random units

The first one, we already have, the second one, that is what you have to create.

Also, you leak a unit handle "exitwhen limit == 0"

You should have that check after lowering the limit:
if limit == 0 then
set u = null
exitwhen true
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Okay, I'm too lazy to update that randomiterator now, for now lets have this.

JASS:
//Requires WorldBounds
//! textmacro IMPLEMENT_BOUNDS takes X, Y
if $X$ < WorldBounds.minX then
    set $X$ = WorldBounds.minX
elseif $X$ > WorldBounds.maxX then
    set $X$ = WorldBounds.maxX
endif
if $Y$ < WorldBounds.minY then
    set $Y$ = WorldBounds.minY
elseif $Y$ > WorldBounds.maxY then
    set $Y$ = WorldBounds.maxY
endif
//! endtextmacro

Doesn't need an extra function call but creates spaghetti code =P

EDIT: It doesn't have to be in a library after all
 
Last edited:
Level 1
Joined
Mar 7, 2016
Messages
5
Must take a boolean parameter to add from filtering that prevents dead units or somewhat to be picked.
I agree with it,but the main question is that it is a library,many codes will quote it,then if different code have different boolean,what boolean should I to add from fitering?
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Credits goes to Vexorian. I just rewrote his script and made it shorter using zinc.
JASS:
//! zinc
library BoolexprUtils {

    public boolexpr BOOLEXPR_TRUE, BOOLEXPR_FALSE;

    module Init {
        static method onInit() {
            BOOLEXPR_TRUE = Filter(function() -> boolean {return true;});
            BOOLEXPR_FALSE = Filter(function() -> boolean {return false;});
        }
    }

    struct S extends array {module Init;}

}
//! endzinc
 
Last edited:

Kazeon

Hosted Project: EC
Level 32
Joined
Oct 12, 2011
Messages
3,440
Most people do not realize amphibious units are not the same as ground unit. This is the condition to check it:

1. Checks if unit is amphibious
JASS:
function IsUnitAmphibious takes unit u returns boolean
    return not (IsUnitType(u, UNIT_TYPE_GROUND) or IsUnitType(u, UNIT_TYPE_FLYING))
endfunction

2. Checks if unit is ground or amphibious:
JASS:
function IsUnitGroundOrAmphibiousFail takes unit u returns boolean
    @ return IsUnitAmphibious(u) or IsUnitType(u, UNIT_TYPE_GROUND) <= not nerdly [email protected]
endfunction
use this instead
JASS:
function IsUnitGroundOrAmphibious takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_GROUND) or not IsUnitType(u, UNIT_TYPE_FLYING)
endfunction

3. Checks if unit is flying or amphibious (will be rarely useful):
JASS:
function IsUnitFlyingOrAmphibious takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_FLYING) or not IsUnitType(u, UNIT_TYPE_GROUND)
endfunction
 
Last edited:
Maybe someone will find a use, as well:

JASS:
struct Repair extends array
    public static constant integer HUMAN_SPELL           = 'Ahrp'
    public static constant integer HUMAN_ORDER           = 852024
    public static constant integer HUMAN_ORDER_ON        = 852025
    public static constant integer HUMAN_ORDER_OFF       = 852026
   
    public static constant integer ORC_SPELL             = 'Arep'
    public static constant integer ORC_ORDER             = 852024
    public static constant integer ORC_ORDER_ON          = 852025
    public static constant integer ORC_ORDER_OFF         = 852026
   
    public static constant integer NIGHT_ELVES_SPELL     = 'Aren'
    public static constant integer NIGHT_ELVES_ORDER     = 852161
    public static constant integer NIGHT_ELVES_ORDER_ON  = 852162
    public static constant integer NIGHT_ELVES_ORDER_OFF = 852163
   
    public static constant integer UNDEAD_SPELL          = 'Arst'
    public static constant integer UNDEAD_ORDER          = 852202
    public static constant integer UNDEAD_ORDER_ON       = 852203
    public static constant integer UNDEAD_ORDER_OFF      = 852204
   
    public static method IsRepairAbility takes integer id returns boolean
        return id == HUMAN_SPELL or id == ORC_SPELL or id == NIGHT_ELVES_SPELL or id == UNDEAD_SPELL
    endmethod
   
    public static method IsRepairOrder takes integer id returns boolean
        return id == HUMAN_ORDER or id == ORC_ORDER or id == NIGHT_ELVES_ORDER or id == UNDEAD_ORDER
    endmethod
   
    public static method IsRepairOrderOn takes integer id returns boolean
        return id == HUMAN_ORDER_ON or id == ORC_ORDER_ON or id == NIGHT_ELVES_ORDER_ON or id == UNDEAD_ORDER_ON
    endmethod
   
    public static method IsRepairOrderOff takes integer id returns boolean
        return id == HUMAN_ORDER_OFF or id == ORC_ORDER_OFF or id == NIGHT_ELVES_ORDER_OFF or id == UNDEAD_ORDER_OFF
    endmethod
endstruct
 
Level 22
Joined
Feb 27, 2007
Messages
3,784
For getting locusted units in range/of player

JASS:
library LocustUnits initializer init //has optional GroupUtils
    globals
        private boolexpr filt
        private integer ID = 'Aloc'
    endglobals
   
    private function IsLocust takes nothing returns boolean
        return GetUnitAbilityLevel(GetFilterUnit(), ID) > 0
    endfunction
   
    function GroupAddLocustUnitsOfPlayer takes group TarG, player TarP returns nothing
        call GroupEnumUnitsOfPlayer(TarG, TarP, filt)
    endfunction
   
    function GroupAddLocustUnitsInRange takes group TarG, real TarX, real TarY, real R, boolexpr someFilter returns nothing
        local integer i = -1
        local unit u
        local group g
        local real x
        local real y
        set R = R*R
       
        static if LIBRARY_GroupUtils then
            set g = NewGroup()
        else
            set g = CreateGroup()
        endif
       
        loop
            set i = i+1
            exitwhen i > 15
            call GroupEnumUnitsOfPlayer(g,Player(i),And(filt, someFilter))
           
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                call GroupRemoveUnit(g,u)
               
                set x = TarX-GetUnitX(u)
                set y = TarY-GetUnitY(u)
                if x*x+y*y <= R then
                    call GroupAddUnit(TarG,u)
                endif
            endloop
        endloop

        static if LIBRARY_GroupUtils then
            call ReleaseGroup(g)
        else
            call DestroyGroup(g)
        endif
        set g = null
        set u = null
    endfunction
   
    private function init takes nothing returns nothing
        set filt = Filter(function IsLocust)
    endfunction
endlibrary
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Maybe this can be useful =)
JASS:
//! zinc
library ExitWarcraft { //Credits: Aniki

    //! novjass
    /*=========== API ===========*/
        function ExitWarcraft()
    /* Exits the Warcraft 3 Game */
    /*===========================*/
    //! endnovjass

    public function ExitWarcraft() {ExecuteFunc("ExitWarcraft");}

}
//! endzinc
 
Last edited:

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Recursion can be deadly =):
JASS:
function crash takes nothing returns nothing
   call ExecuteFunc("crash")
endfunction
Nice! lol, I always complicate myself =D

Edited my post

EDIT:

maYbe GUI support can be added to run the trigger. >_>
How about hook DoNothing ExitWarcraft? GUI users should not be using this function after all =).
 
Last edited:

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Another one
JASS:
library CodeArray /*


    */requires /*

    */Typecast /*  - http://www.hiveworkshop.com/threads/accessing-memory-from-the-script-its-time-of-the-revolution.279262/

    |=====|
    | API |
    |=====|

        //! runtextmacro GLOBAL_CODE_ARRAY("PRIVACY", "NAME")
            - Declares a global code array

    */
    //! textmacro GLOBAL_CODE_ARRAY takes PRIVACY, NAME
    $PRIVACY$ struct $NAME$ extends array

        private static integer codes

        static method operator [] takes integer index returns code
            return I2C(codes[index])
        endmethod

        static method operator []= takes integer index, code c returns nothing
            set codes[index] = C2I(c)
        endmethod

    endstruct
    //! endtextmacro


endlibrary
 
Last edited:
Level 32
Joined
Apr 24, 2012
Messages
5,112
JASS:
/**********************************************************
*
*   FatalError
*   v1.1.2.1
*   By Magtheridon96 (Special Thanks to Nestharus)
*
*   Uses:
*   -----
*
*       - Annoying a player. lol
*
*   API:
*   ----
*
*       - function ExitGame             takes nothing           returns nothing
*       - function ExitGameForPlayer    takes player p          returns nothing
*
*       - function FreezeGame           takes nothing           returns nothing
*       - function FreezeGameForPlayer  takes player p          returns nothing
*
*       - function CrashGame            takes nothing           returns nothing
*       - function CrashGameForPlayer   takes player p          returns nothing
*
*       - function DesyncGameForPlayer  takes player p          returns nothing
*
*       - function EatRAM               takes nothing           returns nothing
*           - This function can take up about 1 GB of memory in a minute.
*           - Use this on cheaters ;D
*           - This function may crash the game at one point.
*
*       - function StopThread          takes nothing           returns nothing
*
**********************************************************/
library FatalError
   
    globals
        private trigger Q = CreateTrigger()
    endglobals
   
    function ExitGame takes nothing returns nothing
        loop
            call ExecuteFunc("ExitGame")
        endloop
    endfunction
   
    function ExitGameForPlayer takes player p returns nothing
        if GetLocalPlayer()==p then
            call ExitGame()
        endif
    endfunction
   
    function FreezeGame takes nothing returns nothing
        loop
            call TriggerSyncReady()
            call ExecuteFunc("FreezeGame")
        endloop
    endfunction
   
    function FreezeGameForPlayer takes player p returns nothing
        if GetLocalPlayer()==p then
            call FreezeGame()
        endif
    endfunction
   
    function CrashGame takes nothing returns nothing
        call Player(-1)
    endfunction
   
    function CrashGameForPlayer takes player p returns nothing
        if GetLocalPlayer()==p then
            call CrashGame()
        endif
    endfunction
   
    function DesyncGameForPlayer takes player p returns nothing
        if GetLocalPlayer()==p then
            call CreateTrigger()
        endif
    endfunction
   
    private function Z takes nothing returns boolean
        local location l
        local integer i = 1000
        loop
            exitwhen 0==i
            set l = Location(0,0)
            set l = Location(0,0)
            set l = Location(0,0)
            set i=i-1
        endloop
        return false
    endfunction
   
    function EatRAM takes nothing returns boolean
        loop
            call TriggerEvaluate(Q)
        endloop
        return false
    endfunction
   
    function StopThread takes nothing returns nothing
        local integer i = 1/0
    endfunction
   
    private module Init
        private static method onInit takes nothing returns nothing
            call TriggerAddCondition(Q,Condition(function Z))
        endmethod
    endmodule
    private struct Inits extends array
        implement Init
    endstruct
endlibrary

you forgot that this existed lol

link: Fatal Error
 
Level 22
Joined
Feb 27, 2007
Messages
3,784
This is dumb and really simple, but I needed a way to remove an effect without showing its death animation. (Specifically to replace it with something else.) I didn't see something like this in this thread from my searching.

Edit: see below
 
Last edited:
Level 36
Joined
Sep 26, 2009
Messages
8,444
This is dumb and really simple, but I needed a way to remove an effect without showing its death animation. (Specifically to replace it with something else.) I didn't see something like this in this thread from my searching.
JASS:
library RemoveEffect
  //Destroying an effect always plays its death animation and any associated sounds.
  //This library fixes it in a simple way: move the effect to a location where nobody can see or hear it.

  globals
    private real SAFE_X = -3900.
    private real SAFE_Y =  3900.
    private real SAFE_Z = -1000. //not strictly necessary

    private real TIMESCALE = 10. //doesn't really matter but we set it to > 0 so the animations actually finish
  endglobals

  function RemoveEffect takes effect e returns nothing
    call BlzSetSpecialEffectPosition(e, SAFE_X, SAFE_Y, SAFE_Z)
    call BlzSetSpecialEffectTimeScale(e, TIMESCALE)
    call DestroyEffect(e)
  endfunction
endlibrary

If the effect is some kind of missile with a trail (like Phoenix Fire) this will cause a trail to appear between the special effect and its destination.
 
Level 22
Joined
Feb 27, 2007
Messages
3,784
If the effect is some kind of missile with a trail (like Phoenix Fire) this will cause a trail to appear between the special effect and its destination.
Huh, didn't notice that. This one shouldn't.
JASS:
library RemoveEffect
  //Destroying an effect always plays its death animation and any associated sounds.
  //This library fixes it in a simple way: move the effect to a location where nobody can see or hear it.

  globals
    private real SAFE_X = -3900.
    private real SAFE_Y =  3900.
    private real SAFE_Z = -1000. //not strictly necessary

    private real TIMESCALE = 10. //doesn't really matter but we set it to > 0 so the animations actually finish
  endglobals

  function RemoveEffect takes effect e returns nothing
    call BlzSetSpecialEffectAlpha(e, 255)
    call BlzSetSpecialEffectZ(e, SAFE_Z)
    call BlzSetSpecialEffectPosition(e, SAFE_X, SAFE_Y, SAFE_Z)
    call BlzSetSpecialEffectTimeScale(e, TIMESCALE)
    call DestroyEffect(e)
  endfunction
endlibrary
 
Level 3
Joined
Jun 30, 2017
Messages
30
A bit of code used for functions that are not allowed to have arguments, such as timer functions, triggeraction/condition functions, enumDestruct/Item functions, filterfuncs, etc...

Lua:
FunctionUtils = {}

function SetFunctionParameters(func, ...)
    FunctionUtils[func] = {...}
end

function GetFunctionParameters(func)
    return table.unpack(FunctionUtils[func])
end

How to use:

Lua:
function test1()

    local argument1, argument2, argument3 = GetFunctionParameters(test1)

-- function does stuff...

end

SetFunctionParameters(test1, argument1, argument2, argument3)
-- call the test1 function in whatever way.
 
Last edited:
Level 14
Joined
May 16, 2012
Messages
541
JASS:
library TimerOne
    private module Init
        private static method onInit takes nothing returns nothing
            call TimerStart(CreateTimer(),1.0,true,function e)
        endmethod
    endmodule
    struct TimerOne extends array
        private static trigger t = CreateTrigger()
        private static method e takes nothing returns nothing
            call TriggerEvaluate(t)
        endmethod
        static method register takes boolexpr b returns nothing
            call TriggerAddCondition(t,b)
        endmethod
        implement Init
    endstruct
endlibrary

I wrote this because I found that the most common timer I'm using in any of my maps is one that expires every second.
I used this system to replace about 20 timer registerations in my map :p

It may seem useful if you have countless 1-second periodic timers :p

Sorry for replaying to a post from 9 years, but i think this is very interesting and potentially useful to me, since this concept could be extrapolated to multiple timeouts. I'm trying to understand how i would convert multiple triggers that use a timer and a hash-table that maps handles to the timer created to this snipped.
Example: How something as simple as this could be done with this snippet? What i mean is, how can i access the stuff that i would normally save in a hash-table in the parent key of the timer with this code?

JASS:
scope Example initializer Init

private function DoSomethingPeriodically takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit  u = LoadUnitHandle(aHashTable, GetHandleId(t), 1)

    //Doing something periodically with unit u
  
    //if conditions were met then i would do this
    call FlushChildHashtable(aHashTable, GetHandleId(t))
    call PauseTimer(t)
    call DestroyTimer(t)
  
    set t = null
    set u = null
endfunction

private function Conditions takes nothing returns nothing
    local unit  u = GetTriggerUnit()
    local timer t = CreateTimer()

    call SaveUnitHandle(aHashTable, GetHandleId(t), 1, u)
    call TimerStart(t, 1.0, true, function DoSomethingPeriodically)

    set u = null
    set t = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
    call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function Conditions)
endfunction

endscope
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
I said it's impossible to do it using only one timer in the manner of method you described above, like
JASS:
private function DoSomethingPeriodically takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit  u = LoadUnitHandle(aHashTable, GetHandleId(t), 1)

    //Doing something periodically with unit u
 
    //if conditions were met then i would do this
    call FlushChildHashtable(aHashTable, GetHandleId(t))
    call PauseTimer(t)
    call DestroyTimer(t)
 
    set t = null
    set u = null
endfunction
i.e, using hashtable + GetHandleId() as parent key.

But of course no problem cannot be solved by adding layers of abstraction in one's approach.
JASS:
    module TimerOne
        private thistype prev
        private thistype next
        private thistype data

        private static method onTimerExpire takes nothing returns nothing
            local thistype node = thistype(0).next
            loop
                exitwhen node == list
                if not node.data.onTimerPeriod() then
                    set node.next.prev = node.prev
                    set node.prev.next = node.next
                endif
                set node = node.next
            endloop
        endmethod

        static method startTimerOne takes integer data returns nothing
            local thistype node = Node.allocate()
            if thistype(0).next == 0 then
                call TimerOne.register(function thistype.onTimerExpire)
            endif
            set node.prev = list.prev
            set node.next = list
            set list.prev = node
            set node.prev.next = node
            set node.data = data
        endmethod
    endmodule

...

struct MyStruct
    private method onTimerPeriod takes nothing returns boolean
        set this.xxx // this -> the attached data

        ...

        return <conditionToContinue>
    endmethod

    implement TimerOne

    private static method onInit takes nothing returns nothing
        call startTimerOne(<dataAttachment>) // Now you can attach data while still using only 1 timer
    endmethod
endstruct
 

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
678
Overrides ForGroup() so that GUI users can use waits inside unitgroup enumerations now that we have [Lua] Perfect PolledWait (GUI-friendly).

forgroupoverride.lua
Lua:
-- forgroupoverride.lua
do
    local enumUnit = nil [email protected] unit

    [email protected] whichGroup group
    [email protected] callback function
    function ForGroup(whichGroup, callback, ...)
        for i = 1, BlzGroupGetSize(whichGroup) do
            local prevEnumUnit = enumUnit
            enumUnit = BlzGroupUnitAt(whichGroup, i)
            callback(...)
            enumUnit = prevEnumUnit
        end
    end

    [email protected] unit
    function GetEnumUnit() return enumUnit end
end
 
Last edited:
Top