Нужна наработка по отскоку отраженного снаряда от юнита, или подскажите как сделать, патч любой но обязательно чтобы на векторах, можно даже на джасах на 1.26 (на луа сам перепишу). Вроде немногожко что-то понимаю, уже второй день ковыряю вот это
тут во первых от клифа отскок, а во вторых у меня явно что-то не так, дот продукт всегда нулевой. Не думаю что осилю код из варлоков после депротекта, так как там рикошет будет просто внутри кучи систем.
В общем, сделайте за меня, помогите пожалуйста, желательно готовой картой чисто с этой системой.
Возможно, с течением времени, будет появляться информация о моих попытках, где я застрял
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
32
9 месяцев назад
0
код jass
((
ang= ang - 180.00 + 2.00 * ( Atan2( cy - dx, cx - dx ) * bj_RADTODEG )// рикошет, угол падения = углу отражения и все такое...
))
Как то давно для своей карты делал, ang текущий угол юнита (или что там у тебя) cx-cy - координаты юнита (или что там у тебя(, dx-dy координаты препятствия, т.е того от чего идет рикошет.
4
27
9 месяцев назад
4
Возможно, с течением времени, будет появляться информация о моих попытках, где я застрял
ну вот лично моя попытка
просто проверяю 4 стороны предметом на наличие квадратных карт путей, потом проверяю юнитов
пример ENAleksey не удалось разобрать, судя по всему там нормальный рикошет даже от всяких холмов, со всеми 3 координатами
код
library MyLib
globals
    constant hashtable H = InitHashtable( )
    constant group TempGroup = CreateGroup( )
    constant location LFZ = Location( 0.00, 0.00 )
    item TempItem = null
endglobals

native UnitAlive takes unit id returns boolean

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

struct vector
    real x
    real y
    real z
    
    method normalize takes nothing returns nothing
        local real l = SquareRoot( x * x + y * y + z * z )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x * ( 1.00 / l )
        set y = y * ( 1.00 / l )
        set z = z * ( 1.00 / 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
        
        call this.normalize( )
        
        return this
    endmethod
endstruct

struct MyStruct
    unit dummy
    real x
    real y
    real z
    real time
    group g
    vector v
endstruct

private function Move takes nothing returns nothing
    local MyStruct A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x
    local real y
    local real x1
    local real y1
    local real a
    local boolean array b
    local unit u
    
    set A.x = A.x + 5.00 * A.v.x
    set A.y = A.y + 5.00 * A.v.y
    set A.z = A.z + 5.00 * A.v.z
    
    call SetItemPosition( TempItem, A.x, A.y )
    call SetItemVisible( TempItem, false )
    
    set x = GetItemX( TempItem )
    set y = GetItemY( TempItem )
    
    if ( x - 1.00 > A.x or x + 1.00 < A.x ) or ( y - 1.00 > A.y or y + 1.00 < A.y ) then
        set A.x = A.x - 5.00 * A.v.x
        set A.y = A.y - 5.00 * A.v.y
        set A.z = A.z - 5.00 * A.v.z
        
        // right
        set x = A.x + 5.00
        set y = A.y
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        
        set b[0] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        // left
        set x = A.x - 5.00
        set y = A.y
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        set b[1] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        // up
        set x = A.x
        set y = A.y + 5.00
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        set b[2] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        // down
        set x = A.x
        set y = A.y - 5.00
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        set b[3] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        if b[0] or b[1] or b[2] or b[3] then
            if b[0] or b[1] then
                set A.v.x = -A.v.x
            else
                set A.v.y = -A.v.y
            endif
        else
            set A.v.x = -A.v.x
            set A.v.y = -A.v.y
        endif
    else // units
        call GroupEnumUnitsInRange( TempGroup, A.x, A.y, 64.00, null )
        call GroupRemoveUnit( TempGroup, A.dummy )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if not IsUnitInGroup( u, A.g ) and UnitAlive( u ) and GetUnitTypeId( u ) == 'hfoo' then
                set x1 = GetUnitX( u )
                set y1 = GetUnitY( u )
                set a = Atan2( y1 - A.y, x1 - A.x ) + bj_PI - Atan2( A.v.y, A.v.x )
                
                set x = A.v.x
                set A.v.x = x * Cos( a ) - A.v.y * Sin( a )
                set A.v.y = A.v.y * Cos( a ) + x * Sin( a )
                call GroupClear( A.g )
                call GroupAddUnit( A.g, u )
                
                set A.time = 0.25
            endif
        endloop
    endif
    
    set A.time = A.time - 0.01
    
    if A.time == 0.00 then
        call GroupClear( A.g )
    endif
    
    call SetUnitX( A.dummy, A.x )
    call SetUnitY( A.dummy, A.y )
    call SetUnitFlyHeight( A.dummy, A.z - GetLocZ( A.x, A.y ), 0.00 )
endfunction

function Nin_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local MyStruct A = MyStruct.create( )
    local unit u = GetTriggerUnit( )
    local real x = GetSpellTargetX( )
    local real y = GetSpellTargetY( )
    local real z = GetLocZ( x, y )
    
    set A.x = GetUnitX( u )
    set A.y = GetUnitY( u )
    set A.z = GetLocZ( A.x, A.y )
    
    set A.v = vector.create( x - A.x, y - A.y, /*z - A.z*/0.00 )
    set A.dummy = CreateUnit( GetOwningPlayer( u ), 'hfoo', A.x, A.y, Atan2( y - A.y, x - A.x ) * bj_RADTODEG )
    call UnitAddAbility( A.dummy, 'Arav' )
    
    set A.g = CreateGroup( )
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.01, true, function Move )
    
    set u = null
    set t = null
endfunction
endlibrary

//===========================================================================
function InitTrig_Nin takes nothing returns nothing
    set gg_trg_Nin = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Nin, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Nin, function Nin_Actions )
    
    set TempItem = CreateItem( 'spsh', 0.00, 0.00 )
    call SetItemVisible( TempItem, false )
endfunction

Загруженные файлы
3
32
9 месяцев назад
3
Судя по видео, работает как мне нужно, спасибо большое
2
18
9 месяцев назад
2
Берги, может отметить лучший ответ?)
0
27
9 месяцев назад
0
Vlod, просто это не тот рикошет что нужен, желательно как тут
4
27
9 месяцев назад
4
вторая попытка
код
library MyLib
globals
    constant hashtable H = InitHashtable( )
    constant group TempGroup = CreateGroup( )
    constant location LFZ = Location( 0.00, 0.00 )
    item TempItem = null
endglobals

native UnitAlive takes unit id returns boolean

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

struct vector
    real x
    real y
    real z
    
    method normalize takes nothing returns nothing
        local real l = SquareRoot( x * x + y * y + z * z )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x * ( 1.00 / l )
        set y = y * ( 1.00 / l )
        set z = z * ( 1.00 / 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
        
        call this.normalize( )
        
        return this
    endmethod
endstruct

struct MyStruct
    unit dummy
    real x
    real y
    real z
    real time
    group g
    vector v
endstruct

private function Move takes nothing returns nothing
    local MyStruct A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x
    local real y
    local real x1
    local real y1
    local real a
    local boolean array b
    local unit u
    
    set A.x = A.x + 5.00 * A.v.x
    set A.y = A.y + 5.00 * A.v.y
    set A.z = A.z + 5.00 * A.v.z
    
    call SetItemPosition( TempItem, A.x, A.y )
    call SetItemVisible( TempItem, false )
    
    set x = GetItemX( TempItem )
    set y = GetItemY( TempItem )
    
    if ( x - 1.00 > A.x or x + 1.00 < A.x ) or ( y - 1.00 > A.y or y + 1.00 < A.y ) then
        set A.x = A.x - 5.00 * A.v.x
        set A.y = A.y - 5.00 * A.v.y
        set A.z = A.z - 5.00 * A.v.z
        
        // right
        set x = A.x + 5.00
        set y = A.y
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        
        set b[0] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        // left
        set x = A.x - 5.00
        set y = A.y
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        set b[1] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        // up
        set x = A.x
        set y = A.y + 5.00
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        set b[2] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        // down
        set x = A.x
        set y = A.y - 5.00
        call SetItemPosition( TempItem, x, y )
        call SetItemVisible( TempItem, false )
        
        set x1 = GetItemX( TempItem )
        set y1 = GetItemY( TempItem )
        set b[3] = ( x1 - 1.00 > x or x1 + 1.00 < x ) or ( y1 - 1.00 > y or y1 + 1.00 < y )
        
        if b[0] or b[1] or b[2] or b[3] then
            if b[0] or b[1] then
                set A.v.x = -A.v.x
            else
                set A.v.y = -A.v.y
            endif
        else
            set A.v.x = -A.v.x
            set A.v.y = -A.v.y
        endif
    else // units
        call GroupEnumUnitsInRange( TempGroup, A.x, A.y, 64.00, null )
        call GroupRemoveUnit( TempGroup, A.dummy )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if not IsUnitInGroup( u, A.g ) and UnitAlive( u ) and GetUnitTypeId( u ) == 'hfoo' then
                set x1 = GetUnitX( u )
                set y1 = GetUnitY( u )
                set a = Atan2( A.y - y1, A.x - x1 )
                
                set bj_lastCreatedUnit = CreateUnit( Player( 0x00 ), 'u000', x1 + 24.00 * Cos( a ), y1 + 24.00 * Sin( a ), a * bj_RADTODEG )
                call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
                call SetUnitX( bj_lastCreatedUnit, x1 + 32.00 * Cos( a ) )
                call SetUnitY( bj_lastCreatedUnit, y1 + 32.00 * Sin( a ) )
                call SetUnitTimeScale( bj_lastCreatedUnit, 2.00 )
                
                set a = a + ( a - ( Atan2( A.v.y, A.v.x ) - 180.00 * bj_DEGTORAD ) )
                
                //set x = A.v.x
                set A.v.x = Cos( a )//A.v.x * Cos( a ) - A.v.y * Sin( a )
                set A.v.y = Sin( a )//A.v.y * Cos( a ) + x * Sin( a )
                call GroupClear( A.g )
                call GroupAddUnit( A.g, u )
                
                set A.time = 0.25
            endif
        endloop
    endif
    
    set A.time = A.time - 0.01
    
    if A.time == 0.00 then
        call GroupClear( A.g )
    endif
    
    call SetUnitX( A.dummy, A.x )
    call SetUnitY( A.dummy, A.y )
    call SetUnitFlyHeight( A.dummy, A.z - GetLocZ( A.x, A.y ), 0.00 )
endfunction

function Nin_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local MyStruct A = MyStruct.create( )
    local unit u = GetTriggerUnit( )
    local real x = GetSpellTargetX( )
    local real y = GetSpellTargetY( )
    local real z = GetLocZ( x, y )
    
    set A.x = GetUnitX( u )
    set A.y = GetUnitY( u )
    set A.z = GetLocZ( A.x, A.y )
    
    set A.v = vector.create( x - A.x, y - A.y, /*z - A.z*/0.00 )
    set A.dummy = CreateUnit( GetOwningPlayer( u ), 'hfoo', A.x, A.y, Atan2( y - A.y, x - A.x ) * bj_RADTODEG )
    call UnitAddAbility( A.dummy, 'Arav' )
    
    set A.g = CreateGroup( )
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.01, true, function Move )
    
    set u = null
    set t = null
endfunction
endlibrary

//===========================================================================
function InitTrig_Nin takes nothing returns nothing
    set gg_trg_Nin = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Nin, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Nin, function Nin_Actions )
    
    set TempItem = CreateItem( 'spsh', 0.00, 0.00 )
    call SetItemVisible( TempItem, false )
endfunction

Загруженные файлы
2
32
9 месяцев назад
2
вторая попытка
тут ещё лучше 👍
Чтобы оставить комментарий, пожалуйста, войдите на сайт.