• 🏆 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 17
Joined
Apr 27, 2008
Messages
2,455
You can still have a trigger whic execute himself inside his action, kinda the same.
Worse, it's even a common error from newbies (using a trigger action which fire again the same event while they don't disable the trigger.

(i suppose it's flood time, i join the party)
 
Level 13
Joined
Mar 16, 2008
Messages
941
This is probably similar, but not good enough :p

  • CrashGUI
    • Events
      • Unit - A unit Gains a level
    • Conditions
    • Actions
      • Custom script: local unit u = GetTriggerUnit()
      • Custom script: call SetHeroLevel(u,GetHeroLevel(u)+1,true)
      • Custom script: set u = null
I bet that this trigger stops at max-level, what would cause something between 9-49 executions (level 10-50 like used in most maps).
If you want a more complex way use a typical damage-detection mistake ;)
 
I bet that this trigger stops at max-level, what would cause something between 9-49 executions (level 10-50 like used in most maps).
If you want a more complex way use a typical damage-detection mistake ;)

Then how about this:

  • Crash
    • Events
      • Unit - Lich King 0058 <gen> Takes damage
    • Conditions
    • Actions
      • Custom script: local unit u = GetTriggerUnit()
      • Custom script: call UnitDamageTarget(u,u,1.0,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
      • Custom script: set u = null
 
Just to get this thread back on-topic:

JASS:
library ReviveDestructables requires TimerUtils
    globals
        private constant real DELAY = 10.0
        private constant boolean SHOW_BIRTH = false
        private constant trigger TRIG = CreateTrigger()
    endglobals
    
    private module Init
        static method add takes nothing returns nothing
            call TriggerRegisterDeathEvent(TRIG,GetEnumDestructable())
        endmethod
        static method filter takes nothing returns boolean
            return true
        endmethod
        private static method onInit takes nothing returns nothing
            local rect r = Rect(-32256,-32256,32256,32256)
            call EnumDestructablesInRect(r,function thistype.filter,function thistype.add)
            call TriggerAddCondition(TRIG,Condition(function thistype.run))
            call RemoveRect(r)
            set r = null
        endmethod
    endmodule
    
    private struct Destructables
        destructable d
        method destroy takes nothing returns nothing
            set .d = null
            call .deallocate()
        endmethod
        static method expire takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype this = GetTimerData(t)
            call DestructableRestoreLife(.d,GetDestructableMaxLife(.d),SHOW_BIRTH)
            call ReleaseTimer(t)
            call .destroy()
            set t = null
        endmethod
        static method run takes nothing returns boolean
            local thistype this = thistype.allocate()
            local timer t = NewTimer()
            set .d = GetTriggerDestructable()
            call SetTimerData(t,this)
            call TimerStart(t,DELAY,false,function thistype.expire)
            set t = null
            return false
        endmethod
        implement Init
    endstruct
endlibrary
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
JASS:
function SaveTheTread takes nothing returns resource

   local resource lasthope = UsefulUnapprovedResource[GetRandomInt(1,1337)]
   if resource == null then
      call KillStarcraft2()
      call BackTo2007()
   endif
   return lasthope

endfunction
 
Here's a zLoc library.
This way, you could avoid creating multiple zLoc's.

JASS:
library ZLoc
    struct zLoc extends array
        private static location zLoc
        static method move takes real x, real y returns nothing
            call MoveLocation(thistype.zLoc,x,y)
        endmethod
        static method getZ takes nothing returns real
            return GetLocationZ(thistype.zLoc)
        endmethod
        private static method onInit takes nothing returns nothing
            set thistype.zLoc = Location(0,0)
        endmethod
    endstruct
endlibrary
 
Last edited:

BBQ

BBQ

Level 4
Joined
Jun 7, 2011
Messages
97
Here's a zLoc library.
This way, you could avoid creating multiple zLoc's.

JASS:
library ZLoc
    struct zLoc extends array
        readonly static location zLoc
        static method move takes real x, real y returns nothing
            call MoveLocation(thistype.zLoc,x,y)
        endmethod
        static method getZ takes nothing returns real
            return GetLocationZ(thistype.zLoc)
        endmethod
    endstruct
endlibrary

You forgot to create the location...
 
Level 13
Joined
Mar 16, 2008
Messages
941
Is there ANY reason to use structs and two methods?
Since the location is private the move method does nothing unless you use the getZ method while getZ is useless without move.
Wouldnt a library like this fit it much more?
JASS:
library ZLoc
    globals
        private location z = Location(0, 0)
    endglobals
    
    function GetPointZ takes real x, real y returns real
        call MoveLocation(z, x, y)
        return GetLocationZ(z)
    endfunction
endlibrary
 
Last edited:
Level 20
Joined
Jul 6, 2009
Messages
1,885
You could also add GetUnitZ
JASS:
library Z
    globals
        private location z = Location(0, 0)
    endglobals
    
    function GetPointZ takes real x, real y returns real
        call MoveLocation(z, x, y)
        return GetLocationZ(z)
    endfunction

    function GetUnitZ takes unit u returns real
        return GetPointZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u)
    endfunction
endlibrary
 
Why are you guys under the impression that GetPointZ will inline? It is two lines, and for JassHelper/optimizer inlining to take place it must be 1 line.

Well, if you're sure about it... :p
This only proves that my API is much better :D
Thanks for backing me up Bribe :)
Oh and Garfield, with your function, the final library would look like this:

JASS:
library ZLoc
    globals
        private location z = Location(0,0)
    endglobals
    struct ZLoc extends array
        static method move takes real x, real y returns nothing
            call MoveLocation(z,x,y)
        endmethod
        static method getZ takes nothing returns real
            return GetLocationZ(z)
        endmethod
        implement optional UnitZ
    endstruct
endlibrary

Plugin:
JASS:
module UnitZ
    static method getUnitZ takes unit u returns real
        call thistype.move(GetUnitX(u),GetUnitY(u))
        return GetUnitFlyHeight(u) + thistype.getZ()
    endmethod
    static method setUnitZ takes unit u, real h returns nothing
        call SetUnitFlyHeight(u,h-(thistype.getUnitZ(u)+GetUnitFlyHeight(u)),0)
    endmethod
endmodule

edit

If you don't like OO APIs:

JASS:
library ZLoc
    globals
        private location z = Location(0,0)
    endglobals
    function MoveZ takes real x, real y returns nothing
        call MoveLocation(z,x,y)
    endfunction
    function GetZ takes nothing returns real
        return GetLocationZ(z)
    endfunction
    function GetUnitZ takes unit u returns real
        call MoveZ(GetUnitX(u),GetUnitY(u))
        return GetUnitFlyHeight(u) + GetZ()
    endfunction
    function SetUnitZ takes unit u, real h returns nothing
        call SetUnitFlyHeight(u,h-(GetUnitZ(u)+GetUnitFlyHeight(u)),0)
    endfunction
endlibrary

edit
I think a SetUnitZ would be appropriate here.. hmmm... Let me think..
 
Last edited:
There are plenty of Z-based libraries out there. The thing that makes your library so unique is that yours is the first one built that is inline friendly (worth using)

How could someone go wrong with a ZLoc library =P
Do you think I should add a SetUnitZ function?
MoveZ and GetZ would inline, but GetUnitZ and SetUnitZ wouldn't ... actually, no.. SetUnitZ will inline, but GetUnitZ wouldn't :p
JASS:
function SetUnitZ takes unit u, real h returns nothing
    call SetUnitFlyHeight(u,h-(GetUnitZ(u)+GetUnitFlyHeight(u)),0)
endfunction
That would inline nicely :)
I think adding it would be best :D
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
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.parent.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.parent.right=child
	endif
	set child.right=node
	set node.parent=child
endmethod
 
Last edited:
Meh, because of jass integer limit it would be better to just use an array (initialized at map init)

The factorial of 15 is already too big xD

lol xD xD
If only WC3 was 64-bit :p
Actually, nvm because even it were then the max value would be Factorial(20) xD xD

I could use BigInt for this :p

Here's a BigInt version:

JASS:
library Factorial requires BigInt

    function Factorial takes integer i returns BigInt
        local BigInt k = BigInt.convertString("1",Base["0123456789"])
        if i<=0 then
            call k.destroy()
            return BigInt.convertString("0",Base["0123456789"])
        endif
        loop
            exitwhen i<=1
            call k.multiply(i)
            set i=i-1
        endloop
        return k
    endfunction

endlibrary
 
Last edited:
Level 19
Joined
Feb 4, 2009
Messages
1,313
why multiply with 1?
also for bigger values you could use an approximation
I remember something like
Code:
sqrt(2.0*pi*n)*(n/e)^n*(1.0+1.0/(12.0*n))
seems to be quite accurate
http://www.wolframalpha.com/input/?i=plot+abs%28sqrt%282pi*n%29*%28n%2Fe%29^n*%281%2B1%2F%2812*n%29%29-n!%29%2Fn!+with+n+from+1+to+1000
there should be even more accurate approximations but I guess this is enough


for n up to 20 it won't make much of a difference though

edit:
of course there is an article about it on wikipedia
http://en.wikipedia.org/wiki/Stirling's_approximation#Speed_of_convergence_and_error_estimates

with integers you won't get past ~15
with reals it works up to ~35

I once required binomial coefficients for a bezier curve function and got a huge speed boost from buffering results
since it won't work past 35 in this case it makes sense to do it here as well so you can have very accurate results (reals cut half of the accuracy anyway) with just one array lookup

a class for floating point numbers would benefit from this most
but who needs that for wc3 (unless someone wants to make bezier curves with lots of control points)
 
Last edited:
I tried

Sqrt(2*pi*n) * (n/e)^n

For 3! , I got ~5.83

Hmmm....
Maybe your solution could work with reals :p

I'll make 2 versions of the Factorial function:

- Accurate & Slow
- Approximate & Fast

I'll edit this post with the new library in a minute :p

edit
I tried it again for 3! with your first formula and I got ~5.88

edit

Unfortunately, we don't have a BigFloat library and the BigInt library doesn't support the function SquareRoot :p

JASS:
library Factorial requires BigInt
    globals
        private constant real TWOPI = 6.2831853
        private constant real E     = 2.718282
        private Base b10
    endglobals
    
    // Limited to 35! but very fast
    function Factorial takes integer i returns real
        return SquareRoot(TWOPI*i)*Pow(i/E,i)
    endfunction
    
    // Slow but accurate
    // Limited to 2728!
    function BigFactorial takes integer i returns BigInt
        local BigInt k = BigInt.convertString("1",b10)
        if i<=0 then
            call k.destroy()
            return BigInt.convertString("0",b10)
        endif
        loop
            exitwhen i<=1
            call k.multiply(i)
            set i=i-1
        endloop
        return k
    endfunction

    private module Init
        private static method onInit takes nothing returns nothing
            set b10 = Base["0123456789"]
        endmethod
    endmodule
    private struct Inits extends array
        implement Init
    endstruct    
endlibrary
 
Last edited:
Top