Добавлен , опубликован
Существует специальная тема Способности и алгоритмы на заказ, где любой желающий может помочь с вашими фантазиями и где я тоже иногда зависаю. Кроме того, есть платные заказы, например, можете обратиться к 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
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
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, чтоб ты не думал, что я ничем не занимался
Кроме этого в планах сделать кат со всеми выполненными заказами в самом ресурсе, чтобы люди могли искать интересующие спеллы не бегая по страницам комментариев
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.