28

» WarCraft 3 / как задать модель поведения юниту?

prorokkk, а ты знаешь какие-то другие способы приказать юниту делать что тебе надо?
28

» WarCraft 3 / Движение дамми юнита

jasonrus96, просто пробуй улучшать свой код, начиная банально с табуляции и названий функций, заканчивая структурами и сложными системами, на рефе и вовсе можно на луа перейти спокойно

Тебе просто практика нужна
28

» WarCraft 3 / Движение дамми юнита

jasonrus96, так от моего описания ничем не отличается
так перезаписывай локалки в лупе просто
В луп перемещено создание таймера со структурой и всеми вытекающими
28

» WarCraft 3 / Движение дамми юнита

код
library ShootSystemLib
globals
    constant hashtable H = InitHashtable( )
    constant group TempGroup = CreateGroup( )
    constant location LFZ = Location( 0.00, 0.00 )
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 bullet
    unit caster
    unit dummy
    player p
    
    real x
    real y
    real z
    real s // speed
    real d // distance
    real r // radius
    
    vector v
endstruct

function Move takes nothing returns nothing
    local bullet A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    
    set A.x = A.x + A.s * A.v.x * Cos( A.v.z )
    set A.y = A.y + A.s * A.v.y * Cos( A.v.z )
    set A.z = A.z + A.s * A.v.z
    
    set A.d = A.d - A.s
    
    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 )
    
    call GroupEnumUnitsInRange( TempGroup, A.x, A.y, A.r, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if UnitAlive( u ) and IsUnitEnemy( u, A.p ) and RAbsBJ( GetUnitFlyHeight( u ) - GetUnitFlyHeight( A.dummy ) ) <= 100.00 then
            call GroupClear( TempGroup )
            call UnitDamageTarget( A.caster, u, 100.00, false, false, null, null, null )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", u, "chest" ) )
        endif
    endloop
    
    if A.d <= 0.00 or A.z - GetLocZ( A.x, A.y ) <= 20.00 then
        call PauseTimer( GetExpiredTimer( ) )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call DestroyTimer( GetExpiredTimer( ) )
        
        call KillUnit( A.dummy )
        
        set A.dummy = null
        set A.caster = null
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    local timer t
    local bullet A
    local real x = GetSpellTargetX( )
    local real y = GetSpellTargetY( )
    local real z = GetLocZ( x, y ) + 50.00
    local integer i = 12
    
    loop
        set t = CreateTimer( )
        set A = bullet.create( )
        set A.caster = GetTriggerUnit( )
        set A.p = GetOwningPlayer( A.caster )
        
        // for offset
        set A.x = GetUnitX( A.caster )
        set A.y = GetUnitY( A.caster )
        set A.z = GetUnitFlyHeight( A.caster ) + GetLocZ( A.x, A.y ) + 50.00
        
        set A.v = vector.create( x - A.x, y - A.y, z - A.z )
        
        set A.x = A.x + 50.00 * A.v.x * Cos( A.v.z )
        set A.y = A.y + 50.00 * A.v.y * Cos( A.v.z )
        set A.z = GetUnitFlyHeight( A.caster ) + GetLocZ( A.x, A.y ) + 50.00
        
        // for move
        set A.v.x = x - A.x
        set A.v.y = y - A.y
        set A.v.z = z - A.z
        
        call A.v.normalize( )
        
        set A.v.x = A.v.x + GetRandomReal( -0.15, 0.15 )
        set A.v.y = A.v.y + GetRandomReal( -0.15, 0.15 )
        set A.v.z = A.v.z + GetRandomReal( -0.15, 0.15 )
        
        set A.d = 1200.00
        set A.s = 1500.00 * 0.03125
        set A.r = 40.00
        
        set A.dummy = CreateUnit( A.p, 'u000', A.x, A.y, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
        call SetUnitPathing( A.dummy, false )
        call UnitAddAbility( A.dummy, 'Arav' )
        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 )
        
        call SaveInteger( H, GetHandleId( t ), 0, A )
        call TimerStart( t, 0.03125, true, function Move )
        
        set i = i - 1
        exitwhen i <= 0
    endloop
    set t = null
endfunction

//===========================================================================
function Untitled_Trigger_001_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_001, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Untitled_Trigger_001, Condition( function Untitled_Trigger_001_Conditions ) )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction
endlibrary
Загруженные файлы
28

» WarCraft 3 / Движение дамми юнита

jasonrus96, так перезаписывай локалки в лупе просто, в чём проблема..

ты хочешь все снаряды к одному таймеру привязать что ли?
28

» WarCraft 3 / как задать модель поведения юниту?

prorokkk, нейтральным ты никак не прикажешь, ими управляет бот. Отдавать юнита нужно слоту игрока
28

» WarCraft 3 / Движение дамми юнита

jasonrus96, у меня рефа нет так что как-то так
код
library ShootSystemLib
globals
    constant hashtable H = InitHashtable( )
    constant group TempGroup = CreateGroup( )
    constant location LFZ = Location( 0.00, 0.00 )
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 bullet
    unit caster
    unit dummy
    player p
    
    real x
    real y
    real z
    real s // speed
    real d // distance
    real r // radius
    
    vector v
endstruct

function Move takes nothing returns nothing
    local bullet A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    
    set A.x = A.x + A.s * A.v.x * Cos( A.v.z )
    set A.y = A.y + A.s * A.v.y * Cos( A.v.z )
    set A.z = A.z + A.s * A.v.z
    
    set A.d = A.d - A.s
    
    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 )
    
    call GroupEnumUnitsInRange( TempGroup, A.x, A.y, A.r, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if UnitAlive( u ) and IsUnitEnemy( u, A.p ) and RAbsBJ( GetUnitFlyHeight( u ) - GetUnitFlyHeight( A.dummy ) ) <= 100.00 then
            call GroupClear( TempGroup )
            call UnitDamageTarget( A.caster, u, 100.00, false, false, null, null, null )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", u, "chest" ) )
        endif
    endloop
    
    if A.d <= 0.00 or A.z - GetLocZ( A.x, A.y ) <= 20.00 then
        call PauseTimer( GetExpiredTimer( ) )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call DestroyTimer( GetExpiredTimer( ) )
        
        call KillUnit( A.dummy )
        
        set A.dummy = null
        set A.caster = null
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local bullet A = bullet.create( )
    local real x = GetSpellTargetX( )
    local real y = GetSpellTargetY( )
    local real z = GetLocZ( x, y ) + 50.00
    
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    
    // for offset
    set A.x = GetUnitX( A.caster )
    set A.y = GetUnitY( A.caster )
    set A.z = GetUnitFlyHeight( A.caster ) + GetLocZ( A.x, A.y ) + 50.00
    
    set A.v = vector.create( x - A.x, y - A.y, z - A.z )
    
    set A.x = A.x + 50.00 * A.v.x * Cos( A.v.z )
    set A.y = A.y + 50.00 * A.v.y * Cos( A.v.z )
    set A.z = GetUnitFlyHeight( A.caster ) + GetLocZ( A.x, A.y ) + 50.00
    
    // for move
    set A.v.x = x - A.x
    set A.v.y = y - A.y
    set A.v.z = z - A.z
    
    call A.v.normalize( )
    
    set A.d = 1200.00
    set A.s = 1500.00 * 0.03125
    set A.r = 40.00
    
    set A.dummy = CreateUnit( A.p, 'u000', A.x, A.y, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
    call SetUnitPathing( A.dummy, false )
    call UnitAddAbility( A.dummy, 'Arav' )
    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 )
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.03125, true, function Move )
    
    set t = null
endfunction

//===========================================================================
function Untitled_Trigger_001_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_001, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Untitled_Trigger_001, Condition( function Untitled_Trigger_001_Conditions ) )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction
endlibrary

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

» WarCraft 3 / Движение дамми юнита

jasonrus96, просто указанные тобой переменные помещенные в структуре, которая на самом деле массивная целочисленная, сейчас попробую набросать
28

» WarCraft 3 / Движение дамми юнита

Нашел нужно было в переменную maxDist исправить на maxDis 😅
пользовался бы структурами, с такими проблемами не мучился, потому что компилятор помог бы)
28

» WarCraft 3 / Движение дамми юнита

Дамик создается нормально в нужном направлении но не летит
попробуй тогда продебажить угол и скорость
28

» WarCraft 3 / Движение дамми юнита

Когда скилом код юзаешь все работает.
хочешь сказать что условие или событие не срабатывает? или даммик всё-таки создаётся но не летит?
28

» WarCraft 3 / Движение дамми юнита

jasonrus96, а, ну я по названию триггера вижу, обычный выстрел хочешь сделать при клике пкм?
28

» WarCraft 3 / Движение дамми юнита

Пользуйся структурами, с ними проще и удобнее работать, да и оптимизированнее будут
В какую сторону юнит летит тогда? Или ты хочешь чтобы снаряд преследовал юнита, которого ты к курсору прицепил?
28

» WarCraft 3 / Помогите с библиотеками

ну создай просто конструктор и деконструктор, потом переделывай всю свою систему под это дело

ограниченное количество массива в warcraft 3 около 10 000
8192
28

» WarCraft 3 / Как сделать способность, без обязательной цели

LAMLAN, у утечки памяти разный "вес", ограничение идёт (т.е. краш) когда вар занимает больше 900мб памяти

Посмотреть можно через диспетчер задач у процесса war3.exe
28

» WarCraft 3 / Как сделать способность, без обязательной цели

LAMLAN, да, из-за утечек может крашнуться карта, когда вар начнёт занимать больше 900мб памяти. До этого момента по идее ещё лаги начнут появляться. Так что злоупотреблять утечками не стоит. Если ты работаешь в джнгп с включенным сджассом и вджассом, можешь закинуть счётчик хэндлов в карту

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

Он вроде не объясняет конкретно в том видео, там самое последнее видео про утечки

Мне пересматривать лень
28

» WarCraft 3 / Триггеры

Mikel 1990, WaitForCondition (every 0.01) не подходит потому что не заставляет срабатывать действия каждые 0.01 секунд, так что в твоём случае нет причин беспокоиться, если всё работает как нужно
28

» WarCraft 3 / Naruto Bleach War v0.3a (Dota Mod)

Nikolay36, делись прогрессом и идеями, будет интересно узнавать что к чему и помогать с развитием