Добавлен , опубликован
Способ реализации:
когда-то давно, будучи совсем маленьким крохотным ребеночком, я увидел невероятно красивую вещь от великолепного Vlod'a - Частицы/Particles
я не спал днями и ночами, забыл как правильно питаться, ждал пока он выложит код, чтобы я мог насладиться всеми блаженствами этого мира перед упокоем, но этого так и не случилось и я не знаю жив ли бедный влод сейчас, я скучаю за ним
в итоге я решил попробовать повторить его штуку, но с открытым кодом


новичкам будет интересно, а старички кыш, я себе самооценку пытаюс чинить
раскрыть
library paricleslib
globals
    constant hashtable H = InitHashtable( )
    private constant group TempGroup = CreateGroup( )
    private unit bj_closestUnit
endglobals

private function GetClosestUnitInRangeXY takes real x, real y, real r returns unit
    local unit u
    local real d
    
    set bj_closestUnit = null
    
    call GroupEnumUnitsInRange( TempGroup, x, y, r + 200.00, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        set d = SquareRoot( ( x - GetUnitX( u ) ) * ( x - GetUnitX( u ) ) + ( y - GetUnitY( u ) ) * ( y - GetUnitY( u ) ) )
        
        if d < r then
            set r = d
            set bj_closestUnit = u
        endif
    endloop
    
    return bj_closestUnit
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

private struct particlesS
    timer t
    effect eff
    real time
    real timeMax
    real yawSpeed
    real yawCurrent
    real yawLast
    real speed
    real alpha
    real rollCurrent
    
    vector p
    vector l
    vector last
    vector v
endstruct

private function Move takes nothing returns nothing
    local particlesS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x
    local real y
    local real rollTarget
    local vector v
    
    set A.time = A.time - 0.01
    
    if GetClosestUnitInRangeXY( A.p.x, A.p.y, 400.00 ) != null then // пошук найближчого юніта у радіусі 400
        set v = vector.create( GetUnitX( bj_closestUnit ) - A.l.x, GetUnitY( bj_closestUnit ) - A.l.y, GetAxisZ( GetUnitX( bj_closestUnit ), GetUnitY( bj_closestUnit ) ) + GetUnitFlyHeight( bj_closestUnit ) + 50.00 - A.l.z )
        call v.normalize( )
        
        set A.v.x = A.v.x + ( v.x - A.v.x ) * 0.03 // 0.03 - швидкість повороту частинок у позицію цілі
        set A.v.y = A.v.y + ( v.y - A.v.y ) * 0.03
        set A.v.z = A.v.z + ( v.z - A.v.z ) * 0.03
        call v.destroy( )
        
        call A.v.normalize( )
        
        set A.yawCurrent = Atan2( A.v.y, A.v.x )
        
        set rollTarget = A.yawCurrent - A.yawLast
        
        if rollTarget > bj_PI then
            set rollTarget = rollTarget - bj_PI * 2.00
        elseif rollTarget < -bj_PI then
            set rollTarget = rollTarget + bj_PI * 2.00
        endif
        
        set rollTarget = rollTarget * 45.00 * bj_RADTODEG // кут роллу при цілі
        
        set A.speed = A.speed * 1.002 // прискорення руху до цілі
    else // стан спокою
        set x = A.v.x
        set y = A.v.y
        set A.v.x = x * Cos( A.yawSpeed ) - y * Sin( A.yawSpeed )
        set A.v.y = x * Sin( A.yawSpeed ) + y * Cos( A.yawSpeed )
        
        set A.yawCurrent = A.yawCurrent + A.yawSpeed
        set rollTarget = A.yawSpeed * 45.00 * bj_RADTODEG // кут роллу у стані спокою
        
        set A.speed = A.speed * 0.995 // сповільнення руху
    endif
    
    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
    
    set A.rollCurrent = A.rollCurrent + ( rollTarget - A.rollCurrent ) * 0.02 // згладжування роллу
    
    set A.alpha = A.alpha - 2.55 / A.timeMax
    
    if A.alpha < 0.00 then
        set A.alpha = 0.00
    endif
    
    call SetSpecialEffectVertexColour( A.eff, 255, 255, 255, R2I( A.alpha ) )
    call SetSpecialEffectPositionWithZ( A.eff, A.l.x, A.l.y, A.l.z )
    call SetSpecialEffectOrientation( A.eff, A.yawCurrent * bj_RADTODEG, Atan2( A.v.z, SquareRoot( A.v.x * A.v.x + A.v.y * A.v.y ) ) * bj_RADTODEG, A.rollCurrent )
    
    if A.time <= 0.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call DestroyEffect( A.eff )
        call SetSpecialEffectVisible( A.eff, false )
        
        set A.t = null
        set A.eff = null
        call A.l.destroy( )
        call A.v.destroy( )
        call A.p.destroy( )
        call A.last.destroy( )
        call A.destroy( )
    else
        set A.yawLast = A.yawCurrent
        //set A.yawSpeed = A.yawSpeed * 1.005 // прискорення повороту у стані спокою
        set A.last.x = A.l.x
        set A.last.y = A.l.y
        set A.last.z = A.l.z
    endif
endfunction

private function Create takes nothing returns nothing
    local particlesS A
    local integer i = 2//GetRandomInt( 20, 30 ) // кількість створення частинок за раз
    
    loop
        exitwhen i <= 0
        set i = i - 1
        
        set A = particlesS.create( )
        
        set A.t = CreateTimer( )
        set A.l = vector.create( 5.00, 16.00, 80.00 ) // точка появи частинок
        set A.p = vector.create( A.l.x, A.l.y, A.l.z )
        set A.v = vector.create( GetRandomReal( -1.00, 1.00 ), GetRandomReal( -1.00, 1.00 ), GetRandomReal( -0.15, 0.60 ) ) // рандомізація польоту частинок
        set A.last = vector.create( A.l.x, A.l.y, A.l.z )
        set A.speed = GetRandomReal( 1.25, 1.50 ) // швидкість частинок
        set A.time = GetRandomReal( 1.75, 2.25 ) // час існування частинок
        set A.timeMax = A.time
        set A.yawSpeed = 0.01 // швидкість повороту частинок
        set A.alpha = 255.00 // початкова прозорість
        set A.rollCurrent = 0.00
        
        call A.v.normalize( )
        
        set A.yawCurrent = Atan2( A.v.y, A.v.x )
        
        set A.eff = AddSpecialEffect( "Abilities\\Spells\\Other\\Parasite\\ParasiteMissile.mdl", A.l.x, A.l.y )
        
        call SetSpecialEffectAnimation( A.eff, "stand" ) // скидання анімації "birth" заради більшого спокою та тиші
        //Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl
        //Abilities\\Weapons\\QuillSprayMissile\\QuillSprayMissile.mdl
        //Abilities\\Spells\\Items\\PotionOfOmniscience\\CrystalBallCaster.mdl
        //Abilities\\Spells\\Undead\\Possession\\PossessionMissile.mdl
        //Abilities\\Spells\\Items\\PotionOfOmniscience\\CrystalBallCaster.mdl
        // Abilities\\Weapons\\PriestMissile\\PriestMissile.mdl
        //Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl
        //Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl
        //Abilities\\Weapons\\MurgulMagicMissile\\MurgulMagicMissile.mdl
        call SetSpecialEffectZ( A.eff, A.l.z )
        call SetSpecialEffectScale( A.eff, 0.50 ) // розмір ефекту
        
        call SaveInteger( H, GetHandleId( A.t ), 0, A )
        call TimerStart( A.t, 0.01, true, function Move )
    endloop
endfunction

function Trig_Melee_Initialization_Actions takes nothing returns nothing
    call TimerStart( CreateTimer( ), 0.10, true, function Create ) // періодичність створення частинок
    call SetDayNightModels( "", "" )
endfunction

//===========================================================================
function InitTrig_Melee_Initialization takes nothing returns nothing
    set gg_trg_Melee_Initialization = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Melee_Initialization, function Trig_Melee_Initialization_Actions )
endfunction
endlibrary

сделано на UjAPI
`
ОЖИДАНИЕ РЕКЛАМЫ...
19
Вот он, один из последних столпов камунити Варкрафта.
1
Крутой столп! Думаю люди будут скачивать для своих доп кампаний, очень впишеться в кампании про Даларан, магов и эльфов:)
28
Вышла новая версия!
Прокрутить к ресурсу

версия для ванилки (без южапи и мемхака)

раскрыть
library paricleslib
globals
    constant hashtable H = InitHashtable( )
    private constant group TempGroup = CreateGroup( )
    private unit bj_closestUnit
    constant location LFZ = Location( 0.00, 0.00 )
endglobals

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

private function GetClosestUnitInRangeXY takes real x, real y, real r returns unit
    local unit u
    local real d
    
    set bj_closestUnit = null
    
    call GroupEnumUnitsInRange( TempGroup, x, y, r + 200.00, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        set d = SquareRoot( ( x - GetUnitX( u ) ) * ( x - GetUnitX( u ) ) + ( y - GetUnitY( u ) ) * ( y - GetUnitY( u ) ) )
        
        if d < r then
            set r = d
            set bj_closestUnit = u
        endif
    endloop
    
    return bj_closestUnit
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

private struct particlesS
    timer t
    unit eff
    real time
    real timeMax
    real yawSpeed
    real yawCurrent
    real yawLast
    real speed
    real alpha
    
    vector p
    vector l
    vector last
    vector v
endstruct

private function Move takes nothing returns nothing
    local particlesS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x
    local real y
    local vector v
    
    set A.time = A.time - 0.01
    
    if GetClosestUnitInRangeXY( A.p.x, A.p.y, 400.00 ) != null then // пошук найближчого юніта у радіусі 400
        set v = vector.create( GetUnitX( bj_closestUnit ) - A.l.x, GetUnitY( bj_closestUnit ) - A.l.y, GetLocZ( GetUnitX( bj_closestUnit ), GetUnitY( bj_closestUnit ) ) + GetUnitFlyHeight( bj_closestUnit ) + 50.00 - A.l.z )
        call v.normalize( )
        
        set A.v.x = A.v.x + ( v.x - A.v.x ) * 0.03 // 0.03 - швидкість повороту частинок у позицію цілі
        set A.v.y = A.v.y + ( v.y - A.v.y ) * 0.03
        set A.v.z = A.v.z + ( v.z - A.v.z ) * 0.03
        call v.destroy( )
        
        call A.v.normalize( )
        
        set A.yawCurrent = Atan2( A.v.y, A.v.x )
        
        set A.speed = A.speed * 1.002 // прискорення руху до цілі
    else // стан спокою
        set x = A.v.x
        set y = A.v.y
        set A.v.x = x * Cos( A.yawSpeed ) - y * Sin( A.yawSpeed )
        set A.v.y = x * Sin( A.yawSpeed ) + y * Cos( A.yawSpeed )
        
        set A.yawCurrent = A.yawCurrent + A.yawSpeed
        
        set A.speed = A.speed * 0.995 // сповільнення руху
    endif
    
    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
    
    set A.alpha = A.alpha - 2.55 / A.timeMax
    
    if A.alpha < 0.00 then
        set A.alpha = 0.00
    endif
    
    call SetUnitVertexColor( A.eff, 255, 255, 255, R2I( A.alpha ) )
    call SetUnitX( A.eff, A.l.x )
    call SetUnitY( A.eff, A.l.y )
    call SetUnitFlyHeight( A.eff, A.l.z - GetLocZ( A.l.x, A.l.y ), 0.00 )
    call SetUnitFacingTimed( A.eff, A.yawCurrent, 0.00 )
    
    if A.time <= 0.00 then
        call PauseTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        call DestroyTimer( A.t )
        
        call KillUnit( A.eff )
        call RemoveUnit( A.eff )
        
        set A.t = null
        set A.eff = null
        call A.l.destroy( )
        call A.v.destroy( )
        call A.p.destroy( )
        call A.last.destroy( )
        call A.destroy( )
    else
        set A.yawLast = A.yawCurrent
        //set A.yawSpeed = A.yawSpeed * 1.005 // прискорення повороту у стані спокою
        set A.last.x = A.l.x
        set A.last.y = A.l.y
        set A.last.z = A.l.z
    endif
endfunction

private function Create takes nothing returns nothing
    local particlesS A
    local integer i = 2//GetRandomInt( 20, 30 ) // кількість створення частинок за раз
    
    loop
        exitwhen i <= 0
        set i = i - 1
        
        set A = particlesS.create( )
        
        set A.t = CreateTimer( )
        set A.l = vector.create( 5.00, 16.00, 80.00 ) // точка появи частинок
        set A.l.z = A.l.z + GetLocZ( A.l.x, A.l.y )
        set A.p = vector.create( A.l.x, A.l.y, A.l.z )
        set A.v = vector.create( GetRandomReal( -1.00, 1.00 ), GetRandomReal( -1.00, 1.00 ), GetRandomReal( -0.15, 0.60 ) ) // рандомізація польоту частинок
        set A.last = vector.create( A.l.x, A.l.y, A.l.z )
        set A.speed = GetRandomReal( 1.25, 1.50 ) // швидкість частинок
        set A.time = GetRandomReal( 1.75, 2.25 ) // час існування частинок
        set A.timeMax = A.time
        set A.yawSpeed = 0.01 // швидкість повороту частинок
        set A.alpha = 255.00 // початкова прозорість
        
        call A.v.normalize( )
        
        set A.yawCurrent = Atan2( A.v.y, A.v.x )
        
        set A.eff = CreateUnit( Player( 0x0F ), 'u000', A.l.x, A.l.y, A.yawCurrent )
        call SetUnitPathing( A.eff, false )
        call UnitAddAbility( A.eff, 'Arav' )
        call SetUnitFlyHeight( A.eff, A.l.z, 0.00 )
        call SetUnitX( A.eff, A.l.x )
        call SetUnitY( A.eff, A.l.y )
        
        //call SetSpecialEffectAnimation( A.eff, "stand" ) // скидання анімації "birth" заради більшого спокою та тиші
        //Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl
        //Abilities\\Weapons\\QuillSprayMissile\\QuillSprayMissile.mdl
        //Abilities\\Spells\\Items\\PotionOfOmniscience\\CrystalBallCaster.mdl
        //Abilities\\Spells\\Undead\\Possession\\PossessionMissile.mdl
        //Abilities\\Spells\\Items\\PotionOfOmniscience\\CrystalBallCaster.mdl
        // Abilities\\Weapons\\PriestMissile\\PriestMissile.mdl
        //Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl
        //Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl
        //Abilities\\Weapons\\MurgulMagicMissile\\MurgulMagicMissile.mdl
        //call SetSpecialEffectZ( A.eff, A.l.z )
        //call SetSpecialEffectScale( A.eff, 0.50 ) // розмір ефекту
        
        call SaveInteger( H, GetHandleId( A.t ), 0, A )
        call TimerStart( A.t, 0.01, true, function Move )
    endloop
endfunction

function Trig_Melee_Initialization_Actions takes nothing returns nothing
    call TimerStart( CreateTimer( ), 0.10, true, function Create ) // періодичність створення частинок
    call SetDayNightModels( "", "" )
endfunction

//===========================================================================
function InitTrig_Melee_Initialization takes nothing returns nothing
    set gg_trg_Melee_Initialization = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Melee_Initialization, function Trig_Melee_Initialization_Actions )
endfunction
endlibrary
Чтобы оставить комментарий, пожалуйста, войдите на сайт.