| 09-30-2009, 03:09 PM | #1 |
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; 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 |
Do you set Hash = InitHashtable()? |
| 09-30-2009, 03:35 PM | #3 | |
Quote:
|
| 09-30-2009, 03:36 PM | #4 |
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: 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 |
@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 |
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 |
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; JASS://=========================================================================== //== //== PauseUtils //== ¯¯¯¯¯¯¯¯¯¯¯ //== Written by Cheezeman //== //== This module lets you pause and unpause a unit just like normally, //== but without having to worry about the stacking issues //== with normal PauseUnit() (where you can pause a unit a million times //== but only one unpause is sufficient) //== //== call StopUnit( unit whichUnit, boolean flag ) //== True pauses the unit like normally, while false atempts to //== unpause the unit, which isn't possible if the unit is affected //== by other pauses (a.k.a. its pause-referance is not 0) //== //== call ResetUnit( unit whichUnit ) //== Unpauses the unit and resets its pause-referance meter //== //== ____________________ //== I Version 1.0 I //== I Made by Cheezeman I //== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ //=========================================================================== library PauseUtils initializer Init globals private hashtable Hash endglobals function StopUnit takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, 0, GetHandleId( u ) ) if flag then if i == 0 then call PauseUnit( u, true ) 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 ) ) call PauseUnit( u, false ) endif endif endfunction function ResetUnit takes unit u returns nothing call RemoveSavedInteger( Hash, 0, GetHandleId( u ) ) call PauseUnit( u, false ) endfunction private function Init takes nothing returns nothing set Hash = InitHashtable() endfunction endlibrary |
| 09-30-2009, 08:24 PM | #8 |
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 |
Sorry, I couldn't test it, but could you take a look at this: 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 |
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 |
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? JASS://=========================================================================== //== //== StackingUtils //== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ //== Written by Cheezeman //== //== This module lets you use many natives, but without having to worry //== about if it'll stack or not. //== For example; You have two abilities that pauses a unit over time. The //== unit will be unpause when the first spell's duration runs out, no matter //== what. //== What do you do? //== You replace PauseUnit() with PauseUnitStack() //== There are many natives included in this pack, some more useful than the //== others //== //== Natives //== ¯¯¯¯¯¯¯ //== call PauseUnitStack( unit whichUnit, boolean flag ) //== call ShowUnitStack( unit whichUnit, boolean flag ) //== call SetUnitPathingStack( unit whichUnit, boolean flag ) //== call SetUnitInvulnerableStack( unit whichUnit, boolean flag ) //== //== call SetUnitExplodedStack( unit whichUnit, boolean flag ) //== call SetUnitUseFoodStack( unit whichUnit, boolean flag ) //== call UnitAddAbilityStack( unit whichUnit, integer abilityId ) //== call UnitRemoveAbilityStack( unit whichUnit, integer abilityId ) //== //== ____________________ //== I Pack 1.0 I //== I Made by Cheezeman I //== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ //=========================================================================== library StackingUtils initializer Init globals private hashtable Hash private constant integer PAUSE_KEY = 0 private constant integer HIDE_KEY = 1 private constant integer INVURN_KEY = 2 private constant integer EXPLODE_KEY = 3 private constant integer SUPPLY_KEY = 4 private constant integer COLLISION_KEY = 5 private constant integer ADD_ABIL_KEY = 6 endglobals //=========================================================================== function PauseUnitStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, PAUSE_KEY, GetHandleId( u ) ) if flag then if i == 0 then call PauseUnit( u, true ) endif call SaveInteger( Hash, PAUSE_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, PAUSE_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, PAUSE_KEY, GetHandleId( u ) ) call PauseUnit( u, false ) endif endif endfunction //=========================================================================== function ShowUnitStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, HIDE_KEY, GetHandleId( u ) ) if flag then if i == 0 then call ShowUnit( u, true ) endif call SaveInteger( Hash, HIDE_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, HIDE_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, HIDE_KEY, GetHandleId( u ) ) call ShowUnit( u, false ) endif endif endfunction //=========================================================================== function SetUnitInvulnerableStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, INVURN_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitInvulnerable( u, true ) endif call SaveInteger( Hash, INVURN_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, INVURN_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, INVURN_KEY, GetHandleId( u ) ) call SetUnitInvulnerable( u, false ) endif endif endfunction //=========================================================================== function SetUnitExplodedStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, EXPLODE_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitExploded( u, true ) endif call SaveInteger( Hash, EXPLODE_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, EXPLODE_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, EXPLODE_KEY, GetHandleId( u ) ) call SetUnitExploded( u, false ) endif endif endfunction //=========================================================================== function SetUnitUseFoodStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, SUPPLY_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitUseFood( u, true ) endif call SaveInteger( Hash, SUPPLY_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, SUPPLY_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, SUPPLY_KEY, GetHandleId( u ) ) call SetUnitUseFood( u, false ) endif endif endfunction //=========================================================================== function SetUnitPathingStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, COLLISION_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitPathing( u, true ) endif call SaveInteger( Hash, COLLISION_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, COLLISION_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, COLLISION_KEY, GetHandleId( u ) ) call SetUnitPathing( u, false ) endif endif endfunction //=========================================================================== 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 //=========================================================================== private function Init takes nothing returns nothing set Hash = InitHashtable() endfunction endlibrary |
| 10-01-2009, 09:48 AM | #12 |
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 |
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 |
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 JASS://=========================================================================== //== //== StackingUtils //== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ //== Written by Cheezeman //== //== This module lets you use many natives, but without having to worry //== about if it'll stack or not. //== For example; You have two abilities that pauses a unit over time. The //== unit will be unpause when the first spell's duration runs out, no matter //== what. //== What do you do? //== You replace PauseUnit() with PauseUnitStack() //== There are many natives included in this pack, some more useful than the //== others //== //== Natives //== ¯¯¯¯¯¯¯ //== call PauseUnitStack( unit whichUnit, boolean flag ) //== call ShowUnitStack( unit whichUnit, boolean flag ) //== call SetUnitPathingStack( unit whichUnit, boolean flag ) //== call SetUnitInvulnerableStack( unit whichUnit, boolean flag ) //== //== call SetUnitExplodedStack( unit whichUnit, boolean flag ) //== call SetUnitUseFoodStack( unit whichUnit, boolean flag ) //== call UnitAddAbilityStack( unit whichUnit, integer abilityId ) //== call UnitRemoveAbilityStack( unit whichUnit, integer abilityId ) //== //== ____________________ //== I Pack 1.1 I //== I Made by Cheezeman I //== ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ //=========================================================================== library StackingUtils initializer Init globals private hashtable Hash private constant integer PAUSE_KEY = 0 private constant integer HIDE_KEY = 1 private constant integer INVURN_KEY = 2 private constant integer EXPLODE_KEY = 3 private constant integer SUPPLY_KEY = 4 private constant integer COLLISION_KEY = 5 private constant integer ADD_ABIL_KEY = 6 endglobals //=========================================================================== function PauseUnitStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, PAUSE_KEY, GetHandleId( u ) ) if flag then if i == 0 then call PauseUnit( u, true ) endif call SaveInteger( Hash, PAUSE_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, PAUSE_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, PAUSE_KEY, GetHandleId( u ) ) call PauseUnit( u, false ) endif endif endfunction //=========================================================================== function ShowUnitStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, HIDE_KEY, GetHandleId( u ) ) if flag then if i == 0 then call ShowUnit( u, true ) endif call SaveInteger( Hash, HIDE_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, HIDE_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, HIDE_KEY, GetHandleId( u ) ) call ShowUnit( u, false ) endif endif endfunction //=========================================================================== function SetUnitInvulnerableStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, INVURN_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitInvulnerable( u, true ) endif call SaveInteger( Hash, INVURN_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, INVURN_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, INVURN_KEY, GetHandleId( u ) ) call SetUnitInvulnerable( u, false ) endif endif endfunction //=========================================================================== function SetUnitExplodedStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, EXPLODE_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitExploded( u, true ) endif call SaveInteger( Hash, EXPLODE_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, EXPLODE_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, EXPLODE_KEY, GetHandleId( u ) ) call SetUnitExploded( u, false ) endif endif endfunction //=========================================================================== function SetUnitUseFoodStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, SUPPLY_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitUseFood( u, true ) endif call SaveInteger( Hash, SUPPLY_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, SUPPLY_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, SUPPLY_KEY, GetHandleId( u ) ) call SetUnitUseFood( u, false ) endif endif endfunction //=========================================================================== function SetUnitPathingStack takes unit u, boolean flag returns nothing local integer i = LoadInteger( Hash, COLLISION_KEY, GetHandleId( u ) ) if flag then if i == 0 then call SetUnitPathing( u, true ) endif call SaveInteger( Hash, COLLISION_KEY, GetHandleId( u ), i + 1 ) else call SaveInteger( Hash, COLLISION_KEY, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, COLLISION_KEY, GetHandleId( u ) ) call SetUnitPathing( u, false ) endif endif endfunction //=========================================================================== function UnitAddAbilityStack takes unit u, integer abil_id returns nothing local integer i = LoadInteger( Hash, abil_id, GetHandleId( u ) ) if i == 0 then call UnitAddAbility( u, abil_id ) endif call SaveInteger( Hash, abil_id, GetHandleId( u ), i + 1 ) endfunction function UnitRemoveAbilityStack takes unit u, integer abil_id returns nothing local integer i = LoadInteger( Hash, abil_id, GetHandleId( u ) ) call SaveInteger( Hash, abil_id, GetHandleId( u ), i - 1 ) if i - 1 <= 0 then call RemoveSavedInteger( Hash, abil_id, GetHandleId( u ) ) call UnitRemoveAbility( u, abil_id ) endif endfunction //=========================================================================== private function Init takes nothing returns nothing set Hash = InitHashtable() endfunction endlibrary saw792 That problem was discovered in the second post... |
| 10-01-2009, 07:57 PM | #15 | |
Quote:
|
