| 06-17-2009, 05:17 PM | #1 |
This is a script I wrote for temporarily adding abilites to units. I would like feedback or possible bugs pointed out. Thanks! JASS:library TimedAbility initializer Init needs Table,TimerUtils globals //=========================================== // This is a sort of Chaining Hash implementation. // // For each pair (abitype,unit) added to the system, a struct is created. // The table binds the structs to the unit, and the abitype is found through // chainsearching / listing through the structs belonging to that unit. //=========================================== private HandleTable tbl endglobals //========================================================= // Struct Data // Contains data, and also serves as list item. //========================================================= private struct Data unit u timer t integer abi // For list implementation Data next static method create takes unit u returns Data local Data d2 local Data d = Data.allocate() set d.u=u set d.next=0 set d2=Data(tbl[u]) if d2!=0 then set d.next=d2 endif set tbl[u]=d return d endmethod method onDestroy takes nothing returns nothing local Data d2 = Data(tbl[.u]) // Is this first in the list? if d2==this then // Does the list have more Data? if .next!=0 then set tbl[.u]=.next else // This was the only data in the list call tbl.flush(.u) endif else // Not first in list // Find previous data. loop exitwhen d2.next == this set d2=d2.next endloop // link previous to next set d2.next=.next endif set .u=null set .t=null endmethod endstruct //========================================================= private function End takes nothing returns nothing local Data d=Data(GetTimerData(GetExpiredTimer())) // If unit is not removed. if GetUnitTypeId(d.u)!=0 then call UnitRemoveAbility(d.u,d.abi) endif call d.destroy() call ReleaseTimer(GetExpiredTimer()) endfunction public function Add takes unit u, integer abicode, integer level, real duration returns nothing local Data d if GetUnitAbilityLevel(u,abicode) > 0 then // Unit is already affected! set d = Data(tbl[u]) loop // This is to prevent users from doing stupid things. // I won't even put 'debug' around it, since stupid // things would cause the game to crash. if d==0 then call BJDebugMsg("TimedAbility: The ability "+GetObjectName(abicode)+" was added to "+GetUnitName(u)+", but not from this system.") return endif // Find the data that points to our ability. exitwhen d.abi==abicode set d=d.next endloop // Reset the existing timer. call TimerStart(d.t,duration,false,function End) else // Unit is not previously affected. // Create timer. call UnitAddAbility(u,abicode) set d=Data.create(u) set d.t=NewTimer() set d.abi=abicode call SetTimerData(d.t,d) call TimerStart(d.t,duration,false,function End) endif // Everything went well. Set the desired level. call SetUnitAbilityLevel(u,abicode,level) endfunction //========================================================= private function Init takes nothing returns nothing set tbl=HandleTable.create() endfunction endlibrary |
