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

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
JASS:
//! textmacro continue_loop takes TO_CONTINUE
   exitwhen not ($TO_CONTINUE$)
//! endtextmacro
Is that what you're looking for?

//! runtextmacro continue_loop("true") makes the loop go on, while //! runtextmacro continue_loop("false") breaks it.

But any textmacro-based API is horribly stupid, ugly, and pointless.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Tree Rotation Snippets

JASS:
static method rotateLeft takes Tree tree, Node node returns nothing
    local thistype child=node.right
	set node.right=child.left
	set child.left.parent=node
	set child.parent=node.parent
	if (0==node.parent) then
		set tree.first=child
	elseif (node==node.parent.left) then
		set node.parent.left=child
	else
		set node.paernt.right=child
	endif
	set child.left=node
	set node.parent=child
endmethod

static method rotateRight takes Tree tree, Node node returns nothing
    local thistype child=node.left
	set node.left=child.right
	set child.right.parent=node
	set child.parent=node.parent
	if (0==node.parent) then
		set tree.first=child
	elseif (node==node.parent.left) then
		set node.parent.left=child
	else
		set node.paernt.right=child
	endif
	set child.right=node
	set node.parent=child
endmethod

I am not sure how this is to be used. "Tree" and "thistype" are really vague.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
iirc, this will compile unless you use jasshelper.(Uber avatar magtheridon^^)
JASS:
function NoVJassConfirmer takes nothing returns boolean
    if true then
        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "This map have no VJass, trust me")
        return true
    endif
endfunction
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
JASS:
function RefreshUI takes unit u returns nothing
   call UnitAddAbility(u,'Fake')
   call UnitRemoveAbility(u,'Fake')
endfunction

Sometimes the unit interface isn't refreshed enough quickly, for example if you use intensively the xp (i mean like change it several times with short time intervals, the xp bar won't be refreshed enough to get a smooth result)

Instead of 'Fake' you are supposed to use an ability which does nothing and will never be added without this function.

Maybe there is a better way but i don't know something else.
 
JASS:
library DynamicHandles
    globals
        unit            Temp_Unit                   = null
        unit            Temp_Unit2                  = null
        unit            Temp_Unit3                  = null
        destructable    Temp_Destructable           = null
        destructable    Temp_Destructable2          = null
        destructable    Temp_Destructable3          = null
        widget          Temp_Widget                 = null
        widget          Temp_Widget2                = null
        widget          Temp_Widget3                = null
        item            Temp_Item                   = null
        item            Temp_Item2                  = null
        item            Temp_Item3                  = null
        player          Temp_Player                 = null
        player          Temp_Player2                = null
        player          Temp_Player3                = null
    endglobals
endlibrary

This library is quite useful.
Instead of wasting performance by creating a local variable, you would use these.
Treat them as if they were local variables :)
You don't have to null them though ^^
 

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
JASS:
library DynamicHandles
    globals
        unit            Temp_Unit                   = null
        unit            Temp_Unit2                  = null
        unit            Temp_Unit3                  = null
        destructable    Temp_Destructable           = null
        destructable    Temp_Destructable2          = null
        destructable    Temp_Destructable3          = null
        widget          Temp_Widget                 = null
        widget          Temp_Widget2                = null
        widget          Temp_Widget3                = null
        item            Temp_Item                   = null
        item            Temp_Item2                  = null
        item            Temp_Item3                  = null
        player          Temp_Player                 = null
        player          Temp_Player2                = null
        player          Temp_Player3                = null
    endglobals
endlibrary

This library is quite useful.
Instead of wasting performance by creating a local variable, you would use these.
Treat them as if they were local variables :)
You don't have to null them though ^^

Local variables perform much faster than globals, so that library is very, very useless.
 
Level 13
Joined
Mar 16, 2008
Messages
941
This neads a LOT of performance test.
Dont know where you got your slower from, but the last tests IÍ've seen stated that globals are only 10% slower then locals and that the allocation takes more time then most ppl think, making globals faster while being <~10-12 orders in comparison to the allocated and used local.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
This neads a LOT of performance test.
Dont know where you got your slower from, but the last tests IÍ've seen stated that globals are only 10% slower then locals and that the allocation takes more time then most ppl think, making globals faster while being <~10-12 orders in comparison to the allocated and used local.

That's 100% wrong, you can't benchmark globals.. lookup time on variables depends both on the variable name and the number of variables in the given scope of the map.

Local scope is tiny, making locals very fast to look up.

Global scope is huge (typically tons of global variables declared), making global variables very slow to look up.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
//Requires
//  BigInt          hiveworkshop.com/forums/jass-functions-413/system-bigint-188973/
//  Base            hiveworkshop.com/forums/submissions-414/snippet-base-188814/
//  Ascii           wc3c.net/showthread.php?t=110153
//  Table           hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
library NumberStack uses BigInt
    /***********************************************************************
    *
    *   struct NumberStack extends array
    *
    *       Base internalBase
    *           -   The base stored in the NumberStack.
    *
    *       readonly string string
    *           -   The NumberStack as a string
    *
    *       readonly integer remaining
    *           -   Remaining number in stack (does not pop it, just returns it)
    *
    *       static method create takes Base base returns NumberStack
    *           -   Returned value is a BigInt
    *
    *       method destroy takes nothing returns nothing
    *           -   Destroys number stack
    *
    *       static method convert takes string str, Base base returns NumberStack
    *           -   Converts string into NumberStack
    *
    *       method push takes integer value, integer maxValue returns nothing
    *           -   Adds new number to NumberStack
    *           -   Value is the value of the number and maxValue is the max
    *           -   that the number can be
    *
    *       method pop takes integer maxValue returns integer
    *           -   Pops value from NumberStack and returns it
    *           -   Numbers are popped in the reverse order of when they were pushed
    *
    *           Visual
    *               Push 3 -> 3
    *               Push 4 -> 4,3
    *               Push 1 -> 1,4,3
    *
    *               Pop -> 4,3 returns 1
    *               Pop -> 3 returns 4
    *               Pop -> 0 returns 3
    *
    ***********************************************************************/
    private module NumberStackInit
        private static method onInit takes nothing returns nothing
            set epusht = CreateTrigger()
            call TriggerAddCondition(epusht, Condition(function thistype.epush))
        endmethod
    endmodule
    struct NumberStack extends array
        private Base baset
    
        private static trigger epusht
        private static BigInt epushThis
        private static integer epushValue
        private static integer epushMaxValue
        
        static method create takes Base base returns NumberStack
            local thistype this = BigInt.create()
            set this.baset = base
            return this
        endmethod
        method operator internalBase takes nothing returns Base
            return baset
        endmethod
        method operator internalBase= takes Base b returns nothing
            set baset = b
        endmethod
        static method convert takes string str, Base base returns NumberStack
            local thistype this = BigInt.convertString(str, base)
            set BigInt(this).base = 0
            set this.baset = base
            return this
        endmethod
        private static method epush takes nothing returns boolean
            call epushThis.multiply(epushMaxValue + 1)
            call epushThis.add(epushValue)
            return false
        endmethod
        method push takes integer value, integer maxValue returns nothing
            set epushThis = this
            set epushValue = value
            set epushMaxValue = maxValue
            call TriggerEvaluate(epusht)
        endmethod
        method pop takes integer maxValue returns integer
            return BigInt(this).divide(maxValue+1)
        endmethod
        method operator string takes nothing returns string
            set BigInt(this).base = this.baset
            return BigInt(this).toString()
        endmethod
        method destroy takes nothing returns nothing
            call BigInt(this).destroy()
        endmethod
        method operator remaining takes nothing returns integer
            return BigInt(this).toInt()
        endmethod
        
        implement NumberStackInit
    endstruct
endlibrary

//Insecure Save
/*****************************************************
//the passed in value is like an encryption key
//no repeated values allowed
//bigger this passed in value, smaller the code will be
local NumberStack c = NumberStack.create(Base["abcdefghijklmnopqrstuvwxyz"])

call c.push(10,10)  //push 10 on to stack
call c.push(20,20)  //push 20 on to stack
call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,c.string)

call c.destroy()
*****************************************************/

//Insecure Load
/*****************************************************
local NumberStack c = NumberStack.convert(GetEventPlayerChatString(),Base["abcdefghijklmnopqrstuvwxyz"])

call c.pop(20)      //20
call c.pop(10)      //10

call c.destroy()
*****************************************************/
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
//Requires
//  Scrambler       hiveworkshop.com/forums/submissions-414/snippet-salt-189766/
//  NumberStack     hiveworkshop.com/forums/1993458-post521.html
library EncryptNumber uses Scrambler, NumberStack
    /***********************************************************************
    *
    *   Security Details
    *
    *       -   Player Unique Base
    *       -   Player Unique Shuffling
    *
    ***********************************************************************
    *
    *   function EncryptNumber takes NumberStack stack, integer security, integer forPlayerId returns nothing
    *       -   Encrypts a BigInt given max security, shuffles, and player id
    *       
    *       ->  security is the maximum value the security can be. Bigger means more secure but larger codes.
    *       ->  6-7 digits is usually good here
    *       
    *       ->  security is how many times to shuffle the number (make it impossible to read it)
    *       ->  3 shuffles is recommended
    *       ->  if this function freezes the game for a while, lower the amount of shuffles
    *       
    *       ->  the player id is the id of the player to encrypt the value for (GetPlayerId(player))
    *
    *   function DecryptNumber takes string number, string encryptionKey, integer security, integer forPlayerId returns NumberStack
    *       -   Decrypts a BigInt given its base, security, shuffles, and player id
    *       -   Returns 0 if decryption failed
    *
    ***********************************************************************/
    globals
        private Table array bases
    endglobals
    private function GetPlayerBase takes Base base, integer pid returns Base
        local string b
        local BigInt i
        if (not bases[pid].has(base)) then
            set b = base.string
            set i = BigInt.convertString(base.string,Base[SubString(b,1,2)+SubString(b,0,1)+SubString(b,2,base.size)])
            call Scramble(i, pid, 3, i.base, true)
            set bases[pid][base] = Base[i.toString()]
            call i.destroy()
        endif
        return bases[pid][base]
    endfunction
    function EncryptNumber takes NumberStack number, integer security, integer forPlayerId returns nothing
        local BigInt checksum
        
        //apply player unique shuffle
        if (0 < security) then
            call Shuffle(number, forPlayerId, security)
        endif
        
        //get player unique base
        set number.internalBase = GetPlayerBase(number.internalBase, forPlayerId)
    endfunction
    function DecryptNumber takes string saveCode, Base base, integer security, integer forPlayerId returns NumberStack
        //convert to BigInt using player unique base
        local BigInt number
        set base = GetPlayerBase(base, forPlayerId)
        
        if (not base.isValid(saveCode)) then
            return 0
        endif
        
        set number = BigInt.convertString(saveCode, base)
        set number.base = 0
        
        //remove player unique shuffle
        if (0 < security) then
            call Unshuffle(number, forPlayerId, security)
        endif
        
        return number
    endfunction
    private module I
        private static method onInit takes nothing returns nothing
            local integer i=11
            loop
                set bases[i]=Table.create()
                exitwhen 0==i
                set i=i-1
            endloop
        endmethod
    endmodule
    private struct N extends array
        implement I
    endstruct
endlibrary
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
Someone else wrote this before and we argued that it wouldn't be useful for save/load, but with the above 2 scripts, I figured it would be useful. His was a bit different, including global constants. Mine uses pure locals for more dynamism.

It is better to color using BigInt digits directly, but since EncryptNumber returns a string this is now ok I suppose ;p.

JASS:
library ColorCodeString
    function ColorCodeString takes string s, string numColor, string lowerColor, string upperColor, string specColor, integer start returns string
        local string ns = ""
        local string c
        local integer m = StringLength(s)
        local integer i = start
        local boolean l
        loop
            exitwhen m == i
            
            set c = SubString(s,i,i+1)
            
            if (c!=" ") then
                set l=StringCase(c,false)==c
                
                //special or number
                if (c==StringCase(c,true) and l) then
                    //number
                    if ("0"==c or 0!=S2I(c)) then
                        set ns=ns+"|cff"+numColor+c
                    //special
                    else
                        set ns=ns+"|cff"+specColor+c
                    endif
                //lowercase
                elseif (l) then
                    set ns=ns+"|cff"+lowerColor+c
                //uppercase
                else
                    set ns=ns+"|cff"+upperColor+c
                endif
            else
                set ns=ns+" "
            endif
            
            set i = i + 1
        endloop
        return ns
    endfunction
endlibrary

Demo
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,ColorCodeString("1 n N !", "40e0d0", "ff69b4", "00AA00", "ffff00",0))
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library AddRepeatedString
    //adds a string to another string in spaced intervals
    //call AddRepeatedString(1234567,"-",3,0) -> 123-456-7
    function AddRepeatedString takes string s, string str, integer spacing, integer start returns string
        local integer i = StringLength(s)
        local integer p = 1
        loop
            exitwhen p*spacing+start>=i
            set s = SubString(s,0,p*spacing+p+start-1)+str+SubString(s,p*spacing+p+start-1,StringLength(s))
            set p=p+1
        endloop
        return s
    endfunction
endlibrary

call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,AddRepeatedString("123456712345671234567","-",4,0))
 
Last edited:
JASS:
if (c!=" ") then
                set l=StringCase(c,false)==c

FAIL! :p
I think you know what I'm talking about ;)
By the way, those lines are from "ColorCodeString"

JASS:
exitwhen p*spacing>=i

More Fail? :p

edit

In ColorCodeString:

exitwhen 0 == i

Moving that to the beginning of the loop would immediately exit if you were given an empty string :p


Offtopic: If I'm wrong, it's because I havent slept all night and it's 8 am at the moment.
 
But you still didnt fix the order of the comparisons :/
Variable reads are obviously slower than direct values:
if (c!=" ") then
->
if (" "!=c) then
Variable reads are faster than natives:
set l=StringCase(c,false)==c
->
set l=c==StringCase(c,false)

Variable reads are faster than operations:
exitwhen p*spacing>=i
->
exitwhen i<=p*spacing

:3

What happened to SpeedFreak-Nestharus? D:
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
I am sorry if I am wrong but...

Variable reads are obviously slower than direct values:
if (c!=" ") then
->
if (" "!=c) then
What
Variable reads are faster than natives:
set l=StringCase(c,false)==c
->
set l=c==StringCase(c,false)
the hell
Variable reads are faster than operations:
exitwhen p*spacing>=i
->
exitwhen i<=p*spacing
is the difference?You have to evaluate two sides of the comparasion anyway.

Btw here is my function which I wrote to get a job at blizzard.
JASS:
function IsEqualBJ takes integer firstNumber, integer secondNumber returns boolean
    local boolean result
    if GetBooleanOr(firstNumber < secondNumber, firstNumber > secondNumber) then
        set result = FALSE
        return result
    endif
    set result = TRUE
    return result
endfunction
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Nestharus said:
Someone else wrote this before and we argued that it wouldn't be useful for save/load, but with the above 2 scripts, I figured it would be useful. His was a bit different, including global constants. Mine uses pure locals for more dynamism.

I've never argued that it woudn't be useful for a save/load, pretty much the opposite.
And again i can't think about any real case where you would need dynamic colors instead of constant ones.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library SaveInventory /*
*************************************************************************************
*
*   Saves hero inventory
*
*************************************************************************************
*
*   */uses/*
*
*       */ NumberStack /*       hiveworkshop.com/forums/1993458-post521.html
*       */ Catalog /*           hiveworkshop.com/forums/jass-functions-413/snippet-catalog-192452/
*
************************************************************************************
*
*   function SaveInventory takes NumberStack stack, unit whichUnit, Catalog itemCatalog returns nothing
*
*   function LoadInventory takes NumberStack stack, unit whichUnit, Catalog itemCatalog returns nothing
*   function UnloadInventory takes unit whichUnit returns nothing
*
*   itemCatalog
*
*       Must pass a catalog of items. If doing hero specific inventories, pass in the catalog specific
*       to the hero. If doing more complex, go for a custom solution.
*
************************************************************************************/
    function SaveInventory takes NumberStack stack, unit whichUnit, Catalog itemCatalog returns nothing
        local integer inventorySize = UnitInventorySize(whichUnit)
        local integer itemSlot = 0
        local integer inventoryCount = 0
        local integer array items
        local integer catalogCount = itemCatalog.count
        
        //retrieve all non null items in inventory
        loop
            exitwhen inventorySize==itemSlot
            if (null!=UnitItemInSlot(whichUnit,itemSlot)) then
                set items[inventoryCount]=itemCatalog.id(GetItemTypeId(UnitItemInSlot(whichUnit,itemSlot)))
                if (0 != items[inventoryCount]) then
                    set inventoryCount=inventoryCount+1
                endif
            endif
            set itemSlot=itemSlot+1
        endloop
        
        //if there is an empty slot in inventory, push 0 on to stack (boolean)
        if (inventoryCount<inventorySize) then
            call stack.push(0,catalogCount)
        endif
        
        //push all non null items in inventory on to stack
        loop
            exitwhen 0==inventoryCount
            set inventoryCount=inventoryCount-1
            call stack.push(items[inventoryCount],catalogCount)
        endloop
    endfunction
    
    function LoadInventory takes NumberStack stack, unit whichUnit, Catalog itemCatalog returns nothing
        local integer inventorySize = UnitInventorySize(whichUnit)
        local integer itemSlot = 0
        local integer catalogCount = itemCatalog.count
        local integer loadItem
        loop
            exitwhen inventorySize==itemSlot
            set loadItem=stack.pop(catalogCount)
            exitwhen 0==loadItem
            call UnitAddItemToSlotById(whichUnit,itemCatalog.raw(loadItem),itemSlot)
            set itemSlot=itemSlot+1
        endloop
    endfunction
    
    function UnloadInventory takes unit whichUnit returns nothing
        local integer slot = UnitInventorySize(whichUnit)
        loop
            exitwhen 0 == slot
            set slot = slot - 1
            if (null != UnitItemInSlot(whichUnit, slot)) then
                call RemoveItem(UnitItemInSlot(whichUnit, slot))
            endif
        endloop
    endfunction
endlibrary
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library SaveItemCharges /*
*************************************************************************************
*
*   Saves item charges. If an item has no charge, no data is saved at all. If no
*   items in inventory have chages, then absolutely no data is saved. Can use this script
*   with absolutely no cost if the map does not yet have items with charges.
*
*   *************************************************************************************
*   *
*   *   these two tables must be created by the user
*   *   itemMaxChargeTable should have an integer signifying max item charges
*   *   itemPerishableTable should have a boolean signifying whether item is perishable or not
*   *
*   *   itemMaxChargeTable
*   *       ->      maxCharges[itemTypeId]=maxCharges
*   *
*   *   itemPerishableTable
*   *       ->      isPerishable[itemTypeId].boolean=true
*   *   
*   *************************************************************************************
*
*************************************************************************************
*
*   */uses/*
*
*       */ NumberStack /*       hiveworkshop.com/forums/1993458-post521.html
*       */ Table /*             hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
*
************************************************************************************
*
*   function SaveItemCharges takes NumberStack stack, unit whichUnit, Table itemMaxChargeTable, Table itemPerishableTable returns nothing
*   function LoadItemCharges takes NumberStack stack, unit whichUnit, Table itemMaxChargeTable, Table itemPerishableTable returns nothing
*
*   Basic Demos
*
*   ************************************************************************************
*   *
*   *   Table maxCharges = Table.create()
*   *   Table isPerishable = Table.create()
*   *
*   *   set maxCharges['item']=20
*   *   set isPerishable['item'].boolean=true
*   *
*   ************************************************************************************
*   *
*   *   call SaveItemCharges(stack,someUnit,maxCharges,isPerishable)
*   *
*   ************************************************************************************
*   *
*   *   call LoadItemCharges(stack,someUnit,maxCharges,isPerishable)
*   *
*   ************************************************************************************
*
************************************************************************************/
    function SaveItemCharges takes NumberStack stack, unit whichUnit, Table itemMaxChargeTable, Table itemPerishableTable returns nothing
        local integer inventorySize = UnitInventorySize(whichUnit)
        local integer itemSlot = 0
        local integer maxCharges = 0
        local integer itemTypeId
        local item currentItem
        local integer itemCount=0
        loop
            exitwhen itemSlot == inventorySize
            set currentItem=UnitItemInSlot(whichUnit,itemSlot)
            if (null!=currentItem) then
                set itemCount=itemCount+1
                set itemTypeId = GetItemTypeId(currentItem)
                set maxCharges = itemMaxChargeTable[itemTypeId]
                if (0<maxCharges) then
                    if (itemPerishableTable.boolean[itemTypeId]) then
                        if (1 < maxCharges) then
                            call stack.push(GetItemCharges(currentItem)-1,maxCharges-1)
                        endif
                    else
                        call stack.push(GetItemCharges(currentItem),maxCharges)
                    endif
                endif
            endif
            set itemSlot = itemSlot + 1
        endloop
        set currentItem=null
    endfunction
    
    function LoadItemCharges takes NumberStack stack, unit whichUnit, Table itemMaxChargeTable, Table itemPerishableTable returns nothing
        local integer inventorySize = UnitInventorySize(whichUnit)
        local integer itemSlot = 0
        local integer maxCharges = 0
        local integer itemTypeId
        local item currentItem
        loop
            exitwhen itemSlot == inventorySize
            set currentItem=UnitItemInSlot(whichUnit,itemSlot)
            if (null!=currentItem) then
                set itemTypeId = GetItemTypeId(currentItem)
                set maxCharges = itemMaxChargeTable[itemTypeId]
                if (0<maxCharges) then
                    if (itemPerishableTable.boolean[itemTypeId]) then
                        if (1 < maxCharges) then
                            call SetItemCharges(currentItem,stack.pop(maxCharges-1)+1)
                        endif
                    else
                        call SetItemCharges(currentItem,stack.pop(maxCharges))
                    endif
                endif
            endif
            set itemSlot = itemSlot + 1
        endloop
        set currentItem=null
    endfunction
endlibrary
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Btw here is my function which I wrote to get a job at blizzard.
JASS:
function IsEqualBJ takes integer firstNumber, integer secondNumber returns boolean
    local boolean result
    if GetBooleanOr(firstNumber < secondNumber, firstNumber > secondNumber) then
        set result = FALSE
        return result
    endif
    set result = TRUE
    return result
endfunction

This is great
 
is the difference?You have to evaluate two sides of the comparasion anyway.

There's a marginal speed difference (Either in all cases or in cases where there's a value like null, 0, or "".
Actually, we need to benchmark these.

JASS:
function IsEqualBJ takes integer firstNumber, integer secondNumber returns boolean
    local boolean result
    if GetBooleanOr(firstNumber < secondNumber, firstNumber > secondNumber) then
        set result = FALSE
        return result
    endif
    set result = TRUE
    return result
endfunction

Cool :)

I wrote this:

JASS:
function IsEqualBJ takes integer i, integer j returns boolean
    return i==j
endfunction

And they didnt hire me :'(


edit

This should help a lot of "vJASSers" :p

JASS:
library StructHelper
    // Just make your struct extend an array and use these textmacros like this:
    //
    // struct MyStruct extends array
    //     //! runtextmacro STRUCT_INDEX_DATA()
    //     unit blabla
    //     integer hi
    //     static method create takes nothing returns thistype
    //         // declare all your locals here
    //         //! runtextmacro STRUCT_ALLOC()
    //         call DoNothing() // lol..
    //         set .blabla = null
    //         set .hi = 23
    //         return this
    //     endmethod
    //     method destroy takes nothing returns nothing
    //         // null all your variables, etc..
    //         //! runtextmacro STRUCT_DEALLOC()
    //     endmethod
    // endstruct

    //! textmacro STRUCT_INDEX_DATA
        private static integer instanceCount = 0 // I dont want name collisions :/
        private static integer instanceRecycler = 0 // I dont want name collisions :/
        private thistype recycleNext // I still dont want name collsions :/ :S
    //! endtextmacro

    //! textmacro STRUCT_ALLOC
        local thistype this
        if 0==instanceRecycler then
            set instanceCount = instanceCount + 1
            set this = instanceCount
        else
            set this = instanceRecycler
            set instanceRecycler = .recycleNext
        endif
    //! endtextmacro

    //! textmacro STRUCT_DEALLOC
        set .recycleNext = instanceRecycler
        set instanceRecycler = this
    //! endtextmacro
endlibrary

Problem NormalStructs? *trollface*
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library GetMapMaxHeroLevel
    globals
        private integer m
    endglobals
    function GetMapMaxHeroLevel takes nothing returns integer
        return m
    endfunction
    private module N
        private static method onInit takes nothing returns nothing
            local unit u=CreateUnit(Player(15),'Hpal',0,0,0)
            call SetHeroLevel(u,6553,false)
            set m=GetHeroLevel(u)
            call RemoveUnit(u)
            set u=null
        endmethod
    endmodule
    private struct I extends array
        implement N
    endstruct
endlibrary
 
Last edited:
Because that's hardware-related.

That's right :D

---------

We still need to check if the same applies for:
null==someHandle
""==someString
:S

Oh and Nestharus:
JASS:
call SetHeroLevel(u,10000,true)

Could you test if this would work?
I once tried it but the unit would always stop at level 3751 (Even with the max level in the Gameplay constants set to 10000)
I bet it's cause blizzard does it with a loop >.<
That's likely why special effects are created for each level :/
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
SetHeroLevel is buggy. SetHeroLevel(6553) will set it to the max level. Anything above 6553 doesn't work. You have to set to 6553 (max level) and then strip to get down to correct level between 6553 and 10000.

JASS:
library SetHeroLevelX
    function SetHeroLevelX takes unit whichUnit, integer level returns nothing
        if (level<6553) then
            call SetHeroLevel(whichUnit,level,false)
        else
            call SetHeroLevel(whichUnit,6553,false)
            if (GetHeroLevel(whichUnit)!=level) then
                call UnitStripHeroLevel(whichUnit,GetHeroLevel(whichUnit)-level)
            endif
        endif
    endfunction
endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library SaveXP /*
*************************************************************************************
*
*   Saves hero level and hero xp
*
*************************************************************************************
*
*   */uses/*
*
*       */ NumberStack /*       hiveworkshop.com/forums/1993458-post521.html
*       */ optional UnitIndexer /*
*
************************************************************************************
*
*   function SaveHeroXP takes NumberStack stack, unit whichUnit, integer accuracy returns nothing
*   function LoadHeroXP takes NumberStack stack, unit whichUnit, integer accuracy returns nothing
*
*
*   Accuracy
*
*       Accuracy is how many decimals (up to 2)
*
*       accuracy          output
*       ------------------------
*              0              0%
*              1              5%
*              2             50%
*              3           50.0%
*              4          50.00%
*
************************************************************************************/
    globals
        private unit dummyUnit
        private integer maxLevel
    endglobals
    
    private function GetMaxXP takes integer level returns integer
        local integer xp
        
        call SetHeroLevel(dummyUnit, level+1, false)
        set xp = GetHeroXP(dummyUnit) - 1
        call UnitStripHeroLevel(dummyUnit, level+2)
        
        return xp
    endfunction
    private function GetMinXP takes integer level returns integer
        local integer xp
        
        if (1 == level) then
            return 0
        endif
        
        call SetHeroLevel(dummyUnit, level, false)
        set xp = GetHeroXP(dummyUnit)
        call UnitStripHeroLevel(dummyUnit, level+1)
        
        return xp
    endfunction
    
    private function SaveXP takes NumberStack stack, unit whichUnit, integer accuracy returns nothing
        local integer level = GetHeroLevel(whichUnit)
        local real max = Pow(10, accuracy)
        local integer maxi = R2I(max+.5)
        local integer minXp = GetMinXP(level)
        local integer maxXp = GetMaxXP(level) - minXp
        local integer xp = GetHeroXP(whichUnit) - minXp
        local integer percentXp = R2I((xp*max)/maxXp)
        
        call stack.push(percentXp, maxi)
    endfunction
    
    private function LoadXP takes NumberStack stack, unit whichUnit, integer accuracy returns nothing
        local integer level = GetHeroLevel(whichUnit)
        local real max = Pow(10, accuracy)
        local integer maxi = R2I(max+.5)
        local integer minXp = GetMinXP(level)
        local integer maxXp = GetMaxXP(level) - minXp
        local integer percentXp = stack.pop(maxi)
        local integer xp = R2I(percentXp*maxXp/max)
        
        call AddHeroXP(whichUnit, xp, false)
    endfunction
    
    function SaveHeroXP takes NumberStack stack, unit whichUnit, integer accuracy returns nothing
        if (GetHeroLevel(whichUnit) != maxLevel and 0 < accuracy) then
            call SaveXP(stack, whichUnit, accuracy)
        endif
        call stack.push(GetHeroLevel(whichUnit)-1,maxLevel-1)
    endfunction
    
    function LoadHeroXP takes NumberStack stack, unit whichUnit, integer accuracy returns nothing
        local integer level = stack.pop(maxLevel-1)+1
        
        if (level != 1) then
            call SetHeroLevel(whichUnit, level, false)
        endif
        
        if (level != maxLevel and 0 < accuracy) then
            call LoadXP(stack, whichUnit,accuracy)
        endif
    endfunction
    
    private module InitMod
        private static method onInit takes nothing returns nothing
            static if LIBRARY_UnitIndexer then
                set UnitIndexer.enabled = false
            endif
            set dummyUnit = CreateUnit(Player(15), 'Hpal', 0, 0, 270)
            call UnitAddAbility(dummyUnit, 'Aloc')
            call SetUnitPosition(dummyUnit, 64000, 64000)
            static if LIBRARY_UnitIndexer then
                set UnitIndexer.enabled = true
            endif
            
            call SetHeroLevel(dummyUnit, 10000, false)
            set maxLevel = GetHeroLevel(dummyUnit)
            
            call UnitStripHeroLevel(dummyUnit, 10001)
        endmethod
    endmodule
    private struct Init extends array
        implement InitMod
    endstruct
endlibrary
 
Last edited:
Top