library AdvancedAbilityAnimations initializer Init
// Created by Uncle
globals
private constant integer ALTERNATE_ABILITY_ID = 'AAAT'
// Define the ALTERNATE_ABILITY_ID to match the rawcode
// of the AAA_Has_Alternate_Tag ability, which you should have
// imported from the demo map. This is necessary if you plan
// on taking advantage of alternate animations.
private constant boolean DOES_USE_CAST_BACKSWING = true
// Define the DOES_USE_CAST_BACKSWING boolean.
// If any unit has an Art - Cast Backswing > 0.00 then
// keep this set to true. Otherwise, set it to false to
// make the system slightly more efficient.
////////////////////////////////////////////////////////
// STOP - Do NOT modify anything else below this line //
private hashtable hash = InitHashtable()
private unit caster
private integer abilityId
private integer timerHandle
private timer abilityTimer
// References to your AAA_ variables
private integer castAnim // animation index
private real castDuration // animation standard duration
private real castTime // animation desired duration
// KEYS in the Hashtable
private constant integer KEY_UNIT = 0
private constant integer KEY_ABIL = 1
private constant integer KEY_ANIM = 0
private constant integer KEY_DURATION = 1
private constant integer KEY_ANIM_ALT = 2
private constant integer KEY_DURATION_ALT = 3
private constant integer KEY_REGISTERED = 4
endglobals
private function StopCasting takes nothing returns nothing
set abilityId = GetSpellAbilityId()
// Return if this ability is not registered
if LoadBoolean(hash, abilityId, KEY_REGISTERED) == false then
return
endif
set caster = GetTriggerUnit()
call SetUnitTimeScale(caster, 1.0)
set abilityTimer = LoadTimerHandle(hash, GetHandleId(caster), 0)
if abilityTimer != null then
call FlushChildHashtable(hash, GetHandleId(abilityTimer))
call FlushChildHashtable(hash, GetHandleId(caster))
call DestroyTimer(abilityTimer)
endif
endfunction
private function BeginCastingCallback takes nothing returns nothing
set abilityTimer = GetExpiredTimer()
set timerHandle = GetHandleId(abilityTimer)
set caster = LoadUnitHandle(hash, timerHandle, KEY_UNIT)
if IsUnitType(caster, UNIT_TYPE_DEAD) or GetUnitTypeId(caster) == 0 then
return
endif
set abilityId = LoadInteger(hash, timerHandle, KEY_ABIL)
set castTime = BlzGetAbilityRealLevelField(BlzGetUnitAbility(caster, abilityId), ABILITY_RLF_CASTING_TIME, GetUnitAbilityLevel(caster, abilityId) - 1)
// Variables used to play the special cast animation
if GetUnitAbilityLevel(caster, udg_AAA__Alt_Ability) > 0 then
// It has the alternate animation tag
set castAnim = LoadInteger(hash, abilityId, KEY_ANIM_ALT)
if castAnim == 0 then
// It must have registered a string
call SetUnitAnimation(caster, LoadStr(hash, abilityId, KEY_ANIM_ALT))
else
call SetUnitAnimationByIndex(caster, castAnim)
endif
set castDuration = LoadReal(hash, abilityId, KEY_DURATION_ALT)
else
// It does not have an alternate animation tag
set castAnim = LoadInteger(hash, abilityId, KEY_ANIM)
call DisplayTextToPlayer(Player(0), 0, 0, "castAnim: " + I2S(castAnim))
if castAnim == 0 then
// It must have registered a string
call SetUnitAnimation(caster, LoadStr(hash, abilityId, KEY_ANIM))
else
call SetUnitAnimationByIndex(caster, castAnim)
endif
set castDuration = LoadReal(hash, abilityId, KEY_DURATION)
endif
// Avoid dividing by zero (castDuration should always be > 0 at this stage)
if castTime <= 0 then
set castTime = 0.01
endif
call SetUnitTimeScale(caster, castDuration / castTime)
call FlushChildHashtable(hash, timerHandle)
call FlushChildHashtable(hash, GetHandleId(caster))
call DestroyTimer(abilityTimer)
endfunction
private function BeginCasting takes nothing returns nothing
set abilityId = GetSpellAbilityId()
// Return if this ability is not registered
if LoadBoolean(hash, abilityId, KEY_REGISTERED) == false then
return
endif
set caster = GetTriggerUnit()
set abilityTimer = CreateTimer()
set timerHandle = GetHandleId(abilityTimer)
call SaveUnitHandle(hash, timerHandle, KEY_UNIT, caster)
call SaveInteger(hash, timerHandle, KEY_ABIL, abilityId)
call SaveTimerHandle(hash, GetHandleId(caster), 0, abilityTimer)
call TimerStart(abilityTimer, 0, false, function BeginCastingCallback)
endfunction
////////////
// [JASS] //
////////////
// Note: A value of -1 or a "" string ignores those animation options!
function AAA_Register takes integer abilId, integer animIndex, string animString, real abilDuration returns nothing
if abilDuration <= 0 then
call DisplayTextToPlayer(Player(0), 0, 0, "[AAA Error] Ability " + GetAbilityName(abilId) + " was not registered! abilDuration must be > 0.")
return
endif
if animString != "" then
call SaveStr(hash, abilId, KEY_ANIM, animString)
call SaveReal(hash, abilId, KEY_DURATION, abilDuration)
elseif animIndex > -1 then
call SaveInteger(hash, abilId, KEY_ANIM, animIndex)
call SaveReal(hash, abilId, KEY_DURATION, abilDuration)
endif
// Mark this ability as registered
call SaveBoolean(hash, abilId, KEY_REGISTERED, true)
endfunction
function AAA_Register_Alt takes integer abilId, integer animIndex, string animString, real abilDuration returns nothing
if abilDuration <= 0 then
call DisplayTextToPlayer(Player(0), 0, 0, "[AAA Error] Ability " + GetAbilityName(abilId) + " was not registered! abilDuration must be > 0.")
return
endif
if animString != "" then
call SaveStr(hash, abilId, KEY_ANIM_ALT, animString)
call SaveReal(hash, abilId, KEY_DURATION_ALT, abilDuration)
elseif animIndex > -1 then
call SaveInteger(hash, abilId, KEY_ANIM_ALT, animIndex)
call SaveReal(hash, abilId, KEY_DURATION_ALT, abilDuration)
endif
// Mark this ability as registered
call SaveBoolean(hash, abilId, KEY_REGISTERED, true)
endfunction
///////////
// [GUI] //
///////////
function AAA_Register_Ability takes nothing returns nothing
local integer id = udg_AAA__Abil_Type
if udg_AAA__Anim_Duration <= 0 then
call DisplayTextToPlayer(Player(0), 0, 0, "[AAA Error] Ability " + GetAbilityName(id) + " was not registered! Anim_Duration must be > 0.")
return
endif
if udg_AAA__Anim_Index > -1 then
call SaveInteger(hash, id, KEY_ANIM, udg_AAA__Anim_Index)
call SaveReal(hash, id, KEY_DURATION, udg_AAA__Anim_Duration)
elseif udg_AAA__Anim_String != "" then
call SaveStr(hash, id, KEY_ANIM, udg_AAA__Anim_String)
call SaveReal(hash, id, KEY_DURATION, udg_AAA__Anim_Duration)
endif
// A value of -1 represents unused
if udg_AAA__Anim_Index_Alt > -1 then
call SaveInteger(hash, id, KEY_ANIM_ALT, udg_AAA__Anim_Index_Alt)
call SaveReal(hash, id, KEY_DURATION_ALT, udg_AAA__Anim_Duration_Alt)
elseif udg_AAA__Anim_String_Alt != "" then
call SaveStr(hash, id, KEY_ANIM_ALT, udg_AAA__Anim_String_Alt)
call SaveReal(hash, id, KEY_DURATION_ALT, udg_AAA__Anim_Duration_Alt)
endif
// Mark this ability as registered
call SaveBoolean(hash, id, KEY_REGISTERED, true)
// Reset variables to unused state
set udg_AAA__Anim_Index = -1
set udg_AAA__Anim_Index_Alt = -1
set udg_AAA__Anim_String = ""
set udg_AAA__Anim_String_Alt = ""
endfunction
private function Init takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
// The ability used to determine alternate animations
set udg_AAA__Alt_Ability = ALTERNATE_ABILITY_ID
// A value of -1 represents unused
set udg_AAA__Anim_Index = -1
set udg_AAA__Anim_Index_Alt = -1
set udg_AAA__Anim_String = ""
set udg_AAA__Anim_String_Alt = ""
call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_SPELL_CHANNEL)
call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_SPELL_ENDCAST)
// Art - Cast Backswing may need to be accounted for (if > 0.00)
if DOES_USE_CAST_BACKSWING then
call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_SPELL_EFFECT)
endif
call TriggerAddAction(t1, function BeginCasting)
call TriggerAddAction(t2, function StopCasting)
set t1 = null
set t2 = null
endfunction
endlibrary