Добавлен Hodor,
опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Прочее
Тип:
Способность
Версия Warcraft:
1.26
Spirit Breaker прямо из доты 6.83d
СПИСОК ИСПРАВЛЕНИЙ
ChargeOfDarkness :
Теперь можно изучать прямо во время разбега или перезарядки способности
Теперь можно изучать прямо во время разбега или перезарядки способности
EmpoweringHaste :
Теперь не сбивает текущий приказ и не проигрывает анимацию spell morph
(но сбивает ChargeOfDarkness)
Сделано на основе "Стремительность", вместо "Берсерк"!
Теперь не сбивает текущий приказ и не проигрывает анимацию spell morph
(но сбивает ChargeOfDarkness)
Сделано на основе "Стремительность", вместо "Берсерк"!
NetherStrike :
При получении стана или если цель далеко убежит, то способность автоматически отменяется
При получении стана или если цель далеко убежит, то способность автоматически отменяется
Написано на vJass с define из cJass
Почти у каждой функции есть комментарий того, что делает функция
Все используемые абилки и т.д лежат в константах у каждой библиотеки
DotA
library DotA initializer DotaInit
globals
hashtable udg_dotaHash = InitHashtable()
timer udg_dotaTimer = CreateTimer()
region global_region //Регион в котором не будет работать отталкивание юнита от GreaterBash
endglobals
private function DotaInit takes nothing returns nothing
set global_region = CreateRegion()
//В регион надо добавлять области в которых не будет работать отталкивание юнита от GreaterBash
//Пример:
//call RegionAddRect( global_region, bj_mapInitialPlayableArea )
call TimerStart( udg_dotaTimer, 99999.00, false, null )
endfunction
endlibrary
DestroyTrigger
library DestroyTriggerEx initializer InitDestroyTrigger requires DotA
globals
private trigger array triggers
private real array time
private integer count = 0
endglobals
private function ErrorMsg takes nothing returns nothing
//Выводит сообщение об ошибке
local integer i = 0
loop
call DisplayTimedTextToPlayer(Player(i), 0, 0, 120, "|c00ff0303An internal checksum has failed|r" )
set i = i+1
exitwhen i == 12
endloop
endfunction
function DestroyTriggerEx takes trigger trg returns nothing
//Добавляет триггер в очередь для удаления
call DisableTrigger( trg )
set count = count+1
set triggers[count] = trg
set time[count] = TimerGetElapsed(udg_dotaTimer)+60
if count > 8000 then
call ErrorMsg()
endif
endfunction
private function ClearQueue takes integer i returns nothing
if i != count then
set triggers[i] = triggers[count]
set time[i] = time[count]
endif
set triggers[count] = null
set time[count] = 0
set count = count-1
endfunction
private function DestroyTrigger_Actions takes nothing returns boolean
local real r = TimerGetElapsed(udg_dotaTimer)
local integer i
set i = 1
loop
exitwhen i > count
if time[i] < r then
if triggers[i] == null or IsTriggerEnabled(triggers[i]) == true then
call ErrorMsg()
else
call DestroyTrigger( triggers[i] )
endif
call ClearQueue( i )
else
set i = i + 1
endif
endloop
return false
endfunction
private function InitDestroyTrigger takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterTimerEvent( trg, 15, true )
call TriggerAddCondition( trg, Condition(function DestroyTrigger_Actions) )
endfunction
endlibrary
Recycle
library Recycle initializer InitRecycle requires DotA
globals
private group array groups
private boolean array groupIsUsed
private boolean error = false
private integer firstGroupHandleId = 0
private integer number = 0
private real errorTime = 0.
private string errorText = ""
endglobals
private function Display takes nothing returns nothing
call DisplayTimedTextToPlayer( GetEnumPlayer(), 0, 0, errorTime, errorText )
endfunction
private function DisplayError takes force f, real r, string s returns nothing
set errorText = s
set errorTime = r
call ForForce( f, function Display )
endfunction
function RecycleGroup takes group g returns nothing
//Функция очищает группу и делает её доступной для повторного использования
local integer i = GetHandleId(g)-firstGroupHandleId
if i < 0 or i > 120 then
set error = true
else
call GroupClear( g )
set groupIsUsed[i] = false
set number = i
endif
endfunction
function GetGroup takes nothing returns group
//Возвращает доступную для использования группу
local integer i = number
loop
exitwhen i == number-1
if groupIsUsed[i] == false then
set number = i+1
if number == 120 then
set number = 0
endif
set groupIsUsed[i] = true
return groups[i]
endif
set i = i+1
if i == 120 then
set i = 0
endif
endloop
call DisplayError( bj_FORCE_ALL_PLAYERS, 5.00, "|c00ff0303CRITICAL ERROR: FOUND NO AVAILABLE GROUPS|r" )
return CreateGroup()
endfunction
function RecycleCheck takes nothing returns boolean
//Проверка на количество групп которые в данный момент используются
local integer groupCount = 0
local integer i = 0
loop
exitwhen i == 120
if groupIsUsed[i] == true then
set groupCount = groupCount+1
endif
set i = i+1
endloop
if groupCount > 100 or error then
call DisplayError( bj_FORCE_ALL_PLAYERS, 5.00, I2S(groupCount) )
endif
return false
endfunction
private function InitRecycle takes nothing returns nothing
local integer i = 0
set number = 0
set groups[i] = CreateGroup()
set groupIsUsed[i] = false
set i = i+1
set firstGroupHandleId = GetHandleId( groups[0] )
loop
exitwhen i == 120
set groups[i] = CreateGroup()
set groupIsUsed[i] = false
set i = i+1
endloop
endfunction
endlibrary
OtherFunctions
library OtherFunctions requires DotA, DestroyTriggerEx, Recycle
globals
private integer destroyedDestructables = 0 //Нужно для подсчета уничтоженных разрушаемых объектов
define
Spellcaster = 'e00E' //Spellcaster
PreloaderHero = 'H00Y' //Preloader Hero
Marker = 'A04R' //Marker
enddefine
endglobals
function BlockAbility takes unit u returns boolean
//Здесь нужно указывать все бафы которые могут блокировать одну направленную способность
//Пример:
//return GetUnitAbilityLevel(u, 'B0BI') > 0 or GetUnitAbilityLevel(u, 'BNss') > 0
return false
endfunction
private function BashOn takes nothing returns boolean
//Включает срабатывание GreaterBash при атаке юнита
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
call SaveInteger( udg_dotaHash, GetHandleId( LoadUnitHandle(udg_dotaHash, trgH, 14) ), LoadInteger(udg_dotaHash, trgH, 33 ), 2 )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
set trg = null
return false
endfunction
function BashOff takes unit u, integer i, real r returns nothing
//Выключает срабатывание GreaterBash при атаке юнита (не влияет на GreaterBash от способностей)
local trigger trg = CreateTrigger()
call TriggerAddCondition( trg, Condition(function BashOn) )
call TriggerRegisterTimerEvent( trg, r, false )
call SaveInteger ( udg_dotaHash, GetHandleId(u) , i , 1 )
call SaveUnitHandle( udg_dotaHash, GetHandleId(trg) , 14 , u )
call SaveInteger ( udg_dotaHash, GetHandleId(trg) , 33 , i )
set trg = null
endfunction
function IsDestructable takes destructable d returns boolean
//Здесь нужно указывать все деревья и разрушаемые объекты, которые могут быть в карте
return GetDestructableTypeId(d) == 'NTtc' or GetDestructableTypeId(d) == 'NTtw' or GetDestructableTypeId(d) == 'ATtr' or GetDestructableTypeId(d) == 'LTlt'
endfunction
function DamageToUnit takes unit attacker, unit target, integer i, real damage returns nothing
//Нанесение урона
if i == 0 then
return
endif
if i == 1 then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_NORMAL , DAMAGE_TYPE_FIRE , WEAPON_TYPE_WHOKNOWS )
elseif i == 2 then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_HERO , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS )
elseif i == 3 then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_HERO , DAMAGE_TYPE_MAGIC , WEAPON_TYPE_WHOKNOWS )
elseif i == 4 then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_PIERCE , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS )
elseif i == 5 then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_NORMAL , DAMAGE_TYPE_NORMAL , WEAPON_TYPE_WHOKNOWS )
elseif i == 6 then
call SetUnitState( target, UNIT_STATE_LIFE, RMaxBJ( GetUnitState(target, UNIT_STATE_LIFE)-damage, 1 ) )
if GetUnitState( target, UNIT_STATE_LIFE ) < 2 then
call UnitRemoveBuffs( target, true,true )
//call UnitRemoveAbility( target, 'Aetl' )
call UnitDamageTarget( CreateUnit(GetOwningPlayer(attacker), Spellcaster, 0, 0, 0), target, 100000000.00, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
endif
elseif i == 7 then
//В этом if нужно указывать способности имея которые юнит получает больше магического урона
//Оригинал:
//if GetUnitAbilityLevel(target, 'Aetl') > 0 or GetUnitAbilityLevel(target, 'B01N') > 0 then
if false then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_HERO, DAMAGE_TYPE_MAGIC , WEAPON_TYPE_WHOKNOWS )
else
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNIVERSAL , WEAPON_TYPE_WHOKNOWS )
endif
elseif i == 8 then
call UnitDamageTarget( attacker, target, damage, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS )
endif
endfunction
function SafeRealX takes real x returns real
//Чтобы X не выходила за пределы карты, иначе - вернет значение недалеко от границы игровой карты
local real r = GetRectMinX(bj_mapInitialPlayableArea)+50
if x < r then
return r
endif
set r = GetRectMaxX(bj_mapInitialPlayableArea)-50
if x > r then
return r
endif
return x
endfunction
function SafeRealY takes real y returns real
//Чтобы Y не выходила за пределы карты, иначе - вернет значение недалеко от границы игровой карты
local real r = GetRectMinY(bj_mapInitialPlayableArea)+50
if y < r then
return r
endif
set r = GetRectMaxY(bj_mapInitialPlayableArea)-50
if y > r then
return r
endif
return y
endfunction
function AbilityInit takes integer i returns nothing
local unit u = CreateUnit( Player(15), PreloaderHero, 0, 0, 270 )
call UnitAddAbility( u, i )
call UnitRemoveAbility( u, i )
call RemoveUnit( u )
set u = null
endfunction
function DistanceBetweenUnits takes unit u_1, unit u_2 returns real
//Возвращает расстояние между координатами юнитов
local real x1 = GetUnitX( u_1 )
local real y1 = GetUnitY( u_1 )
local real x2 = GetUnitX( u_2 )
local real y2 = GetUnitY( u_2 )
if u_1 == null or u_2 == null then
return I2R(9999999999)
else
return SquareRoot( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) )
endif
return 1.0
endfunction
function DistanceBetweenCoordinates takes real x1, real y1, real x2, real y2 returns real
//Возвращает расстояние между координатами
return SquareRoot( ((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)) )
endfunction
function AngleBetweenUnits takes unit u_1, unit u_2 returns real
//Возвращает угол между юнитами
return bj_RADTODEG*Atan2( GetUnitY(u_2)-GetUnitY(u_1), GetUnitX(u_2)-GetUnitX(u_1) )
endfunction
function AnyUnitEvent takes trigger trg, playerunitevent whichEvent returns nothing
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent( trg, Player(i), whichEvent, null )
set i = i+1
exitwhen i == 16
endloop
endfunction
function KillDestructables_Actions takes nothing returns nothing
if IsDestructable(GetEnumDestructable()) and IsDestructableAliveBJ(GetEnumDestructable()) then
set destroyedDestructables = destroyedDestructables + 1
call KillDestructable( GetEnumDestructable() )
endif
endfunction
function KillDestructables takes real x, real y, real radius returns integer
//Уничтожение деревьев или декораций, которые мешают
//Например если отменить ChargeOfDarkness возле деревьев
//Или юнит-цель в момент столкновения будет находиться возле деревьев
local rect r = Rect( x-radius, y-radius, x+radius, y+radius )
set destroyedDestructables = 0
call EnumDestructablesInRect( r, null, function KillDestructables_Actions )
call RemoveRect( r )
set r = null
//Возвращает количество уничтоженных разрушаемых объектов
return destroyedDestructables
endfunction
function AddAbility takes unit u, integer i returns nothing
call UnitAddAbility( u, i )
call UnitMakeAbilityPermanent( u, true, i )
endfunction
function IfUnitExist takes unit u returns boolean
//Проверка, существует юнит или он мертв
return GetUnitTypeId(u) < 1 or IsUnitType(u, UNIT_TYPE_DEAD) == true
endfunction
function IfHaveStopBuff takes unit u returns boolean
//Здесь нужно указывать все бафы имея которые ChargeOfDarkness сбивается
//Пример:
//return (GetUnitAbilityLevel(u, 'B00H') > 0) or (GetUnitAbilityLevel(u, 'BOhx') > 0)
return false
endfunction
function IfHavePauseOrBuff takes unit u returns boolean
//Проверка, находится ли юнит в паузе или имеет баф который останавливает применение способности
return IfHaveStopBuff( u ) or IsUnitPaused( u )
endfunction
function Ancient_Exception takes unit u returns boolean
//Юниты с классификацией "Древо" игнорируются поиском цели
//Но эта функция делает исключение для некоторых юнитов с этой классификацией
local integer i = GetUnitTypeId(u)
//Пример:
//return i == 'n004' or i == 'n01G' or i == 'n01C' or i == 'n018'
return false
endfunction
function CheckUnit takes nothing returns boolean
//Проверка на враждебность двух юнитов и на то чтобы GetFilterUnit() не был зданием или дамми юнитом
return IsUnitEnemy(global_caster, GetOwningPlayer(GetFilterUnit()) ) and (GetUnitAbilityLevel( GetFilterUnit(), Marker ) == 0 and IsUnitType( GetFilterUnit(), UNIT_TYPE_STRUCTURE ) == false and IfUnitExist(GetFilterUnit()) == false) and (IsUnitType( GetFilterUnit() ,UNIT_TYPE_ANCIENT ) == false or Ancient_Exception(GetFilterUnit()))
endfunction
endlibrary
SpellcasterRemove
library SpellcasterRemove initializer InitSpellcasterRemove requires OtherFunctions
define
Spellcaster = 'e00E' //Spellcaster
enddefine
private function SpellcasterRemove_Actions takes nothing returns nothing
local unit u = GetEnteringUnit()
//if GetUnitTypeId( GetEnteringUnit()) == 'e00E' or GetUnitTypeId(GetEnteringUnit()) == 'e022' then
if GetUnitTypeId( u ) == Spellcaster then
call ShowUnit( u, false )
call SetUnitPathing( u, false )
call SetUnitInvulnerable( u, true )
call UnitApplyTimedLife( u, 'BTLF', 20.00 )
endif
set u = null
endfunction
private function InitSpellcasterRemove takes nothing returns nothing
local trigger trg = CreateTrigger( )
call TriggerRegisterEnterRectSimple( trg, bj_mapInitialPlayableArea )
call TriggerAddCondition( trg, Condition(function SpellcasterRemove_Actions) )
set trg = null
endfunction
endlibrary
ChargeOfDarkness
library ChargeOfDarkness initializer InitChargeOfDarkness requires OtherFunctions, GreaterBash
globals
private real find_distance = 0.00 //Нужно для сравнивания расстояний, чтобы найти ближайшего юнита (если target умрет)
unit global_caster = null //Используется в FindFilter и CheckUnit(OtherFunctions)
private unit foundUnit = null //Ближайший юнит к умершему target, это нужно чтобы caster находил новую цель при разбеге (если target умрет)
private unit darkness_caster = null
private unit darkness_target = null
private integer darkness_abilityLvl = 0 //Непонятная integer, нигде не используется
private group group_NotBash //Эта группа нужна чтобы на юнитов не накладывался GreaterBash, когда caster бежит
define
SwapAbilityContainer = 'A003' //SwapAbilityContainer
Cooldown = 'A312' //Charge of Darkness (on cooldown)
ChargeOfDarknessAbility = 'A1P8' //Charge of Darkness
EmpoweringHasteAbility = 'A004' //Empowering Haste
NetherStrikeAbility = 'A0G4' //Nether Strike
NetherStrikeUpgrade = 'A1D8' //Nether Strike Upgrade
GreaterBashAbility = 'A0G5' //Greater Bash
AttributeBonus = 'Aamk' //Attribute Bonus
Marker = 'A04R' //Marker
ChargeOfDarknessAddBuff = 'A24L' //Charge of Darkness Add Buff
ChargeOfDarknessBuff = 'B0ED' //Charge of Darkness (buff)
SpellImmunity = 'A179' //Spell Immunity
Spellcaster = 'e00E' //Spellcaster
ChargeOfDarknessStun = 'A0GS' //Charge of Darkness Stun
GrandMagus = 'E02X' //Grand Magus (Rubick)
VisionDummy = 'o00Q' //Vision Dummy
Generic_Stun = 'A0X6' //Generic_Stun
enddefine
endglobals
private function Cooldown_Remove takes nothing returns boolean
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId ( trg )
local unit u = LoadUnitHandle( udg_dotaHash, trgH, 2 )
call UnitRemoveAbility( u, Cooldown )
call UnitRemoveAbility( u, SwapAbilityContainer )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
set trg = null
set u = null
return false
endfunction
private function Cooldown_Start takes unit u returns nothing
//Эта функция запускает триггер который через 12 секунд уберет перезарядку у способности
local trigger trg
local integer trgH
if IfUnitExist(u) == true then
call UnitRemoveAbility( u, Cooldown )
call UnitRemoveAbility( u, SwapAbilityContainer )
else
set trg = CreateTrigger()
set trgH = GetHandleId( trg )
call TriggerRegisterDeathEvent( trg, u )
call TriggerRegisterTimerEvent( trg, 12, false )
call TriggerAddCondition( trg, Condition(function Cooldown_Remove) )
call SaveUnitHandle( udg_dotaHash, trgH, 2, u )
endif
set trg = null
endfunction
private function ChargeOfDarkness_Bash takes nothing returns nothing
//Если на пути кастера находятся юниты, то на них кидается GreaterBash
//
//Строки if IsUnitInGroup( GetEnumUnit(), group_NotBash ) == false then
//call GroupAddUnit( group_NotBash, GetEnumUnit() )
//Отвечают за то, чтобы GreaterBash повторно не кидался на юнитов
if IsUnitInGroup( GetEnumUnit(), group_NotBash ) == false then
call GroupAddUnit( group_NotBash, GetEnumUnit() )
call GreaterBash( darkness_caster, GetEnumUnit(), false, true )
endif
endfunction
private function OrderCheck takes integer i returns boolean
//Проверка на приказ, это нужно чтобы ChargeOfDarkness не сбивался если менять вещи в инвентаре
if i == ChargeOfDarknessAbility or i == EmpoweringHasteAbility or i == NetherStrikeAbility or i == NetherStrikeUpgrade or i == GreaterBashAbility or i == AttributeBonus then
return true
endif
if i == 852002 or i == 852003 or i == 852004 or i == 852005 or i == 852006 or i == 852007 then
return true
endif
if i > 1000000 then
return true
endif
return false
endfunction
private function FindFilter takes nothing returns boolean
//Функция поиска ближайшего юнита
if (IsUnitEnemy( global_caster, GetOwningPlayer(GetFilterUnit()) ) and (GetUnitAbilityLevel( GetFilterUnit(), Marker ) == 0 and IsUnitType( GetFilterUnit(), UNIT_TYPE_STRUCTURE ) == false and IfUnitExist( GetFilterUnit() ) == false) and (IsUnitType( GetFilterUnit(), UNIT_TYPE_ANCIENT ) == false or Ancient_Exception(GetFilterUnit()) ) ) and IsUnitVisible( GetFilterUnit(), GetOwningPlayer(darkness_caster) ) == true then
if DistanceBetweenUnits( darkness_target, GetFilterUnit() ) < find_distance then
set find_distance = DistanceBetweenUnits( darkness_target, GetFilterUnit() )
set foundUnit = GetFilterUnit()
endif
endif
return false
endfunction
private function Find takes unit caster, unit target returns unit
//Поиск ближайшей цели, если target умрет
local group g = GetGroup()
set global_caster = caster
set darkness_caster = caster
set foundUnit = null
set find_distance = 999999
set darkness_target = target
call GroupEnumUnitsInRange( g, GetUnitX(target), GetUnitY(target), 4000, Condition(function FindFilter) )
call RecycleGroup( g )
set g = null
return foundUnit
endfunction
private function ChargeOfDarkness_Move takes nothing returns boolean
//Главная функция, отвечает за движение, ручную остановку способности и прочее
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local unit target = LoadUnitHandle( udg_dotaHash, trgH, 17 )
local unit dummy = LoadUnitHandle( udg_dotaHash, trgH, 19 )
local integer abilityLvl = LoadInteger( udg_dotaHash, trgH, 5 )
local real moveReal = (550+50*abilityLvl)*0.02
local real casterX = LoadReal( udg_dotaHash, trgH, 23 )
local real casterY = LoadReal( udg_dotaHash, trgH, 24 )
local real PolarProjectionX
local real PolarProjectionY
local real moveAngle
local real distanceBetweenCasterAndTarget
local string effectString
local group g
if (GetTriggerEventId() == EVENT_WIDGET_DEATH and GetTriggerUnit() == caster) or GetTriggerEventId() == EVENT_UNIT_ISSUED_ORDER or GetTriggerEventId() == EVENT_UNIT_ISSUED_POINT_ORDER or GetTriggerEventId() == EVENT_UNIT_ISSUED_TARGET_ORDER or IfHavePauseOrBuff(caster) or LoadReal(udg_dotaHash, trgH, 442) < TimerGetElapsed(udg_dotaTimer) then
if (GetTriggerEventId() != EVENT_UNIT_ISSUED_ORDER and GetTriggerEventId() != EVENT_UNIT_ISSUED_POINT_ORDER and GetTriggerEventId() != EVENT_UNIT_ISSUED_TARGET_ORDER) or ((GetTriggerEventId() == EVENT_UNIT_ISSUED_ORDER or GetTriggerEventId() == EVENT_UNIT_ISSUED_POINT_ORDER or GetTriggerEventId() == EVENT_UNIT_ISSUED_TARGET_ORDER) and OrderCheck(GetIssuedOrderId()) == false) then
//Останавливает способность если юнит умер, получил паузу/сбивающий бафф, или отдал приказ (кроме приказа для смены положения предметов в инвентаре)
call Cooldown_Start( caster )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 175) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 176) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 177) )
call UnitRemoveAbility( target, ChargeOfDarknessAddBuff )
call UnitRemoveAbility( target, ChargeOfDarknessBuff )
call RecycleGroup( LoadGroupHandle(udg_dotaHash, trgH, 187) )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
call SetUnitTimeScale( caster, 1 )
call KillUnit( dummy )
call SetUnitPathing( caster, true )
call SetUnitVertexColor( caster, 255, 255, 255, 255 )
call UnitRemoveAbility( caster, SpellImmunity )
call KillDestructables( GetUnitX(caster), GetUnitY(caster), 200 )
if GetTriggerEventId() != EVENT_WIDGET_DEATH then
call ResetUnitAnimation( caster )
endif
endif
elseif GetTriggerEventId() == EVENT_WIDGET_DEATH and GetTriggerUnit() == target then
//Находит новую цель если target умирает
set effectString = ""
if IsPlayerAlly( GetLocalPlayer(), GetOwningPlayer(caster) ) then
set effectString = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl"
endif
call UnitRemoveAbility( target, ChargeOfDarknessAddBuff )
call UnitRemoveAbility( target, ChargeOfDarknessBuff )
set target = Find( caster, target )
if target != null then
call SaveUnitHandle( udg_dotaHash, trgH, 17, target )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 175) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 176) )
call SaveEffectHandle( udg_dotaHash, trgH, 175, AddSpecialEffectTarget(effectString, target, "overhead") )
call SaveEffectHandle( udg_dotaHash, trgH, 176, AddSpecialEffectTarget(effectString, target, "overhead") )
call SaveReal( udg_dotaHash, trgH, 442, (TimerGetElapsed(udg_dotaTimer)+50)*1.0 )
call TriggerRegisterDeathEvent( trg, target )
else
call Cooldown_Start( caster )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 175) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 176) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 177) )
call UnitRemoveAbility( target, ChargeOfDarknessAddBuff )
call UnitRemoveAbility( target, ChargeOfDarknessBuff )
call RecycleGroup( LoadGroupHandle(udg_dotaHash, trgH, 187) )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
call SetUnitTimeScale( caster, 1 )
call KillUnit( dummy )
call SetUnitPathing( caster, true )
call ResetUnitAnimation( caster )
call SetUnitVertexColor( caster, 255, 255, 255, 255 )
call UnitRemoveAbility( caster, SpellImmunity )
call SetUnitPosition( caster, GetUnitX(caster), GetUnitY(caster) )
call KillDestructables( GetUnitX(caster), GetUnitY(caster), 500 )
endif
else
//Движение юнита или остановка по достижению цели
set distanceBetweenCasterAndTarget = DistanceBetweenCoordinates( GetUnitX(caster), GetUnitY(caster), GetUnitX(target), GetUnitY(target) )
if distanceBetweenCasterAndTarget < 100 then
//Завершает ChargeOfDarkness
call Cooldown_Start( caster )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 175) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 176) )
call DestroyEffect( LoadEffectHandle(udg_dotaHash, trgH, 177) )
call UnitRemoveAbility( target, ChargeOfDarknessAddBuff )
call UnitRemoveAbility( target, ChargeOfDarknessBuff )
call RecycleGroup( LoadGroupHandle(udg_dotaHash, trgH, 187) )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
call SetUnitTimeScale( caster, 1 )
call KillUnit( dummy )
set dummy = CreateUnit( GetOwningPlayer(target), Spellcaster, GetUnitX(target), GetUnitY(target), 0 )
call UnitAddAbility( dummy, ChargeOfDarknessStun )
call SetUnitAbilityLevel( dummy, ChargeOfDarknessStun, abilityLvl )
call IssueTargetOrder( dummy, "thunderbolt", target )
call SetUnitPathing( caster, true )
call SetUnitVertexColor( caster, 255, 255, 255, 255 )
call UnitRemoveAbility( caster, SpellImmunity )
call SetUnitPosition( caster, GetUnitX(caster), GetUnitY(caster) )
call KillDestructables( GetUnitX(caster), GetUnitY(caster), 200 )
set darkness_abilityLvl = abilityLvl
call IssueTargetOrder( caster, "attack", target )
else
//Перемещение кастера
if GetTriggerEvalCount( trg ) == 1 then
call DisableTrigger( trg )
call IssueImmediateOrder( caster, "holdposition" )
call EnableTrigger( trg )
endif
if ModuloInteger( GetTriggerEvalCount(trg), 65 ) == 0 then
if GetUnitTypeId( caster ) == GrandMagus then
call SetUnitAnimationByIndex( caster, 1 )
else
call SetUnitAnimationByIndex( caster, 2 )
endif
endif
set moveAngle = AngleBetweenUnits( caster, target )*bj_DEGTORAD
call SetUnitFacing( caster, moveAngle*bj_RADTODEG )
set PolarProjectionX = casterX + moveReal*Cos(moveAngle)
set PolarProjectionY = casterY + moveReal*Sin(moveAngle)
call SetUnitX( caster, PolarProjectionX )
call SetUnitY( caster, PolarProjectionY )
call SetUnitX( dummy, GetUnitX(target) )
call SetUnitY( dummy, GetUnitY(target) )
call SaveReal( udg_dotaHash, trgH, 23, (PolarProjectionX)*1.0 )
call SaveReal( udg_dotaHash, trgH, 24, (PolarProjectionY)*1.0 )
set group_NotBash = LoadGroupHandle( udg_dotaHash, trgH, 187 )
set g = GetGroup()
set global_caster = caster
set darkness_caster = caster
call GroupEnumUnitsInRange( g, PolarProjectionX, PolarProjectionY, 325, Condition(function CheckUnit) )
set darkness_abilityLvl = abilityLvl
call ForGroup( g, function ChargeOfDarkness_Bash )
call RecycleGroup( g )
set g = null
if distanceBetweenCasterAndTarget < 3000 and GetUnitAbilityLevel( target, ChargeOfDarknessAddBuff ) == 0 then
endif
endif
endif
set trg = null
set caster = null
set target = null
set dummy = null
return false
endfunction
private function ChargeOfDarkness_Actions takes nothing returns nothing
//Старт способности ChargeOfDarkness
local trigger trg = CreateTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local unit dummy = CreateUnit( GetOwningPlayer(caster), VisionDummy, GetUnitX(target), GetUnitY(target), 0 )
local integer abilityLvl = GetUnitAbilityLevel( caster, ChargeOfDarknessAbility )
local string effectString = ""
call AddAbility( caster, SwapAbilityContainer )
call SetPlayerAbilityAvailable( GetOwningPlayer(caster), SwapAbilityContainer, false )
call AddAbility( caster, Cooldown )
if IsPlayerAlly( GetLocalPlayer(), GetOwningPlayer(caster) ) then
set effectString = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlTarget.mdl"
call PingMinimapEx( GetUnitX(target), GetUnitY(target), 2, 255, 255, 255, false )
endif
call IssueTargetOrder( caster, "move", target )
call SetUnitPathing( caster, false )
//Здесь нужно настраивать для моделей номер анимации Walk
//У Rubick это 1
//У Barathrum это 2
if GetUnitTypeId( caster ) == GrandMagus then
call SetUnitAnimationByIndex( caster, 1 )
else
call SetUnitAnimationByIndex( caster, 2 )
endif
call SetUnitTimeScale( caster, 2.5 )
call SetPlayerAbilityAvailable( GetOwningPlayer(caster), SpellImmunity, false )
call SetUnitVertexColor( caster, 255, 255, 255, 100 )
call SaveUnitHandle ( udg_dotaHash, trgH, 2 , caster )
call SaveUnitHandle ( udg_dotaHash, trgH, 17 , target )
call SaveUnitHandle ( udg_dotaHash, trgH, 19 , dummy )
call SaveInteger ( udg_dotaHash, trgH, 5 , abilityLvl )
call SaveReal ( udg_dotaHash, trgH, 442 ,(TimerGetElapsed(udg_dotaTimer)+50)*1.0 )
call SaveReal ( udg_dotaHash, trgH, 23 , GetUnitX(caster)*1.0 )
call SaveReal ( udg_dotaHash, trgH, 24 , GetUnitY(caster)*1.0 )
call SaveEffectHandle( udg_dotaHash, trgH, 175 , AddSpecialEffectTarget(effectString,target,"overhead") )
call SaveEffectHandle( udg_dotaHash, trgH, 176 , AddSpecialEffectTarget(effectString,target,"overhead") )
call SaveEffectHandle( udg_dotaHash, trgH, 177 , AddSpecialEffectTarget("war3mapImported\\ShockwaveMissilePurple.mdx",caster,"origin") )
call SaveGroupHandle ( udg_dotaHash, trgH, 187 , GetGroup() )
call TriggerRegisterTimerEvent( trg, 0.02, true )
call TriggerRegisterDeathEvent( trg, caster )
call TriggerRegisterDeathEvent( trg, target )
call TriggerRegisterUnitEvent ( trg, caster, EVENT_UNIT_ISSUED_ORDER )
call TriggerRegisterUnitEvent ( trg, caster, EVENT_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterUnitEvent ( trg, caster, EVENT_UNIT_ISSUED_TARGET_ORDER )
call TriggerAddCondition( trg, Condition(function ChargeOfDarkness_Move) )
set trg = null
set caster = null
set target = null
set dummy = null
endfunction
private function ChargeOfDarkness_Conditions takes nothing returns boolean
if GetSpellAbilityId() == ChargeOfDarknessAbility and BlockAbility( GetSpellTargetUnit() ) == false then
call ChargeOfDarkness_Actions()
elseif GetSpellAbilityId() == ChargeOfDarknessAbility then
call IssueImmediateOrder( GetTriggerUnit(), "stop" )
endif
return false
endfunction
private function InitChargeOfDarkness takes nothing returns nothing
local trigger trg = CreateTrigger()
call AnyUnitEvent( trg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( trg, Condition(function ChargeOfDarkness_Conditions) )
call AbilityInit( Generic_Stun )
endfunction
endlibrary
NetherStrike
library NetherStrike initializer InitNetherStrike requires OtherFunctions, GreaterBash
globals
private unit strike_caster = null
define
SpellImmunity = 'A179' //Spell Immunity
NetherStrikeAbility = 'A0G4' //Nether Strike
NetherStrikeUpgrade = 'A1D8' //Nether Strike Upgrade
enddefine
endglobals
private function NetherStrike_Bash takes unit caster, unit target returns nothing
//Вызывает GreaterBash
local trigger trg
local integer trgH
local real angle = Atan2( GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster) )
local integer i = 4
call GreaterBash( caster, target, true, true )
set trg = null
endfunction
private function BashForGroup takes nothing returns nothing
call NetherStrike_Bash( strike_caster, GetEnumUnit() )
endfunction
private function NetherStrike_AlternativeBash takes unit caster, unit target returns nothing
//Используется только если уровень NetherStrike равен 0
local group g = GetGroup()
set global_caster = caster
set strike_caster = caster
call GroupEnumUnitsInRange( g, GetUnitX(caster), GetUnitY(caster), 275, Condition(function CheckUnit) )
call ForGroup( g, function BashForGroup )
call RecycleGroup( g )
set g = null
endfunction
private function NetherStrike_Move takes nothing returns boolean
//Используется для прыжка кастера
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local unit target = LoadUnitHandle( udg_dotaHash, trgH, 17 )
local integer trgCount = GetTriggerEvalCount( trg )
local integer alpha
local integer abilityLvl
local real angle
local real targetX = LoadReal( udg_dotaHash, trgH, 23 )
local real targetY = LoadReal( udg_dotaHash, trgH, 24 )
local real current_targetX = GetUnitX( target )
local real current_targetY = GetUnitY( target )
local real distance = DistanceBetweenCoordinates( current_targetX, current_targetY, targetX, targetY )
call SaveReal( udg_dotaHash, trgH, 23, current_targetX*1.0 )
call SaveReal( udg_dotaHash, trgH, 24, current_targetY*1.0 )
if GetTriggerEventId() == EVENT_UNIT_DEATH or trgCount == 200 or distance > 1800 then
//Отменяет способность если target или caster умирают. Или если расстояние между ними становится больше 1800
//Или если прошло 0.1 секунды с момента прыжка
call SetUnitVertexColor( caster, 255, 255, 255, 255 )
call UnitShareVision( target, GetOwningPlayer(caster), false )
call UnitRemoveAbility( caster, SpellImmunity )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
else
//Меняет прозрачность юнита из расчета на кол-во срабатываний триггера
if trgCount < 100 then
set alpha = trgCount
else
set alpha = 200-trgCount
endif
call SetUnitVertexColor( caster, 255, 255, 255, 255*(100-alpha)/100 )
if trgCount == 100 then
//Прыжок юнита
set abilityLvl = LoadInteger( udg_dotaHash, trgH, 5 )
set angle = Atan2( GetUnitY(target)-GetUnitY(caster), GetUnitX(target)-GetUnitX(caster) )
call SetUnitPosition( caster, GetUnitX(target)+80*Cos(angle), GetUnitY(target)+80*Sin(angle) )
call SetUnitAnimation( caster, "attack" )
call IssueTargetOrder( caster, "attack", target )
if GetUnitAbilityLevel( caster, NetherStrikeAbility ) > 0 then
call NetherStrike_Bash( caster, target )
else
call NetherStrike_AlternativeBash( caster, target )
endif
call DamageToUnit( caster, target, 1, 50+100*abilityLvl )
endif
endif
set trg = null
set caster = null
set target = null
return false
endfunction
private function NetherStrike_Start takes nothing returns nothing
//Срабатывает спустя время подготовки заклинания
local trigger trg = CreateTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = GetTriggerUnit()
local unit target = GetSpellTargetUnit()
local integer abilityLvl = GetUnitAbilityLevel( caster, NetherStrikeAbility )
if abilityLvl == 0 then
set abilityLvl = GetUnitAbilityLevel( caster, NetherStrikeUpgrade )
endif
call UnitShareVision( target, GetOwningPlayer(caster), true )
call IssueImmediateOrder( caster, "halt" )
call SaveUnitHandle( udg_dotaHash, trgH, 2 , caster )
call SaveUnitHandle( udg_dotaHash, trgH, 17 , target )
call SaveInteger ( udg_dotaHash, trgH, 5 , abilityLvl )
call SaveReal ( udg_dotaHash, trgH, 23 , GetUnitX(target)*1.0 )
call SaveReal ( udg_dotaHash, trgH, 24 , GetUnitY(target)*1.0 )
call TriggerRegisterTimerEvent( trg, 0.001, true )
call TriggerRegisterUnitEvent( trg, caster, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( trg, target, EVENT_UNIT_DEATH )
call TriggerAddCondition( trg, Condition(function NetherStrike_Move) )
call SetPlayerAbilityAvailable( GetOwningPlayer(caster), SpellImmunity, false )
set trg = null
set caster = null
set target = null
endfunction
private function PlayAnimation takes nothing returns boolean
//Проигрывание анимации
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = LoadUnitHandle( udg_dotaHash, trgH, 2 )
call SetUnitAnimation( caster, "spell morph" )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
set trg = null
set caster = null
return false
endfunction
private function ShareVision takes nothing returns boolean
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local unit target = LoadUnitHandle( udg_dotaHash, trgH, 17 )
call UnitShareVision( target, GetOwningPlayer(caster), false )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
set trg = null
set caster = null
set target = null
return false
endfunction
private function NetherStrike_Channel takes nothing returns nothing
//Срабатывает когда кастер нажимает способность на цель
local trigger trg = CreateTrigger()
local integer trgH = GetHandleId(trg)
local unit caster = GetTriggerUnit()
call SaveUnitHandle( udg_dotaHash, trgH, 2, caster )
call TriggerRegisterTimerEvent( trg, 0., true )
call TriggerAddCondition( trg, Condition(function PlayAnimation) )
set trg = CreateTrigger()
set trgH = GetHandleId( trg )
call SaveUnitHandle( udg_dotaHash, trgH, 2, caster )
call SaveUnitHandle( udg_dotaHash, trgH, 17, GetSpellTargetUnit() )
call TriggerRegisterTimerEvent( trg, 1., true )
call TriggerAddCondition( trg, Condition(function ShareVision) )
call UnitShareVision( GetSpellTargetUnit(), GetOwningPlayer(caster), true )
set trg = null
set caster = null
endfunction
private function NetherStrike_Conditions takes nothing returns boolean
if GetSpellAbilityId() == NetherStrikeAbility or GetSpellAbilityId() == NetherStrikeUpgrade then
if BlockAbility(GetSpellTargetUnit()) == false then
if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT then
call NetherStrike_Start()
elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_CHANNEL then
call NetherStrike_Channel()
else
call IssueImmediateOrder( GetTriggerUnit(), "stop" )
endif
endif
endif
return false
endfunction
private function InitNetherStrike takes nothing returns nothing
local trigger trg = CreateTrigger()
call AnyUnitEvent( trg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call AnyUnitEvent( trg, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
call AnyUnitEvent( trg, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
call TriggerAddCondition( trg, Condition(function NetherStrike_Conditions) )
set trg = null
endfunction
endlibrary
EmpoweringHaste
library EmpoweringHaste initializer InitEmpoweringHaste requires OtherFunctions
define
EmpoweringHasteAbility = 'A004' //Empowering Haste
EmpoweringHasteNormal = 'A30W' //Empowering Haste Container - Normal
EmpoweringHasteStrong = 'A30H' //Empowering Haste Container - Strong
EmpoweringHasteWeak = 'A30P' //Empowering Haste Container - Weak
enddefine
private function EmpoweringHaste_Normal takes nothing returns boolean
//Возвращение в нормальную скорость перемещения
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local integer abilityLvl = GetUnitAbilityLevel( caster, EmpoweringHasteAbility )
call UnitRemoveAbility( caster, EmpoweringHasteNormal )
call UnitRemoveAbility( caster, EmpoweringHasteWeak )
call AddAbility( caster, EmpoweringHasteNormal )
call SetUnitAbilityLevel( caster, EmpoweringHasteNormal,abilityLvl )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
set trg = null
set caster = null
return false
endfunction
private function EmpoweringHaste_Weak takes nothing returns boolean
//Изменение скорости на минимальную скорость перемещения
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local integer abilityLvl = GetUnitAbilityLevel( caster, EmpoweringHasteAbility )
call UnitRemoveAbility( caster, EmpoweringHasteNormal )
call UnitRemoveAbility( caster, EmpoweringHasteStrong )
call AddAbility( caster, EmpoweringHasteWeak )
call SetUnitAbilityLevel( caster, EmpoweringHasteWeak, abilityLvl )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
set trg = CreateTrigger()
set trgH = GetHandleId( trg )
call TriggerRegisterTimerEvent( trg, 10, false )
call TriggerAddCondition( trg, Condition(function EmpoweringHaste_Normal) )
call SaveUnitHandle( udg_dotaHash, trgH, 2, caster )
set trg = null
set caster = null
return false
endfunction
private function EmpoweringHaste_Actions takes nothing returns nothing
//Изменение скорости на максимальную скорость перемещения
local trigger trg = CreateTrigger()
local integer trgH = GetHandleId( trg )
local unit caster = GetTriggerUnit()
local integer abilityLvl = GetUnitAbilityLevel( caster, EmpoweringHasteAbility )
call TriggerRegisterTimerEvent( trg, 6, false )
call TriggerAddCondition( trg, Condition(function EmpoweringHaste_Weak) )
call SaveUnitHandle( udg_dotaHash, trgH, 2, caster )
call UnitRemoveAbility( caster, EmpoweringHasteNormal )
call UnitRemoveAbility( caster, EmpoweringHasteWeak )
call AddAbility( caster, EmpoweringHasteStrong )
call SetUnitAbilityLevel( caster, EmpoweringHasteStrong, abilityLvl )
set trg = null
set caster = null
endfunction
private function EmpoweringHaste_Conditions takes nothing returns boolean
if GetSpellAbilityId() == EmpoweringHasteAbility then
call EmpoweringHaste_Actions()
endif
return false
endfunction
private function PermanentBonus_Actions takes nothing returns nothing
//Получение постоянного бонуса при изучении EmpoweringHaste
local integer abilityLvl = GetUnitAbilityLevel( GetTriggerUnit(), EmpoweringHasteAbility )
call SetPlayerAbilityAvailable( GetOwningPlayer(GetTriggerUnit()), EmpoweringHasteStrong, false )
call SetPlayerAbilityAvailable( GetOwningPlayer(GetTriggerUnit()), EmpoweringHasteNormal, false )
call SetPlayerAbilityAvailable( GetOwningPlayer(GetTriggerUnit()), EmpoweringHasteWeak, false )
call AddAbility( GetTriggerUnit(), EmpoweringHasteNormal )
call SetUnitAbilityLevel( GetTriggerUnit(), EmpoweringHasteNormal, abilityLvl )
endfunction
private function PermanentBonus_Conditions takes nothing returns boolean
if GetLearnedSkill() == EmpoweringHasteAbility and IsUnitIllusion(GetTriggerUnit()) == false then
call PermanentBonus_Actions()
endif
return false
endfunction
private function InitEmpoweringHaste takes nothing returns nothing
local trigger trg = CreateTrigger()
call AnyUnitEvent( trg, EVENT_PLAYER_HERO_SKILL )
call TriggerAddCondition( trg, Condition(function PermanentBonus_Conditions) )
set trg = CreateTrigger()
call AnyUnitEvent( trg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( trg, Condition(function EmpoweringHaste_Conditions) )
set trg = null
endfunction
endlibrary
GreaterBash
library GreaterBash initializer InitGreaterBash requires OtherFunctions
define
trgTime = 3 //Время удаления временного бонуса к скорости, который дается при срабатывании GreaterBash
SpiritbashContainer = 'A24H' //Spiritbash Container
SpiritbashBuff = 'B0EC' //Spiritbash
GreaterBashAbility = 'A0G5' //Greater Bash
Spellcaster = 'e00E' //Spellcaster
GreaterBashStun = 'A1WQ' //Greater Bash Stun
enddefine
private function SpeedBonusRemove takes nothing returns boolean
//Удаляет бонус к скорости
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit attacker = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local real time = LoadReal( udg_dotaHash, GetHandleId(attacker), 685 )
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
if time < TimerGetElapsed(udg_dotaTimer) or GetTriggerEventId() == EVENT_WIDGET_DEATH then
call SaveReal( udg_dotaHash, GetHandleId(attacker), 685, 0*1.0 )
call UnitRemoveAbility( attacker, SpiritbashContainer )
call UnitRemoveAbility( attacker, SpiritbashBuff )
endif
set trg = null
set attacker = null
return false
endfunction
private function SpeedBonus takes unit u returns nothing
//Добавляет бонус к скорости после срабатывания GreaterBash
local trigger trg = CreateTrigger()
local integer trgH = GetHandleId( trg )
call AddAbility( u, SpiritbashContainer )
call SetPlayerAbilityAvailable( GetOwningPlayer(u), SpiritbashContainer, false )
call SaveReal( udg_dotaHash, GetHandleId(u), 685, (TimerGetElapsed(udg_dotaTimer)+trgTime-0.01)*1.0)
call TriggerRegisterTimerEvent( trg, trgTime, false )
call TriggerRegisterDeathEvent( trg, u )
call TriggerAddCondition( trg, Condition(function SpeedBonusRemove) )
call SaveUnitHandle( udg_dotaHash, trgH, 2, u )
set trg = null
endfunction
private function GreaterBash_Actions takes nothing returns boolean
//Отталкивание юнита
local trigger trg = GetTriggeringTrigger()
local integer trgH = GetHandleId( trg )
local unit target = LoadUnitHandle( udg_dotaHash, trgH, 17 )
local unit attacker = LoadUnitHandle( udg_dotaHash, trgH, 2 )
local real angle = LoadReal( udg_dotaHash, trgH, 13 )
local real x = GetUnitX( target )
local real y = GetUnitY( target )
local integer trgCount = GetTriggerEvalCount( trg )
local real r = LoadReal( udg_dotaHash, trgH, 193 )
local integer i = LoadInteger( udg_dotaHash, trgH, 12 )
if trgCount > 35 then
call SaveReal( udg_dotaHash, trgH, 193, (r*0.98)*1.0 )
endif
if GetTriggerEventId() == EVENT_UNIT_DEATH or trgCount > i then
call FlushChildHashtable( udg_dotaHash, trgH )
call DestroyTriggerEx( trg )
else
call DestroyEffect( AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl", x, y) )
call KillDestructables( x, y, 150 )
set x = SafeRealX( x+r*Cos(angle) )
set y = SafeRealY( y+r*Sin(angle) )
if IsPointInRegion(global_region, x*1.0, y*1.0) == false then
call SetUnitX( target, x )
call SetUnitY( target, y )
endif
if trgCount == 1 and LoadBoolean(udg_dotaHash, trgH, 698) == false then
call IssueTargetOrder( attacker, "attack", target )
endif
endif
set trg = null
set target = null
set attacker = null
return false
endfunction
function GreaterBash takes unit attacker, unit target, boolean b, boolean off returns nothing
local trigger trg
local integer trgH
local real angle = Atan2( GetUnitY(target)-GetUnitY(attacker), GetUnitX(target)-GetUnitX(attacker) )
local integer abilityLvl = GetUnitAbilityLevel( attacker, GreaterBashAbility )
local unit dummy
if b then
endif
//Здесь нужно указывать все способности или бафы, имея которые не будет срабатывать GreaterBash
//Оригинал:
//if abilityLvl > 0 and GetUnitAbilityLevel(attacker, 'BNdo') == 0 then
if abilityLvl > 0 then
set dummy = CreateUnit( GetOwningPlayer(target), Spellcaster, GetUnitX(target), GetUnitY(target), 0 )
call AddAbility( dummy, GreaterBashStun )
call SetUnitAbilityLevel( dummy, GreaterBashStun, abilityLvl )
if IssueTargetOrder( dummy, "thunderbolt", target ) then
//Если можно кинуть стан на цель, значит сработает отталкивание юнита
set trg = CreateTrigger()
set trgH = GetHandleId( trg )
call DestroyEffect( AddSpecialEffectTarget("Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", attacker, "weapon") )
call SaveUnitHandle( udg_dotaHash, trgH, 2 , attacker )
call SaveUnitHandle( udg_dotaHash, trgH, 17 , target )
call SaveReal ( udg_dotaHash, trgH, 13 , angle*1.0 )
call SaveReal ( udg_dotaHash, trgH, 193 , 2*1.0 )
call SaveBoolean ( udg_dotaHash, trgH, 698 , off )
call SaveInteger ( udg_dotaHash, trgH, 12 , 80+20*abilityLvl )
call TriggerRegisterUnitEvent( trg,target, EVENT_UNIT_DEATH )
call TriggerRegisterTimerEvent( trg, 0.01, true)
call TriggerAddCondition( trg, Condition(function GreaterBash_Actions) )
call DamageToUnit( attacker, target, 1, GetUnitMoveSpeed(attacker)*(0.16+0.06*abilityLvl) )
call SpeedBonus( attacker )
endif
if off == false then
call BashOff( attacker, 4276, 1.5 )
endif
endif
set trg = null
set attacker = null
set target = null
set dummy = null
endfunction
private function GreaterBash_Conditions takes nothing returns boolean
//Здесь дополнительная проверка чтобы GreaterBash при атаке не срабатывал повторно в течении 1.5 секунды
if GetUnitAbilityLevel(GetAttacker(), GreaterBashAbility) > 0 and IsUnitIllusion(GetAttacker()) == false and IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(GetAttacker()))and GetRandomInt(1, 100) <= 17 and ( LoadInteger(udg_dotaHash,GetHandleId(GetAttacker()), 4276) == 1 ) == false then
call GreaterBash( GetAttacker(), GetTriggerUnit(), false, false )
endif
return false
endfunction
private function InitGreaterBash takes nothing returns nothing
local trigger trg = CreateTrigger()
call AnyUnitEvent( trg, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( trg, Condition(function GreaterBash_Conditions) )
set trg = null
endfunction
endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
только на этих 2 активных способностях правда будет не особо видно но если в карте более 100 активных способностей то результат заметен невооружённым глазом
Отредактирован Hodor
Отредактирован Hodor
Отредактирован Hodor
Обновил ресурс
точнее бонус к скорости от фаз