28

» WarCraft 3 / Заклинания на заказ

nazarpunk, такими жуткими костылями я не хочу развлекаться, в особенности если это какая-то 480х480 карта
28

» WarCraft 3 / Заклинания на заказ

ShadowNinja, координаты мышки можно отловить только на мемхаке/южапи, во втором случае оно даже сразу засинханным будет, на ванилке разве что с помощью пкм управлять направлением луча
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, есть всё на ванилке. Если я предлагаю какие-то варианты недоступные стандартными методами, я говорю, что данный метод нестандартный
Я пытался прикрепить эффекты юниту, но мне не удалось прикрепить туда, где я ожидал их увидеть, ни на правой руке, ни на оружии, а значит, соответствующих аттачментов нет
Мне, как спеллмейкеру, звуки в модели порой мешают. Я хочу сам решать какой звук создавать и какой громкости
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, есть ещё 2 варианта, это переделать не под "юнит атакован", а "юнит получает урон", но в данном случае уклонение уже не сработает вроде, только блокирование урона, при этом, не будет казусов, учитывающих факторы старта вылета снаряда и скорость снаряда (потому что абилка срабатывает, когда снаряд ещё даже не появился, при запахе атакующего)
Либо кастомная автоатака в карте)
28

» WarCraft 3 / Заклинания на заказ

лишние звуки и точки крепления?
Да, во время рывка ты слышишь какой-то лишний звук, во время критического удара то же самое, точек крепления будто вовсе нет, хотел эффект прикрепить к оружию/правой руке. Но мне уже всё равно даже если исправленную модель зальют
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, не вижу во втором варианте что-то связанное с блокированием урона. Только перемещение влево/вправо и добавление критического шанса для следующей автоатаки. Есть 2 варианта, либо заблокировать урон с автоатаки во время рывка, либо добавить 100% уклонение на время рывка, что подходит?
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, а, только сейчас увидел что ты там изменённую модельку кинул, ну импортируешь заменой свою модель и посмотришь как оно выглядит
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, хотел сделать спеллпак на эту модель, но она конченная какая-то, лишние звуки, нет точек крепления нормальных, забил короче
28

» WarCraft 3 / Заклинания на заказ

Выполнение заказа

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

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

инструкция по импорту
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости уворота, дальности, угла)
на видео демонстрация 100% уворота, чтобы не дожидаться выпадения шансов (в карте 15/20/25%)
кроме этого, длительность уворота поставил не 1.20, а 0.50, потому что ну это капес перебор дружище, впрочем, всё в твоих руках, угол настроил не под 90 градусов, а 50, чтобы кружился вокруг атакующего противника и делал нырки при беге к дальнику ближе к его стороне, но опять же, всё настраиваемо
кроме того, пока юнит не нанесёт критический удар, он добавлен в группу для проверки, планировал это делать только на время самого уворота, но понял, что слишком большая потеря контроля происходит, если тебя устраивает шанс того, что игрок может всё время в уворотах находиться на поле боя и не иметь возможности убежать/ударить - убери всё, что связано с TempGroup
Загруженные файлы
28

» WarCraft 3 / Как вывести Jass на новый уровень? Jass.

human1, он продолжает рофлить, но в целом, это забавно)
Правда новичков такое наверное отпугивать будет, что не совсем желательно
28

» WarCraft 3 / процентное увеличение маг урона как сделать?

Если это какая-то одиночная карта, то можно выдать абилку рунных браслетов с отрицательным значением противникам
28

» WarCraft 3 / Способности и алгоритмы на заказ

SebastianCarrey, прочитай инструкцию по импорту хотя бы.. я зря её написал что ли
То, что ты показал на скрине, обведено комментарием с помощью /* */, это значит, что при компиляции этот код удаляется. Убери просто вначале слэш со звездой и в конце звезду со слэшем
28

» WarCraft 3 / Способности и алгоритмы на заказ

SebastianCarrey,
  1. равкод абилки укажи в коде, чтоб работала
  2. в редакторе объектов...
  3. потому что в коде нужно заполнить параметры для следующих уровней, я же шаблон не просто так тыкнул
28

» WarCraft 3 / Заклинания на заказ

Выполнение заказа

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

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

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

» WarCraft 3 / Заклинания на заказ

ShadowNinja, идея не самая оригинальная, в морозко делал уже подобное для босса, но пока делал именно этот заказ, появилась идея чтобы око саргараса спавнить над головой кастера и создавать такой же луч, который будет учитывать сферические координаты и направлен под наклоном в землю соответственно, клик правой кнопкой мыши позволит перенаправить такой луч на новую точку, но чтобы такое сделать нужен мемхак/южапи, поскольку требуется динамическое управление ориентацией модели, можно и на ванилке через кость и SetUnitLookAt, но не хочу этими костылями мазаться, тем более вне заказа
28

» WarCraft 3 / Заклинания на заказ

Выполнение заказа

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

инструкция по импорту
скопировать папку 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

» WarCraft 3 / Заклинания на заказ

Meddin, ломает игру потка неуязвимости, которая делает channel ульты имбовыми
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, и заказы, пожалуйста, отдельным комментарием, а не в ветке ответов, потому что другие не увидят этот заказ, если не полезут сюда в ответы
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, как долго длится усиление крита во втором варианте после уворота? Пока не будет нанесена автоатака? На ванилке, заставить сделать автоатаку можно только приказом, а значит, её можно будет отменить. После уворота атаковать ближнюю цель или того, кто атаковал?
28

» WarCraft 3 / Заклинания на заказ

Shermanator00, птички везде прикольно смотрятся если знать как их юзать, к примеру, демонстрация Частицы/Particles от Vlod'a