Name | Type | is_array | initial_value |
TAabi | abilcode | No | |
TAabiLvl | integer | No | |
TAattachPoint | string | No | |
TAbuff | buffcode | No | |
TAbuffCheckDelay | real | No | |
TAduration | real | No | |
TAeffect | string | No | |
TAremoveOnDeath | boolean | No | |
TAunit | unit | No |
//TESH.scrollpos=3
//TESH.alwaysfold=0
//--------------------------------------------------------------------------------------
library TimedAbility // v.1.1 by ZibiTheWand3r3r. Allows to add an ability to unit for given duration.
//--------------------------------------------------------------------------------------
// API
// nothing UnitAddTimedAbility(unit <u>, integer <abiId>, integer <abiLevel>, real <duration>,
// boolean <removeOnDeath>, integer <buffId>, real <delay>, string <eff>, string <attachmentPoint>)
// additional function (for one-level ability & without checking for buff & without effect):
// nothing UnitAddTimedAbility_Simple(unit <u>, integer <abiId>, real <duration>, boolean <removeOnDeath>)
//
// If unit already has ability <abiId> then this library will:
// overwrite ability level / duration / effect - if previously added <abiId> comes from this library
// overwrite ability level - if <abiId> do not comes from this library
// it will set-back to old level (coming from non-library ability) after instance expires
// If <buffId> is specified and there's no buff on unit <u> - instance will be ended.
// Checking for buff begins after <delay> value (sec); <delay> should be >=0.00
// Use <buffId>==0 and <delay>==0.00 to not checking for a buff.
// Use <eff>==null and <attachmentPoint>==null to not play speccial effect on unit <u>
//
// Do not use with hero-ability if this ability is used as normal, level-able ability by any hero in your map.
//--------------------------------------------------------------------------------------
native UnitAlive takes unit id returns boolean
//--------------------------------------------------------------------------------------
globals
private constant boolean DEBUG = true
private constant real INTERVAL = 0.10
private integer maxId = 0
private unit array instTarget
private integer array instAbilityId
private real array instDuration
private boolean array instRemoveWhenUnitDies
private integer array instBuffId
private real array instBuffCheckDelay
private integer array instCounter
private boolean array instBuffSet
private effect array instEffect
private integer array externalAbiLevel
private timer t = CreateTimer()
endglobals
//-----------------------------------------------------------
private function Loop takes nothing returns nothing
local integer id=1
loop
exitwhen id>maxId
if instBuffSet[id] then
set instCounter[id] = instCounter[id] - 1
if instCounter[id] <= 0 and (GetUnitAbilityLevel(instTarget[id], instBuffId[id])==0) then
set instDuration[id]=0.00
endif
endif
set instDuration[id] = instDuration[id] - INTERVAL
if instDuration[id] <= 0.00 or (instRemoveWhenUnitDies[id] and (not UnitAlive(instTarget[id]))) then
static if DEBUG then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "ABI instance ended " + GetObjectName(instAbilityId[id]) + " on unit " + GetUnitName(instTarget[id]))
endif
//---
call DestroyEffect(instEffect[id])
if externalAbiLevel[id]==0 then //remove ability
call UnitRemoveAbility(instTarget[id], instAbilityId[id])
else // set back to old level
call SetUnitAbilityLevel(instTarget[id], instAbilityId[id], externalAbiLevel[id])
endif
//---
//dealloc: /move data from max to current/
set instTarget[id] = instTarget[maxId]
set instAbilityId[id] = instAbilityId[maxId]
set instDuration[id] = instDuration[maxId]
set instRemoveWhenUnitDies[id] = instRemoveWhenUnitDies[maxId]
set instBuffId[id] = instBuffId[maxId]
set instBuffCheckDelay[id] = instBuffCheckDelay[maxId]
set instCounter[id] = instCounter[maxId]
set instBuffSet[id] = instBuffSet[maxId]
set instEffect[id] = instEffect[maxId]
set externalAbiLevel[id] = externalAbiLevel[maxId]
//clean:
set instTarget[maxId]=null
set instEffect[maxId]=null
//---
set maxId=maxId-1
set id=id-1
if maxId==0 then
call PauseTimer(t)
endif
endif
set id=id+1
endloop
endfunction
//----------------------------------------------------------------------------------------------
private function Update takes unit u, integer abiId, integer abiLevel, real duration, string eff, string attachmentPoint returns boolean
local integer id=1
loop
exitwhen id>maxId
if u==instTarget[id] and abiId==instAbilityId[id] then
set instDuration[id] = duration //overwrite duration
call SetUnitAbilityLevel(u, abiId, abiLevel) //overwrite ability level
//overwrite effect:
call DestroyEffect(instEffect[id])
if not (eff==null or attachmentPoint==null or eff=="" or attachmentPoint=="") then
set instEffect[id] = AddSpecialEffectTarget(eff, u, attachmentPoint)
endif
//---
static if DEBUG then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetUnitName(u) +" updated duration/level/efect on ability "+ GetObjectName(abiId))
endif
return true
endif
set id=id+1
endloop
return false
endfunction
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
function UnitAddTimedAbility takes unit u, integer abiId, integer abiLevel, real duration, boolean removeOnDeath, integer buffId, real delay, string eff, string attachmentPoint returns nothing
local integer oldLevel = GetUnitAbilityLevel(u, abiId) //remember ability level
if oldLevel>0 and Update(u, abiId, abiLevel, duration, eff, attachmentPoint) then
return //has ability [from this library] and ability was updated succefully
endif
set maxId = maxId + 1
set instTarget[maxId] = u
set instAbilityId[maxId] = abiId
set instDuration[maxId] = duration
set instRemoveWhenUnitDies[maxId] = removeOnDeath
set instBuffId[maxId] = buffId
set instBuffCheckDelay[maxId] = delay
set instCounter[maxId] = 0
if delay>0.00 then
set instCounter[maxId] = R2I(delay/INTERVAL) + 1 //for delayed check buff
endif
set instBuffSet[maxId] = (buffId != 0)
set instEffect[maxId] = null
if not (eff==null or attachmentPoint==null or eff=="" or attachmentPoint=="") then
set instEffect[maxId] = AddSpecialEffectTarget(eff, u, attachmentPoint)
endif
set externalAbiLevel[maxId] = oldLevel
call UnitAddAbility(u, abiId)
call SetUnitAbilityLevel(u, abiId, abiLevel)
if maxId==1 then
call TimerStart(t, INTERVAL, true, function Loop)
endif
endfunction
//---------------------------------------------------------------------------
function UnitAddTimedAbility_Simple takes unit u, integer abiId, real duration, boolean removeOnDeath returns nothing
call UnitAddTimedAbility(u, abiId, 1, duration, removeOnDeath, 0, 0.00, null, null)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_ef_Actions takes nothing returns nothing
local string ef="Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl"
local string ef1="Abilities\\Spells\\Other\\FrostDamage\\FrostDamage.mdl"
local unit u = gg_unit_Emoo_0004
call UnitAddTimedAbility(u, 'AHbz', 3, 25.00, true, 'BHad', 1.50, ef, "overhead")
call UnitAddTimedAbility(u, 'A002', 2, 25.00, false, 0, 0.00, ef1, "origin")
call UnitAddTimedAbility_Simple(u, 'AItg', 15.00, true)
endfunction
//===========================================================================
function InitTrig_esc takes nothing returns nothing
set gg_trg_esc = CreateTrigger( )
call TriggerRegisterPlayerEventEndCinematic( gg_trg_esc, Player(0) )
call TriggerAddAction( gg_trg_esc, function Trig_ef_Actions )
endfunction