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
хотя как по мне проще будет написать с 0
и я бы триггеры заменил на таймеры
и раз юзаешь cjass то юзай его полностью
а то гдето есть, гдето нету
если ктото захочет дать эти абилки многим юнитам то будет ппц
думаю даже при 100 юнитах будут лаги
ладно, мне просто влом внимательно изучать триги, если там такая система, что работает просто замена ивента, чтобы только на атаку все равно срабатывало - ок
Ред. Hodor
только на этих 2 активных способностях правда будет не особо видно но если в карте более 100 активных способностей то результат заметен невооружённым глазом
Ред. Hodor
Ред. Hodor
Ред. Hodor
Обновил ресурс
точнее бонус к скорости от фаз