• 🏆 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 9
Joined
Nov 28, 2008
Messages
704
Out of curiosity, would it be worth it to create a custom spells library for the purpose of efficientizing? For exmaple, I started one here:

JASS:
library CustomSpells initializer Init

    private hashtable Hash

    #define private SPELL_BEGIN_KEY = 0

    private function interface SpellFunction takes nothing returns nothing

    private void OnBegin(){
        SpellFunction(LoadInteger(Hash, SPELL_BEGIN_KEY, GetSpellAbilityId())).execute()

    }
    private void Init(){
        trigger t = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
        TriggerAddAction(t, function OnBegin)
        Hash = InitHashtable()




    }
    public void AddOnBegin(int id, SpellFunction sf){
        SaveInteger(Hash, SPELL_BEGIN_KEY, id, int(sf))
    }
endlibrary

I mean, say something like dota uses like 100 triggers of detecting casted spells. Each one of those triggers is gonna "trigger" every time a unit casts a spell, whereupon it will try to look at a condition or something. The concept of this library would be to simply save these triggers in a hash, making all of your custom spells only have one trigger "fire", and not even bother to check if the function called is the spell being casted, which would then save time.

I mean, theoretically, it seems like a good idea to efficientize (also it saves time), but is it really worth the effort?
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
something to change the pathing in a region
can be used to change tile/terrain pathing and to save pathing blockers

JASS:
function SetPathingRect takes rect re, pathingtype pt, boolean pathable returns nothing
    //probably this trigger won't work if you don't snap the regions to the grid

    //available pathing types
//PATHING_TYPE_ANY                 //if this is false you can't walk/build/fly on it
//PATHING_TYPE_WALKABILITY         //if this is false you can't walk on it
//PATHING_TYPE_FLYABILITY          //if this is false you can't fly on it
//PATHING_TYPE_BUILDABILITY        //if this is false you can't build on it
//PATHING_TYPE_PEONHARVESTPATHING  //don't know
//PATHING_TYPE_BLIGHTPATHING       //if this is false you can't build ziggs on it
//PATHING_TYPE_FLOATABILITY        //don't know
//PATHING_TYPE_AMPHIBIOUSPATHING   //don't know

    local real r = 32  //size of pathing blocks
    local real x = GetRectMinX(re)
    local real y
    local real x2 = GetRectMaxX(re)
    local real y2 = GetRectMaxY(re)

    loop
        exitwhen x == x2
        set y = GetRectMinY(re)
        loop
            exitwhen y == y2
            call SetTerrainPathable(x, y, pt, pathable)
            set y = y + r
        endloop
        set x = x + r
    endloop
endfunction
edit:
thanks to YourNameHere
-fixed unnecessary nulling and removing
edit2: well...actually I know what the types stand for but I did not test if they are what they are supposed to be :p
 

Attachments

  • SetPathingRect.w3x
    12.9 KB · Views: 51
Last edited:
I don't know if this is useful, but I heard hashtables are slower if they have lots of things stored in them. In that case, you might want dynamic hashtables.
I present to you, HashtableUtils (WARNING: Zinc code):

JASS:
//! zinc
library HashtableUtils
{
    integer Count = 0;
    hashtable HashArr[];
    
    public function NewHashtable () -> hashtable
    {
        if (Count > 0)
        {
            Count -= 1;
            return HashArr[Count];
        }
        else
        {
            return InitHashtable();
        }
    }
    
    public function ReleaseHashtable (hashtable h)
    {
        if (h != null)
        {
            FlushParentHashtable(h);
            HashArr[Count] = h;
            Count += 1;
        }
        else
        {
            debug BJDebugMsg("HashtableUtils: attempt to release a null hashtable");
        }
    }
}
//! endzinc
 
Level 12
Joined
Jul 27, 2008
Messages
1,181
Here goes, we don't have one so I thought I'd share. Fix as possible, and adapt to zinc/vJASS/cJASS freely (i mean for repost). Dunno how useful it is to you, it certainly is for me:
call CreateTimedEffect(x, y, time, modelname)
Creates an effect at specified coords, for specified duration.
call CreateTimedEffectAtUnit(unit, time, modelname, attachpoint)
Same as above, at unit, at specified attachment point.

JASS:
function CreateTimedEffect_Cleanup takes nothing returns nothing
    local timer cleanup_cte_tim = GetExpiredTimer()
    call DestroyEffect(LoadEffectHandle(udg_cte_Table, GetHandleId(cleanup_cte_tim), 0))
    call FlushChildHashtable(udg_cte_Table, GetHandleId(cleanup_cte_tim))
    call DestroyTimer(cleanup_cte_tim)
    set cleanup_cte_tim = null
endfunction

function CreateTimedEffect takes real x, real y, real t, string s returns nothing
    local effect cte_eff = AddSpecialEffect(s, x, y)
    local timer cte_tim = CreateTimer()
    
    call SaveEffectHandle(udg_cte_Table, GetHandleId(cte_tim), 0, cte_eff)
    call TimerStart(cte_tim, t, false, function CreateTimedEffect_Cleanup)
    
    set cte_eff = null
    set cte_tim = null
endfunction 


function CreateTimedEffectAtUnit takes unit u, real t, string s, string p returns nothing
    local effect cteu_eff = AddSpecialEffectTarget(s, u, p)
    local timer cteu_tim = CreateTimer()
    
    call SaveEffectHandle(udg_cte_Table, GetHandleId(cteu_tim), 0, cteu_eff)
    call TimerStart(cteu_tim, t, false, function CreateTimedEffect_Cleanup)
    
    set cteu_eff = null
    set cteu_tim = null
endfunction
 
Level 9
Joined
Nov 28, 2008
Messages
704
I really hope Hashtables dont get slower with more things. As far as I've heard, They have O(1) time or close to meaning that wouldnt happen.

On the plus side, it makes my C++ bst equivilent better if they do :O.
 
Level 16
Joined
Feb 22, 2006
Messages
960
hm... some small math functions and a bool to string function (may already been posted but who knows :O)

JASS:
function factorial takes integer n returns integer
    if n <= 1 then
        return 1
    endif
    return n*factorial(n-1)
endfunction

function parity takes integer n returns boolean
    return ModuloInteger(n,2) != 1
endfunction

function B2S takes boolean b returns string
    if b then
        return "True"
    endif
    return "False"
endfunction
 
JASS:
globals
     private unit u = null
endglobals

function UNIT2B takes unit u returns boolean
    if u != null then
        return true
    endif
    return false
endfunction

function B2UNIT takes boolean b returns unit
    if b == true then
        set u = CreateUnit(Player(15), 'rofl', 0., 0., 0.)
        call HideUnit(u)
        return u
    endif
    return null
endfunction
What about this? XD
 
Level 11
Joined
Apr 29, 2007
Messages
826
Haven't seen anything like this around.

JASS:
    function GetClosestNumberToX takes integer base, integer x returns integer
        if base == 0 or IAbsBJ(base) <= IAbsBJ(x) then
            return x
        endif
        
        loop
            exitwhen base-base/x*x == 0
            
            if base-base/x*x <= x/2 then
                set base = base - 1
            else
                set base = base + 1
            endif
        endloop
        
        return base
    endfunction
Example:
GetClosestNumberToX(10, 3) returns 9
GetClosestNumberToX(5, 13) returns 13

and so on.
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Coordinate- Snippets


Original thread: http://www.hiveworkshop.com/forums/graveyard-418/ispointinrectangle-180617/
JASS:
library IsPointInRectangle
    //determins if point P is in rectangle ABCD
    function IsPointInRectangle takes real ax, real ay, real bx, real by, real cx, real cy, real dx, real dy, real px, real py returns boolean
        local real cross0 = (py-ay)*(bx-ax)-(px-ax)*(by-ay)
        local real cross1 = (py-cy)*(ax-cx)-(px-cx)*(ay-cy)
        local real cross4 = (py-dy)*(ax-dx)-(px-dx)*(ay-dy)
        
        return ((cross0*cross1 >= 0) and (((py-by)*(cx-bx)-(px-bx)*(cy-by))*cross1 >= 0)) or ((cross0*cross4 >= 0) and (((py-by)*(dx-bx)-(px-bx)*(dy-by))*cross4 >= 0))
    endfunction
endlibrary

Original thread: http://www.hiveworkshop.com/forums/graveyard-418/snippet-gettrianglecentroid-180605/
JASS:
library GetTriangleCentroid
    //get centroid x,y of triangle ABC
    
    function GetTriangleCentroidX takes real ax, real bx, real cx returns real
        return (ax+bx+cx)/3
    endfunction
    
    function GetTriangleCentroidY takes real ay, real by, real cy returns real
        return (ay+by+cy)/3
    endfunction
endlibrary

Original thread: http://www.hiveworkshop.com/forums/graveyard-418/snippet-pointintriangle-180407/
JASS:
library IsPointInTriangle

//check to see if a point P is in triangle ABC
function IsPointInTriangle takes real ax, real ay, real bx, real by, real cx, real cy, real px, real py returns boolean
    local real cross0 = (py-ay)*(bx-ax)-(px-ax)*(by-ay)
    local real cross1 = (py-cy)*(ax-cx)-(px-cx)*(ay-cy)
    return (cross0*cross1 >= 0) and (((py-by)*(cx-bx)-(px-bx)*(cy-by))*cross1 >= 0)
endfunction

endlibrary

Original thread: http://www.hiveworkshop.com/forums/submissions-414/snippet-lineslopeintercept-180760/
JASS:
library LineSlopeIntercept
    //returns the slope given vector [(x1, y1), (x2, y2)]
    function GetVectorSlope takes real x1, real y1, real x2, real y2 returns real
        return (y2-y1)/(x2-x1)
    endfunction
    
    //returns y intercept given point (x,y) and slope m
    function GetLineYIntercept takes real x, real y, real m returns real
        return y-m*x
    endfunction
endlibrary

Original thread: http://www.hiveworkshop.com/forums/submissions-414/snippet-ispointonline-180759/
JASS:
function IsPointOnLine takes real slope, real yIntercept, real x, real y returns boolean
    return y == slope * x + yIntercept
endfunction

Original thread: http://www.hiveworkshop.com/forums/submissions-414/snippet-getintersectiondistance-180948/
JASS:
// We've got a line given by P1(x1, y1) and P2(x2, y2) as well as a ray given by P3(x3, y3) and angle a.
// This function returns the distance from P3 to the intersection point.
// The distance returned is negative if the ray points away from the line.
//
library GetIntersectionDistance

function GetIntersectionDistance takes real x1, real y1, real x2, real y2, real x3, real y3, real a returns real
    local real m = x1 - x2
    if (m == 0) then // Avoid division by zero
        return (x1 - x3) / Cos(a)
    endif
    set m = (y1 - y2) / m
    if (m == Tan(a)) then // Parallel (avoid division by zero again: Sin(a) - Tan(a) * Cos(a) == 0)
        return 0.
    endif
    return (m * (x3 - x1) + y1 - y3) / (Sin(a) - m * Cos(a))
endfunction

endlibrary
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
IsUnitTypeId

I don't really know if it worths a thread in the submissions.
It highlights a bug, but it's also a very specific usage, especially if you don't care about saved game then it's definitely the shortest snippet here.

So for the story for my GetWorker library (the unit which fire the construction events) i needed to know if a received order was a construction order or not (an unitid or not).
But i found a jass bug UnitId2String(<valid unitid>) always returns null when it's a loaded game.
I've checked the whole natives and i've only found this way :

JASS:
library IsUnitTypeId requires optional Table // Table is optional only if you don't care about saved game, i could use an hashtable but meh just use Table 
 
globals 
    private constant boolean CARE_ABOUT_SAVED_GAMES = true // self descriptive, true or false make your choice 
endglobals 
 
// don't touch below this line  
 
globals 
    private boolean Is_game_loaded = false 
endglobals 
 
static if CARE_ABOUT_SAVED_GAMES then // works for a global block but not for a variable inside a global block 
    globals 
        private Table Tab 
    endglobals 
endif 
 
function IsGameLoaded takes nothing returns boolean 
    return Is_game_loaded 
endfunction  
 
function IsUnitTypeId takes integer unitid returns boolean 
 
    static if CARE_ABOUT_SAVED_GAMES then 
     
        local unit u 
        if IsGameLoaded() then  
 
            if Tab.exists(unitid) then  
                return Tab[unitid] != 0 
            endif 
         
            // IsUnitIdType is not enough , IsUnitHeroId only check if the first letter of the id is an uppercase and not if the id is a valid hero id 
            // so i've figured only this way, or you can use a third party tool instead, like GMSI, but imho it's overskilled here     
            set u = CreateUnit(Player(13),unitid,0.,0.,0.)  
         
            if u != null then  
                call RemoveUnit(u)  
                set u = null  
                set Tab[unitid] = 1  
                return true  
            else  
                set Tab[unitid] = 0  
                return false  
            endif  
         
        endif 
     
    endif 
     
    return UnitId2String(unitid) != null // always returns null when the game was saved and loaded, and yes it's a bug 
     
endfunction 
 
private function GameLoaded takes nothing returns boolean 
    set Is_game_loaded = true 
    call DestroyBoolExpr(Condition(function GameLoaded)) 
    call DestroyTrigger(GetTriggeringTrigger()) 
    return false 
endfunction 
 
static if CARE_ABOUT_SAVED_GAMES then 
 
// coz of vJass madness initializer module priority, even if i hardly see the usefulness of registring a such event on a module initializer ... 
// but in some case this kind of initializer can be "handy", here we avoid an unecessary init 
 
    module onInit 
 
        static method onInit takes nothing returns nothing 
            local trigger trig = CreateTrigger() 
            call TriggerRegisterGameEvent(trig,EVENT_GAME_LOADED) 
            call TriggerAddCondition(trig,Condition(function GameLoaded)) 
            set trig = null 
            static if CARE_ABOUT_SAVED_GAMES then 
                set Tab = Table.create() 
            endif 
        endmethod 
 
    endmodule 
 
    struct s_dummy extends array 
        implement onInit 
    endstruct 
 
endif 
 
endlibrary
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Those static if's will fail if the user sets CARE_ABOUT_SAVED_GAMES to false, try it out. Not that it's been heavily announced but a new Table has been developed which rolls all over Vexorian's original, so it should be clarified this uses Vexorian's and not that one (.exists(10) was changed to .has(10) to better match Hashtable naming conventions).

Also, a lot of those static if's need to be coupled with "and LIBRARY_Table"
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
My bad because it compiled i assumed it worked as intented (static if).
I haven't applied the gold rule "always check generated vJass code and at very least always test it".

So there is no way avoid a global declaration with static if ?

Here is the fix :

JASS:
library IsUnitTypeId requires optional Table // Table is optional only if you don't care about saved game, i could use an hashtable but meh just use Table 
 
globals 
    private constant boolean CARE_ABOUT_SAVED_GAMES = true // self descriptive, true or false make your choice 
endglobals 
 
// don't touch below this line  
 
globals 
    private boolean Is_game_loaded = true 
    private integer Tab 
endglobals 
 
 
 
function IsGameLoaded takes nothing returns boolean 
    return Is_game_loaded 
endfunction  
 
function IsUnitTypeId takes integer unitid returns boolean 
 
    static if CARE_ABOUT_SAVED_GAMES then 
     
        local unit u 
        if IsGameLoaded() then  
 
            if Table(Tab).exists(unitid) then  
                return Table(Tab)[unitid] != 0 
            endif 
         
            // IsUnitIdType is not enough , IsUnitHeroId only check if the first letter of the id is an uppercase and not if the id is a valid hero id 
            // so i've figured only this way, or you can use a third party tool instead, like GMSI, but imho it's overskilled here     
            set u = CreateUnit(Player(13),unitid,0.,0.,0.)  
         
            if u != null then  
                call RemoveUnit(u)  
                set u = null  
                set Table(Tab)[unitid] = 1  
                return true  
            else  
                set Table(Tab)[unitid] = 0  
                return false  
            endif  
         
        endif 
     
    endif 
     
    return UnitId2String(unitid) != null // always returns null when the game was saved and loaded, and yes it's a bug 
     
endfunction 
 
private function GameLoaded takes nothing returns boolean 
    set Is_game_loaded = true 
    call DestroyBoolExpr(Condition(function GameLoaded)) 
    call DestroyTrigger(GetTriggeringTrigger()) 
    return false 
endfunction 
 
static if CARE_ABOUT_SAVED_GAMES then 
 
// coz of vJass madness initializer module priority, even if i hardly see the usefulness of registring a such event on a module initializer ... 
// but in some case this kind of initializer can be "handy", here we avoid an unecessary init 
 
    module onInit 
 
        static method onInit takes nothing returns nothing 
            local trigger trig = CreateTrigger() 
            call TriggerRegisterGameEvent(trig,EVENT_GAME_LOADED) 
            call TriggerAddCondition(trig,Condition(function GameLoaded)) 
            set trig = null 
            static if CARE_ABOUT_SAVED_GAMES then 
                set Tab = integer(Table.create()) 
            endif 
        endmethod 
 
    endmodule 
 
    struct s_dummy extends array 
        implement onInit 
    endstruct 
 
endif 
 
endlibrary

Until your Table is approved i will keep Vexorian's one.
Even if i like some features of yours i would still keep to use an hashtable if i need 2 index (never needed more).
There is no need of "LIBRARY_Table" except preventing people being dumb and ignore the library requirement.
I consider overkilled to use one hahstable to use only one index of it, i prefer an useful library requirement.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Oh yeah static member in a struct, i've forgotten that.

Fixed the boolean default value which should be false instead of true, improved the usage of static if.
But now it's really funny how senseless the code is, especially when you don't care about saved game, even if with static if only comments will be spammed and can be handle with an optimizer (the way how jasshelper handle ignored code).

JASS:
library IsUnitTypeId requires optional Table // Table is optional only if you don't care about saved game, i could use an hashtable but meh just use Table 
 
globals 
    private constant boolean CARE_ABOUT_SAVED_GAMES = true // self descriptive, true or false make your choice 
endglobals 
 
// don't touch below this line 
 
static if CARE_ABOUT_SAVED_GAMES then 
 
    private keyword s_dummy 
     
    private function GameLoaded takes nothing returns boolean  
        set s_dummy.is_game_loaded = true  
        call DestroyBoolExpr(Condition(function GameLoaded))  
        call DestroyTrigger(GetTriggeringTrigger())  
        return false  
    endfunction  
     
    // coz of vJass madness initializer module priority, even if i hardly see the usefulness of registring a such event on a module initializer ... 
    // but in some case this kind of initializer can be "handy", here we avoid an unecessary init 
  
    private module onInit  
  
        static method onInit takes nothing returns nothing  
            local trigger trig = CreateTrigger()  
            call TriggerRegisterGameEvent(trig,EVENT_GAME_LOADED)  
            call TriggerAddCondition(trig,Condition(function GameLoaded))  
            set trig = null  
            set s_dummy.tab = Table.create() 
        endmethod  
  
    endmodule  
  
    private struct s_dummy extends array // the extends array avoid some unneeded stuff 
        static Table tab 
        static boolean is_game_loaded = false 
        implement onInit  
    endstruct  
     
    function IsGameLoaded takes nothing returns boolean 
        return s_dummy.is_game_loaded 
    endfunction 
     
endif 
 
function IsUnitTypeId takes integer unitid returns boolean 
 
    static if CARE_ABOUT_SAVED_GAMES then 
 
        local unit u 
        if IsGameLoaded() then 
 
            if s_dummy.tab.exists(unitid) then 
                return s_dummy.tab[unitid] != 0 
            endif 
 
            // IsUnitIdType is not enough , IsUnitHeroId only check if the first letter of the id is an uppercase and not if the id is a valid hero id 
            // so i've figured only this way, or you can use a third party tool instead, like GMSI, but imho it's overskilled here 
            set u = CreateUnit(Player(13),unitid,0.,0.,0.) 
 
            if u != null then 
                call RemoveUnit(u) 
                set u = null 
                set s_dummy.tab[unitid] = 1 
                return true 
            else 
                set s_dummy.tab[unitid] = 0 
                return false 
            endif 
 
        endif 
 
    endif 
 
    return UnitId2String(unitid) != null // always returns null when the game was saved and loaded, and yes it's a bug 
      
endfunction 
 
endlibrary
So i've the feeling that it should be much better to don't have this static boolean, and if the mapmaker doesn't care about saved game then he can just inline UnitId2String(<integer>) != null.

What's your opinion ?
Or maybe i should add a constant boolean NOBODY_GIVES_A_SHIT_TO_IT ? :p
 
I don't really expect this to be linked in the first post or anything, but here are some useful cinematic functions I've used in the past:
JASS:
//SetCameraField() has an input of degrees, but GetCameraField() returns radians.
//This script will keep everything in degrees for ease of usage.
function GetCameraFieldEx takes camerafield whichField returns real
    if (whichField != CAMERA_FIELD_FARZ and whichField != CAMERA_FIELD_TARGET_DISTANCE and whichField != CAMERA_FIELD_ZOFFSET) then
        return GetCameraField(whichField) * bj_RADTODEG
    endif
    return GetCameraField(whichField)
endfunction

//This function will control whether or not transmissions can be skipped
function EnableTransmissionSkip takes boolean flag returns nothing
    if (flag) then
        call DestroyTrigger(bj_cineSceneBeingSkipped) //just in case it was created in this function
        call TryInitCinematicBehaviorBJ() //recreate it
    else
        if (bj_cineSceneBeingSkipped == null) then //if it is null, create it
            set bj_cineSceneBeingSkipped = CreateTrigger() //creating it without events will bypass the init behavior
        else
            call DisableTrigger(bj_cineSceneBeingSkipped) //disable it if it already exists
        endif
    endif
endfunction
 
Last edited by a moderator:
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library KnuthChecksum uses BigInt
    function GetKnuthChecksum takes BigInt k, BigInt m returns BigInt
        local BigInt c = k.copy()
        
        call c.add(3)
        call c.multiplyBig(k)
        
        set k = c.modBig(m)
        
        call c.destroy()
        
        return k
    endfunction
endlibrary

Demo
JASS:
struct Tester extends array
    private static method onInit takes nothing returns nothing
        local string checksumStr = "3234567"
        local BigInt security = BigInt.convertString(checksumStr, Base["0123456789"])
        local BigInt int = BigInt.convertString("1234567890123456789", Base["0123456789"])
        local BigInt checksum = KnuthChecksum(int, security)
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, int.toString())
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, checksum.toString())
    endmethod
endstruct

Outputs:
Code:
1=1(1+3) = 4
2=2(2+3) = 10
3=3(3+3) = 18
4=4(4+3) = 28

Cycles every m
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
s_dummy in the IsUnitTypeId... won't that throw a syntax error?
And why it would ? (vJass uses double underscore not single)

(structs with underscore don't compile with JassHelper)
Actually they do (i used them like that since my beginning with vJass which is few years), but ofc for naming variables and functions you have to begin with a letter and end with a letter or a number, so it's the same for a struct since methods and members are named depends the struct name.

You can argue that my naming convention for struct is ugly, but anyway it's just for the initializer and to avoiding an unneeded global variable in case you don't care about saved game. It's not like there is an other way, coz of vJass parsing order and besides the user doesn't have to use the struct anyway.

Even if i've already stated that in this case you should probably just inline "UnitId2String(<integer>) != null",
Hell i just follow the jass philosophy, "dont have a decent naming convention" :p

CreateTimer,CreateUnit,... and tadaa DialogCreate,InitHashtable and such other not consistent examples in all functions.
 
Last edited:
Don't know if this exists in here already, nor that if it even has use, but here it is:
JASS:
function valueBetween takes integer oInt1, integer oInt2 returns integer
  
  
  // Let us calculate the value between the integers.
  //
  if ( oInt1 > oInt2 ) then
    
	return ( oInt1 - oInt2 ) / 2
	
  else if ( oInt1 < oInt2 ) then
    
	return ( oInt2 - oInt1 ) / 2
	
  endif
  
endfunction

  // Just to make this function a little bit clearer, I made a examble.
  //
  // call valueBetween( 2, 1 )
  //   [ return  =  0.5 ]
  //
  // call valueBetween( 1, 2 )
  //   [ return  = -0.5 ]
  //

If it bugs for someone then I don't know the reason, I lost the text file containing the full version of it :D
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
It won't compile since you don't have a return outside the if (which will be btw the forgotten case where integer1 == integer2).
But anyway i would just inline that :

JASS:
set i = i1 - i2
if i <0 then
set i = -i
endif
Or just use IAbsBJ(i1-i2)
 
Last edited:
EDIT: This also doesn't count as a submission because it kind of depends on the map for the condition of "is playing". ;o Some people might use unused players for things like creeps, and may want them to have registries as well. But it can all be fixed by modifying the condition.

A simple script but it has great uses. It isn't a solid submission as it really depends on the map, but:
JASS:
// Sets a boolean of a player's playing state
library IsPlaying
    struct IsPlaying extends array
        static boolean array player
        static method operator [] takes integer i returns boolean
            return thistype.player[i]
        endmethod
        static method onInit takes nothing returns nothing
            local integer i = 11
            loop
                set thistype.player[i] = GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER 
                //modify this condition as needed
                exitwhen i == 0 
                set i = i - 1
            endloop
        endmethod
    endstruct   
endlibrary

That sets a player's playing state on map initialization. Then it allows you to retrieve it either by IsPlaying[integer] or IsPlaying.player[integer]. Why did I make this though? Well, let's say you do something as simple as this:
JASS:
library TriggerRegisterAnyUnitEvent
    function TriggerRegisterAnyUnitEvent takes trigger t, playerunitevent whichEvent returns nothing
        local integer i = 15
        loop
            if IsPlaying[i] or i > 11 then
                call TriggerRegisterPlayerUnitEvent(t,Player(i),whichEvent,null)
            endif
            exitwhen i == 0
            set i = i - 1
        endloop
    endfunction
endlibrary

That replaces the standard register. It registers it only for Player(12)-Player(15) and any players that are playing. However, the original one registers it for all players, even if it is unneeded. They do that in case you have units on the map that can cast it as part of their AI or something. However, I personally didn't like that as I wanted more control over who I wanted to register it for. That's why I made the script.

For example, in a map with 10 registries using the normal TriggerRegisterAnyUnitEventBJ, I had 272 total handles (running single-player). In a map using the modified one with 10 registries, I had 162 handles (running single-player). That is a saving of 110 handles. Not bad. :)

Overall, that script isn't really meant as a solid submission because it really depends on the map, but this is more of a "throw-out-there" script in case people want to gain a lot of efficiency, especially in single player maps or maps without all the player slots filled up. ;D
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Could be done using http://www.hiveworkshop.com/forums/jass-functions-413/system-playermanager-142554/ via:

JASS:
library TriggerRegisterAnyUnitEvent requires PlayerManager
    function TriggerRegisterAnyUnitEvent takes trigger t, playerunitevent whichEvent returns nothing
        local ActivePlayer p = 0
        loop
            call TriggerRegisterPlayerUnitEvent(t, p.get, whichEvent, null)
            set p = p.next
            exitwhen p.end
        endloop
    endfunction
endlibrary
 
Top