HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

hook game crash

09-30-2009, 03:09 PM#1
Cheezeman
Hello!
So I made this custom module to help me pause a unit without stacking issues.
I think you can figure out what it does by looking at it

However, this is the first time I'm using the hook syntax (is it called that?), and whenever it's used the game crash without an error message.
Here it is;
Collapse JASS:
    globals
        private hashtable Hash
    endglobals

    function StopUnit takes unit u, boolean flag returns nothing
        local integer i = LoadInteger( Hash, 0, GetHandleId( u ) )
        call BJDebugMsg( "stop" )
        if flag then
            call SaveInteger( Hash, 0, GetHandleId( u ), i + 1 )
            call PauseUnit( u, true )
        else
            call SaveInteger( Hash, 0, GetHandleId( u ), i - 1 )
            if i - 1 <= 0 then
                call RemoveSavedInteger( Hash, 0, GetHandleId( u ) )
                call PauseUnit( u, false )
            endif
        endif
    endfunction
    hook PauseUnit StopUnit

P.S I've tried placing the hook both above and below the function
09-30-2009, 03:30 PM#2
Hans_Maulwurf
Do you set Hash = InitHashtable()?
09-30-2009, 03:35 PM#3
Skater
Quote:
Originally Posted by Cheezeman
Hello!
So I made this custom module to help me pause a unit without stacking issues.
I think you can figure out what it does by looking at it

However, this is the first time I'm using the hook syntax (is it called that?), and whenever it's used the game crash without an error message.
Here it is;
Collapse JASS:
    globals
        private hashtable Hash
    endglobals

    function StopUnit takes unit u, boolean flag returns nothing
        local integer i = LoadInteger( Hash, 0, GetHandleId( u ) )
        call BJDebugMsg( "stop" )
        if flag then
            call SaveInteger( Hash, 0, GetHandleId( u ), i + 1 )
            call PauseUnit( u, true )
        else
            call SaveInteger( Hash, 0, GetHandleId( u ), i - 1 )
            if i - 1 <= 0 then
                call RemoveSavedInteger( Hash, 0, GetHandleId( u ) )
                call PauseUnit( u, false )
            endif
        endif
    endfunction
    hook PauseUnit StopUnit

P.S I've tried placing the hook both above and below the function
I think those calls are also replaced with 'StopUnit'
09-30-2009, 03:36 PM#4
Viikuna-
Infinitive Loop maybe? Or is that blocked in these hook thingies?

edit. Damn, Skater was faster.

Well, anyways, just get unit indexing system and use some PauseUnitEx.

Something like this:

Collapse JASS:
if boolean then
    if PauseInteger[ unitId] == 0 then
        call PauseUnit(unit, true)
    endif
    set PauseInteger[ unitId] = PauseInteger[unitId] + 1
else
    if PauseInteger[unitId] == 1 then
        set PauseInteger[ unitId] = 0
        call PauseUnit(unit,false)
    else
    set PauseInteger[ unitId] = PauseInteger[unitId] - 1
    endif
endif
09-30-2009, 03:56 PM#5
Cheezeman
@Hans
Yes I initialize it

@Skater
Damn this is probably it... Is there any solution?

@Viikuna
Wouldn't that still mean the user of my spell have to replace all his PauseUnit() with PauseUnitEx(), correct?
09-30-2009, 07:59 PM#6
Viikuna-
Yep, but thats why custom functions exist.

I personally never really understood whats so cool about hooking natives, when you can do same thing with a custom functions.
09-30-2009, 08:14 PM#7
Cheezeman
Well, what I'm trying to do is kinda stupid but I'm trying to protect the user from himself;
If my spell unpause a unit that should still be paused (from another spell), it's a problem. The hook will fix that, without any effort from the map maker.

This is however a minor problem, since a map maker should be able to take care of himself and change all PauseUnit() natives into StopUnit().

I say that hooked natives inside 'hooking' functions should remain unchanged, but what's my opinion worth here anyway...

If anyone's interested (probably not) in my module here it is;
Expand JASS:
09-30-2009, 08:24 PM#8
Viikuna-
Dont bother. Just make your spell with normal pausing.

When people import stuff spells to their maps, they have to edit them anyways to get them working together with maps systems, so they can as well replace PauseUnit with PauseUnitEx.

If mapmaker doesnt have PauseUnitEx in his map, he deserves to get bugs. What you need to do, is mention all this in your spells comments, so people know that this problem exists.

If someone someday releases some pack with PauseUnitEx, SetUnitInvulnerableEx, SetUnitPathingEx and others, and this pack gets aproved, you can update your spell to use that pack.

edit. Well, actually, dont wait. Go and release a pack like that yourself. Its only a few minutes work to do.

edit2. And oh yea. Im not even sure about if there is something like this already. Havent checkd yet.
09-30-2009, 09:24 PM#9
Hans_Maulwurf
Sorry, I couldn't test it, but could you take a look at this:
Collapse JASS:
    globals
        private hashtable Hash
        private boolean AntiLoop
    endglobals
    
    function StopUnit takes unit u, boolean flag returns nothing
    if not AntiLoop then
        local integer i = LoadInteger( Hash, 0, GetHandleId( u ) )
        if flag then
            if i == 0 then
                set AntiLoop = true
                call PauseUnit( u, true )
                set AntiLoop = false
            endif
            call SaveInteger( Hash, 0, GetHandleId( u ), i + 1 )
        else
            call SaveInteger( Hash, 0, GetHandleId( u ), i - 1 )
            if i - 1 <= 0 then
                call RemoveSavedInteger( Hash, 0, GetHandleId( u ) )
                set AntiLoop = true
                call PauseUnit( u, false )
                set AntiLoop = false
            endif
        endif
    endif
    endfunction

hook PauseUnit StopUnit

should work
10-01-2009, 07:14 AM#10
TheWye
I'm sorry if this is out of topic, but... what is hook? I tried looking for it in the vJass manual but I can't seem to find it.. I searched for it in the forums as well but I don't find anything useful...

Again, apologies...
10-01-2009, 07:25 AM#11
Cheezeman
if you hook a native (like "hook GetTriggerUnit MyCustomFunction") it will replace all GetTriggerUnit in the map with MyCustomFunction.

I'm checking out Hans_Maulwurf's script now

Yes, Viikuna, it should be simple. But it'll require alot of updates with new function replacments all the time
I'll see what I can do.

----Edit
Hans; you've successfully prevented the endless loop, but the PauseUnit native is still worthless (it just creates an integer and checks if the loop should run)

----Edit
I wrote this in about 15min, any more natives I should add?
Expand JASS:
10-01-2009, 09:48 AM#12
Viikuna-
Well, you should use integer arrays and unit indexing system for getting indexes, since its faster than playing with hashtables.

Also, adding multiple instances of same ability to unit is usually needed, but then again, people can use the native in that case, since this doesnt take anything away from them which is kinda cool and everything...

Yea, actually, you could make both Unitindexing and hashtable versions and submit them both, so people can just pick a one and use it.

edit. That anti loop thingy is actually kinda cool. Maybe it could be useful for some people who have too many PauseUnit calls in their map to be replaced or something.
10-01-2009, 11:44 AM#13
saw792
Collapse JASS:
    globals
        private hashtable Hash
    endglobals

    function StopUnit takes unit u, boolean flag returns nothing
        local integer i = LoadInteger( Hash, 0, GetHandleId( u ) )
        call BJDebugMsg( "stop" )
        if flag then
            call SaveInteger( Hash, 0, GetHandleId( u ), i + 1 )
            //call PauseUnit( u, true )
        else
            call SaveInteger( Hash, 0, GetHandleId( u ), i - 1 )
            if i - 1 <= 0 then
                call RemoveSavedInteger( Hash, 0, GetHandleId( u ) )
                set flag = false
                //call PauseUnit( u, false )
            else
              return
            endif
        endif
    endfunction
    hook PauseUnit StopUnit

Will that work?
10-01-2009, 03:57 PM#14
Cheezeman
Viikuna
Hm... will it be like timerutils which has a blue and red flavor?
And that addabilitystack was meant in cases like you want to add 25% evasion to all units in aoe, and then remove it unless another instance of the spell is running.
You can easily do this kind of custom system for yourself, but hey, what are modules made for anyway...

----Edit
And I just found a mayor error in that section of the code...
Here's the new version
Expand JASS:


saw792
That problem was discovered in the second post...
10-01-2009, 07:57 PM#15
Bobo_The_Kodo
Quote:
Collapse JASS:
    function UnitAddAbilityStack takes unit u, integer abil_id returns nothing
        local integer i = LoadInteger( Hash, ADD_ABIL_KEY, GetHandleId( u ) )
        if i == 0 then
            call UnitAddAbility( u, abil_id )
        endif
        call SaveInteger( Hash, ADD_ABIL_KEY, GetHandleId( u ), i + 1 )
    endfunction
    
    function UnitRemoveAbilityStack takes unit u, integer abil_id returns nothing
        local integer i = LoadInteger( Hash, ADD_ABIL_KEY, GetHandleId( u ) )
        call SaveInteger( Hash, ADD_ABIL_KEY, GetHandleId( u ), i - 1 )
        if i - 1 <= 0 then
            call RemoveSavedInteger( Hash, ADD_ABIL_KEY, GetHandleId( u ) )
            call UnitRemoveAbility( u, abil_id )
        endif
    endfunction
Fail ><