Добавлен , опубликован
пример движения по безье (без лишней воды), для пеших и летающих юнитов
код
globals
    unit target
    
    real distance
    real startx
    real starty
    real startz
    real midx
    real midy
    real midz
    real endx
    real endy
    real endz
    
    real time
    real maxTime = 2.00
    real timerPeriodic = 0.01
    
    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

function move takes nothing returns nothing
    local real a1 = startx
    local real b1 = 2.00 * (midx - startx)
    local real c1 = startx - 2.00 * midx + endx
    local real a2 = starty
    local real b2 = 2.00 * (midy - starty)
    local real c2 = starty - 2.00 * midy + endy
    local real a3 = startz
    local real b3 = 2.00 * (midz - startz)
    local real c3 = startz - 2.00 * midz + endz
    local real x  = a1 + (b1 + c1 * time) * time
    local real y  = a2 + (b2 + c2 * time) * time
    local real z  = a3 + (b3 + c3 * time) * time
    
    set time = time + ( timerPeriodic / maxTime )
    
    if time > 1.00 then
        call PauseTimer( GetExpiredTimer( ) )
        call DestroyTimer( GetExpiredTimer( ) )
    endif
    
    call SetUnitX( target, x )
    call SetUnitY( target, y )
    
    if not IsUnitType( target, UNIT_TYPE_FLYING ) then
        call SetUnitFlyHeight( target, z - GetLocZ( x, y ), 0.00 )
    else
        if GetLocZ( x, y ) < 0.00 then
            call SetUnitFlyHeight( target, z, 0.00 )
        else
            call SetUnitFlyHeight( target, z - GetLocZ( x, y ), 0.00 )
        endif
    endif
endfunction

function Trig_Attack_Actions takes nothing returns nothing
    local real a
    set target = GetTriggerUnit( )
    
    if not IsUnitType( target, UNIT_TYPE_FLYING ) then
        set distance = 400.00
        set startx = GetUnitX( target )
        set starty = GetUnitY( target )
        set startz = GetLocZ( startx, starty )
        
        set a = Atan2( starty - GetUnitY( GetAttacker( ) ), startx - GetUnitX( GetAttacker( ) ) )
        
        set midx = startx + distance / 2.00 * Cos( a )
        set midy = starty + distance / 2.00 * Sin( a )
        set midz = GetLocZ( midx, midy )
        
        if midz < 0.00 then
            set midz = -midz
        endif
        
        set endx = startx + distance * Cos( a )
        set endy = starty + distance * Sin( a )
        set endz = GetLocZ( endx, endy )
        
        if startz < endz then
            set midz = midz + endz
        else
            set midz = midz + startz
        endif
        
        set midz = midz + 200.00
        
        set time = 0.00
        
        call UnitAddAbility( target, 'Arav' )
        call UnitRemoveAbility( target, 'Arav' )
        
        call TimerStart( CreateTimer( ), timerPeriodic, true, function move )
    
    else // для летающих (flying)
    
        set target = GetTriggerUnit( )
        set distance = 400.00
        set startx = GetUnitX( target )
        set starty = GetUnitY( target )
        set startz = GetLocZ( startx, starty )
        
        if startz < 0.00 then
            set startz = 0.00
        endif
        
        set startz = startz + GetUnitFlyHeight( target )
        
        set a = Atan2( starty - GetUnitY( GetAttacker( ) ), startx - GetUnitX( GetAttacker( ) ) )
        
        set midx = startx + distance / 2.00 * Cos( a )
        set midy = starty + distance / 2.00 * Sin( a )
        set midz = GetLocZ( midx, midy )
        
        if midz < 0.00 then
            set midz = 0.00
        endif
        
        set midz = midz + GetUnitFlyHeight( target )
        
        set endx = startx + distance * Cos( a )
        set endy = starty + distance * Sin( a )
        set endz = GetLocZ( endx, endy )
        
        if endz < 0.00 then
            set endz = 0.00
        endif
        
        set endz = endz + GetUnitFlyHeight( target )
        
        if startz < endz then
            set midz = midz + endz
        else
            set midz = midz + startz
        endif
        
        set midz = midz + 200.00
        
        set time = 0.00
        
        call UnitAddAbility( target, 'Arav' )
        call UnitRemoveAbility( target, 'Arav' )
        
        call TimerStart( CreateTimer( ), timerPeriodic, true, function move )
    endif
endfunction

//===========================================================================
function InitTrig_Attack takes nothing returns nothing
    set gg_trg_Attack = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Attack, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_Attack, function Trig_Attack_Actions )
endfunction


возможности кривой не заканчиваются на этой убогой параболе само собой
следующая функция:
function BezierCurvePow2_xyz_xyz_xyz(x, y, z, x1, y1, z1, x2, y2, z2, time)
    local a1 = x
    local b1 = 2 * (x1 - x)
    local c1 = x - 2 * x1 + x2
    local a2 = y
    local b2 = 2 * (y1 - y)
    local c2 = y - 2 * y1 + y2
    local a3 = z
    local b3 = 2 * (z1 - z)
    local c3 = z - 2 * z1 + z2
    local x = a1 + (b1 + c1 * time) * time
    local y = a2 + (b2 + c2 * time) * time
    local z = a3 + (b3 + c3 * time) * time
    return x, y, z
end
принимает несколько точек ( начальная, средняя и конечная ), а так же время, которое нужно конвертировать в соотношении до 1 ( т.е. time += timerPeriodic / maxTime )

я думаю уже понятно что с ней можно делать

от Hate

и от меня:
код
library SpellCastLib
globals
    timer TempTimer = CreateTimer( )
    real timerPeriodic = 0.01
    integer max = 0

    unit array dummy
    
    real array startx
    real array starty
    real array startz
    real array midx
    real array midy
    real array midz
    real array endx
    real array endy
    real array endz
    
    real array time
    real array maxTime
    
    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

function move takes nothing returns nothing
    local real x
    local real y
    local real z
    local integer i
    
    set i = 1
    loop
        set x = startx[i] + ( ( 2.00 * ( midx[i] - startx[i] ) ) + ( startx[i] - 2.00 * midx[i] + endx[i] ) * time[i] ) * time[i]
        set y = starty[i] + ( ( 2.00 * ( midy[i] - starty[i] ) ) + ( starty[i] - 2.00 * midy[i] + endy[i] ) * time[i] ) * time[i]
        set z = startz[i] + ( ( 2.00 * ( midz[i] - startz[i] ) ) + ( startz[i] - 2.00 * midz[i] + endz[i] ) * time[i] ) * time[i]
        
        call SetUnitX( dummy[i], x )
        call SetUnitY( dummy[i], y )
        call SetUnitFlyHeight( dummy[i], z - GetLocZ( x, y ), 0.00 )
        
        set time[i] = time[i] + timerPeriodic / maxTime[i]
        
        if time[i] >= 1.00 then
            call KillUnit( dummy[i] )
            set dummy[i] = dummy[max]
            
            set startx[i] = startx[max]
            set starty[i] = starty[max]
            set startz[i] = startz[max]

            set endx[i] = endx[max]
            set endy[i] = endy[max]
            set endz[i] = endz[max]
            
            set midx[i] = midx[max]
            set midy[i] = midy[max]
            set midz[i] = midz[max]
            
            set time[i] = time[max]
            set maxTime[i] = maxTime[max]
            
            set i = i - 1
            set max = max - 1
            
            if max <= 0 then
                call PauseTimer( TempTimer )
            endif
        endif
        
        set i = i + 1
        exitwhen i > max
    endloop
endfunction

function Trig_SpellCast_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit( )
    local real x = GetSpellTargetX( )
    local real y = GetSpellTargetY( )
    local real angle
    local real distance
    local integer i
    
    set bj_groupEnumOwningPlayer = GetOwningPlayer( caster )
    set i = 1
    loop
        set max = max + 1
        
        set startx[max] = GetUnitX( caster )
        set starty[max] = GetUnitY( caster )
        set startz[max] = GetLocZ( startx[max], starty[max] ) + 50.00
        set dummy[max] = CreateUnit( bj_groupEnumOwningPlayer, 'u000', startx[max], starty[max], GetRandomReal( 0.00, 360.00 ) )
        
        call UnitAddAbility( dummy[max], 'Arav' )
        call UnitRemoveAbility( dummy[max], 'Arav' )
        call SetUnitPathing( dummy[max], false )
        call SetUnitX( dummy[max], startx[max] )
        call SetUnitY( dummy[max], starty[max] )
        call SetUnitFlyHeight( dummy[max], startz[max], 0.00 )
        
        set endx[max] = x + GetRandomReal( -250.00, 250.00 ) * Cos( GetRandomReal( 0.00, 360.00 ) * bj_DEGTORAD )
        set endy[max] = y + GetRandomReal( -250.00, 250.00 ) * Sin( GetRandomReal( 0.00, 360.00 ) * bj_DEGTORAD )
        set endz[max] = GetLocZ( endx[max], endy[max] )
        set angle     = Atan2( endy[max] - starty[max], endx[max] - startx[max] )
        set distance  = SquareRoot( ( endx[max] - startx[max] ) * ( endx[max] - startx[max] ) + ( endy[max] - starty[max] ) * ( endy[max] - starty[max] ) )
        
        set midx[max] = startx[max] + ( distance / 2 ) * Cos( angle + GetRandomReal( -90.00, 90.00 ) * bj_DEGTORAD )
        set midy[max] = starty[max] + ( distance / 2 ) * Sin( angle + GetRandomReal( -90.00, 90.00 ) * bj_DEGTORAD )
        set midz[max] = GetLocZ( midx[max], midy[max] )
        
        if startz[max] < endz[max] then
            set midz[max] = midz[max] + endz[max]
        else
            set midz[max] = midz[max] + startz[max]
        endif
        
        set midz[max] = midz[max] + distance
        
        set time[max] = 0.00
        set maxTime[max] = distance * ( timerPeriodic / 2.00 )
        
        if max == 1 then
            call TimerStart( TempTimer, timerPeriodic, true, function move )
        endif
        
        set i = i + 1
        exitwhen i > 10
        call TriggerSleepAction( 0.00 )
    endloop
    
    set caster = null
endfunction

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

//===========================================================================
function InitTrig_SpellCast takes nothing returns nothing
    set gg_trg_SpellCast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SpellCast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_SpellCast, Condition( function Trig_SpellCast_Conditions ) )
    call TriggerAddAction( gg_trg_SpellCast, function Trig_SpellCast_Actions )
endfunction

спасибо N1ghtSiren и Hate
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
3
27
2 года назад
3
Daro, если кому-нибудь надо то пусть хоть статью из этой функции делают, я хвастаться не хочу потому что знаю что я самый помойный чел на хгм, который самостоятельно добился ровно ничего
большая часть материалов из этой страницы даже не моё и не благодаря мне, а благодаря NightSiren'у и Hate'у, которых добавил в благодарности, это они всё придумали, даже видео хейта без его разрешения взял, найтсирен мне не раз помогал подобными функциями и формулами
и ты не представляешь как мне будет стыдно если кто-то посмотрит на это и подумает "оо, dfgdfhg такие прикольные штуки делает крута", мысль об этом заставляет застрелиться
2
12
2 года назад
2
и ты не представляешь как мне будет стыдно если кто-то посмотрит на это и подумает "оо, dfgdfhg такие прикольные штуки делает крута", мысль об этом заставляет застрелиться
Ну тогда давайуже стыдись Даро посмотрел и твой блог и подумал " оо, чел с нечитаемым ником делает такие прикольные штуки , крута вау"..
1
27
2 года назад
1
Загруженные файлы
2
22
2 года назад
Отредактирован Maxlaid
2
я хвастаться не хочу потому что знаю что я самый помойный чел на хгм
А я думал я тут один такой
Загруженные файлы
1
11
2 месяца назад
1
Простите за некропост, выражаю автору благодарочку за скилл. Переписал через хэш без триггерслипа, прилепил урон и вывел в одну функцию, заменил юнита на эффект (для UjPI)
Пример использования: call RocketStrike(caster, x, y, "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl", ammout, dmg, 50., 200., DAMAGE_TYPE_FIRE)
код
// проверка способности
function Trig_MilionGhost_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A026'
endfunction

//движение
function MilionGhostMove takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit GT = LoadUnitHandle(hash, h, 1)
    local effect eff = LoadEffectHandle(hash, h, 2)
    local real startx = LoadReal(hash, h, 3)
    local real starty = LoadReal(hash, h, 4)
    local real startz = LoadReal(hash, h, 5)
    local real midx = LoadReal(hash, h, 6)
    local real midy = LoadReal(hash, h, 7)
    local real midz = LoadReal(hash, h, 8)
    local real endx = LoadReal(hash, h, 9)
    local real endy = LoadReal(hash, h, 10)
    local real endz = LoadReal(hash, h, 11)
    local real time = LoadReal(hash, h, 12)
    local real maxTime = LoadReal(hash, h, 13)
    local real x
    local real y
    local real z
    local real dmg = LoadReal(hash, h, 14)
    local real rng = LoadReal(hash, h, 15)
    local group g 
    local unit un
    local damagetype dmgtype = LoadDamageTypeHandle(hash, h, 16)
    //-------------
    set x = startx + ( ( 2.00 * ( midx - startx ) ) + ( startx - 2.00 * midx + endx ) * time ) * time
    set y = starty + ( ( 2.00 * ( midy - starty ) ) + ( starty - 2.00 * midy + endy ) * time ) * time
    set z = startz + ( ( 2.00 * ( midz - startz ) ) + ( startz - 2.00 * midz + endz ) * time ) * time
    //-------------
    call SetSpecialEffectX(eff, x)
    call SetSpecialEffectY(eff, y)
    call SetSpecialEffectZ(eff, z - GetAxisZ(x, y))
    set time = time + 0.025 / maxTime
    //-------------
    if time >= 1.00 then
        call DestroyEffect(eff)
        call FlushChildHashtable(hash, h)
        call DestroyTimer(t)
        // наносим урон
        //---------------------------
        set g = CreateGroup()
        call GroupEnumUnitsInRange(g, x, y, rng, null)
        loop
            set un = FirstOfGroup(g)
            exitwhen un == null
            if IsUnitEnemy(un, GetOwningPlayer(GT)) and not IsUnitType(un, UNIT_TYPE_DEAD) and not IsUnitType(un, UNIT_TYPE_STRUCTURE) then
               call UnitDamageTarget(GT, un, dmg, true, false, ATTACK_TYPE_NORMAL, dmgtype, WEAPON_TYPE_WHOKNOWS)
                //call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl", un , "orign"))
            endif
            call GroupRemoveUnit(g, un)
        endloop
        call DestroyGroup(g)
        //----------------------------
    else 
        call SaveReal(hash, h, 12, time)
    endif 
    
    //-------------
    set g = null 
    set un = null
    set eff = null
    set GT = null 
    set t = null
    set dmgtype = null
endfunction



// создание эффектов
function MilionGhostCreate takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit GT = LoadUnitHandle(hash, h, 1)
    local integer AmountRocket = LoadInteger(hash, h, 2)
    local real x = LoadReal(hash, h, 3) // центр конечной области
    local real y = LoadReal(hash, h, 4)// центр конечной области
    local timer t1
    local integer h1
    local effect eff
    local real xstart = GetUnitX(GT)
    local real ystart = GetUnitY(GT)
    local real zstart = GetAxisZ(xstart, ystart) + 50
    local real xend //конечная точка способности
    local real yend //конечная точка способности
    local real zend //конечная точка способности
    local real angle
    local real distance
    local real midx // средняя точка способности
    local real midy // средняя точка способности
    local real midz // средняя точка способности
    local real time 
    local real maxtime
    local real Scatter = LoadReal(hash, h, 8)
    local damagetype dmgtype = LoadDamageTypeHandle(hash, h, 9)
    //-------------
    
    if AmountRocket > 0 then
        call SaveInteger(hash, h, 2, AmountRocket-1)
        set t1 = CreateTimer()
        set h1 = GetHandleId(t1)
        //---------       
        set eff = AddSpecialEffect(LoadStr(hash, h, 5), xstart, ystart)
        call SetSpecialEffectZ(eff, zstart)
        
        //высчитываем начало и конец
        set xend = x + GetRandomReal( -Scatter, Scatter ) * Cos( GetRandomReal( 0.00, 360.00 ) * bj_DEGTORAD ) 
        set yend = y + GetRandomReal( -Scatter, Scatter ) * Sin( GetRandomReal( 0.00, 360.00 ) * bj_DEGTORAD )
        set zend = GetAxisZ(xend, yend)
        set angle     = Atan2( yend - ystart, xend - xstart )
        set distance  = SquareRoot( ( xend - xstart ) * ( xend - xstart ) + ( yend - ystart ) * ( yend - ystart ) )
        
        //высчитываем середину
        set midx = xstart + ( distance / 2 ) * Cos( angle + GetRandomReal( -90.00, 90.00 ) * bj_DEGTORAD )
        set midy = ystart + ( distance / 2 ) * Sin( angle + GetRandomReal( -90.00, 90.00 ) * bj_DEGTORAD )
        set midz = GetAxisZ( midx, midy )
        
        // проверка на высоты
        if zstart < zend then
            set midz = midz + zend
        else
            set midz = midz + zstart
        endif
        
        set midz = midz + distance
        
        // время 
        set time = 0
        set maxtime = distance * ( 0.025 / 10.00 )
        
        // всё сохраняем
        call SaveUnitHandle(hash, h1, 1, GT)
        call SaveEffectHandle(hash, h1, 2, eff)
        call SaveReal(hash, h1, 3, xstart)
        call SaveReal(hash, h1, 4, ystart)
        call SaveReal(hash, h1, 5, zstart)
        call SaveReal(hash, h1, 6, midx)
        call SaveReal(hash, h1, 7, midy)
        call SaveReal(hash, h1, 8, midz)
        call SaveReal(hash, h1, 9, xend)
        call SaveReal(hash, h1, 10, yend)
        call SaveReal(hash, h1, 11, zend)
        call SaveReal(hash, h1, 12, time)
        call SaveReal(hash, h1, 13, maxtime)
        call SaveReal(hash, h1, 14, LoadReal(hash, h, 6))
        call SaveReal(hash, h1, 15, LoadReal(hash, h, 7))
        call SaveDamageTypeHandle(hash, h1, 16, dmgtype)
        
        //стартуем
        call TimerStart( t1, 0.025, true, function MilionGhostMove )
        //---------
    else 
        call FlushChildHashtable(hash, h)
        call DestroyTimer(t)
    endif 
    //-------------
    set eff = null
    set t1 = null
    set GT = null 
    set t = null
    set dmgtype = null
endfunction

// функция ракетной атаки
function RocketStrike takes unit GT, real x, real y, string RocketEff, integer AmountRocket, real RocketDmg, real RocketScatter1, real RocketScatterMax, damagetype dmgtype returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    //-------------------
    call SaveUnitHandle(hash, h, 1,GT)
    call SaveInteger(hash, h, 2, AmountRocket)
    call SaveReal(hash, h, 3, x)
    call SaveReal(hash, h, 4, y)
    call SaveStr(hash, h, 5, RocketEff)
    call SaveReal(hash, h, 6, RocketDmg)
    call SaveReal(hash, h, 7, RocketScatter1)
    call SaveReal(hash, h, 8, RocketScatterMax)
    call SaveDamageTypeHandle(hash, h, 9, dmgtype)
    call TimerStart(t, 0.1, true, function MilionGhostCreate)
    //-------------------
    set t = null 
endfunction

// основная функция
function Trig_MilionGhost_Actions takes nothing returns nothing
    local unit GT = GetTriggerUnit()
    local real x = GetSpellTargetX( )
    local real y = GetSpellTargetY( )
    local real dmg = 50.
    local integer kol = 10
    //-------------
    call RocketStrike(GT, x, y, "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl", kol, dmg, 50., 200., DAMAGE_TYPE_FIRE)
    //-------------
    set GT = null 
endfunction

//===========================================================================
function InitTrig_MilionGhost takes nothing returns nothing
    set gg_trg_MilionGhost = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_MilionGhost, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_MilionGhost, Condition( function Trig_MilionGhost_Conditions ) )
    call TriggerAddAction( gg_trg_MilionGhost, function Trig_MilionGhost_Actions )
endfunction
2
37
2 месяца назад
Отредактирован ScorpioT1000
2
Сделал генерацию смешных бошек- аватаров с помощью 9 точек безье, зерно взял как crc32 от юзернейма xgm.guru/users?sort=register
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.