Добавлен , опубликован
Существует специальная тема Способности и алгоритмы на заказ, где любой желающий может помочь с вашими фантазиями и где я тоже иногда зависаю. Кроме того, есть платные заказы, например, можете обратиться к Hate - Заклинания на заказ для Warcraft 3 (Платные) или поискать ещё темы на сайте
Я хочу развивать своё резюме, поэтому можете оставлять заявки и там, и тут. Имейте ввиду, заказы я выполняю бесплатно, на чистом энтузиазме, трачу на это своё свободное время, поскольку воспринимаю это как хобби, всё выполняю при возможности и желании
раскрыть
Я не буду вливаться в ваши проекты и не принимаю деньги, для этого есть платные темы. Авторство или упоминания меня в карте делать не нужно, ибо я буду менять ник. Если появится желание отблагодарить - лайка достаточно
Могу сделать анонимно заклинание, для этого можно обратиться ко мне в личку, но меня расстроит невозможность поделиться им, если оно интересное
Отдаю приоритет именно способностям, алгоритмы/системы, вроде 3д камеры/физики, меня особо не интересуют, да и не всё умею, и не за все заказы возьмусь, не стоит ожидать от меня движущихся птиц и чайники на молниях, матрицу не изучал и с математикой не дру
Работаю на 1.26, могу воспользоваться UjAPI, при создании спелла для рефа
Для меня предпочтительнее пользоваться вджассом, но могу сделать заклинание на чистом джассе и даже гуи, однако имейте ввиду, гуи может многократно усложнить работу, ибо на нём может не хватать функционала для создания вашего спелла. Есть вариант скрестить джасс с гуи, пользуясь TriggerEvaluate

Форма составления заявки

При создании заявки не забудьте указать тип комментария Заказ на работу
# Заказ
**Название:** Название способности (опционально, если заказ один)
**Метод:** GUI/Jass/cJass/vJass/Zinc
**Версия Warcraft III:** Версия варкрафта для этого заказа
**Техническое описание:** Распишите механику способности в деталях
Заявки оставлять в комментариях под этим ресурсом
раскрыть
Название - можно любое указать, вплоть до символа, это поможет в навигации по мере сдачи работ. Не нужно указывать, если в заказе только одна способность, работа сдаётся в ответах под заказом
Метод - выберите для себя комфортный метод, на котором будет выполнена способность. При методе кодом, я укажу комментариями где нужно будет что-то отредактировать. Комфортные для меня методы в порядке убывания: vJass > Jass > cJass > Zinc > GUI
Версия Warcraft III - на определённых версиях не доступен мемхак и сджасс. Чтобы взять ориентир на рефорджед, могу воспользоваться UjAPI. Это необходимо для специфических заказов, к примеру, повышение бонусной силы атаки, где на старых версиях требуется мемхак/южапи/костыли/база данных, а на более новых для этого присутствуют нативки
Техническое описание - укажите что должна делать ваша способность, например:
1 уровень: выпускается волна в точку каста
2 уровень: 2 волны в точку каста с разницей в 20 градусов по бокам
3 уровень: 5 волн, одна посередине и по 2 по бокам с разницей в 10 градусов
Каждая волна движется со скоростью 2000 и дальностью 1000. Радиус поражения 200 и с каждым уровнем увеличивается на 50 вместе с размером волны. Я хочу наносить урон юнитам самостоятельно, на гуи, с помощью TriggerEvaluate, мне нужны будут переменные применяющего юнита и уровень его способности на момент каста абилки, оставь пример нанесения урона с использованием этих переменных
Красивое форматирование приветствуется

Примеры работ

Всё у меня в ресурсах: xgm.guru/u/rsfghd
`
ОЖИДАНИЕ РЕКЛАМЫ...
35
Заказ на работу

Заказ

Название: Боевая тревога
Метод: GUI
Версия Warcraft III: 1.26
Техническое описание: Надо сделать чтобы логово орков принимало не только рабов но и бугаёв и троллей. И скорость атака чтобы росла у логова при большем кол-ве юнитов.
Ответы (2)
28
Выполнение заказа

Заклинание готово!

инструкция по импорту
скопировать триггер Melee Initialization и вставить в свою карту
выдать всем юнитам, которых можно погрузить в бункер, абилку пустышку и указать её в триггерах
в остальном просто скопировать нестандартное в редакторе объектов и закинуть в свою карту
Загруженные файлы
11
Заказ на работу
Название: Песня доблести
Метод: GUI
Версия Warcraft III: 1.26
Техническое описание: Способность можно активировать и деактивировать по желанию, но чтобы была перезарядка после деактивации.
Активирующий "поёт" находится анимации channel и неподвижен, пока не перестанет петь.
При активации, все кто слышит получают следующие эффекты и затем каждые 3 секунды :
-Союзники получают шанс крит. урона 150/200/250% на 15/25/35%, затем каждые 3 секунды восполняют ману на 3/5/9% и здоровье на 1/2/3х интеллекта героя,
-Противники получают штраф промахов 10/15/25%, затем каждые 3 секунды они оглушены на 0.5/1/1.5 секунд. (герои оглушены на 0.5 всегда)
После деактивации, герой отбрасывает врагов рядом и если он пел минимум 9 секунд, то получает бонус к урону 10/20/30.
Название: Воронка смерти
Метод: GUI
Версия Warcraft III: 1.26
Техническое описание: Способность активируется и деактивируется без перезарядки, как огненный плащ иллидана.
При активации постоянно тратит ману, но взамен, все находящиеся рядом лежащие трупы юнитов поглощаются героем и восполняют ему здоровье и ману, на 5%. Это те вида трупы, которые можно было каннибализировать. При этом можно сделать какой нибудь снаряд летящий из трупа в героя типа его частица поглощается в него, а после взорвать труп, чтобы нельзя было повторно его поглотить.
Ответы (16)
28
Shermanator00, какой радиус песни доблести? Баффы/дебаффы (Крит/промах) утрачиваются при окончании песни (или выхода из её радиуса)? Если да, то мгновенно или через 3 секунды? Если герой пел дольше 9 секунд, он получает бонус к урону навсегда? Он стакается или обновляется? Возможен ли вариант написания абилок на джассе/вджассе?
11
rsfghd, радиус 1200, баффы дебаффы утрачиваются через 3 секунды, бонус героя временный скажем 30 секунд и не стакается. Можно на Джассе если на GUI закоплексовано
28
Выполнение заказа

Заклинание готово!

Песня доблести

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
делал на гуи с использованием кастомскриптов для выбора юнитов и удаления точек, в целях оптимизации можешь изменить периодичность таймера TimerMove и его связывающих с 0.01 до 0.03. Таймер Timer и его связывающие с 0.01 до 0.10
Спелл муи
второй спелл завтра сделаю, если с этим всё оке
Загруженные файлы
28
Shermanator00, а, и не забудь сделать прелоад абилок из ро, чтобы первый каст не подлагивал
11
rsfghd, ух ты, спасибо. Готовлю реворк модели бардессы, потом добавлю чтоб проигрывал анимацию Spell slam, где сделан конец заклинания) Да и для какого-нибудь отважного лидера подойдет типа командира-запугивателя
28
Выполнение заказа

Заклинание готово!

Воронка смерти

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
делал на гуи с использованием кастомскриптов для выбора юнитов и удаления точек, в целях оптимизации можешь изменить периодичность таймера TempTimer с 0.01 до 0.10. Таймер TempTimerMove с 0.01 до 0.03, и полностью убрать дополнительного даммика (тёмный хвостик фиолетовой птицы Dummy1)
Спелл муи
Загруженные файлы
11
rsfghd, круто!
я уверен немало кому пригодится такой спелл, снаряд птички наконец - то где то прикольно смотрится
28
Shermanator00, птички везде прикольно смотрятся если знать как их юзать, к примеру, демонстрация Частицы/Particles от Vlod'a
11
Заказ на работу
rsfghd,
Название: Dodge
Метод: GUI
Версия Warcraft III: 1.26
Техническое описание: есть еще идея, www.hiveworkshop.com/threads/knightess-in-plate-armor.352884
я сделал эту модель, и там есть анимация, которая как в дарк соулсе перекат Spell Throw Alternate и уворот spell throw gold. Надо три варианта спеллов:
Первый вариант: расстояние до 400, проиграв анимацию герой быстро переместился перекатом на точку, которую указал игрок и получает сопротивление урону заклинаниям 100% и защиту 1000 на 2 секунд, а затем на 5 секунд получает скорость бега от свитка скорости 25%\50%\75% (необязательно для визуальности можешь в редакторе в разделе "графика" скорости бега поставить 350, а ходьбы 300 так как там walk fast есть).
Второй вариант: шанс 15\20\25% будучи атакованным, герой рандомно переместился вправо ЛИБО (рандомно) влево (влево пока не анимировал еще) и следующий удар будет критическим 150%\200%\250%. Анимация уворота длится 1.2 секунд. Надо чтобы после уклона герой авто-атаку сделал обычную, может быть такое что после уклона анимация атаки не сыграет вроде.
Третий вариант: это для другого персонажа, пусть временным тестером будет Мэв, при нажатии герой высоко отскакивает в противоположную сторону куда она смотрит (назад т.е.) анимацией Spell Slam (вроде), а зона, где она изначально была взрывается через 0.5 сек и наносит 100\200\300 урона в радиусе взрыва, скажем 600
Я думаю что уклон влево\вправо анимация очень медленная, я б хотел посмотреть как оно работает против группы противников) Поэтому добавлю измененный файл снизу. Там Spell throw Gold 0.6 секунд длится вместо 1.2
И еще чтобы эти абилки работали на всех, кто ее может изучить 😀
Загруженные файлы
28
Shermanator00, как долго длится усиление крита во втором варианте после уворота? Пока не будет нанесена автоатака? На ванилке, заставить сделать автоатаку можно только приказом, а значит, её можно будет отменить. После уворота атаковать ближнюю цель или того, кто атаковал?
28
Shermanator00, и заказы, пожалуйста, отдельным комментарием, а не в ветке ответов, потому что другие не увидят этот заказ, если не полезут сюда в ответы
15
rsfghd, выглядит здорово. Кстати, напоминает неуязвимость близзов (ну в частности, из-за эффекта, который ты использовал конечно), уж лучше бы они так сделали, чтобы хп постоянно восстанавливалось сильно, чем просто тупую неуязвимость, когда нельзя атаковать даже противника, что на мой взгляд попросту ломает игру, когда оппонент вынужден убегать или пытаться любой ценой застанить или убить кастующего.
28
Meddin, ломает игру потка неуязвимости, которая делает channel ульты имбовыми
11
rsfghd, да, пока не будет нанесена автоатака, и пусть атакует того кто прокнул
4
Заказ на работу
Я как понимаю нужны оригинальные идеи для спелов!
У меня есть идея: герой стреляет лучом лазера в определенную цель, длится 6/7/8 сек. В это время герой ничего не может делать, а только поворачивается ко врагу передом (из живота или типа того лазер постоянно стреляет). И все вражеские юниты, на которых попал лазер - им постоянно наносится урон и они замедляются (как и цель, если её достаёт лазер). Также если цель будет убегать, то герой разворачивается к ней постоянно и атакует лазером (и наносит урон всем, кого лазер докоснулся). Дальность 900. Если цель убежит или героя потревожат - спелл закончится!
С лвлом повышается урон, замедление передвижения и длительность.
Ответы (12)
28
Выполнение заказа

Заклинание готово!

инструкция по импорту
скопировать папку Initialization и вставить в свою карту
перекопировать редактор объектов и вставить в свою карту
настроить равкоды (кроме BTLF) в триггере Spell в соответствии с редактором
всё остальное, что нужно/можно отредактировать помечено комментариями, на остальное нужны базовые знания джасса

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
    constant location LFZ = Location( 0.00, 0.00 )
    
    private real MaxX
    private real MinX
    private real MaxY
    private real MinY
endglobals

native UnitAlive takes unit id returns boolean

function GetCorX takes real x returns real
    if x > MaxX then
        return MaxX
    elseif x < MinX then
        return MinX
    endif
    
    return x
endfunction

function GetCorY takes real y returns real
    if y > MaxY then
        return MaxY
    elseif y < MinY then
        return MinY
    endif
    
    return y
endfunction

function GetLocZ takes real x, real y returns real
    call MoveLocation( LFZ, x, y )
    return GetLocationZ( LFZ )
endfunction

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

//===========================================================================
function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
    local rect r = GetWorldBounds( )
    
    set MaxX = GetRectMaxX( r )
    set MinX = GetRectMinX( r )
    set MaxY = GetRectMaxY( r )
    set MinY = GetRectMinY( r )
    
    call RemoveRect( r )
    set r = null
endfunction
endlibrary

Spell
library SpellLib
globals
    private constant group TempGroup = CreateGroup( )
    private constant group TempGroup1 = CreateGroup( )
    private unit TempUnit = null
endglobals

struct SpellS
    timer t
    player p
    
    unit caster
    unit target
    unit eye
    unit field
    unit laser
    unit laserBig
    
    vector l
    vector array v[4]
    
    integer lvl
    
    real radius
    real radiusEnd
    
    real damage
    real damagePeriodic
    
    real distance
    
    real time
    real timeMax
    
    attacktype attackType
    damagetype damageType
    weapontype weaponType
endstruct

private function Rotation takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real ax
    local real ay
    local real d
    local unit u
    
    if GetUnitCurrentOrder( A.caster ) == OrderId( "channel" ) then
        set A.time = A.time + 0.01
        set A.timeMax = A.timeMax + 0.01
        
        call SetUnitFacing( A.caster, Atan2( GetUnitY( A.target ) - A.l.y, GetUnitX( A.target ) - A.l.x ) * bj_RADTODEG )
        
        set d = GetUnitFacing( A.caster )
        
        set ax = Cos( d * bj_DEGTORAD )
        set ay = Sin( d * bj_DEGTORAD )
        
        call SetUnitX( A.eye, A.l.x + 275.00 * ax )
        call SetUnitY( A.eye, A.l.y + 275.00 * ay )
        
        call SetUnitX( A.field, A.l.x + 125.00 * ax )
        call SetUnitY( A.field, A.l.y + 125.00 * ay )
        
        call SetUnitFacing( A.eye, d )
        call SetUnitFacing( A.laser, d )
        call SetUnitFacing( A.laserBig, d )
        
        if A.time == 1.15 then
            set A.laser = CreateUnit( A.p, 'u005', A.l.x + 100.00 * ax, A.l.y + 100.00 * ay, d )
            call SetUnitX( A.laser, A.l.x + 100.00 * ax )
            call SetUnitY( A.laser, A.l.y + 100.00 * ay )
            call SetUnitFlyHeight( A.laser, 80.00, 0.00 )
            call UnitApplyTimedLife( A.laser, 'BTLF', 3.00 )
        endif
        
        if A.time >= 1.50 then
            set A.time = 0.00
            
            call SetUnitAnimation( A.field, "birth" )
            call QueueUnitAnimation( A.field, "stand" )
            
            set A.laser = CreateUnit( A.p, 'u007', A.l.x, A.l.y, d )
            call SetUnitFlyHeight( A.laser, 80.00, 0.00 )
            call SetUnitAnimation( A.laser, "death" )
            call UnitApplyTimedLife( A.laser, 'BTLF', 5.00 )
            
            set A.laser = CreateUnit( A.p, 'u001', A.l.x + 125.00 * ax, A.l.y + 125.00 * ay, d )
            call SetUnitX( A.laser, A.l.x + 125.00 * ax )
            call SetUnitY( A.laser, A.l.y + 125.00 * ay )
            call SetUnitFlyHeight( A.laser, 80.00, 0.00 )
            call UnitApplyTimedLife( A.laser, 'BTLF', 3.00 )
        endif
        
        if A.timeMax >= A.damagePeriodic then
            set A.timeMax = 0.00
            
            set d = 0.00
            
            loop
                call GroupEnumUnitsInRange( TempGroup, A.l.x + d * ax, A.l.y + d * ay, A.radius - ( A.radius - A.radiusEnd ) * ( d / A.distance ) + 200.00, null )
                
                loop
                    set u = FirstOfGroup( TempGroup )
                    exitwhen u == null
                    call GroupRemoveUnit( TempGroup, u )
                    
                    if not IsUnitInGroup( u, TempGroup1 ) then
                        if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then // условия для нанесения урона
                            if IsUnitInRangeXY( u, A.l.x + d * ax, A.l.y + d * ay, A.radius - ( A.radius - A.radiusEnd ) * ( d / A.distance ) ) then
                                call SetUnitAbilityLevel( TempUnit, 'A001', A.lvl )
                                call IssueTargetOrder( TempUnit, "slow", u )
                                
                                call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\CarrionSwarm\\CarrionSwarmDamage.mdl", u, "origin" ) )
                                call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
                                call GroupAddUnit( TempGroup1, u )
                            endif
                        endif
                    endif
                endloop
                
                if d + 32.00 > A.distance then
                    set d = A.distance
                else
                    set d = d + 32.00
                endif
                
                exitwhen d >= A.distance
            endloop
            
            call GroupClear( TempGroup1 )
        endif
    else
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call SetUnitAnimation( A.eye, "death" )
        call UnitApplyTimedLife( A.eye, 'BTLF', 3.00 )
        
        call SetUnitAnimation( A.field, "death" )
        call UnitApplyTimedLife( A.field, 'BTLF', 5.00 )
        
        call SetUnitAnimation( A.laserBig, "death" )
        call UnitApplyTimedLife( A.laserBig, 'BTLF', 6.00 )
        
        set A.t = null
        set A.eye = null
        set A.field = null
        set A.laser = null
        set A.laserBig = null
        set A.caster = null
        set A.target = null
        call A.l.destroy( )
        call A.destroy( )
    endif
endfunction

private function CreateEye takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local SpellS B = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 1 )
    local integer k = 0
    local integer i
    local real array x
    local real array y
    local real array z
    local real array x1
    local real array y1
    local real array z1
    local unit u
    
    set A.time = A.time + 0.01 / A.timeMax
    
    if A.time > 1.00 then
        set A.time = 1.00
    endif
    
    loop
        set x[k] = A.v[k].x
        set y[k] = A.v[k].y
        set z[k] = A.v[k].z
        set x1[k] = B.v[k].x
        set y1[k] = B.v[k].y
        set z1[k] = B.v[k].z
        
        set k = k + 1
        exitwhen k >= 4
    endloop
    
    set k = 0
    
    loop
        set i = 0
        
        loop
            set x[i] = ( 1.00 - A.time ) * x[i] + A.time * x[i + 1]
            set y[i] = ( 1.00 - A.time ) * y[i] + A.time * y[i + 1]
            set z[i] = ( 1.00 - A.time ) * z[i] + A.time * z[i + 1]
            set x1[i] = ( 1.00 - A.time ) * x1[i] + A.time * x1[i + 1]
            set y1[i] = ( 1.00 - A.time ) * y1[i] + A.time * y1[i + 1]
            set z1[i] = ( 1.00 - A.time ) * z1[i] + A.time * z1[i + 1]
            
            set i = i + 1
            exitwhen i > 4 - k
        endloop
        
        set k = k + 1
        exitwhen k >= 4 - 1
    endloop
    
    set x[0] = GetCorX( x[0] )
    set y[0] = GetCorY( y[0] )
    
    call SetUnitX( A.eye, x[0] )
    call SetUnitY( A.eye, y[0] )
    call SetUnitFlyHeight( A.eye, z[0] - GetLocZ( x[0], y[0] ), 0.00 )
    
    set x1[0] = GetCorX( x1[0] )
    set y1[0] = GetCorY( y1[0] )
    
    call SetUnitX( B.eye, x1[0] )
    call SetUnitY( B.eye, y1[0] )
    call SetUnitFlyHeight( B.eye, z1[0] - GetLocZ( x1[0], y1[0] ), 0.00 )
    
    if A.time >= 1.00 then
        call PauseTimer( A.t )
        
        call KillUnit( A.eye )
        call KillUnit( B.eye )
        
        set A.v[3].z = GetUnitFacing( A.caster )
        
        set A.eye = CreateUnit( A.p, 'u003', A.v[3].x, A.v[3].y, A.v[3].z )
        call UnitAddAbility( A.eye, 'Arav' )
        call SetUnitX( A.eye, A.v[3].x )
        call SetUnitY( A.eye, A.v[3].y )
        call SetUnitFlyHeight( A.eye, 80.00, 0.00 )
        call KillUnit( A.eye )
        
        set A.eye = CreateUnit( A.p, 'u004', A.v[3].x, A.v[3].y, A.v[3].z )
        call UnitAddAbility( A.eye, 'Arav' )
        call SetUnitX( A.eye, A.v[3].x )
        call SetUnitY( A.eye, A.v[3].y )
        call SetUnitFlyHeight( A.eye, 80.00, 0.00 )
        call KillUnit( A.eye )
        
        set A.field = CreateUnit( A.p, 'u006', A.v[3].x, A.v[3].y, A.v[3].z )
        call SetUnitX( A.field, A.v[3].x )
        call SetUnitY( A.field, A.v[3].y )
        call SetUnitAnimation( A.field, "birth" )
        call QueueUnitAnimation( A.field, "stand" )
            
        set A.laserBig = CreateUnit( A.p, 'u007', A.l.x, A.l.y, A.v[3].z )
        call SetUnitX( A.laserBig, A.l.x )
        call SetUnitY( A.laserBig, A.l.y )
        call SetUnitFlyHeight( A.laserBig, 80.00, 0.00 )
        call SetUnitAnimation( A.laserBig, "birth" )
        call QueueUnitAnimation( A.laserBig, "stand" )
        
        set A.v[3].x = A.v[3].x + 150.00 * Cos( A.v[3].z * bj_DEGTORAD )
        set A.v[3].y = A.v[3].y + 150.00 * Sin( A.v[3].z * bj_DEGTORAD )
        
        set A.eye = CreateUnit( A.p, 'u000', A.v[3].x, A.v[3].y, A.v[3].z )
        call SetUnitX( A.eye, A.v[3].x )
        call SetUnitY( A.eye, A.v[3].y )
        call SetUnitFlyHeight( A.eye, 80.00, 0.00 )
        call SetUnitAnimation( A.eye, "birth" )
        call QueueUnitAnimation( A.eye, "stand" )
        
        set i = 0
        loop
            call A.v[i].destroy( )
            call B.v[i].destroy( )
            
            set i = i + 1
            exitwhen i >= 4
        endloop
        
        call B.destroy( )
        
        set A.time = 1.50
        
        call TimerStart( A.t, 0.01, true, function Rotation )
    endif
endfunction

function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    local SpellS B = SpellS.create( )
    local real a
    
    set A.t = CreateTimer( )
    
    set A.caster = GetTriggerUnit( )
    set A.target = GetSpellTargetUnit( )
    
    set A.p = GetOwningPlayer( A.caster )
    
    set A.l = vector.create( GetUnitX( A.caster ), GetUnitY( A.caster ), 0.00 )
    
    set A.lvl = GetUnitAbilityLevel( A.caster, GetSpellAbilityId( ) )
    
    if A.lvl == 1 then // уровень абилки
        set A.damage = 10.00 // урон
    elseif A.lvl == 2 then
        set A.damage = 25.00
    else
        set A.damage = 40.00
    endif
    
    set A.damagePeriodic = 0.30 // периодичность урона
    
    set A.distance = 900.00 // дистанция
    
    set A.radius = 200.00 // начальный радиус
    set A.radiusEnd = 50.00 // конечный радиус
    
    set A.attackType = null // тип атаки
    set A.damageType = null // тип урона
    set A.weaponType = null // тип оружия (звук)
    
    set A.time = 0.00
    set A.timeMax = 0.80
    
    set A.v[0] = vector.create( A.l.x, A.l.y, 0.00 )
    set A.v[0].z = GetLocZ( A.l.x, A.l.y ) + GetUnitFlyHeight( A.caster ) + 50.00
    
    set a = Atan2( GetUnitY( A.target ) - A.l.y, GetUnitX( A.target ) - A.l.x )
    
    set A.v[1] = vector.create( A.v[0].x - 500.00 * Cos( a - bj_PI * 0.15 ), A.v[0].y - 500.00 * Sin( a - bj_PI * 0.15 ), A.v[0].z + 200.00 )
    set A.v[2] = vector.create( A.v[0].x - 100.00 * Cos( a - bj_PI * 0.15 ), A.v[0].y - 100.00 * Sin( a - bj_PI * 0.15 ), A.v[0].z + 200.00 )
    set A.v[3] = vector.create( A.v[0].x + 125.00 * Cos( a ), A.v[0].y + 125.00 * Sin( a ), 0.00 )
    set A.v[3].z = GetLocZ( A.v[3].x, A.v[3].y ) + 75.00
    
    set A.eye = CreateUnit( A.p, 'u002', A.v[0].x, A.v[0].y, a * bj_RADTODEG )
    call UnitAddAbility( A.eye, 'Arav' )
    call SetUnitX( A.eye, A.v[0].x )
    call SetUnitY( A.eye, A.v[0].y )
    call SetUnitFlyHeight( A.eye, 50.00, 0.00 )
    call SetUnitAnimation( A.eye, "birth" )
    call QueueUnitAnimation( A.eye, "stand" )
    
    set B.v[0] = vector.create( A.l.x, A.l.y, A.l.z )
    set B.v[1] = vector.create( B.v[0].x - 500.00 * Cos( a + bj_PI * 0.15 ), B.v[0].y - 500.00 * Sin( a + bj_PI * 0.15 ), A.v[1].z )
    set B.v[2] = vector.create( B.v[0].x - 100.00 * Cos( a + bj_PI * 0.15 ), B.v[0].y - 100.00 * Sin( a + bj_PI * 0.15 ), A.v[2].z )
    set B.v[3] = vector.create( A.v[3].x, A.v[3].y, A.v[3].z )
    
    set B.eye = CreateUnit( A.p, 'u002', B.v[0].x, B.v[0].y, a * bj_RADTODEG )
    call SetUnitX( B.eye, B.v[0].x )
    call SetUnitY( B.eye, B.v[0].y )
    call UnitAddAbility( B.eye, 'Arav' )
    call SetUnitFlyHeight( B.eye, 50.00, 0.00 )
    call SetUnitAnimation( B.eye, "birth" )
    call QueueUnitAnimation( B.eye, "stand" )
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call SaveInteger( H, GetHandleId( A.t ), 1, B )
    call TimerStart( A.t, 0.01, true, function CreateEye )
endfunction

//===========================================================================

function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
    
    set TempUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u008', 0.00, 0.00, 0.00 )
endfunction
endlibrary

Загруженные файлы
28
ShadowNinja, идея не самая оригинальная, в морозко делал уже подобное для босса, но пока делал именно этот заказ, появилась идея чтобы око саргараса спавнить над головой кастера и создавать такой же луч, который будет учитывать сферические координаты и направлен под наклоном в землю соответственно, клик правой кнопкой мыши позволит перенаправить такой луч на новую точку, но чтобы такое сделать нужен мемхак/южапи, поскольку требуется динамическое управление ориентацией модели, можно и на ванилке через кость и SetUnitLookAt, но не хочу этими костылями мазаться, тем более вне заказа
30
Я как понимаю нужны оригинальные идеи для спелов!
И что в луче лазаря уникального?
4
rsfghd, есть типа такого спелла на Хайве, но только луч за мышкой следует (за курсором)
Однако... В мультиплеере из-за этого спела у половины игроков карта вылетает
28
ShadowNinja, координаты мышки можно отловить только на мемхаке/южапи, во втором случае оно даже сразу засинханным будет, на ванилке разве что с помощью пкм управлять направлением луча
30
rsfghd, далана. На ваниле мышь ловили спамом трекаблов, а на рефе спамом фреймов.
28
nazarpunk, такими жуткими костылями я не хочу развлекаться, в особенности если это какая-то 480х480 карта
4
rsfghd, кстати говоря, можно ещё сделать этот луч не по юниту, а просто в определённую область! (думаю кому-то это будет полезно)
Можно даже сделать так: что бы этот луч влево и вправо поворачивался, вернее сам герой сам автоматически его поворачивал во время использования этой способности (в лево, потом в право и так далее до конца способности)
Так можно больше вражеских юнитов задеть
28
ShadowNinja, а я о чём говорю, когда предлагаю через пкм сделать луч. Кликнул во время каста и юнит повернулся в точку, куда кликнул, если кликнул на юнита, то кастер будет всё время поворачиваться на него, пока в другое место не кликнешь. Единственная проблема это невозможность отменить каст спелла движением. Но можно отменить, например, нажав на S
28
ShadowNinja, в принципе, отменить приказ движением всё же можно, но не через smart, а move
11
Заказ на работу
Дублирую сообщение, чтобы было видно всем:
"Название: Dodge
Метод: GUI
Версия Warcraft III: 1.26
Техническое описание: есть еще идея, www.hiveworkshop.com/threads/knightess-in-plate-armor.352884
я сделал эту модель, и там есть анимация, которая как в дарк соулсе перекат Spell Throw Alternate и уворот spell throw gold. Надо три варианта спеллов:
Первый вариант: расстояние до 400, проиграв анимацию герой быстро переместился перекатом на точку, которую указал игрок и получает сопротивление урону заклинаниям 100% и защиту 1000 на 2 секунд, а затем на 5 секунд получает скорость бега от свитка скорости 25%\50%\75% (необязательно для визуальности можешь в редакторе в разделе "графика" скорости бега поставить 350, а ходьбы 300 так как там walk fast есть).
Второй вариант: шанс 15\20\25% будучи атакованным, герой рандомно переместился вправо ЛИБО (рандомно) влево (влево пока не анимировал еще) и следующий удар будет критическим 150%\200%\250%. Анимация уворота длится 1.2 секунд. Надо чтобы после уклона герой авто-атаку сделал обычную, может быть такое что после уклона анимация атаки не сыграет вроде.
Третий вариант: это для другого персонажа, пусть временным тестером будет Мэв, при нажатии герой высоко отскакивает в противоположную сторону куда она смотрит (назад т.е.) анимацией Spell Slam (вроде), а зона, где она изначально была взрывается через 0.5 сек и наносит 100\200\300 урона в радиусе взрыва, скажем 600
Я думаю что уклон влево\вправо анимация очень медленная, я б хотел посмотреть как оно работает против группы противников) Поэтому добавлю измененный файл снизу. Там Spell throw Gold 0.6 секунд длится вместо 1.2
И еще чтобы эти абилки работали на всех, кто ее может изучить 😀"
Ответы (19)
28
Выполнение заказа

Заклинание готово!

Dodge (первый вариант)

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости переката и времени для баффов)
чисто из спеллмейкерского рационализма, я бы всё же добавил учёт преград для переката и сделал скорость переката (и анимации соответственно) в зависимости от скорости бега, а то глупо выглядит, когда бегает быстрее чем перекатывается, ну, и добавил бы минимальную дистанцию для переката, впрочем, прикладываю ещё одну версию с более быстрым перекатом (0.50 сек вместо 1.00)
Загруженные файлы
28
Выполнение заказа

Заклинание готово!

Dodge (второй вариант)

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости уворота, дальности, угла)
на видео демонстрация 100% уворота, чтобы не дожидаться выпадения шансов (в карте 15/20/25%)
кроме этого, длительность уворота поставил не 1.20, а 0.50, потому что ну это капес перебор дружище, впрочем, всё в твоих руках, угол настроил не под 90 градусов, а 50, чтобы кружился вокруг атакующего противника и делал нырки при беге к дальнику ближе к его стороне, но опять же, всё настраиваемо
кроме того, пока юнит не нанесёт критический удар, он добавлен в группу для проверки, планировал это делать только на время самого уворота, но понял, что слишком большая потеря контроля происходит, если тебя устраивает шанс того, что игрок может всё время в уворотах находиться на поле боя и не иметь возможности убежать/ударить - убери всё, что связано с TempGroup
Загруженные файлы
28
Shermanator00, хотел сделать спеллпак на эту модель, но она конченная какая-то, лишние звуки, нет точек крепления нормальных, забил короче
28
Shermanator00, а, только сейчас увидел что ты там изменённую модельку кинул, ну импортируешь заменой свою модель и посмотришь как оно выглядит
11
rsfghd, лишние звуки и точки крепления? И спасибо за работу, но на видео видно, что она уклоняется но при этом урон проходит
28
Shermanator00, не вижу во втором варианте что-то связанное с блокированием урона. Только перемещение влево/вправо и добавление критического шанса для следующей автоатаки. Есть 2 варианта, либо заблокировать урон с автоатаки во время рывка, либо добавить 100% уклонение на время рывка, что подходит?
28
лишние звуки и точки крепления?
Да, во время рывка ты слышишь какой-то лишний звук, во время критического удара то же самое, точек крепления будто вовсе нет, хотел эффект прикрепить к оружию/правой руке. Но мне уже всё равно даже если исправленную модель зальют
28
Shermanator00, есть ещё 2 варианта, это переделать не под "юнит атакован", а "юнит получает урон", но в данном случае уклонение уже не сработает вроде, только блокирование урона, при этом, не будет казусов, учитывающих факторы старта вылета снаряда и скорость снаряда (потому что абилка срабатывает, когда снаряд ещё даже не появился, при запахе атакующего)
Либо кастомная автоатака в карте)
11
Shermanator00, есть ещё 2 варианта, это переделать не под "юнит атакован", а "юнит получает урон", но в данном случае уклонение уже не сработает вроде, только блокирование урона, при этом, не будет казусов, учитывающих факторы старта вылета снаряда и скорость снаряда (потому что абилка срабатывает, когда снаряд ещё даже не появился, при запахе атакующего)
Либо кастомная автоатака в карте)
Я сделал эту модель и странно, в Magosе посмотрел вроде все атачменты есть. Модель мою промодерировали и сказали что все ок. Звуки я добавил через магос чтобы в игре триггерами не писать. Насчет получение урона: такое возможно сделать только с damage engine (увы старых версия нет только на 1.35+)? Там вроде все есть и блокирование урона и получение урона. Так можно сделать например удар в спину чтобы не нажимать кнопку S постоянно когда юнит атакован и тригерить собсвенно удар в спину.
Юнит получает урон эта функция добавлена в новом патче варкрафта. В старом ее нет(
28
Shermanator00, есть всё на ванилке. Если я предлагаю какие-то варианты недоступные стандартными методами, я говорю, что данный метод нестандартный
Я пытался прикрепить эффекты юниту, но мне не удалось прикрепить туда, где я ожидал их увидеть, ни на правой руке, ни на оружии, а значит, соответствующих аттачментов нет
Мне, как спеллмейкеру, звуки в модели порой мешают. Я хочу сам решать какой звук создавать и какой громкости
11
rsfghd, странно, что никто не писал до этого про точки крепления, но я гляну что там с ними, спасибо.
28
Shermanator00, вот с блоком урона и началом уворота при получении урона, а не замахе
Загруженные файлы
28
Выполнение заказа

Заклинание готово!

Dodge (третий вариант )

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
все настройки на гуи, думаю разберёшься
Загруженные файлы
28
Демонстрация работ
Shermanator00, блин, у тебя такой заказ простой, но даже тут не хватает банального разнообразия, придумывайте более интересные спеллы, например, в прыжке разбрасывает сюрикены в разные стороны, которые при непродолжительном полёте выбирают цели вокруг для преследования, при достижении цели - поджигают её временно, если целей не было обнаружено - падают в точку прыжка, создавая взрыв и поджигая почву на время

если кто-то захочет импортировать, то скопируйте папку Initialization в свою карту, объекты из ро и в триггере Spell настройте под себя 258-265 строки и поменяйте равкод абилки на 283 строке, ну и равкоды даммиков по коду, остальное требует минимальных знаний джасса
Загруженные файлы
28
Shermanator00, демонстративный вариант, если что, написан на вджассе, а не гуи

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
    constant real UNIT_MAX_COLLISION = 200.00
    constant location LFZ = Location( 0.00, 0.00 )
    
    real MaxX
    real MinX
    real MaxY
    real MinY
endglobals

native UnitAlive takes unit id returns boolean

function GetLocZ takes real x, real y returns real
    call MoveLocation( LFZ, x, y )
    return GetLocationZ( LFZ )
endfunction

function GetCorY takes real y returns real
    if y > MaxY then
        return MaxY
    elseif y < MinY then
        return MinY
    endif
    
    return y
endfunction

function GetCorX takes real x returns real
    if x > MaxX then
        return MaxX
    elseif x < MinX then
        return MinX
    endif
    
    return x
endfunction

function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
    return ((4 * h / d) * (d - x) + y1 - y0) * (x / d) + y0
endfunction

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

//===========================================================================
function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
    local rect r = GetWorldBounds( )
    
    set MaxX = GetRectMaxX( r )
    set MinX = GetRectMinX( r )
    set MaxY = GetRectMaxY( r )
    set MinY = GetRectMinY( r )
    
    call RemoveRect( r )
    set r = null
endfunction
endlibrary
Spell
library SpellLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

private struct ProjectileS
    timer t
    unit dummy
    unit dummy1
    
    vector array v[4]
    
    real time
    real timeMax
endstruct

private struct SpellS
    timer t
    unit caster
    player p
    vector v
    vector l
    
    real time
    real timeDamage
    
    real radius
    real damage
    real height
    
    real speed
    real distance
    real distanceMax
    
    attacktype attackType
    damagetype damageType
    weapontype weaponType
endstruct

private function MoveProjectile takes nothing returns nothing
    local ProjectileS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real array x
    local real array y
    local real array z
    local integer k = 0
    local integer i
    
    set A.time = A.time + 0.03125 / A.timeMax
    
    if A.time > 1.00 then
        set A.time = 1.00
    endif
    
    loop
        set x[k] = A.v[k].x
        set y[k] = A.v[k].y
        set z[k] = A.v[k].z
        
        set k = k + 1
        exitwhen k >= 4
    endloop
    
    set k = 0
    
    loop
        set i = 0
        
        loop
            set x[i] = ( 1.00 - A.time ) * x[i] + A.time * x[i + 1]
            set y[i] = ( 1.00 - A.time ) * y[i] + A.time * y[i + 1]
            set z[i] = ( 1.00 - A.time ) * z[i] + A.time * z[i + 1]
            
            set i = i + 1
            exitwhen i > 4 - k
        endloop
        
        set k = k + 1
        exitwhen k >= 4 - 1
    endloop
    
    set x[0] = GetCorX( x[0] )
    set y[0] = GetCorX( y[0] )
    
    call SetUnitX( A.dummy, x[0] )
    call SetUnitY( A.dummy, y[0] )
    call SetUnitFlyHeight( A.dummy, z[0] - GetLocZ( x[0], y[0] ), 0.00 )
    
    call SetUnitX( A.dummy1, x[0] )
    call SetUnitY( A.dummy1, y[0] )
    call SetUnitFlyHeight( A.dummy1, z[0] - GetLocZ( x[0], y[0] ), 0.00 )
    
    if A.time >= 1.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call SetUnitAnimation( A.dummy, "death" )
        call UnitApplyTimedLife( A.dummy, 'BTLF', 1.50 )
        
        call SetUnitAnimation( A.dummy1, "death" )
        call UnitApplyTimedLife( A.dummy1, 'BTLF', 1.50 )
        
        set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.dummy ), 'u002', x[0], y[0], GetRandomReal( 0.00, 360.00 ) )
        call SetUnitX( bj_lastCreatedUnit, x[0] )
        call SetUnitY( bj_lastCreatedUnit, y[0] )
        call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
        call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
        call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.67 )
        call SetUnitScale( bj_lastCreatedUnit, 2.50, 2.50, 2.50 )
        
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl", x[0], y[0] ) )
        
        set i = 0
        
        loop
            call A.v[i].destroy( )
            
            set i = i + 1
            exitwhen i >= 4
        endloop
        
        set A.dummy = null
        set A.dummy1 = null
        call A.destroy( )
    endif
endfunction

private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local ProjectileS B
    local real x
    local real y
    local real z
    local unit u
    local integer i
    
    if A.distance > 0.00 then
        set x = GetCorX( GetUnitX( A.caster ) + A.speed * A.v.x )
        set y = GetCorY( GetUnitY( A.caster ) + A.speed * A.v.y )
        
        if A.speed > A.distance then
            set A.speed = A.distance
        endif
        
        set A.distance = A.distance - A.speed
        
        call SetUnitX( A.caster, x )
        call SetUnitY( A.caster, y )
        call SetUnitFlyHeight( A.caster, ParabolaZ2( A.v.z, A.l.z, A.height, A.distanceMax, A.distance ) - GetLocZ( x, y ), 0.00 )
    endif
    
    if A.time > 0.00 then
        set A.time = A.time - 0.01
        
        if A.time <= 0.00 then
            set x = GetUnitX( A.caster )
            set y = GetUnitY( A.caster )
            set z = GetLocZ( x, y ) + GetUnitFlyHeight( A.caster ) + 85.00
            set i = 10
            
            loop
                set B = ProjectileS.create( )
                
                set B.t = CreateTimer( )
                set B.v[0] = vector.create( x, y, z )
                set B.v[1] = vector.create( x + 200.00 * GetRandomReal( -bj_PI, bj_PI ), y + 200.00 * GetRandomReal( -bj_PI, bj_PI ), GetRandomReal( z + 50.00, z + 200.00 ) )
                set B.v[2] = vector.create( x + 200.00 * GetRandomReal( -bj_PI, bj_PI ), y + 200.00 * GetRandomReal( -bj_PI, bj_PI ), GetRandomReal( z + 50.00, z + 100.00 ) )
                set B.v[3] = vector.create( A.l.x + GetRandomReal( -100.00, 100.00 ), A.l.y + GetRandomReal( -100.00, 100.00 ), A.l.z )
                
                set B.dummy = CreateUnit( A.p, 'u000', B.v[0].x, B.v[0].y, GetRandomReal( 0.00, 360.00 ) )
                call UnitAddAbility( B.dummy, 'Arav' )
                call SetUnitX( B.dummy, B.v[0].x )
                call SetUnitY( B.dummy, B.v[0].y )
                call SetUnitFlyHeight( B.dummy, B.v[0].z - GetLocZ( B.v[0].x, B.v[0].y ), 0.00 )
                call SetUnitAnimation( B.dummy, "birth" )
                call QueueUnitAnimation( B.dummy, "stand" )
                
                set B.dummy1 = CreateUnit( A.p, 'u001', B.v[0].x, B.v[0].y, GetRandomReal( 0.00, 360.00 ) )
                call UnitAddAbility( B.dummy1, 'Arav' )
                call SetUnitX( B.dummy1, B.v[0].x )
                call SetUnitY( B.dummy1, B.v[0].y )
                call SetUnitFlyHeight( B.dummy1, B.v[0].z - GetLocZ( B.v[0].x, B.v[0].y ), 0.00 )
                call SetUnitAnimation( B.dummy1, "birth" )
                call QueueUnitAnimation( B.dummy1, "stand" )
                
                set B.time = 0.00
                set B.timeMax = A.timeDamage
                
                call SaveInteger( H, GetHandleId( B.t ), 0, B )
                call TimerStart( B.t, 0.03125, true, function MoveProjectile )
                
                set i = i - 1
                exitwhen i <= 0
            endloop
        endif
    elseif A.timeDamage > 0.00 then
        set A.timeDamage = A.timeDamage - 0.01
        
        if A.timeDamage <= 0.00 then
            set bj_lastCreatedUnit = CreateUnit( A.p, 'u002', A.l.x, A.l.y, GetRandomReal( 0.00, 360.00 ) )
            call SetUnitX( bj_lastCreatedUnit, A.l.x )
            call SetUnitY( bj_lastCreatedUnit, A.l.y )
            call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
            call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.67 )
            call SetUnitScale( bj_lastCreatedUnit, 5.00, 5.00, 5.00 )
            
            set bj_lastCreatedUnit = CreateUnit( A.p, 'u002', A.l.x, A.l.y, GetRandomReal( 0.00, 360.00 ) )
            call SetUnitX( bj_lastCreatedUnit, A.l.x )
            call SetUnitY( bj_lastCreatedUnit, A.l.y )
            call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
            call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.67 )
            call SetUnitScale( bj_lastCreatedUnit, 8.00, 8.00, 8.00 )
            
            call DestroyEffect( AddSpecialEffect( "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", A.l.x, A.l.y ) )
        
            call GroupEnumUnitsInRange( TempGroup, A.l.x, A.l.y, A.radius + UNIT_MAX_COLLISION, null )
        
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if IsUnitInRangeXY( u, A.l.x, A.l.y, A.radius ) then
                    if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl", u, "chest" ) )
                        call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
                    endif
                endif
            endloop
        endif
    endif
    
    if A.distance <= 0.00 and A.timeDamage <= 0.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        set A.caster = null
        call A.l.destroy( )
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

private function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    
    set A.t = CreateTimer( )
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    
    set A.l = vector.create( GetUnitX( A.caster ), GetUnitY( A.caster ), ( GetUnitFacing( A.caster ) - 180.00 ) * bj_DEGTORAD )
    set A.v = vector.create( Cos( A.l.z ), Sin( A.l.z ), 0.00 )
    set A.l.z = GetLocZ( A.l.x, A.l.y )
    
    set A.damage = 100.00 * GetUnitAbilityLevel( A.caster, GetSpellAbilityId( ) )
    set A.radius = 185.00
    set A.distance = 400.00
    set A.distanceMax = A.distance
    set A.height = A.distance * 0.50
    set A.speed = A.distance * 0.01
    set A.time = 0.20
    set A.timeDamage = 1.20
    
    set A.v.z = GetLocZ( A.l.x + A.distance * A.v.x, A.l.y + A.distance * A.v.y )
    
    set A.attackType = ATTACK_TYPE_MAGIC
    set A.damageType = DAMAGE_TYPE_MAGIC
    set A.weaponType = null
    
    if UnitAddAbility( A.caster, 'Arav' ) then
        call UnitRemoveAbility( A.caster, 'Arav' )
    endif
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call TimerStart( A.t, 0.01, true, function Move )
endfunction

//===========================================================================
private function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId( ) == 'A000'
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
endfunction
endlibrary

28
Демонстрация работ
Shermanator00, вот тут ещё вариант прыжка, этот спеллпак делать начал где-то пол года назад, но мне не понравилось что он недостаточно интересный, поэтому не могу его выкатить, тут телепорт вверх с последующим приземлением, сразу после телепорта раскидывает сюрикены, которые застревают в земле, на них можно наступить и получить урон, через короткое время сюрикены, что остались в земле - возвращаются, попутно задевая всех противников
карту не скину, т.к. планирую переделать и выкатить, надеюсь это поможет немного интереснее фантазировать
Загруженные файлы
2 комментария удалено
4
Вот ещё идея, простая, но всё же (потом возможно ещё идеи оригинальнее накину):
Пассивная способность! Чем меньше у вражеского юнита HP в %, тем больше урона ему наносится! За каждые 10% недостающего HP у врага ему наносится больше урона! К примеру за каждые 10% отсутствующих HP прибавляется 15 ед урона, на 2 лвл 30 ед урона, на 3 лвл 45 ед урона и тд! А если у врага 100% HP, то пассивка ничего не наносит (начинает наносить при 90% HP и менее). Ну или как-то так.
И ещё одна пассивка "наоборот": тоже самое, но урон наносится чем больше у врага HP. При 100% макс урон у пассивки, при 10% HP у врага пассивка урона не наносит!
Вот! Видел похожий спелл на хайве, но там он был сделан криво, глюченый и не MUI. Так что нужен норм такой спелл, хорошо сделанный!
Ответы (1)
4
Этот спелл будет сложновато сделать без костылей?
3
Название: Молот древних (Rolling Slam)
Метод: любой
MUI: нет
Версия: 2.0.1
Цель: Точка на карте
Количество уровней: 4
Описание: Герой бьет перед собой эфирным молотом древних два раза. Сначала он разбивает землю в небольшом радиусе и наносит урон от своей атаки в виде магического урона, перемещаясь чуть вперед. Потом после паузы в 0,5 сек. бьет еще раз и так же перемещается чуть вперед. но уже с большем радиусом поражения.
Радиус первого удара об землю 250 АоЕ (Малый эффект).
Радиус второго удара об землю 375 АоЕ (Большой эффект).
Урон от каждого удара молота древних: 100% урона от атаки + 60/110/160/210 ед. в виде магического урона.
Перезарядка: 8 сек.
  • Если не сложно то сделать отображение урона как при крите над героем только оранжевого цвета;
  • В момент использования способности надо что бы остальный способности становились неактивными пока не пройдут два удара или не собьют способность;
  • Перезарядка начинается только с момента последнего (второго) удара или если собьют заклинание;
  • Не проходит сквозь текстуры, хай и лоу грануды;
  • Без багов если застрянет или герой умрет в процессе каста.
С чего брал идею: www.youtube.com/watch?v=NrMpmUg9Y7g PoE 2 - Rolling Slam со своими доработками :)
.
Предмет 1: "Сотрясатель земли"
Улучшает способность "Молот древних":
! Усиливает дополнительный магический урон до 120/220/360/420.
Если герой убивает противника способностью "Молотом древних", то c 15%-й вероятностью на его месте появляется Землетрясение (Даммик), которое наносит 100 ед. магического урона в сек и замедляет цели в радиусе 300 АоЕ на 35%.
Время существования Землетрясения: 6 сек.
Предмет 2: "Корона титана"
По окончанию действия способности "Молот древних", есть 30% шанс мгновенно ее перезарядить и улучшить ____урон от атаки следующей способности "Молот древних" до 250% (Анимация горения оружия на кончике клинка, с возможностью изменения эффекта) на 5 сек. Шанс на перезарядку не срабатывает от улучшенной версии способности!
Буду использовать это на анимациях Самуро (Мастер клинка) из Reforged
1 удар по земле: Attack 1
2 удар по земле: Attack Slam 1
Можно сразу подогнать спел под его анимации.
Ответы (8)
28
SebastianCarrey, а что насчёт кубиков рандома у атаки? Там есть минимальное и максимальное значение
28
Выполнение заказа

Заклинание готово!

Молот древних (Rolling Slam)

инструкция по импорту
удалить из папки Initialization триггеры, отделённые комментарием (нижние), скопировать папку и вставить в свою карту
поскольку у тебя уже есть триггер AllGlobals из прошлого заказа, тебе нужно просто скопировать строки 56-81 и вставить где-нибудь в своей библиотеке AllGlobalsLib
в триггере Spell всё, что тебе нужно/можно изменить, помечено комментарием
поскольку у тебя уже есть библиотека SpellLib из прошлого заказа, нужно переименовать библиотеку перед импортом, например, на SpellOneLib
на 291 строке укажи абилку ауры замедления у даммика землетрясения
строки 105-109 и 96-100 можно стереть, это дополнительный эффект при наличии усиления абилки, при усилении абилки так же могу порекомендовать изменять иконку способности на более усиленную версию
на строках 89-90 оффсет для удара (чтобы удар происходил на уровне меча, а не прямо под юнитом)
ну и перекопируй редактор объектов

Код
AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
    constant real UNIT_MAX_COLLISION = 200.00
endglobals

native UnitAlive takes unit id returns boolean

function UnitHasItemOfType takes unit u, integer id returns boolean
    local integer i = 0
    
    loop
        if GetItemTypeId( UnitItemInSlot( u, i ) ) == id then
            return true
        endif
        
        set i = i + 1
        exitwhen i >= bj_MAX_INVENTORY
    endloop
    
    return false
endfunction

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

function SetUnitAnimationByIndexTimer takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local unit u = LoadUnitHandle( H, i, 0 )
    
    call SetUnitAnimationByIndex( u, LoadInteger( H, i, 1 ) )
    call QueueUnitAnimation( u, "stand ready" )
    call QueueUnitAnimation( u, "stand" )
    
    call FlushChildHashtable( H, i )
    call DestroyTimer( t )
    
    set u = null
    set t = null
endfunction

function SetUnitAnimationByIndexEx takes unit u, integer i returns nothing
    local timer t = CreateTimer( )
    
    call SaveUnitHandle( H, GetHandleId( t ), 0, u )
    call SaveInteger( H, GetHandleId( t ), 1, i )
    
    call TimerStart( t, 0.00, false, function SetUnitAnimationByIndexTimer )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
//endfunction

Spell
library SpellLib
globals
    private constant group TempGroup = CreateGroup( )
    private item TempItem = null
    private integer UpgradedKill = 0
    
    constant key SpellUpgrade
endglobals

private struct SpellS
    timer t
    unit caster
    unit dummy
    player p
    effect e = null
    ability abil
    integer attack
    integer upgrade1
    integer upgrade2
    
    vector v
    
    real time
    real timePause
    
    real speed
    
    real radius
    real radiusMax
    
    real damage
    
    attacktype attackType
    damagetype damageType
    weapontype weaponType
endstruct

private function RemoveBuff takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    
    call DestroyEffect( LoadEffectHandle( H, i, 0 ) )
    call RemoveSavedHandle( H, GetHandleId( LoadUnitHandle( H, i, 1 ) ), SpellUpgrade )
    
    call FlushChildHashtable( H, i )
    call DestroyTimer( t )
    
    set t = null
endfunction

private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x = GetUnitX( A.caster ) + A.speed * A.v.x
    local real y = GetUnitY( A.caster ) + A.speed * A.v.y
    local real x1
    local real y1
    local unit u
    local boolean stunned = GetUnitAbilityLevel( A.caster, 'BPSE' ) > 0
    
    if not stunned then
        if A.timePause > 0.00 then
            set A.timePause = A.timePause - 0.01
            
            if A.timePause <= 0.00 then
                call SetUnitAnimationByIndex( A.caster, 3 ) // анимация второй атаки
            endif
        endif
        
        if A.timePause <= 0.00 then
            call SetItemPosition( TempItem, x, y )
            call SetItemVisible( TempItem, false )
            
            set x1 = GetItemX( TempItem )
            set y1 = GetItemY( TempItem )
            
            if not ( ( x - 1.00 > x1 or x + 1.00 < x1 ) or ( ( y - 1.00 > y1 ) or ( y + 1.00 < y1 ) ) ) then
                call SetUnitX( A.caster, x )
                call SetUnitY( A.caster, y )
            endif
            
            set A.time = A.time - 0.01
        endif
    else
        call SetUnitAnimation( A.caster, "stand" )
    endif
    
    if A.time <= 0.00 or stunned then
        if not stunned then
            set x = x + 100.00 * A.v.x
            set y = y + 100.00 * A.v.y
            
            if A.attack == 0 then
                call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl", x, y ) ) // эффект первого удара
                
                // доп. эффект от усиления "Корона титана"
                if A.e != null then
                    set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl", x, y )
                    call BlzSetSpecialEffectScale( bj_lastCreatedEffect, 0.75 )
                    call DestroyEffect( bj_lastCreatedEffect )
                endif
            else
                call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", x, y ) ) // эффект второго удара
                
                // доп. эффект от усиления "Корона титана"
                if A.e != null then
                    set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl", x, y )
                    call BlzSetSpecialEffectScale( bj_lastCreatedEffect, 1.15 )
                    call DestroyEffect( bj_lastCreatedEffect )
                endif
                
                set A.radius = A.radiusMax
            endif
            
            call GroupEnumUnitsInRange( TempGroup, x, y, A.radius + UNIT_MAX_COLLISION, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if IsUnitInRangeXY( u, x, y, A.radius ) then
                    if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                        if A.upgrade1 == 1 and GetRandomInt( 1, 100 ) <= 15 then // шанс заспавнить землетрясение при убийстве (15%)
                            set UpgradedKill = 1
                        endif
                        
                        call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
                        
                        set UpgradedKill = 0
                    endif
                endif
            endloop
            
            // плавающий текст
            set bj_lastCreatedTextTag = CreateTextTag( )
            call SetTextTagText( bj_lastCreatedTextTag, I2S( R2I( A.damage ) ) + "!", 12.50 * 0.023 / 10.00 )
            call SetTextTagPosUnit( bj_lastCreatedTextTag, A.caster, 75.00 ) 
            call SetTextTagColor( bj_lastCreatedTextTag, 255, 75, 0, 255 )
            call SetTextTagVelocity( bj_lastCreatedTextTag, 0.00, 0.0355 )
            call SetTextTagPermanent( bj_lastCreatedTextTag, false )
            call SetTextTagLifespan( bj_lastCreatedTextTag, 1.50 )
            call SetTextTagFadepoint( bj_lastCreatedTextTag, 0.00 )
        endif
        
        if A.attack == 0 and not stunned then
            set A.attack = 1
            
            set A.speed = A.speed * 2.00 // ускорение второго удара
            set A.time = 0.70 // время для второго удара
            set A.timePause = 0.50 // пауза перед вторым ударом
        else
            call PauseTimer( A.t )
            call FlushChildHashtable( H, GetHandleId( A.t ) )
            call DestroyTimer( A.t )
            
            call IssueImmediateOrder( A.caster, "stop" )
            
            if A.upgrade2 == 1 and not stunned then
                if GetRandomInt( 1, 100 ) <= 30 then // шанс усилить следующий каст абилки и сбросить перезарядку
                    set A.t = CreateTimer( )
                    
                    call SaveTimerHandle( H, GetHandleId( A.caster ), SpellUpgrade, A.t )
                    
                    call SaveEffectHandle( H, GetHandleId( A.t ), 0, AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", A.caster, "weapon" ) ) // эффект усиления
                    call SaveUnitHandle( H, GetHandleId( A.t ), 1, A.caster )
                    
                    call TimerStart( A.t, 5.00, false, function RemoveBuff ) // время усиления
                    
                    if A.e != null then
                        call BlzStartAbilityCooldown( A.abil, BlzGetAbilityCooldown( A.abil ) )
                    endif
                else
                    call BlzStartAbilityCooldown( A.abil, BlzGetAbilityCooldown( A.abil ) )
                endif
            else
                call BlzStartAbilityCooldown( A.abil, BlzGetAbilityCooldown( A.abil ) )
            endif
            
            call PauseUnit( A.caster, false )
            
            if A.e != null then
                call DestroyEffect( A.e )
                set A.e = null
            endif
            
            set A.t = null
            set A.abil = null
            set A.caster = null
            call A.v.destroy( )
            call A.destroy( )
        endif
    endif
endfunction

private function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    local integer lvl
    local timer t
    
    set A.t = CreateTimer( )
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    set A.abil = GetSpellAbility( )
    
    set A.v = vector.create( GetSpellTargetX( ) - GetUnitX( A.caster ), GetSpellTargetY( ) - GetUnitY( A.caster ), 0.00 )
    call A.v.normalize( )
    
    set A.damage = BlzGetUnitBaseDamageByIndex( A.caster, 0 ) + BlzGetUnitBonusDamageByIndex( A.caster, 0 )
    
    set lvl = GetUnitAbilityLevel( A.caster, GetSpellAbilityId( ) )
    
    if lvl == 1 then // уровень
        set A.damage = A.damage + 60.00 // доп. урон
    elseif lvl == 2 then
        set A.damage = A.damage + 110.00
    elseif lvl == 3 then
        set A.damage = A.damage + 160.00
    else
        set A.damage = A.damage + 210.00
    endif
        
    set A.radius = 250.00 // радиус первого удара
    set A.radiusMax = 375.00 // радиус второго удара
    
    if UnitHasItemOfType( A.caster, 'afac' ) then // "Сотрясатель земли"
        set A.damage = A.damage * 2.00 // доп. урон (х2)
        set A.upgrade1 = 1
    else
        set A.upgrade1 = 0
    endif
    
    if UnitHasItemOfType( A.caster, 'spsh' ) then // "Корона титана", настройки в других частях кода
        set A.upgrade2 = 1
    else
        set A.upgrade2 = 0
    endif
    
    set t = LoadTimerHandle( H, GetHandleId( A.caster ), SpellUpgrade )
    
    if t != null then
        set A.e = LoadEffectHandle( H, GetHandleId( t ), 0 )
       
        call PauseTimer( t )
        call FlushChildHashtable( H, GetHandleId( t ) )
        call DestroyTimer( t )
        
        call RemoveSavedHandle( H, GetHandleId( A.caster ), SpellUpgrade )
        
        set A.damage = A.damage * 2.50 // дополнительный урон от усиления "Корона титана"
        
        set t = null
    endif
    
    set A.attackType = ATTACK_TYPE_MAGIC
    set A.damageType = DAMAGE_TYPE_DEMOLITION
    set A.weaponType = null
    
    set A.time = 0.40 // время для первого удара
    set A.timePause = 0.00
    set A.speed = 1.20 // скорость перемещения
    set A.attack = 0
    
    call PauseUnit( A.caster, true )
    call SetUnitAnimationByIndexEx( A.caster, 2 ) // анимация первой атаки
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call TimerStart( A.t, 0.01, true, function Move )
endfunction

private function Damage takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    
    call GroupEnumUnitsInRange( TempGroup, A.v.x, A.v.y, A.radius + UNIT_MAX_COLLISION, null )
            
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if IsUnitInRangeXY( u, A.v.x, A.v.y, A.radius ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl", u, "chest" ) ) // доп. эффект при попадании
                call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
            endif
        endif
    endloop
    
    set A.time = A.time - 1.00 // периодичность урона землетрясения
    
    if A.time <= 0.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call SetUnitAnimation( A.dummy, "death" )
        call UnitRemoveAbility( A.dummy, 'A001' )
        call UnitApplyTimedLife( A.dummy, 'BTLF', 3.00 ) // время анимации смерти
        
        set A.t = null
        set A.caster = null
        set A.dummy = null
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

private function Spell_Actions_Death takes nothing returns nothing
    local SpellS A
    
    if UpgradedKill == 1 then
        set A = SpellS.create( )
        
        set A.t = CreateTimer( )
        set A.caster = GetKillingUnit( )
        set A.p = GetOwningPlayer( A.caster )
        set A.v = vector.create( GetUnitX( GetTriggerUnit( ) ), GetUnitY( GetTriggerUnit( ) ), 0.00 )
        
        set A.dummy = CreateUnit( A.p, 'u000', A.v.x, A.v.y, GetRandomReal( 0.00, 360.00 ) ) // даммик землетрясения
        
        call SetUnitX( A.dummy, A.v.x )
        call SetUnitY( A.dummy, A.v.y )
        call SetUnitAnimation( A.dummy, "birth" )
        call QueueUnitAnimation( A.dummy, "stand" )
        
        set A.radius = 300.00 // радиус землетрясения
        set A.damage = 100.00 // урон землетрясения
        set A.attackType = ATTACK_TYPE_MAGIC // тип атаки
        set A.damageType = DAMAGE_TYPE_FIRE // тип урона
        set A.weaponType = null // тип оружия (звук)
        set A.time = 6.00 // время землетрясения
        
        call SaveInteger( H, GetHandleId( A.t ), 0, A )
        call TimerStart( A.t, 1.00, true, function Damage ) // периодичность урона землетрясения
    endif
endfunction

//===========================================================================
private function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000' // равкод абилки
endfunction

function InitTrig_Spell takes nothing returns nothing
    local trigger trg = CreateTrigger( )
    
    call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( trg, function Spell_Actions_Death )
    
    set trg = null
    
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
    
    set TempItem = CreateItem( 'spsh', 0.00, 0.00 )
    call SetItemVisible( TempItem, false )
endfunction
endlibrary

Загруженные файлы
28
SebastianCarrey, бле, забыл добавить учёт того, что кастер жив. но комп уже выключил. В общем найди следующую строку в триггере Spell в функции Move: local boolean stunned = GetUnitAbilityLevel( A.caster, 'BPSE' ) > 0 и добавь or not UnitAlive( A.caster )
Должно выйти так:
local boolean stunned = GetUnitAbilityLevel( A.caster, 'BPSE' ) > 0 or not UnitAlive( A.caster )

И чтобы вдруг он при смерти не проиграл анимку Stand, чуть ниже найди call SetUnitAnimation( A.caster, "stand" ), и замени на
if UnitAlive( A.caster ) then
    call SetUnitAnimation( A.caster, "stand" )
endif
3
rsfghd:
Попробую сам поменять))
Тут правда нюанс с КД как я понимаю. Ругается)
Загруженные файлы
3
rsfghd:
Можно сделать от мин до макс значения что бы урон выглядел не статично.
И там же получается суммарный урон выводится? Урон от атаки + фиксированный магический же?
28
SebastianCarrey, посмотрел, к сожалению южапи немного скривил, либо реф с новым патчем изменил аргументы и выглядит следующим образом
BlzGetAbilityCooldown takes integer abilId, integer level returns real
Первым аргументом принимает равкод, а вторым уровень абилки, так что замени все эти строки на
BlzGetAbilityCooldown( 'A000', GetUnitAbilityLevel( A.caster, 'A000' ) )
Где А000 - равкод основной абилки
28
SebastianCarrey, я спрашивал у тебя за мин и макс атаку. Найди строку set A.damage = GetUniBaseDamageByIndex( ... ) и замени ее на
set A.damage = GetRandomInt( BlzGetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE_MINIMUM, 0 ), BlzGetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE_MAXIMUM, 0 ) ) + BlzGetUnitBonusDamageByIndex( A.caster, 0 )
Да, там суммарный урон выводится. Если нужно отдельный, то урон от атаки и абилки нужно записать в разные переменные, если нужно, могу объяснить, там буквально 2 строки написать в разных местах
28
SebastianCarrey, если не справляешься, то могу добавить вышеуказанное и скинуть код/карту
4
Заказ на работу
Придумал ещё спелл, которого нет (по крайней мере нормально сделанного, без багов):
Герой отталкивает вражеского юнита или героя (1 лвл - на 700 дистанцию, 2 лвл - на 800 дистанцию и тд. 5 лвлов всего у способности и враг получает стан на 2-3-5-6-7 сек в конце отталкивания, в зависимости от лвл способности). Knockback
И далее - всех кого этот враг задел, пока он летел назад - они тоже отталкиваются на 300 дистанцию и получают урон (в зависимости от лвл способности) и стан 1 сек!
Также сам враг получает урон каждый раз, когда он отталкивает юнитов собой (какой именно урон - зависит от лвл способности). Т.е. чем больше он оттолкнул, тем больше урона ему наносится! Ну и тем более урона он наносит сам своим юнитам.
Думаю в игре будет круто смотреться.
Ответы (5)
30
ShadowNinja, я даже такую наработку видел. Видать с фантазией у тебя беда...
4
nazarpunk, в этом я крайне сомневаюсь... Где тогда такая наработка, что бы я её скачал? Мне бы она не помешала
4
rsfghd, да, но это не совсем то... Тут смысл в том, что мы именно вражеским героем или юнитом раскидываем армию врага (+ чем больше своих он задел, тем больше ему урон)
Кстати - если он умрёт (враг, который летит) тогда абилка прекращается, и он больше никого раскинуть не сможет! Т.е. лучше выбрать цель на фулл хп
А у этой аббилки самим своим героем жертвуем - в толпу врагов врываемся (а таких абилок на самом деле много)
В геймплейном плане это 2 разные абилки и их в разных ситуациях используют
28
Выполнение заказа

Заклинание готово!

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, перекопировать нестандартное ро и вставить в свою карту
в триггере Spell настроить всё, что помечено комментарием, на своё усмотрение, остальное требует минимальных знаний джасса
выполнено на UjAPI

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
    constant real UNIT_MAX_COLLISION = 200.00
    
    real MaxX
    real MinX
    real MaxY
    real MinY
endglobals

native UnitAlive takes unit id returns boolean

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

function RemoveStun takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    
    call SetUnitStunned( LoadUnitHandle( H, i, 0 ), false )
    call DestroyEffect( LoadEffectHandle( H, i, 1 ) )
    
    call FlushChildHashtable( H, i )
    call DestroyTimer( t )
    
    set t = null
endfunction

function StunUnit takes unit u, real time, effect e returns nothing
    local timer t = CreateTimer( )
    
    call SetUnitStunned( u, true )
    
    call SaveUnitHandle( H, GetHandleId( t ), 0, u )
    call SaveEffectHandle( H, GetHandleId( t ), 1, e )
    call TimerStart( t, time, false, function RemoveStun )
    
    set t = null
endfunction

//===========================================================================
function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
    local rect r = GetWorldBounds( )
    
    set MaxX = GetRectMaxX( r )
    set MinX = GetRectMinX( r )
    set MaxY = GetRectMaxY( r )
    set MinY = GetRectMinY( r )
    
    call RemoveRect( r )
    set r = null
endfunction
endlibrary

Spell
library SpellLib
globals
    private constant group TempGroup = CreateGroup( )
    private item TempItem = null
endglobals

private struct ProjectileS
    timer t
    effect e
    effect e1
    
    real a
    
    vector array v[4]
    vector last
    
    real time
    real timeMax
endstruct

private struct SpellS
    timer t
    unit caster
    unit target
    player p
    vector v
    group g
    integer b
    integer lvl
    
    effect e
    effect e1
    
    real radius
    real damage
    real speed
    real distance
    real time
    
    attacktype attackType
    damagetype damageType
    weapontype weaponType
endstruct

private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local SpellS B
    local real x = GetUnitX( A.target )
    local real y = GetUnitY( A.target )
    local real x1
    local real y1
    local unit u
    
    if A.b == 1 then
        set A.b = 2
        
        set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl", x, y )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, -90.00, 0.00 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", x, y )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, -90.00, 0.00 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl", x, y )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, -90.00, 0.00 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        call UnitDamageTarget( A.caster, A.target, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
        
        call DestroyEffect( A.e )
        call DestroyEffect( A.e1 )
        
        set A.e = AddSpecialEffectTarget( "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeEmbers.mdl", A.target, "origin" )
        set A.e1 = AddSpecialEffectTarget( "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl", A.target, "origin" )
    endif
    
    if A.speed > A.distance then
        set A.speed = A.distance
    endif
    
    set x = x + A.speed * A.v.x
    set y = y + A.speed * A.v.y
    
    if A.b >= 2 then
        set A.b = A.b + 1
        
        if A.b == 6 then
            set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", x, y )
            call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 30.00 )
            call DestroyEffect( bj_lastCreatedEffect )
            
            set A.b = 2
        endif
    endif
    
    set A.distance = A.distance - A.speed
    
    call SetItemPosition( TempItem, x, y )
    call SetItemVisible( TempItem, false )
    
    set x1 = GetItemX( TempItem )
    set y1 = GetItemY( TempItem )
    
    if ( x - 1.00 > x1 or x + 1.00 < x1 ) or ( y - 1.00 > y1 or y + 1.00 < y1 ) then
        set A.distance = 0.00
        call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl", x, y ) )
    else
        call SetUnitX( A.target, x )
        call SetUnitY( A.target, y )
    endif
    
    if A.g != null then
        call GroupEnumUnitsInRange( TempGroup, x, y, A.radius + UNIT_MAX_COLLISION, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if not IsUnitInGroup( u, A.g ) and IsUnitInRange( u, A.target, A.radius ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    call GroupAddUnit( A.g, u )
                    
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl", u, "chest" ) )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl", u, "chest" ) )
                    
                    call UnitDamageTarget( A.caster, A.target, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
                    call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
                    call StunUnit( u, 1.00, AddSpecialEffectTarget( "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", u, "overhead" ) )
                    
                    set B = SpellS.create( )
                    
                    set B.t = CreateTimer( )
                    set B.target = u
                    set B.v = vector.create( GetUnitX( u ) - x, GetUnitY( u ) - y, 0.00 )
                    call B.v.normalize( )
                    set B.b = 0
                    
                    call SetUnitStunned( u, true )
                    
                    set A.speed = A.speed * 0.90
                    set B.speed = A.speed
                    set B.distance = B.speed / 0.015 * 0.50
                    set A.distance = A.distance * 0.90
                    
                    call SaveInteger( H, GetHandleId( B.t ), 0, B )
                    call TimerStart( B.t, 0.01, false, function Move )
                endif
            endif
        endloop
    endif
    
    if A.distance <= 0.00 or not UnitAlive( A.target ) then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        if A.b >= 2 then
            call DestroyEffect( A.e )
            call DestroyEffect( A.e1 )
            set A.e = null
            set A.e1 = null
            
            if UnitAlive( A.target ) then
                call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.target, "chest" ) )
                call StunUnit( A.target, 1.00 + 1.00 * A.lvl, AddSpecialEffectTarget( "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl", A.target, "overhead" ) )
            endif
        endif
        
        call SetUnitStunned( A.target, false )
        
        call DestroyGroup( A.g )
        
        set A.t = null
        set A.g = null
        set A.caster = null
        set A.target = null
        call A.v.destroy( )
        call A.destroy( )
    else
        call TimerStart( A.t, 0.01, false, function Move )
    endif
endfunction

private function MoveProjectile takes nothing returns nothing
    local ProjectileS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real array x
    local real array y
    local real array z
    local integer k = 0
    local integer i
    
    set A.time = A.time + 0.01 / A.timeMax
    
    if A.time >= 0.50 then
        set A.time = A.time + 0.01 / A.timeMax
    endif
    
    if A.time > 1.00 then
        set A.time = 1.00
    endif
    
    loop
        set x[k] = A.v[k].x
        set y[k] = A.v[k].y
        set z[k] = A.v[k].z
        
        set k = k + 1
        exitwhen k >= 4
    endloop
    
    set k = 0
    
    loop
        set i = 0
        
        loop
            set x[i] = ( 1.00 - A.time ) * x[i] + A.time * x[i + 1]
            set y[i] = ( 1.00 - A.time ) * y[i] + A.time * y[i + 1]
            set z[i] = ( 1.00 - A.time ) * z[i] + A.time * z[i + 1]
            
            set i = i + 1
            exitwhen i > 4 - k
        endloop
        
        set k = k + 1
        exitwhen k >= 4 - 1
    endloop
    
    call SetSpecialEffectPositionWithZ( A.e, x[0], y[0], z[0] )
    call SetSpecialEffectPositionWithZ( A.e1, x[0], y[0], z[0] )
    call SetSpecialEffectOrientation( A.e, A.a, Atan2( z[0] - A.last.z, SquareRoot( ( x[0] - A.last.x ) * ( x[0] - A.last.x ) + ( y[0] - A.last.y ) * ( y[0] - A.last.y ) ) ) * bj_RADTODEG, 0.00 )
    call SetSpecialEffectOrientation( A.e1, A.a, Atan2( z[0] - A.last.z, SquareRoot( ( x[0] - A.last.x ) * ( x[0] - A.last.x ) + ( y[0] - A.last.y ) * ( y[0] - A.last.y ) ) ) * bj_RADTODEG, 0.00 )
    
    if A.time >= 1.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call DestroyEffect( A.e )
        call DestroyEffect( A.e1 )
        
        set i = 0
        
        loop
            call A.v[i].destroy( )
            
            set i = i + 1
            exitwhen i >= 4
        endloop
        
        set A.e = null
        set A.e1 = null
        call A.last.destroy( )
        call A.destroy( )
    else
        set A.last.x = x[0]
        set A.last.y = y[0]
        set A.last.z = z[0]
    endif
endfunction

private function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    local ProjectileS B
    local real x
    local real y
    local real z
    local real a
    local real d
    
    set A.t = CreateTimer( )
    set A.caster = GetTriggerUnit( )
    set A.target = GetSpellTargetUnit( )
    set A.p = GetOwningPlayer( A.caster )
    set A.g = CreateGroup( )
    set A.b = 1
    set A.radius = 64.00 // радиус столкновения
    
    set A.e = AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", A.caster, "left hand" )
    set A.e1 = AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", A.caster, "right hand" )
    
    set x = GetUnitX( A.caster )
    set y = GetUnitY( A.caster )
    set z = GetAxisZ( x, y ) + GetUnitFlyHeight( A.caster ) + 50.00
    
    set A.v = vector.create( GetUnitX( A.target ) - x, GetUnitY( A.target ) - y, 0.00 )
    set d = A.v.length( )
    call A.v.normalize( )
    set a = Atan2( A.v.y, A.v.x )
    
    set A.lvl = GetUnitAbilityLevel( A.caster, GetSpellAbilityId( ) )
    
    set A.distance = 600.00 + 100.00 * A.lvl // дистанция
    set A.speed = A.distance * 0.015 // скорость
    set A.damage = 25.00 + 10.00 * A.lvl // урон
    
    set A.attackType = ATTACK_TYPE_MAGIC // тип атаки
    set A.damageType = DAMAGE_TYPE_FIRE // тип урона
    set A.weaponType = null // тип оружия (звук)
    
    call SetUnitStunned( A.target, true )
    call GroupAddUnit( A.g, A.caster )
    call GroupAddUnit( A.g, A.target )
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call TimerStart( A.t, 1.10, false, function Move )
    
    //===
    set B = ProjectileS.create( )
    set B.t = CreateTimer( )
    
    set B.a = a + bj_PI * 0.20
    
    set B.last = vector.create( x, y, z )
    set B.v[0] = vector.create( B.last.x, B.last.y, B.last.z )
    set B.v[1] = vector.create( B.v[0].x - ( d / 2.00 + 500.00 ) * Cos( B.a ), B.v[0].y - ( d / 2.00 + 500.00 ) * Sin( B.a ), B.v[0].z + 300.00 )
    set B.v[2] = vector.create( B.v[0].x + ( d - 200.00 ) * Cos( B.a + bj_PI * 0.10 ), B.v[0].y + ( d - 200.00 ) * Sin( B.a + bj_PI * 0.10 ), B.v[0].z )
    set B.v[3] = vector.create( GetUnitX( A.target ), GetUnitY( A.target ), 0.00 )
    set B.v[3].z = GetAxisZ( B.v[3].x, B.v[3].y ) + 50.00
    
    set B.e = AddSpecialEffect( "units\\human\\phoenix\\phoenix.mdl", B.v[0].x, B.v[0].y )
    call SetSpecialEffectZ( B.e, B.v[0].z )
    call SetSpecialEffectScale( B.e, 0.60 )
    call SetSpecialEffectAlpha( B.e, 155 )
    
    set B.e1 = AddSpecialEffect( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", B.v[0].x, B.v[0].y )
     
    set B.a = B.a * bj_RADTODEG
    set B.time = 0.00
    set B.timeMax = 1.50
    
    call SaveInteger( H, GetHandleId( B.t ), 0, B )
    call TimerStart( B.t, 0.01, true, function MoveProjectile )
    
    //===
    set B = ProjectileS.create( )
    set B.t = CreateTimer( )
    
    set B.a = a - bj_PI * 0.20
    
    set B.last = vector.create( x, y, z )
    set B.v[0] = vector.create( B.last.x, B.last.y, B.last.z )
    set B.v[1] = vector.create( B.v[0].x - ( d / 2.00 + 500.00 ) * Cos( B.a ), B.v[0].y - ( d / 2.00 + 500.00 ) * Sin( B.a ), B.v[0].z + 300.00 )
    set B.v[2] = vector.create( B.v[0].x + ( d - 200.00 ) * Cos( B.a - bj_PI * 0.10 ), B.v[0].y + ( d - 200.00 ) * Sin( B.a - bj_PI * 0.10 ), B.v[0].z )
    set B.v[3] = vector.create( GetUnitX( A.target ), GetUnitY( A.target ), 0.00 )
    set B.v[3].z = GetAxisZ( B.v[3].x, B.v[3].y ) + 50.00
    
    set B.e = AddSpecialEffect( "units\\human\\phoenix\\phoenix.mdl", B.v[0].x, B.v[0].y )
    call SetSpecialEffectZ( B.e, B.v[0].z )
    call SetSpecialEffectScale( B.e, 0.60 )
    call SetSpecialEffectAlpha( B.e, 155 )
    
    set B.e1 = AddSpecialEffect( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", B.v[0].x, B.v[0].y )
    
    set B.a = B.a * bj_RADTODEG
    set B.time = 0.00
    set B.timeMax = 1.50
    
    call SaveInteger( H, GetHandleId( B.t ), 0, B )
    call TimerStart( B.t, 0.01, true, function MoveProjectile )
endfunction

//===========================================================================
private function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000' // равкод
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
    
    set TempItem = CreateItem( 'spsh', 0.00, 0.00 )
    call SetItemVisible( TempItem, false )
endfunction
endlibrary

Загруженные файлы
30

Заказ

Название: Щит
Метод: UjAPI
Версия Warcraft III: На свой вкус
Техническое описание:
Две способности в синергии:
  • Первая кастует channel щит, который ловит все летящие прожектайлы. Даже от автоатаки.
  • Вторая направляет все пойманные прожектайлы в выбранную цель.
Ответы (1)
28
nazarpunk, мб когда апи с прожектайлами починятся и дополнятся, то сделаю заказы с копированием снарядов, сейчас каждый раз на грабли натыкаюсь и тильтую
30

Заказ

Название: Союз крови
Метод: UjAPI
Версия Warcraft III: На свой вкус
Техническое описание:
Три способности в синергии:
  • Первая вешает бафф который распределяет урон по юнитам имеющим этот баф между всеми юнитами имеющими этот бафф.
  • Вторая и третья это channel молния, которая кастуется только в юнита имеющая этот баф. Одна вливает весь урон по кастеру в юнитов имеющих этот баф. Вторая вливает всё лечение кастера в юнитов имеющих этот баф.
30

Заказ

Название: Возмездие
Метод: UjAPI
Версия Warcraft III: На свой вкус
Техническое описание:
Бафф на одиночную цель. Любой прожектайл запущенный юнитом с баффом будет скопирован и запущен от кастера в этого юнита.
30

Заказ

Название: Аркан способности
Метод: UjAPI
Версия Warcraft III: На свой вкус
Техническое описание:
Пассивная способность. Любая способность с целью скастованная на героя с этой пассивкой сжигает у героя затраченную на неё ману и создаёт в инвентаре предмет, который позволяет скастовать эту способность. Лимит стака предметов равен уровню героя.
10
Заказ на работу
Название: наездник
Метод: GUI
Версия Warcraft III: 1.26
Техническое описание:
Герой садится на лошадь, овцу, свинью, при условии что у героя в инвентаре есть седло ( можно любой другой предмет). У животного появляется шкала усталости.
По седлам: 1 ур седла 200м, 2 ур. 400м.
После того как герой слез, усталость животного восполняется 1 ед в пол секунды. Максимально 100
Ответы (1)
28
ME_RiDi, тз с результатом хз. Животным абилку дирижабля дать или это трансформация юнита как с лучница и и гиппогрифами? Или просто периодически героя перемещать в позицию животного? Как затрачивается шкала усталости? Что будет при полном нуле? Нужно ли отображать шкалу? Если да, то каким способом?
4
Хотел ещё одну способность описать... Но кажется автор всё, выгорел)
Или у него больше нет времени. А спамить способностями не хочется
Ответы (2)
28
ShadowNinja, да не выгорел. Пытался заказ назарпанка сделать, а на южапи функции не работали должным образом, анрайз что-то поправил и продолжает исправлять, но я потратил на это выходной. Оставляй заказы, по мере заинтересованности буду делать. Вечером отталкиванием займусь, возьму анимку spell у чародея крови, выпущу двух фениксов по дуге в сторону цели и вместе со свистелками реализую отталкивание. Единственное что мне не очень нравится, это то, что цель может двигаться, из-за этого проблемы логические могут возникнуть. Впрочем, если делать мгновенное отталкивание без украшений, то всё будет оке, но у тебя технические задачи на полёт моей собственной фантазии. Буду делать на южапи
У меня в будние очень мало времени на хобби
28
ShadowNinja, чтоб ты не думал, что я ничем не занимался
Кроме этого в планах сделать кат со всеми выполненными заказами в самом ресурсе, чтобы люди могли искать интересующие спеллы не бегая по страницам комментариев
4
Заказ на работу
Пассивный спелл для определённой модели
Нашёл я на просторах Хайва такую модель, и у неё есть анимация Spell Slam.
Он стреляет перед собой лазерами вот так
Так вот, спелл такой: есть 20% что при каждом выстреле проиграется такая анимация и этот зелёный лазер нанесёт 150 ед урона всем наземным врагам! Именно что бы лазер попал по врагу, как в анимации. Если это возможно, т.е. под кораблём он никого не должен задамажить, а только там где лазер пройдёт (ну или примерно). Притом сама атака тоже должна пройти (помимо этого спелла).
Ну или это будет вместо атаки, если так не получится норм сделать!
Ну или примерно сделать как получится для этой анимации Spell Slam, но спелл должен быть пассивный, а не активный т.к. таких кораблей может быть много
Модельку и картинку прилагаю!
Загруженные файлы
Ответы (11)
28
Выполнение заказа

Заклинание готово!

я немного не понял нужен ли учёт сферических координат, если корабль только по наземным должен дамажить, поэтому просто пихнул проверку, что юнит не летающий
на видосе 100% шанс срабатывания, пассивка срабатывает после получения урона противником, могу переделать под старт вылета снаряда либо при замахе
инструкция по импорту
скопировать папку Initialization и вставить в свою карту
в триггере DamageEvent:
78 строка - указать абилку и шанс такой атаки (абилку выдать юнитам, что должны проводить эту атаку)
85 строка - начальный оффсет угла от взгляда атакующего
86 строка - скорость вращения лазеров
93 строка - через сколько секунд появляются лазеры после начала проигрывания анимки Spell Slam
21-24 строки - оффсеты для лазеров
30 строка - радиус вокруг атакующего
38 строка - ширина лазера (32.00)
47, 49-52 строки - шаг лазера (чем больше тем менее точно, но более оптимизировано, лучше не ставить больше радиуса лазера)
48 строка - дальность лазера
54-55 - эффекты, использовал по сути как дебаг для ориентации скорости, оффсета и угла лазеров, можно удалить строки
58 - максимальный угол лазеров
71 - периодичность таймера (чем больше, тем оптимизированнее и менее точно, при изменении этой строки на 86 строке (0.05) тоже изменить периодичность)
делал на южапи

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
    constant real UNIT_MAX_COLLISION = 200.00
endglobals

native UnitAlive takes unit id returns boolean

//===========================================================================
//function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
//endfunction
endlibrary

DamageEvent
library DamageEventLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

private struct SpellS
    timer t
    unit caster
    player p
    group g
    real angle
    real speed
endstruct

private function Damage takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real d = 0.00 
    local real a = GetUnitFacing( A.caster ) * bj_DEGTORAD
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local real x1 = x + 125.00 * Cos( a + bj_PI * 0.30 )
    local real y1 = y + 125.00 * Sin( a + bj_PI * 0.30 )
    local real x2 = x + 125.00 * Cos( a - bj_PI * 0.30 )
    local real y2 = y + 125.00 * Sin( a - bj_PI * 0.30 )
    local unit u
    
    call GroupEnumUnitsInRange( TempGroup, x, y, 400.00 + UNIT_MAX_COLLISION, null )
    
    set A.angle = A.angle + A.speed
    
    loop
        loop
            set u = GroupForEachUnit( TempGroup )
            exitwhen u == null
            
            if not IsUnitInGroup( u, A.g ) then
                if IsUnitInRangeXY( u, x1, y1, 32.00 ) or IsUnitInRangeXY( u, x2, y2, 32.00 )then
                    if UnitAlive( u ) and IsUnitEnemy( u, A.p ) and not IsUnitType( u, UNIT_TYPE_FLYING ) then
                        call GroupAddUnit( A.g, u )
                        call UnitDamageTarget( A.caster, u, 150.00, false, false, null, null, null )
                    endif
                endif
            endif
        endloop
        
        set d = d + 32.00
        exitwhen d >= 200.00
        set x1 = x1 + 32.00 * Cos( a + A.angle )
        set y1 = y1 + 32.00 * Sin( a + A.angle )
        set x2 = x2 + 32.00 * Cos( a - A.angle )
        set y2 = y2 + 32.00 * Sin( a - A.angle )
        
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", x1, y1 ) )
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", x2, y2 ) )
    endloop
    
    call GroupClear( TempGroup )
    
    if A.angle * bj_RADTODEG >= 120.00 or not UnitAlive( A.caster ) then
        call PauseTimer( A.t )
        call DestroyTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        
        call SetUnitStunned( A.caster, false )
        call DestroyGroup( A.g )
        
        set A.t = null
        set A.g = null
        set A.caster = null
        call A.destroy( )
    else
        call TimerStart( A.t, 0.05, false, function Damage )
    endif
endfunction

private function DamageEvent_Actions takes nothing returns nothing
    local SpellS A
    
    if GetUnitAbilityLevel( GetEventDamageSource( ), 'A000' ) > 0 and GetEventIsAttack( ) and GetRandomInt( 1, 100 ) <= 20 then
        set A = SpellS.create( )
        
        set A.t = CreateTimer( )
        set A.caster = GetEventDamageSource( )
        set A.p = GetOwningPlayer( A.caster )
        set A.g = CreateGroup( )
        set A.angle = 60.00 * bj_DEGTORAD
        set A.speed = 60.00 / 0.75 * 0.05 * bj_DEGTORAD
        
        call SetUnitStunned( A.caster, true )
        call SetUnitAnimation( A.caster, "spell slam" )
        call QueueUnitAnimation( A.caster, "stand" )
        
        call SaveInteger( H, GetHandleId( A.t ), 0, A )
        call TimerStart( A.t, 0.25, false, function Damage )
    endif
endfunction

//===========================================================================
function InitTrig_DamageEvent takes nothing returns nothing
    set gg_trg_DamageEvent = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DamageEvent, EVENT_PLAYER_UNIT_DAMAGED )
    call TriggerAddAction( gg_trg_DamageEvent, function DamageEvent_Actions )
endfunction
endlibrary

Загруженные файлы
12
rsfghd, крутой спелл... А можно его для Reforget версии? А то он на ней не работает (ошибку выписывает)
28
FIRERANGER, скрин ошибки нужен, я просто названия функций не знаю на рефе, но скорее будет жаловаться только на GetEventIsAttack( ) где нужно добавить Blz вначале названия функции
12
rsfghd, вот такие ошибки... Какие-то непонятные! Хотелось бы этот спелл в свою карту в рефоржете
Загруженные файлы
12
rsfghd, да точно... Забыл что эта галочка в каждой новой карте слетает.
Только теперь такая ошибка! Можешь плз пофиксить для рефа?
Загруженные файлы
28
FIRERANGER, добавь приставки Blz к каждой из функций, что показывает тебе ошибка. То есть не SetUnitStunned а BlzSetUnitStunned и всё заработает (если эти функции там есть конечно, иначе действительно придется переписывать некоторые моменты и добавить систему стана)
12
rsfghd, к сожалению нет... Эти 3 ошибки остались... Можешь под реф переделать спелл плз?
А то получается что любая карта с этим спелом на рефе не пойдёт. Хотя большинство старых карт идут хорошо
28
Вышла новая версия! Прокрутить к ресурсу
FIRERANGER, убрал GroupForEachUnit и воспользовался обычным FirstOfGroup, заменил SetUnitStunned на BlzPauseUnitEx
DamageEvent
library DamageEventLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

private struct SpellS
    timer t
    unit caster
    player p
    group g
    real angle
    real speed
endstruct

private function Damage takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real d = 0.00 
    local real a = GetUnitFacing( A.caster ) * bj_DEGTORAD
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local real x1 = x + 125.00 * Cos( a + bj_PI * 0.30 )
    local real y1 = y + 125.00 * Sin( a + bj_PI * 0.30 )
    local real x2 = x + 125.00 * Cos( a - bj_PI * 0.30 )
    local real y2 = y + 125.00 * Sin( a - bj_PI * 0.30 )
    local unit u
    
    set A.angle = A.angle + A.speed
    
    loop
        call GroupEnumUnitsInRange( TempGroup, x, y, 400.00 + UNIT_MAX_COLLISION, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if not IsUnitInGroup( u, A.g ) then
                if IsUnitInRangeXY( u, x1, y1, 32.00 ) or IsUnitInRangeXY( u, x2, y2, 32.00 )then
                    if UnitAlive( u ) and IsUnitEnemy( u, A.p ) and not IsUnitType( u, UNIT_TYPE_FLYING ) then
                        call GroupAddUnit( A.g, u )
                        call UnitDamageTarget( A.caster, u, 150.00, false, false, null, null, null )
                    endif
                endif
            endif
        endloop
        
        set d = d + 32.00
        exitwhen d >= 200.00
        set x1 = x1 + 32.00 * Cos( a + A.angle )
        set y1 = y1 + 32.00 * Sin( a + A.angle )
        set x2 = x2 + 32.00 * Cos( a - A.angle )
        set y2 = y2 + 32.00 * Sin( a - A.angle )
        
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", x1, y1 ) )
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", x2, y2 ) )
    endloop
    
    if A.angle * bj_RADTODEG >= 120.00 or not UnitAlive( A.caster ) then
        call PauseTimer( A.t )
        call DestroyTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        
        call BlzPauseUnitEx( A.caster, false )
        call DestroyGroup( A.g )
        
        set A.t = null
        set A.g = null
        set A.caster = null
        call A.destroy( )
    else
        call TimerStart( A.t, 0.05, false, function Damage )
    endif
endfunction

private function DamageEvent_Actions takes nothing returns nothing
    local SpellS A
    
    if GetUnitAbilityLevel( GetEventDamageSource( ), 'A000' ) > 0 and BlzGetEventIsAttack( ) and GetRandomInt( 1, 100 ) <= 100 then
        set A = SpellS.create( )
        
        set A.t = CreateTimer( )
        set A.caster = GetEventDamageSource( )
        set A.p = GetOwningPlayer( A.caster )
        set A.g = CreateGroup( )
        set A.angle = 60.00 * bj_DEGTORAD
        set A.speed = 60.00 / 0.75 * 0.05 * bj_DEGTORAD
        
        call BlzPauseUnitEx( A.caster, true )
        call SetUnitAnimation( A.caster, "spell slam" )
        call QueueUnitAnimation( A.caster, "stand" )
        
        call SaveInteger( H, GetHandleId( A.t ), 0, A )
        call TimerStart( A.t, 0.25, false, function Damage )
    endif
endfunction

//===========================================================================
function InitTrig_DamageEvent takes nothing returns nothing
    set gg_trg_DamageEvent = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DamageEvent, EVENT_PLAYER_UNIT_DAMAGED )
    call TriggerAddAction( gg_trg_DamageEvent, function DamageEvent_Actions )
endfunction
endlibrary


стоит 100% шанс, как изменить я уже описывал выше
Загруженные файлы
1

Заказ

Название: Название способности (опционально, если заказ один)
Метод: JASS/vJASS
Версия Warcraft III: Любая версия
Загруженные файлы
Ответы (6)
28
UndeadFisher, на стандартных эффектах это будет менее эффектно выглядеть, но попробую что-нибудь придумать
28
Выполнение заказа

Заклинание готово!

инструкция по импорту
удалить триггеры ниже триггера Spell
скопировать папку Initialization и вставить в свою карту
указать равкод абилки на 367 строке триггера Spell
изменить строки 340-344 на свой вкус
всё остальное требует минимальных знаний джасса
сделано на южапи

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
    constant real UNIT_MAX_COLLISION = 200.00
endglobals

native UnitAlive takes unit id returns boolean

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct
endlibrary

//===========================================================================
//function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
//endfunction

Spell
library SpellLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

private struct SpellS
    timer t
    unit caster
    effect e
    player p
    vector v
    vector l
    integer i
    group g
    
    real damage
    real speed
    real distance
    real time
    real radius
    handlelist effectList
    
    attacktype attackType
    damagetype damageType
    weapontype weaponType
endstruct

private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    
    if A.speed > A.distance then
        set A.speed = A.distance
    endif
    
    set A.distance = A.distance - A.speed
    
    set A.l.x = A.l.x + A.speed * A.v.x
    set A.l.y = A.l.y + A.speed * A.v.y
    set A.l.z = A.l.z + A.speed * A.v.z
    
    call SetSpecialEffectPositionWithZ( A.e, A.l.x, A.l.y, A.l.z )
    
    if A.distance <= 0.00 or A.l.z <= GetAxisZ( A.l.x, A.l.y ) + 32.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call DestroyEffect( A.e )
        
        if A.i == 1 then
            call SetSpecialEffectVisible( A.e, false )
            
            set A.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl", A.l.x, A.l.y )
            call SetSpecialEffectZ( A.e, A.l.z )
            call SetSpecialEffectOrientation( A.e, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, 45.00, 0.00 )
            call SetSpecialEffectTimeScale( A.e, 2.00 )
            call DestroyEffect( A.e )
        endif
        
        set A.e = null
        set A.t = null
        call A.l.destroy( )
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

private function Damage takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    
    loop
        set u = FirstOfGroup( A.g )
        exitwhen u == null
        call GroupRemoveUnit( A.g, u )
        
        call SetUnitStunned( u, false )
        call SetUnitTimeScale( u, 1.00 )
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", u, "chest" ) )
        
        call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
    endloop
    
    call PauseUnit( A.caster, false )
    
    set A.l.z = GetUnitFacing( A.caster ) * bj_DEGTORAD
    set A.l.x = A.l.x + 100.00 * Cos( A.l.z )
    set A.l.y = A.l.y + 100.00 * Sin( A.l.z )
    
    call DestroyEffect( A.e )
    
    set A.e = AddSpecialEffect( "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", A.l.x, A.l.y )
    call DestroyEffect( A.e )
    
    loop
        call DestroyEffect( HandleListGetEffectByIndex( A.effectList, A.i ) )
        
        set A.i = A.i - 1
        exitwhen A.i < 0
    endloop
    
    call HandleListDestroy( A.effectList )
    
    call PauseTimer( A.t )
    call FlushChildHashtable( H, GetHandleId( A.t ) )
    call DestroyTimer( A.t )
    
    call DestroyGroup( A.g )
    
    set A.g = null
    set A.t = null
    set A.e = null
    set A.caster = null
    call A.l.destroy( )
    call A.destroy( )
endfunction

private function AddHitEffect takes nothing returns nothing
    local integer i = GetRandomInt( 0, 5 )
    
    if i == 0 then
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", GetEnumUnit( ), "chest" ) )
    elseif i == 1 then
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", GetEnumUnit( ), "head" ) )
    elseif i == 2 then
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", GetEnumUnit( ), "left hand" ) )
    elseif i == 3 then
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", GetEnumUnit( ), "right hand" ) )
    elseif i == 4 then
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", GetEnumUnit( ), "left foot" ) )
    else
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl", GetEnumUnit( ), "right foot" ) )
    endif
endfunction

private function SpawnEffects takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local SpellS B = SpellS.create( )
    local real a = GetRandomReal( -bj_PI, bj_PI )
    local integer i
    
    call ForGroup( A.g, function AddHitEffect )
    
    set B.t = CreateTimer( )
    
    set B.i = 0
    set B.l = vector.create( A.l.x + GetRandomReal( A.radius * 0.80, A.radius ) * Cos( a ), A.l.y + GetRandomReal( A.radius * 0.80, A.radius ) * Sin( a ), A.l.z + GetRandomReal( -900.00, 0.00 ) )
    set a = a + bj_PI + GetRandomReal( -bj_PI, bj_PI ) * 0.25
    set B.v = vector.create( A.l.x + GetRandomReal( A.radius * 0.80, A.radius ) * Cos( a ), A.l.y + GetRandomReal( A.radius * 0.80, A.radius ) * Sin( a ), 0.00 )
    set B.v.z = GetAxisZ( B.v.x, B.v.y ) + B.l.z + GetRandomReal( -400.00, 100.00 )
    set B.v.x = B.v.x - B.l.x
    set B.v.y = B.v.y - B.l.y
    set B.v.z = B.v.z - B.l.z
    
    set B.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl", B.l.x, B.l.y )
    call SetSpecialEffectZ( B.e, B.l.z )
    call SetSpecialEffectOrientation( B.e, Atan2( B.v.y, B.v.x ) * bj_RADTODEG, Atan2( B.v.z, SquareRoot( B.v.x * B.v.x + B.v.y * B.v.y ) ) * bj_RADTODEG, 0.00 )
    call SetSpecialEffectTimeScale( B.e, 2.00 )
    call DestroyEffect( B.e )
    
    set B.e = AddSpecialEffect( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", B.l.x, B.l.y )
    call SetSpecialEffectZ( B.e, B.l.z )
    call SetSpecialEffectOrientation( B.e, Atan2( B.v.y, B.v.x ) * bj_RADTODEG, Atan2( B.v.z, SquareRoot( B.v.x * B.v.x + B.v.y * B.v.y ) ) * bj_RADTODEG, 0.00 )
    call SetSpecialEffectAnimation( B.e, "stand" )
    call SetSpecialEffectScale( B.e, 0.50 )
    
    set B.distance = B.v.length( )
    call B.v.normalize( )
    
    set B.speed = B.distance / 0.15 * 0.01
    
    call SaveInteger( H, GetHandleId( B.t ), 0, B )
    call TimerStart( B.t, 0.01, true, function Move )
    
    set A.time = A.time - 0.05
    
    if A.time <= 0.00 then
        call SetUnitFlyHeight( A.caster, 0.00, 0.00 )
        call ShowUnit( A.caster, true )
        call SetUnitAnimation( A.caster, "stand ready" )
        call QueueUnitAnimationByIndex( A.caster, 3 )
        call QueueUnitAnimation( A.caster, "stand" )
        
        set i = 6
    
        loop
            set B = SpellS.create( )
            set B.t = CreateTimer( )
            
            set B.i = 0
            set B.l = vector.create( A.l.x + A.radius * Cos( a ), A.l.y + A.radius * Sin( a ), A.l.z )
            set B.v = vector.create( A.l.x, A.l.y, 0.00 )
            set B.v.z = GetAxisZ( B.v.x, B.v.y ) + 100.00
            set B.v.x = B.v.x - B.l.x
            set B.v.y = B.v.y - B.l.y
            set B.v.z = B.v.z - B.l.z
            
            set B.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl", B.l.x, B.l.y )
            call SetSpecialEffectZ( B.e, B.l.z )
            call SetSpecialEffectOrientation( B.e, Atan2( B.v.y, B.v.x ) * bj_RADTODEG, Atan2( B.v.z, SquareRoot( B.v.x * B.v.x + B.v.y * B.v.y ) ) * bj_RADTODEG, 0.00 )
            call SetSpecialEffectTimeScale( B.e, 2.00 )
            call DestroyEffect( B.e )
            
            set B.e = AddSpecialEffect( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl", B.l.x, B.l.y )
            call SetSpecialEffectZ( B.e, B.l.z )
            call SetSpecialEffectOrientation( B.e, Atan2( B.v.y, B.v.x ) * bj_RADTODEG, Atan2( B.v.z, SquareRoot( B.v.x * B.v.x + B.v.y * B.v.y ) ) * bj_RADTODEG, 0.00 )
            call SetSpecialEffectAnimation( B.e, "stand" )
            call SetSpecialEffectScale( B.e, 0.50 )
            
            set B.distance = B.v.length( )
            call B.v.normalize( )
            
            set B.speed = B.distance / 0.20 * 0.01
            
            call SaveInteger( H, GetHandleId( B.t ), 0, B )
            call TimerStart( B.t, 0.01, true, function Move )
            
            set i = i - 1
            exitwhen i <= 0
            set a = a - bj_PI / 6.00 * 2.00
        endloop
        
        call DestroyEffect( A.e )
        
        set A.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl", A.l.x, A.l.y )
        call SetSpecialEffectYaw( A.e, GetUnitFacing( A.caster ) )
        call DestroyEffect( A.e )
        
        set A.e = AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.caster, "weapon" )
        
        if GetLocalPlayer( ) == A.p then
            call ClearSelection( )
            call SelectUnit( A.caster, true )
        endif
        
        call TimerStart( A.t, 2.10, false, function Damage )
    endif
endfunction

private function JumpClones takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local SpellS B
    local integer i = 6
    local real a = -bj_PI
    local unit u
    
    call GroupEnumUnitsInRange( TempGroup, A.l.x, A.l.y, A.radius, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if IsUnitInRangeXY( u, A.l.x, A.l.y, A.radius + UNIT_MAX_COLLISION ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                call GroupAddUnit( A.g, u )
                call SetUnitStunned( u, true )
                call SetUnitTimeScale( u, 0.00 )
            endif
        endif
    endloop
    
    call PauseUnit( A.caster, true )
    call ShowUnit( A.caster, false )
    
    set A.l.z = GetAxisZ( A.l.x, A.l.y ) + GetUnitFlyHeight( A.caster )
    
    set A.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl", A.l.x, A.l.y )
    call SetSpecialEffectZ( A.e, A.l.z )
    call SetSpecialEffectYaw( A.e, GetUnitFacing( A.caster ) )
    call DestroyEffect( A.e )
    
    set A.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\Bloodlust\\BloodlustTarget.mdl", A.l.x, A.l.y )
    call SetSpecialEffectZ( A.e, A.l.z / 2.00 )
    call SetSpecialEffectTimeScale( A.e, 0.10 )
    call SetSpecialEffectScale( A.e, 50.00 )
    call SetSpecialEffectAlpha( A.e, 175 )
    
    loop
        set B = SpellS.create( )
        
        set B.t = CreateTimer( )
        
        set B.l = vector.create( A.l.x, A.l.y, A.l.z )
        set B.v = vector.create( Cos( a ), Sin( a ), Cos( bj_PI * 0.50 ) )
        
        set B.i = 1
        set B.speed = 40.00
        set B.distance = A.radius
        
        set B.e = AddSpecialEffect( "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageMissile.mdl", B.l.x, B.l.y )
        call SetSpecialEffectZ( B.e, B.l.z )
        call SetSpecialEffectOrientation( B.e, a * bj_RADTODEG, 45.00, 0.00 )
        
        call SaveInteger( H, GetHandleId( B.t ), 0, B )
        call TimerStart( B.t, 0.01, true, function Move )
        
        set i = i - 1
        exitwhen i <= 0
        set a = a - bj_PI / 5.00
    endloop
    
    set A.radius = A.radius * 1.50
    set A.time = 2.00
    call TimerStart( A.t, 0.05, true, function SpawnEffects )
endfunction

private function Jump takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    
    if UnitAddAbility( A.caster, 'Arav' ) then
        call UnitRemoveAbility( A.caster, 'Arav' )
    endif
    
    call SetUnitFlyHeight( A.caster, 800.00, 800.00 / 0.20 )
    
    call DestroyEffect( A.e )
    
    set A.e = AddSpecialEffect( "Units\\NightElf\\Wisp\\WispExplode.mdl", A.l.x, A.l.y )
    call SetSpecialEffectAnimationOffsetPercent( A.e, 0.20 )
    call SetSpecialEffectTimeScale( A.e, 3.00 )
    call DestroyEffect( A.e )
    
    call TimerStart( A.t, 0.20, false, function JumpClones )
endfunction

private function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    local integer i
    local real a = GetRandomReal( -bj_PI, bj_PI )
    
    set A.t = CreateTimer( )
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    set A.l = vector.create( GetUnitX( A.caster ), GetUnitY( A.caster ), 0.00 )
    set A.g = CreateGroup( )
    set A.e = AddSpecialEffect( "Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl", A.l.x, A.l.y )
    call SetSpecialEffectScale( A.e, 2.00 )
    
    set A.damage = 200.00 // урон
    set A.radius = 600.00 // радиус
    set A.attackType = ATTACK_TYPE_CHAOS // тип атаки
    set A.damageType = DAMAGE_TYPE_SONIC // тип урона
    set A.weaponType = null
    
    set A.effectList = HandleListCreate( )
    
    set A.i = 60 // количество эффектов отображения радиуса
    set i = A.i
    
    loop
        set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Spells\\Orc\\Bloodlust\\BloodlustTarget.mdl", A.l.x + A.radius * Cos( a ), A.l.y + A.radius * Sin( a ) )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
        call HandleListAddHandle( A.effectList, bj_lastCreatedEffect )
        
        set i = i - 1
        exitwhen i <= 0
        set a = a + bj_PI / A.i * 2.00
    endloop
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call TimerStart( A.t, 1.50, false, function Jump )
endfunction

//===========================================================================
private function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
endfunction
endlibrary

Загруженные файлы
28
UndeadFisher, странно, только сейчас заметил на видосе, что при втором касте не заспавнились эффекты, но я не первый раз встречаю такую проблему, возможно дело в компе либо в самом варе, он не отображает порой эффекты, я из-за этой проблемы даже к даммикам возвращался когда-то, с ними всегда всё корректно было
1
rsfghd, Да, встроенные функции спецэффектов имеют свои проблемы, которые остаются нерешёнными. "Фальшивые" юниты не устарели и по-прежнему остаются актуальными.
28
UndeadFisher, мне кажется дело не в самих функциях, эффекты то создаются, но не отображаются
Этот комментарий удален
15
Заказ на работу
Название: Понижение защиты
Метод: Jass
Версия Warcraft III: 1.26
Техническое описание: При атаке у атакованного юнита отнимается защита в зависимости от уровня атакера, например если атакер 10 уровня, то с каждой атаки минусуется по 1 единице защиты за стак, если 20 уровень, то минусуется 2 единицы за стак и так до 100 уровня.
Максимум стаков - 7, когда достигает максимального стака, накидывается сайленс на 2 секунды, и через 5 секунд защита добавляется обратно.
Ответы (10)
28
Выполнение заказа

Заклинание готово!

Понижение защиты

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, перекопировать редактор объектов и вставить в свою карту, в триггере Melee Initialization настроить бд в соответствии с редактором объектов
в триггере EventDamage на 81 строке указать даммика, что будет кастовать таргетный сайленс
на 70 строке можно изменить время спадения дебаффа на броню
на 61 строке можешь настроить формулу уменьшения брони
на 54 строке аура торнадо для отображения дебаффа на юните + статус бар (на 24-25 то же самое)
советую сделать прелоад ауры, чтобы при первом получении не происходил пролаг

Код

EventDamage
function SetBonusArmorNegative takes unit u, integer value returns nothing
    local integer i = udg_BDMax
    
    loop
        exitwhen i <= 0
        
        if udg_BDValue[i] <= value then
            call UnitAddAbility( u, udg_BDAbil[i] )
        
            set value = value - udg_BDValue[i]
        else
            call UnitRemoveAbility( u, udg_BDAbil[i] )
        endif
        
        set i = i - 1
    endloop
endfunction

function RemoveDebuff takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local unit u = LoadUnitHandle( udg_H, i, 0 )
    
    call UnitRemoveAbility( u, 'A009' )
    call UnitRemoveAbility( u, 'B000' )
    call SetBonusArmorNegative( u, 0 )
        
    call RemoveSavedInteger( udg_H, GetHandleId( u ), 0 )
    
    call FlushChildHashtable( udg_H, i )
    call DestroyTimer( t )
    
    set u = null
    set t = null
endfunction

function Trig_EventDamage_Actions takes nothing returns nothing
    local unit damaged
    local timer t
    local integer i
    local integer stack
    
    if GetUnitAbilityLevel( GetTriggerUnit( ), 'Bspo' ) > 0 then
        set damaged = GetTriggerUnit( )
        call UnitRemoveAbility( damaged, 'Bspo' )
        
        set t = LoadTimerHandle( udg_H, GetHandleId( damaged ), 0 )
        
        if t == null then
            set t = CreateTimer( )
            
            call SaveTimerHandle( udg_H, GetHandleId( damaged ), 0, t )
            call UnitAddAbility( damaged, 'A009' )
            call SaveUnitHandle( udg_H, GetHandleId( t ), 0, damaged )
        endif
        
        set i = GetHandleId( t )
        set stack = LoadInteger( udg_H, i, 1 ) + 1
        
        call SetUnitAbilityLevel( damaged, 'A009', stack )
        call SetBonusArmorNegative( damaged, IMaxBJ( 1, R2I( GetHeroLevel( GetEventDamageSource( ) ) * 0.10 ) ) * stack )
        
        if stack < udg_BDMax then
            call SaveInteger( udg_H, i, 1, stack )
        else
            call IssueTargetOrder( udg_TempUnit, "soulburn", damaged )
        endif
        
        call TimerStart( t, 5.00, false, function RemoveDebuff )
        
        set t = null
        set damaged = null
    endif
endfunction

//===========================================================================
function InitTrig_EventDamage takes nothing returns nothing
    set gg_trg_EventDamage = CreateTrigger(  )
    call TriggerAddAction( gg_trg_EventDamage, function Trig_EventDamage_Actions )
    set udg_TempUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u000', 0.00, 0.00, 0.00 )
endfunction
28
LastUchiha, если ты захочешь отнимать больше защиты или добавить больше стаков, что превысит 123 единицы (1+2+4+8+16+32+64), то добавь просто новые значения в бд (х2 предыдущего числа, т.е. 128/256/512/1024...), и не забудь указать новое количество индексов для BDMax
28
LastUchiha, стаки на 63 строке триггера EventDamage, но я пихнул туда udg_BDMax, поскольку подходило под тз, лучше просто указать макс кол-во стаков
28
LastUchiha, ахахаха, блин, извиняюсь, перед сном делал спелл, вытащи из лупа в первом триггере всё, кроме добавления события, поставь чуть ниже/выше пика юнитов, а то там хэштаблица создаётся на каждого выбранного юнита
15
rsfghd, если продолжать бить юнита когда у него максимальный дебафф, то начнутся лаги, а именно фпс будет всё ниже и ниже садится.
28
Вышла новая версия! Прокрутить к ресурсу
LastUchiha, я сначала подумал, что может в цикле накосячил из-за недосыпа, но нет, это сайленс прикалывается. Когда обнулял значения сайленса, поставил периодичность урона на 0.00, в итоге, оно, похоже, каждые 0.00 секунд дамажило с 0 урона, вызывая триггер получения урона, решилось просто - выставил периодичность урона на 99999999999999, ну и приколы..

вот обновлённая карта с исправлением предыдущего косяка
15
rsfghd, защита возобновляться должна просто через 5 секунд, а тут если юнит за эти 5 секунд был атакован, то нужно опять ждать 5 секунд и так по кругу.
28
LastUchiha, напиши просто, что через 5 секунд после получения последнего стака - все стаки должны сброситься, так будет понятнее, перенеси строку call TimerStart( t, 5.00, false, function RemoveDebuff ) рядом к строке call SaveInteger( udg_H, i, 1, stack )
должно выйти так
        if stack < udg_BDMax then
            call SaveInteger( udg_H, i, 1, stack )
        	call TimerStart( t, 5.00, false, function RemoveDebuff )
        else
            call IssueTargetOrder( udg_TempUnit, "soulburn", damaged )
        endif
время таймера будет обновляться каждый раз, когда юнит получает автоатаку, за исключением наличия последнего стака
15

Заказ

Название: Божественная призма
Метод: Jass
Версия Warcraft III: 1.26а
Техническое описание: Если цель – противник, он получает 400 ед. урона от светлой магии и отражает энергию, которая восполняет 300 ед. здоровья 5 вашим союзникам в радиусе 30 м.
Если цель – союзник, он восстанавливает 600 ед. здоровья и отражает энергию, которая наносит 190 ед. урона от светлой магии 5 противникам в радиусе 30 м.
Ответы (6)
28
Desgul, светлая магия и отражение энергии это снаряд, молния или мгновенное?
28
Выполнение заказа

Заклинание готово!

Божественная призма

инструкция по импорту
скопировать папку Initialization и вставить в свою карту
скопировать даммика и абилку из ро и вставить в свою карту
в триггере Spell:
153 строка - указать равкод абилки
30-32 строки - указать скорость полёта снаряда
60 строка - количество целей для урона/хила после основной
54 строка - хил основной цели
57 строка - урон основной цели
62 строка - радиус с максимальной коллизией у юнита (+200)
71 строка - радиус
103 строка - хил второстепенных целей
105 строка - урон второстепенных целей
заменить 'u000' в коде на своего даммика

Код

Spell
function GetLocZ takes real x, real y returns real
    call MoveLocation( udg_LFZ, x, y )
    return GetLocationZ( udg_LFZ )
endfunction

function Move takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local integer k
    local player p
    local unit caster
    local unit target = LoadUnitHandle( udg_H, i, 1 )
    local unit dummy = LoadUnitHandle( udg_H, i, 2 )
    local unit u
    local real x = GetUnitX( dummy )
    local real y = GetUnitY( dummy )
    local real z = LoadReal( udg_H, i, 3 )
    local real x1 = GetUnitX( target )
    local real y1 = GetUnitY( target )
    local real z1 = GetLocZ( x1, y1 ) + GetUnitFlyHeight( target ) + 50.00
    local real ax = x1 - x
    local real ay = y1 - y
    local real az = z1 - z
    local real d = RMaxBJ( 1.00, SquareRoot( ax * ax + ay * ay + az * az ) )
    
    set ax = ax / d
    set ay = ay / d
    set az = az / d
    
    set x = x + 20.00 * ax
    set y = y + 20.00 * ay
    set z = z + 20.00 * az
    
    call SetUnitX( dummy, x )
    call SetUnitY( dummy, y )
    call SetUnitFlyHeight( dummy, z - GetLocZ( x, y ), 0.00 )
    
    if IsUnitInRange( dummy, target, 0.00 ) and SquareRoot( ( z1 - z ) * ( z1 - z ) ) <= 100.00 then
        call SetUnitAnimation( dummy, "death" )
        call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
        
        set caster = LoadUnitHandle( udg_H, i, 0 )
        set p = GetOwningPlayer( caster )
        
        set k = LoadInteger( udg_H, i, 4 )
        
        call PauseTimer( t )
        call FlushChildHashtable( udg_H, GetHandleId( t ) )
        call DestroyTimer( t )
        
        if k == 1 then
            if IsUnitAlly( target, p ) then
                if not IsUnitType( target, UNIT_TYPE_DEAD ) then
                    call SetWidgetLife( target, GetWidgetLife( target ) + 600.00 )
                endif
            else
                call UnitDamageTarget( caster, target, 400.00, false, false, null, null, null )
            endif
            
            set k = 5
            
            call GroupEnumUnitsInRange( udg_TempGroup, x, y, 700.00, null )
            
            call GroupRemoveUnit( udg_TempGroup, target )
            
            loop
                set u = FirstOfGroup( udg_TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( udg_TempGroup, u )
                
                if IsUnitInRangeXY( u, x, y, 500.00 ) then
                    if not IsUnitType( u, UNIT_TYPE_DEAD ) then
                        if ( IsUnitAlly( target, p ) and not IsUnitAlly( u, p ) ) or ( IsUnitAlly( u, p ) and not IsUnitAlly( target, p ) ) then
                            set t = CreateTimer( )
                            set i = GetHandleId( t )
                            
                            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( caster ), 'u000', x, y, Atan2( GetUnitY( u ) - y, GetUnitX( u ) - x ) * bj_RADTODEG )
                            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
                            call SetUnitX( bj_lastCreatedUnit, x )
                            call SetUnitY( bj_lastCreatedUnit, y )
                            call SetUnitFlyHeight( bj_lastCreatedUnit, z - GetLocZ( x, y ), 0.00 )
                            call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
                            call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
                            
                            call SaveUnitHandle( udg_H, i, 0, caster )
                            call SaveUnitHandle( udg_H, i, 1, u )
                            call SaveUnitHandle( udg_H, i, 2, bj_lastCreatedUnit )
                            call SaveReal( udg_H, i, 3, z )
                            call SaveInteger( udg_H, i, 4, 0 )
                            call TimerStart( t, 0.01, true, function Move )
                            
                            set i = i - 1
                            
                            if i <= 0 then
                                call GroupClear( udg_TempGroup )
                            endif
                        endif
                    endif
                endif
            endloop
        else
            if IsUnitAlly( target, GetOwningPlayer( caster ) ) then
                call SetWidgetLife( target, GetWidgetLife( target ) + 300.00 )
            else
                call UnitDamageTarget( caster, target, 190.00, false, false, null, null, null )
            endif
        endif
        
        set caster = null
    else
        call SaveReal( udg_H, i, 3, z )
    endif
    
    set t = null
    set dummy = null
    set target = null
endfunction

function Trig_Spell_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local integer i = GetHandleId( t )
    local unit caster = GetTriggerUnit( )
    local unit target = GetSpellTargetUnit( )
    local real x = GetUnitX( caster )
    local real y = GetUnitY( caster )
    local real z = GetUnitFlyHeight( caster ) + 50.00
    
    set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( caster ), 'u000', x, y, Atan2( GetUnitY( target ) - y, GetUnitX( target ) - x ) * bj_RADTODEG )
    call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
    call SetUnitX( bj_lastCreatedUnit, x )
    call SetUnitY( bj_lastCreatedUnit, y )
    call SetUnitFlyHeight( bj_lastCreatedUnit, z, 0.00 )
    call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
    call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
    
    set z = z + GetLocZ( x, y )
    
    call SaveUnitHandle( udg_H, i, 0, caster )
    call SaveUnitHandle( udg_H, i, 1, target )
    call SaveUnitHandle( udg_H, i, 2, bj_lastCreatedUnit )
    call SaveReal( udg_H, i, 3, z )
    call SaveInteger( udg_H, i, 4, 1 )
    call TimerStart( t, 0.01, true, function Move )
    
    set t = null
    set caster = null
    set target = null
endfunction

//===========================================================================
function Trig_Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Trig_Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Trig_Spell_Actions )
endfunction
Загруженные файлы
30

Заказ

Метод: UjAPI
Версия Warcraft III: Версия варкрафта для этого заказа
Техническое описание: Две способности в синергии

Водный элементаль

Почти обычный призыв элементаля, но...
Если призвать элементаля на воде, то он получит 10% за уровень способности здоровья и урона.
Если призвать элементаля с целью в другого водного элементаля, то цель взорвётся нанеся всем вокруг урон в размере 10% за уровень способности от оставшегося хп. Призванный элементаль получит добавку к урону в размере 10% за уровень способности.

Цепная молния

Её нельзя напрямую кастануть в водного элементаля. Но если при прыжке в радиусе доступности будет водный элементаль, то она перепрыгнет на него, вылечит ему столько хп сколько должна была нанести урона и раздвоившись продолжит прыгать. Одна и та же цепная молния не может два раза попасть в одного и того же водяного элементаля.
Ответы (1)
28
nazarpunk, проверка на наличие воды в точке на южапи некорректно работает, поэтому заказ выполнять не буду
1

Заказ

Метод: JASS/vJASS
Версия Warcraft III: Любая версия
Техническое описание:
Загруженные файлы
Ответы (3)
28
Gosick3000, АХАХАХАХ, рад видеть любителя работ blink'a, всегда мечтал научиться делать такие же спеллы, и даже попробовал что-то придумать: xgm.guru/p/wc3/UjAPI-Bahisa-Spellpack-qQU
Следующим спеллпаком хотел лучницу сделать, но нет идей для оригинальной ульты и одного обычного скилла. Мб возьму опалесценцию из отчаяния
Без должных моделек с анимациями и эффектами будет убого выглядеть. В следующий раз лучше предоставлять материалы для работы, чтобы мог более корректно выполнить тз
Попробую на стандарте что-то придумать с этим
1
rsfghd,
У меня есть модели пыли, но, к сожалению, другие модели я предоставить не могу.
Загруженные файлы
28
Выполнение заказа

Заклинание готово!

Подобрать эффекты, модельки, немного подогнать под это дело код и в принципе будет сносно. Но у блинка так-то сделана иначе сама система кастов, типа нет таргетных абилок (ими нужно попадать) и в зависимости от того есть ли в радиусе поражения юнит, какая разница высот, какая дистанция между ними - происходят соответствующие действия, вроде прыжка/телепорта вверх, сокращение дистанции телепортами и т.д. и т.п.
инструкция по импорту
убрать триггер Untitled Trigger 001 и скопировать папку Initialization в свою карту
в триггере Spell на 232 строке указать равкод абилки
на 177 строке указать урон от первого удара
на 87 строке урон от второго удара
на 65 урон от серии ударов
на 142 урон при окончании серии ударов
всё остальное требует минимальных знаний джасса

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
endglobals

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

function ParabolaZ takes real h, real d, real x returns real
    return (4 * h / d) * (d - x) * (x / d)
endfunction

private function AlphaTeleportPeriodic takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local real r = LoadReal( H, i, 1 ) + 0.01
    local real k = LoadReal( H, i, 2 )
    
    call SetUnitVertexColor( LoadUnitHandle( H, i, 0 ), 255, 255, 255, R2I( 255.00 - ParabolaZ( 255.00, k, r ) ) )
    
    if r >= k then
        call PauseTimer( t )
        call DestroyTimer( t )
        call FlushChildHashtable( H, i )
    else
        call SaveReal( H, i, 1, r )
    endif
    
    set t = null
endfunction

function AlphaTeleport takes unit u, real time returns nothing
    local timer t = CreateTimer( )
    local integer i = GetHandleId( t )
    
    call SaveUnitHandle( H, i, 0, u )
    call SaveReal( H, i, 1, 0.00 )
    call SaveReal( H, i, 2, time )
    call TimerStart( t, 0.01, true, function AlphaTeleportPeriodic )
    
    set t = null
endfunction

private function Falling takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local unit u = LoadUnitHandle( H, i, 0 )
    local real s = LoadReal( H, i, 1 ) - 0.25
    local real f = GetUnitFlyHeight( u ) + s
    
    call SetUnitFlyHeight( u, f, 0.00 )
    
    if f <= 0.00 then
        call PauseTimer( t )
        call FlushChildHashtable( H, i )
        call DestroyTimer( t )
        
        call RemoveSavedHandle( H, GetHandleId( u ), UnitFallingKey )
    else
        call SaveReal( H, i, 1, s )
    endif
    
    set t = null
    set u = null
endfunction

function UnitStartFalling takes unit u, real speed returns nothing
    local timer t = LoadTimerHandle( H, GetHandleId( u ), UnitFallingKey )
    
    if t == null then
        set t = CreateTimer( )
        
        call SaveTimerHandle( H, GetHandleId( u ), UnitFallingKey, t )
        call SaveUnitHandle( H, GetHandleId( t ), 0, u )
        
        call TimerStart( t, 0.01, true, function Falling )
    endif
    
    call SaveReal( H, GetHandleId( t ), 1, speed )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
//endfunction

Spell
library SpellLib
globals
    constant key UnitFallingKey
endglobals

private struct SpellS
    timer t
    unit caster
    unit target
    real time
    real speed
    integer action
    boolean localPlayer
    vector v
endstruct

private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x
    local real y
    
    if A.action < 4 then
        set x = GetUnitX( A.target ) + A.speed * A.v.x
        set y = GetUnitY( A.target ) + A.speed * A.v.y
    
        call SetUnitX( A.target, x )
        call SetUnitY( A.target, y )
        
        set A.time = A.time - 0.01
    else
        set x = GetUnitX( A.caster ) - A.speed * A.v.x
        set y = GetUnitY( A.caster ) - A.speed * A.v.y
    
        call SetUnitX( A.caster, x )
        call SetUnitY( A.caster, y )
    endif
    
    if A.localPlayer then
        call SetCameraField( CAMERA_FIELD_ZOFFSET, GetUnitFlyHeight( A.caster ), 0.25 )
    endif
    
    if A.action == 0 then
        if A.time <= 0.10 then
            call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.caster ) + 60.00, 0.00 )
        endif
    elseif A.action == 1 or A.action == 2 then
        if A.action == 2 then
            if A.time == 0.20 then
                call SetUnitTimeScale( A.caster, 2.00 )
                call SetUnitAnimation( A.caster, "attack slam" )
                call QueueUnitAnimation( A.caster, "stand" )
            elseif A.time == 0.10 then
                call SetUnitTimeScale( A.caster, 1.00 )
            endif
        endif
        
        if A.time == 0.10 then
            call AlphaTeleport( A.caster, 0.20 )
        endif
    elseif A.action == 3 then
        call SetUnitFlyHeight( A.target, GetUnitFlyHeight( A.target ) - 0.25, 0.00 )
        call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.target ) + 50.00, 0.00 )
        call UnitStartFalling( A.target, 0.00 )
        
        call UnitDamageTarget( A.caster, A.target, 1.00, false, false, null, null, null )
        
        if GetRandomInt( 0, 1 ) == 0 then
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdl", A.target, "overhead" ) )
        else
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdl", A.caster, "weapon" ) )
        endif
    endif
    
    if A.time <= 0.00 or ( A.action == 4 and GetUnitFlyHeight( A.caster ) <= 0.11 ) then
        if A.action == 0 then
            call SetUnitTimeScale( A.caster, 2.00 )
            
            call SetUnitAnimationByIndex( A.caster, 5 )
            call QueueUnitAnimation( A.caster, "stand" )
            
            set A.time = 0.25
            set A.action = 1
        elseif A.action == 1 then
            set A.action = 2
            set A.speed = 12.00
            
            call UnitDamageTarget( A.caster, A.target, 50.00, false, false, null, null, null )
            
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.target, "chest" ) )
            
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            call SetUnitX( A.caster, x - 128.00 * A.v.x )
            call SetUnitY( A.caster, y - 128.00 * A.v.y )
            call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.target ), 0.00 )
            
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            call UnitStartFalling( A.caster, 0.00 )
            set A.time = 0.30
        elseif A.action == 2 then
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            call SetUnitX( A.caster, x - 96.00 * A.v.x )
            call SetUnitY( A.caster, y - 96.00 * A.v.y )
            call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.target ), 0.00 )
            
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            set A.speed = 0.00
            
            call UnitStartFalling( A.caster, 0.00 )
            call UnitStartFalling( A.target, 0.00 )
            
            set A.time = 0.50
            set A.action = 3
        elseif A.action == 3 then
            set A.action = 4
            set A.time = 0.01
            set A.speed = 2.50
            
            call UnitDamageTarget( A.caster, A.target, 10.00, false, false, null, null, null )
            
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.target, "overhead" ) )
            
            call UnitStartFalling( A.caster, 10.00 )
            call UnitStartFalling( A.target, -20.00 )
        elseif A.action == 4 then
            call PauseTimer( A.t )
            call FlushChildHashtable( H, GetHandleId( A.t ) )
            call DestroyTimer( A.t )
            
            call PauseUnit( A.caster, false )
            call PauseUnit( A.target, false )
            
            set A.t = null
            set A.caster = null
            set A.target = null
            call A.v.destroy( )
            call A.destroy( )
        endif
    endif
endfunction

private function Slam takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x = GetUnitX( A.target )
    local real y = GetUnitY( A.target )
    
    if UnitAddAbility( A.target, 'Arav' ) then
        call UnitRemoveAbility( A.target, 'Arav' )
    endif
    
    if UnitAddAbility( A.caster, 'Arav' ) then
        call UnitRemoveAbility( A.caster, 'Arav' )
    endif
    
    call UnitDamageTarget( A.caster, A.target, 40.00, false, false, null, null, null )
    
    call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) ) )
    
    set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u001', x, y, GetUnitFacing( A.caster ) )
    call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
    call SetUnitX( bj_lastCreatedUnit, x )
    call SetUnitY( bj_lastCreatedUnit, y )
    call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
    call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
    call SetUnitTimeScale( bj_lastCreatedUnit, 1.50 )
    
    call UnitStartFalling( A.target, 17.50 )
    
    call SetUnitTimeScale( A.caster, 1.00 )
    call SetUnitAnimation( A.caster, "attack slam" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    set A.action = 0
    set A.speed = 3.00
    set A.time = 0.30
    
    call TimerStart( A.t, 0.01, true, function Move )
endfunction

private function SetAnim takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    
    call PauseUnit( A.caster, true )
    call SetUnitTimeScale( A.caster, 2.00 )
    call SetUnitAnimation( A.caster, "spell slam" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    call TimerStart( A.t, 0.30, false, function Slam )
endfunction

private function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    
    set A.t = CreateTimer( )
    set A.caster = GetTriggerUnit( )
    set A.target = GetSpellTargetUnit( )
    set A.v = vector.create( GetUnitX( A.target ) - GetUnitX( A.caster ), GetUnitY( A.target ) - GetUnitY( A.caster ), 0.00 )
    call A.v.normalize( )
    
    set A.localPlayer = GetLocalPlayer( ) == GetOwningPlayer( A.caster )
    
    call PauseUnit( A.target, true )
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call TimerStart( A.t, 0.00, false, function SetAnim )
endfunction

//===========================================================================
private function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
endfunction
endlibrary

Загруженные файлы
15

Заказ

Название: Ярость Синдрагосы
Метод: Jass
Версия Warcraft III: 1.26a
Техническое описание: как на видео только что бы начинала лететь за спиной катера
Призывает Синдрагосу, которая дышит холодом на противников перед вами на расстоянии до 40 м, нанося 400 урона и (снижая скорость передвижения на 50%) на 10 сек.
Загруженные файлы
Ответы (2)
28
Выполнение заказа

Заклинание готово!

Ярость Синдрагосы

инструкция по импорту
скопировать папку Initialization и вставить в свою карту
перекопировать редактор объектов и вставить в свою карту
в триггере Spell на строках:
272 - указать равкод даммика который кастует замедление
261 - указать абилку призыва дракона
235-236 - смещение проявления дракона за спину кастера
238 - равкод дракона
244 - стартовая высота дракона (400)
245 - высота дракона во время полёта (300 - какую высоту установить, 100 - с какой скоростью установить эту высоту, т.е. с учётом стартовой высоты, дракон достигнет этой высоты за одну секунду)
246 - раскрас дракона (последний аргумент должен быть на 0)
251 - максимальное расстояние всего полёта с учётом проявления и исчезновения
140 - скорость полёта дракона
154 - при какой оставшейся дистанции начать выпускать ледяные волны
156 - индекс анимки полёта дракона
160 - при какой оставшейся дистанции начать исчезновение дракона
161 - формула исчезновения дракона ( 255.00 / ( указать параметр на 160 строке / speed ) )
162 - раскрас дракона, последний параметр не нужно трогать
164 - формула взлёта дракона ( скорость взлёта * ( 1.00 - d / указать параметр на 160 строке ) )
167 - другой индекс анимки полёта дракона (взмах крыльями)
170 - указать параметр на 160 строке + параметр на 173 строке
173 - периодичность спавна ледяных волн в зависимости от пройденной дистанции (т.е. каждые 35 единиц)
177-178 - смещение начала волны поближе к морде дракона
180 - равкод ледяной волны
186 - стартовая высота волны (на 75 единиц ниже высоты дракона)
192 - указать параметр на 170 строке
204 - дистанция до которой дракон должен проявиться
205 - формула проявления дракона ( 255.00 / ( ( максимальная дистанция - параметр на 204 строке ) / speed ) )
206 - то же самое, что и 162
32-33 - скорость полёта волны
37 - скорость полёта волны по Z
43 - радиус урона (300 + макс коллизия)
53 - радиус урона
57 - приказ замедления
58 - урон
64-110 - визуальные кPаКаЗяБрЫ

Код

Spell
function GetCorX takes real x returns real
if x > udg_MapRectXY[0] then
return udg_MapRectXY[0]
elseif x < udg_MapRectXY[1] then
return udg_MapRectXY[1]
endif

return x
endfunction
function GetCorY takes real y returns real
if y > udg_MapRectXY[2] then
return udg_MapRectXY[2]
elseif y < udg_MapRectXY[3] then
return udg_MapRectXY[3]
endif

return y
endfunction
function MoveEffect takes nothing returns nothing
local timer t = GetExpiredTimer( )
local integer i = GetHandleId( t )
local unit u
local unit caster
local unit dummy = LoadUnitHandle( udg_H, i, 0 )
local real x = GetUnitX( dummy )
local real y = GetUnitY( dummy )
local real a = GetUnitFacing( dummy ) * bj_DEGTORAD
local group g

set x = GetCorX( x + 10.00 * Cos( a ) )
set y = GetCorY( y + 10.00 * Sin( a ) )

call SetUnitX( dummy, x )
call SetUnitY( dummy, y )
call SetUnitFlyHeight( dummy, GetUnitFlyHeight( dummy ) - 5.00, 0.00 )

if GetUnitFlyHeight( dummy ) <= 0.11 then
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 1.00 )

call GroupEnumUnitsInRange( udg_TempGroup, x, y, 500.00, null )
set caster = LoadUnitHandle( udg_H, i, 1 )
set g = LoadGroupHandle( udg_H, i, 2 )
set bj_groupEnumOwningPlayer = GetOwningPlayer( caster )

loop
set u = FirstOfGroup( udg_TempGroup )
exitwhen u == null
call GroupRemoveUnit( udg_TempGroup, u )

if IsUnitInRangeXY( u, x, y, 300.00 ) then
if not IsUnitInGroup( u, g ) then
if IsUnitEnemy( u, bj_groupEnumOwningPlayer ) and not IsUnitType( u, UNIT_TYPE_DEAD ) then
call GroupAddUnit( g, u )
call IssueTargetOrder( udg_TempUnit, "frostnova", u )
call UnitDamageTarget( caster, u, 100.00, false, false, null, null, null )
endif
endif
endif
endloop

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u003', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u004', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u005', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u006', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u007', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u008', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

if LoadInteger( udg_H, i, 3 ) == 1 then
call DestroyGroup( g )
endif

call PauseTimer( t )
call FlushChildHashtable( udg_H, i )
call DestroyTimer( t )

set g = null
set caster = null
endif

set t = null
set dummy = null
endfunction
function Move takes nothing returns nothing
local timer t = GetExpiredTimer( )
local timer n
local integer i = GetHandleId( t )
local integer j
local unit caster = LoadUnitHandle( udg_H, i, 0 )
local unit dummy = LoadUnitHandle( udg_H, i, 1 )
local real x = GetUnitX( dummy )
local real y = GetUnitY( dummy )
local real a = GetUnitFacing( dummy ) * bj_DEGTORAD
local real d = LoadReal( udg_H, i, 3 )
local real r
local real speed = 5.00

if speed > d then
set speed = d
endif

set x = GetCorX( x + speed * Cos( a ) )
set y = GetCorY( y + speed * Sin( a ) )

call SetUnitX( dummy, x )
call SetUnitY( dummy, y )

set d = d - speed

if d <= 2300 then
if LoadInteger( udg_H, i, 4 ) == 0 then
call SetUnitAnimationByIndex( dummy, 4 )
call SaveInteger( udg_H, i, 4, 1 )
endif

if d <= 400.00 then
set r = LoadReal( udg_H, i, 5 ) - 255.00 / ( 400.00 / speed )
call SetUnitVertexColor( dummy, 175, 175, 175, R2I( r ) )
call SaveReal( udg_H, i, 5, r )
call SetUnitFlyHeight( dummy, GetUnitFlyHeight( dummy ) + 5.00 * ( 1.00 - d / 400.00 ), 0.00 )

if LoadInteger( udg_H, i, 4 ) == 1 then
call SetUnitAnimationByIndex( dummy, 3 )
call SaveInteger( udg_H, i, 4, 2 )
endif
elseif d > 435.00 then
set r = LoadReal( udg_H, i, 6 ) + speed

if r >= 35.00 then
set r = 0.00
set n = CreateTimer( )
set j = GetHandleId( n )
set x = GetCorX( x + 275.00 * Cos( a ) )
set y = GetCorY( y + 275.00 * Sin( a ) )

set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( caster ), 'u002', x, y, a * bj_RADTODEG )
call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
call SetUnitX( bj_lastCreatedUnit, x )
call SetUnitY( bj_lastCreatedUnit, y )
call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( dummy ) - 75.00, 0.00 )

call SaveUnitHandle( udg_H, j, 0, bj_lastCreatedUnit )
call SaveUnitHandle( udg_H, j, 1, caster )
call SaveGroupHandle( udg_H, j, 2, LoadGroupHandle( udg_H, i, 2 ) )

if d - speed <= 435.00 then
call SaveInteger( udg_H, j, 3, 1 )
endif

call TimerStart( n, 0.01, true, function MoveEffect )
set n = null
endif

call SaveReal( udg_H, i, 6, r )
endif
endif

if d > 2000.00 then
set r = LoadReal( udg_H, i, 5 ) + 255.00 / ( ( 2500.00 - 2000.00 ) / speed )
call SetUnitVertexColor( dummy, 175, 175, 175, R2I( r ) )
call SaveReal( udg_H, i, 5, r )
endif

if d <= 0.00 then
call PauseTimer( t )
call FlushChildHashtable( udg_H, i )
call DestroyTimer( t )

call SetUnitVertexColor( dummy, 0, 0, 0, 0 )
call KillUnit( dummy )
else
call SaveReal( udg_H, i, 3, d )
endif

set t = null
set dummy = null
set caster = null
endfunction
function Trig_Spell_Actions takes nothing returns nothing
local timer t = CreateTimer( )
local integer i = GetHandleId( t )
local unit caster = GetTriggerUnit( )
local real x = GetUnitX( caster )
local real y = GetUnitY( caster )
local real a = Atan2( GetSpellTargetY( ) - y, GetSpellTargetX( ) - x )

set x = GetCorX( x - 800.00 * Cos( a ) )
set y = GetCorY( y - 800.00 * Sin( a ) )

set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( caster ), 'u001', x, y, a * bj_RADTODEG )
call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
call SetUnitX( bj_lastCreatedUnit, x )
call SetUnitY( bj_lastCreatedUnit, y )
call SetUnitFlyHeight( bj_lastCreatedUnit, 400.00, 0.00 )
call SetUnitFlyHeight( bj_lastCreatedUnit, 300.00, 100.00 )
call SetUnitVertexColor( bj_lastCreatedUnit, 175, 175, 175, 0 )

call SaveUnitHandle( udg_H, i, 0, caster )
call SaveUnitHandle( udg_H, i, 1, bj_lastCreatedUnit )
call SaveGroupHandle( udg_H, i, 2, CreateGroup( ) )
call SaveReal( udg_H, i, 3, 2500.00 )

call TimerStart( t, 0.01, true, function Move )

set t = null
set caster = null
endfunction
===========================================================================
function Trig_Spell_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function InitTrig_Spell takes nothing returns nothing
local rect r = GetWorldBounds( )

set gg_trg_Spell = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Spell, Condition( function Trig_Spell_Conditions ) )
call TriggerAddAction( gg_trg_Spell, function Trig_Spell_Actions )

set udg_TempUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u009', 0.00, 0.00, 0.00 )

set udg_MapRectXY[0] = GetRectMaxX( r )
set udg_MapRectXY[1] = GetRectMinX( r )
set udg_MapRectXY[2] = GetRectMaxY( r )
set udg_MapRectXY[3] = GetRectMinY( r )

call RemoveRect( r )

set r = null
endfunction
""
Загруженные файлы
28
Desgul, бле, код в кавычки забыл обернуть и отредактировать уже нельзя, офигенно 👍
4
Заказ на работу
ДЫМОВАЯ ГРАНАТА
Герой бросает дымовую гранату, которая взрывается в указанной точке и окутывает область дымом на несколько сек (размер области и время действия зависит от лвл способности)!
В выбранной области у всех врагов: понижается броня, они получают % шанс на промах от каждой атаки, а также они не могут кастовать способности (безмолвие) всё это пока они стоят в этой области дыма!
А все союзники и юниты игрока в этой области получают: + к броне, а сам герой, который скастовал, получает невидимость стоя в это облаке (при атаке невидимость не спадает, или спадает, но на 1 сек)
P.S. Желательно что бы на рефоржете работало тоже, для всех версий
Загруженные файлы
3
Название: Несгибаемая ярость (F)
Метод: Jass
Версия Warcraft III: Главное что бы на рефе работала :)
Описание: Пассивно повышает силу героя на 3/6/9/12 ед. Каждая обычная атака героя восстанавливает ему 2/3/4/5 ед. маны за удар.
Когда здоровье героя падает до нуля, он не умирает а получает полную невосприимчивость к любому виду урона в течении следующих 3 сек., и получает бонусный вампиризм в размере 25%/50%/75%/100% от нанесенного урона (как от атак так и от способностей героя).
Перезарядка способности: 65/55/45/35 сек.
  1. Важно! что бы работала с сделанным спеллом "Молот Древних" (Rolling Slam). Что бы во время анимации атак он тоже становился невосприимчивым у урону а не погибал.
  2. Когда навык находиться на перезарядке после возможной смерти, бонус к силе не сбивается и атаки все так же накапливают ману за удары.
Название: Угрожающий клич (D)
"Не героическая способность" Будет с самого начала уже у варвара.
Метод: Jass
Версия Warcraft III: Главное что бы на рефе работала :)
Описание: Герой издает боевой крик (волна от героя во все стороны) радиусом 1000 АоЕ, который вгоняет противников с 1 по 24 уровень в состояние "Страха", от чего они теряют возможность атаковать, замедляются в скорости передвижения на 25% и бегут прочь в течении 6 сек.
Перезарядка: 50 сек.
"Зов битвы" Предмет усиления способности:
Снижает перезарядку способности "Угрожающий клич" до 35 сек. и когда герой использует её, он повышает свою силу на 5 ед. + 1 ед. за каждый уровень персонажа на 6 сек. Противники погибшие под действием эффекта способности взрываются, нанося по 25 ед. + 300% от силы магического урона всем врагам в радиусе 250 АоЕ.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.