Omnislash Juggernaut'а из доты 6.83с с восстановленными именами функций и переменных.
OMNISLASH
JASS
function NoPossibleTargets takes unit whichUnit returns boolean
local integer id=GetUnitTypeId(whichUnit)
return id=='n004' or id=='n01G' or id=='n01C' or id=='n018' or id=='e00K' or id=='e00I' or id=='e00L' or id=='e01J'
endfunction
function IsUnitDead takes unit u returns boolean
return IsUnitType( u, UNIT_TYPE_DEAD ) or GetUnitTypeId( u ) < 1
endfunction
// Фильтр группы - враги для udg_TempUnit, живые, без способности 'A04R'(маркер курьера и осадных войск), не здание, не древо, видимый, не запрещенный юнит...
function Only_Avalible_Units_Conditions takes nothing returns boolean
return((IsUnitEnemy(udg_TempUnit,GetOwningPlayer(GetFilterUnit()))and(GetUnitAbilityLevel(GetFilterUnit(),'A04R')==0 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and IsUnitDead(GetFilterUnit())==false)and(IsUnitType(GetFilterUnit(),UNIT_TYPE_ANCIENT)==false or NoPossibleTargets(GetFilterUnit())))and IsUnitVisible(GetFilterUnit(),GetOwningPlayer(udg_TempUnit)))and GetUnitTypeId(GetFilterUnit())!='n0F5'
endfunction
function Juggernaut_Hit takes unit juggernaut, unit enemy returns nothing // функция отвечает за псевдо удары и пермещение.
local real ang = GetRandomReal( 0, 360 )
local real JX = GetUnitX( enemy ) + 50 * Cos( ang * bj_DEGTORAD )
local real JY = GetUnitY( enemy ) + 50 * Sin( ang * bj_DEGTORAD )
local real dmg = GetRandomReal( 200, 225 )
if ( ( LoadInteger( udg__htb_DATA, ( GetHandleId( ( juggernaut ) ) ), ( ( 4256 ) ) ) ) == 1 ) == false then
call SetUnitPosition( juggernaut, JX, JY )
else
call SetUnitX( juggernaut, JX )
call SetUnitY( juggernaut, JY )
endif
call SetUnitFacing( juggernaut, bj_RADTODEG * Atan2( GetUnitY( enemy ) - GetUnitY( juggernaut ), GetUnitX( enemy ) - GetUnitX( juggernaut ) ) )
call SetUnitAnimation( juggernaut, "Attack" )
call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl", juggernaut, "chest" ) )
if IsUnitType( enemy, UNIT_TYPE_HERO ) == false and IsUnitType( enemy, UNIT_TYPE_ANCIENT ) == false then // в оригинале используется функция I2T для проверки что юнит не принадлежит игрокам
set dmg = 99999
endif
call UnitDamageTarget(juggernaut,enemy,dmg,true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS) // в оригинале используется функция P6I( juggernaut, enemy, 2, dmg ) из отдельной функции нанесения урона, тип урона идентичен
if ( ( LoadInteger( udg__htb_DATA, ( GetHandleId( ( juggernaut ) ) ), ( ( 4256 ) ) ) ) == 1 ) == false then
call IssueTargetOrder( juggernaut, "attack", enemy )
endif
endfunction
function Omnislash_Firs_Target takes nothing returns boolean // функция нанесения удара первой цели
local trigger TempTrigger = GetTriggeringTrigger( )
local integer id = GetHandleId( TempTrigger )
local unit juggernaut = ( LoadUnitHandle( udg__htb_DATA, ( id ), ( 14 ) ) )
local unit enemy = ( LoadUnitHandle( udg__htb_DATA, ( id ), ( 17 ) ) )
call Juggernaut_Hit( juggernaut, enemy )
call FlushChildHashtable( udg__htb_DATA, ( id ) )
call DestroyTrigger( TempTrigger ) // в оригинале используется функция S0I( TempTrigger ) из отдельной системы удаления триггеров
set TempTrigger = null
set juggernaut = null
set enemy = null
return false
endfunction
function Omnislash_Pick_Targets takes unit juggernaut returns nothing // функция поиска и нанесения ударов последующим целям.
local group grp = CreateGroup() // в оригинале используется функция NTI(...) из отдельной системы создания и удаления групп
set udg_TempUnit = juggernaut
call GroupEnumUnitsInRange( grp, GetUnitX( juggernaut ), GetUnitY( juggernaut ), 450, Condition( function Only_Avalible_Units_Conditions ) )
set udg_TempUnit = GroupPickRandomUnit( grp )
if udg_TempUnit != null then
call Juggernaut_Hit( juggernaut, udg_TempUnit )
endif
call DestroyGroup( grp ) // в оригинале используется функция NSI(...) из отдельной системы создания и удаления групп
set grp = null
endfunction
function Timer_Omnislash_Hits_Expires takes nothing returns boolean // таймер задержки ударов, 0.4 сек. Эта функция проверяет число ударов и наличие допустимых целей...
local trigger TempTrigger = GetTriggeringTrigger( )
local integer id = GetHandleId( TempTrigger )
local unit juggernaut = ( LoadUnitHandle( udg__htb_DATA, ( id ), ( 14 ) ) )
local unit dummy = ( LoadUnitHandle( udg__htb_DATA, ( id ), ( 19 ) ) )
local integer attacks = ( LoadInteger( udg__htb_DATA, ( id ), ( 216 ) ) )
local integer BladeFuryLvl = ( LoadInteger( udg__htb_DATA, ( id ), ( 325 ) ) )
local integer CurAttacks = ( LoadInteger( udg__htb_DATA, ( id ), ( 28 ) ) )
local unit enemy // эта переменная не используется в функции
if CurAttacks > attacks then
call KillUnit( dummy )
call DestroyEffect( ( LoadEffectHandle( udg__htb_DATA, ( id ), ( 32 ) ) ) )
call FlushChildHashtable( udg__htb_DATA, ( id ) )
call DestroyTrigger( TempTrigger ) // в оригинале используется функция S0I( TempTrigger ) из отдельной системы удаления триггеров
call SetPlayerAbilityAvailable( GetOwningPlayer( juggernaut ), 'A05G', true )
call SetUnitPathing( juggernaut, true )
call SetUnitInvulnerable( juggernaut, false )
call SaveInteger( udg__htb_DATA, ( GetHandleId( ( juggernaut ) ) ), ( ( 4253 ) ), ( 2 ) )
call SetUnitVertexColor( juggernaut, 255, 255, 255, 255 )
else
call SaveInteger( udg__htb_DATA, ( id ), ( 28 ), ( CurAttacks + 1 ) )
call Omnislash_Pick_Targets( juggernaut )
if udg_TempUnit == null then
call KillUnit( dummy )
call DestroyEffect( ( LoadEffectHandle( udg__htb_DATA, ( id ), ( 32 ) ) ) )
call FlushChildHashtable( udg__htb_DATA, ( id ) )
call DestroyTrigger( TempTrigger ) // в оригинале используется функция S0I( TempTrigger ) из отдельной системы удаления триггеров
call SetPlayerAbilityAvailable( GetOwningPlayer( juggernaut ), 'A05G', true )
call SetUnitPathing( juggernaut, true )
call SetUnitInvulnerable( juggernaut, false )
call SaveInteger( udg__htb_DATA, ( GetHandleId( ( juggernaut ) ) ), ( ( 4253 ) ), ( 2 ) )
call SetUnitVertexColor( juggernaut, 255, 255, 255, 255 )
endif
endif
set TempTrigger = null
set juggernaut = null
set enemy = null
set dummy = null
return false
endfunction
function Trig_Omnislash_Actions takes nothing returns nothing // начало Omnislash
// 'A0M1' - Omnislash ( обычный )
// 'A1AX' - Omnislash upgrade ( улучшенный Aghanim's Scepter )
// 'A05G' - Blade Fury
// 'o00D' - Vision Dummy, дамми юнит с радиусом обзора в 200 ед. обладает 'A04R' Marker
local unit juggernaut = GetTriggerUnit( )
local unit enemy = GetSpellTargetUnit( )
local integer level = GetUnitAbilityLevel( juggernaut, 'A0M1' )
local trigger TempTrigger = CreateTrigger( )
local integer id = GetHandleId( TempTrigger )
local integer BladeFuryLvl = GetUnitAbilityLevel( juggernaut, 'A05G' )
local player pl = GetOwningPlayer( juggernaut )
local integer attacks = 3
local unit dummy = CreateUnit( GetOwningPlayer( juggernaut ), 'o00D', GetUnitX( juggernaut ), GetUnitY( juggernaut ), 0 )
if level == 0 then
set level = GetUnitAbilityLevel( juggernaut, 'A1AX' )
if level == 1 then
set attacks = 6
elseif level == 2 then
set attacks = 9
elseif level == 3 then
set attacks = 12
endif
elseif level == 2 then
set attacks = 6
elseif level == 3 then
set attacks = 9
endif
call SetPlayerAbilityAvailable( pl, 'A05G', false )
call SetUnitVertexColor( juggernaut, 255, 255, 255, 125 )
call SetUnitPathing( juggernaut, false )
call SetUnitInvulnerable( juggernaut, true )
call SaveInteger( udg__htb_DATA, ( GetHandleId( ( juggernaut ) ) ), ( ( 4253 ) ), ( 1 ) )
call SaveUnitHandle( udg__htb_DATA, ( id ), ( 14 ), ( juggernaut ) )
call SaveUnitHandle( udg__htb_DATA, ( id ), ( 17 ), ( enemy ) )
call TriggerRegisterTimerEvent( TempTrigger, 0, false )
call TriggerAddCondition( TempTrigger, Condition( function Omnislash_Firs_Target ) ) // для первого удара // Создает утечку типа triggercondition, в коде не предусмотренно его удаление
set TempTrigger = CreateTrigger( )
set id = GetHandleId( TempTrigger )
call SaveUnitHandle( udg__htb_DATA, ( id ), ( 14 ), ( juggernaut ) )
call SaveUnitHandle( udg__htb_DATA, ( id ), ( 19 ), ( dummy ) )
call SaveInteger( udg__htb_DATA, ( id ), ( 216 ), ( attacks ) )
call SaveInteger( udg__htb_DATA, ( id ), ( 325 ), ( BladeFuryLvl ) )
call SaveInteger( udg__htb_DATA, ( id ), ( 28 ), ( 2 ) )
call SaveEffectHandle( udg__htb_DATA, ( id ), ( 32 ), ( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", juggernaut, "weapon" ) ) )
call TriggerRegisterTimerEvent( TempTrigger, 0.4, true ) // для остальных
call TriggerAddCondition( TempTrigger, Condition( function Timer_Omnislash_Hits_Expires ) ) // для остальных ударов // Создает утечку типа triggercondition, в коде не предусмотренно его удаление
// set dummy = null ВНИМАНИЕ IceFrog не обнулил переменную dummmy, имейте это ввиду если собираетесь использовать этот код!
set juggernaut = null
set enemy = null
set TempTrigger = null
set pl = null
endfunction
function Trig_Omnislash_Conditions takes nothing returns boolean // точно такая же проверка, какую способность применил герой?
// 'A0M1' - Omnislash ( обычный )
// 'A1AX' - Omnislash upgrade ( улучшенный Aghanim's Scepter )
if GetSpellAbilityId( ) == 'A0M1' or GetSpellAbilityId( ) == 'A1AX' then
call Trig_Omnislash_Actions( )
endif
return false
endfunction
function Timer_Omnislash_Animation_Expires takes nothing returns boolean // заставляет героя проиграть анимацию 'stand - 4'
local trigger TempTrigger = GetTriggeringTrigger( )
local integer id = GetHandleId( TempTrigger )
local unit juggernaut = ( LoadUnitHandle( udg__htb_DATA, ( id ), ( 2 ) ) )
call FlushChildHashtable( udg__htb_DATA, ( id ) )
call DestroyTrigger( TempTrigger ) // в оригинале используется функция S0I( TempTrigger ) из отдельной системы удаления триггеров
call SetUnitAnimationByIndex( juggernaut, 4 )
set TempTrigger = null
set juggernaut = null
return false
endfunction
function Trig_Omnislash_Animation_Actions takes nothing returns nothing // формирует задержку для проигрывания анимации 'stand - 4'
local unit juggernaut = GetTriggerUnit( )
local trigger TempTrigger = CreateTrigger( )
local integer id = GetHandleId( TempTrigger )
call TriggerRegisterTimerEvent( TempTrigger, 0.01, false )
call TriggerAddCondition( TempTrigger, Condition( function Timer_Omnislash_Animation_Expires ) ) // Создает утечку типа triggercondition, в коде не предусмотренно его удаление
call SaveUnitHandle( udg__htb_DATA, ( id ), ( 2 ), ( juggernaut ) )
set TempTrigger = null
set juggernaut = null
endfunction
function Trig_Omnislash_Animation_Conditions takes nothing returns boolean // проверка id способностей.
// 'A0M1' - Omnislash ( обычный )
// 'A1AX' - Omnislash upgrade ( улучшенный Aghanim's Scepter )
if GetSpellAbilityId( ) == 'A0M1' or GetSpellAbilityId( ) == 'A1AX' then
call Trig_Omnislash_Animation_Actions( )
endif
return false
endfunction
//===========================================================================
function InitTrig_Omnislash takes nothing returns nothing // инициализация триггера, эта функция вызовется после старта карты
local trigger TempTrigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( TempTrigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( TempTrigger, Condition( function Trig_Omnislash_Conditions ) )
set TempTrigger = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( TempTrigger, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( TempTrigger, Condition( function Trig_Omnislash_Animation_Conditions ) )
set TempTrigger = null
endfunction
Перемешает героя к цели заклинания и наносит от 3 до 15 псевдо ударов с физическим уроном от 200 до 225 ед. Если рядом находятся другие противники то часть ударов пройдут по ним, убивает не героев.
ВНИМАНИЕ
В коде встречаются ошибки и недоработки, имейте это в виду если собираетесь использовать этот код
Все претензии по качеству кода прошу писать IceFrog
Все претензии по качеству кода прошу писать IceFrog
Омнислеш не тока был много раз, но еще и совсем разный. Поделок на эту тему много, но они другие... Вот у нас фейт болт был, фрог юзает для молний дамми каст цепи молний к примеру, а тот что у нас выложен кастом молнии, созданные кодом а не дамми юнитом.
Я показываю решения принятые в доте, а не пытаюсь сделать наработки скиллов из доты для импорта в свою карту. Как вы заметили фрог не супер пупер тру кодер, и каждый из юзеров XGM сможет сделать круче, некоторым стоит только немного поучится.
Отредактирован Melissa
Melissa:
Период триггера = базовое время атаки юнита/4 + добавка анимации точки повреждения. Примерно 0.35-0.4 сек
Отредактирован Melissa
хотели бы предотвратить - паузили бы его