(xgm.guru/p/100/216603) - Предыдущая тема.
Предыстория та же. Делаю скилл сюрикена на JASS (летит в точку и возвращается назад, по пути раздавая люлей врагам). Скилл доделал и он работает, но оставляет много утечек.
Наполовину переписал код по совету UrsaBoss, попутно убирая все BJ, но сейчас в очередной раз залип на пустом месте. Для движения сюрикена я использовал PolarProjectionBJ, но этот BJ надобно убрать, но как грамотно рассписать все расчеты по формуле - понять не могу.
Здесь требуется избавиться от BJ:
call SetUnitPositionLoc(suriken,PolarProjectionBJ(GetUnitLoc(suriken),20.00,AngleBetweenPoints(GetUnitLoc​(suriken),GetUnitLoc(caster))))
Код целиком:
function Trig_Suriken_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A01G'
endfunction

function Flyin takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(udg_Hash,GetHandleId(t),1)
    local unit suriken = LoadUnitHandle(udg_Hash,GetHandleId(t),2)
    local location endfly = LoadLocationHandle(udg_Hash,GetHandleId(t),3)
    local group pool = CreateGroup()
    local unit g
    local real dx = GetLocationX(endfly) - GetLocationX(GetUnitLoc(suriken))
    local real dy = GetLocationY(endfly) - GetLocationY(GetUnitLoc(suriken))
    if SquareRoot(dx * dx + dy * dy) >= 10 then
        call SetUnitPositionLoc(suriken,PolarProjectionBJ(GetUnitLoc(suriken),20.00,GetUnitFacing(suriken)))
        call GroupEnumUnitsInRange(pool,GetUnitX(suriken),GetUnitY(suriken),150.00,null)
        loop
            set g = FirstOfGroup(pool)
            exitwhen g == null
            if IsUnitEnemy(g, GetOwningPlayer(caster)) == true then
                call UnitDamageTarget(caster,g,40.00,false,false,null,null,null)
            endif
            call GroupRemoveUnit(pool,g)
        endloop
    else
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Hash,h)
    endif
    call RemoveLocation(endfly)
    set t = null
    set h = 0
    set caster = null
    set suriken = null
    set endfly = null
    set pool = null
    set g = null
    set dx = 0
    set dy = 0
endfunction

function Flyout takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(udg_Hash,GetHandleId(t),1)
    local unit suriken = LoadUnitHandle(udg_Hash,GetHandleId(t),2)
    local real endfly_x = LoadReal(udg_Hash,GetHandleId(t),3)
    local real endfly_y = LoadReal(udg_Hash,GetHandleId(t),4)
    local group pool = CreateGroup()
    local unit g
    local real dx = GetLocationX(GetUnitLoc(caster)) - GetLocationX(GetUnitLoc(suriken))
    local real dy = GetLocationY(GetUnitLoc(caster)) - GetLocationY(GetUnitLoc(suriken))
    if SquareRoot(dx * dx + dy * dy) >= 50 then
        call SetUnitPositionLoc(suriken,PolarProjectionBJ(GetUnitLoc(suriken),20.00,AngleBetweenPoints(GetUnitLoc(suriken),GetUnitLoc(caster))))
        call GroupEnumUnitsInRange(pool,GetUnitX(suriken),GetUnitY(suriken),150.00,null)
        loop
            set g = FirstOfGroup(pool)
            exitwhen g == null
            if IsUnitEnemy(g, GetOwningPlayer(caster)) == true then
                call UnitDamageTarget(caster,g,40.00,false,false,null,null,null)
            endif
            call GroupRemoveUnit(pool,g)
        endloop
    else
        call KillUnit(suriken)
        call TriggerSleepAction(1.0)
        call RemoveUnit(suriken)
        call DestroyTimer(t)
    endif
    set t = null
    set h = 0
    set caster = null
    set suriken = null
    set endfly_x = 0
    set endfly_y = 0
    set pool = null
    set g = null
    set dx = 0
    set dy = 0
endfunction

function Trig_Suriken_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit caster = GetSpellAbilityUnit()
    local unit suriken = CreateUnit(GetOwningPlayer(caster),'u001',GetUnitX(caster),GetUnitY(caster),GetUnitFacing(caster))
    local real endfly_x = GetUnitX(caster) + 2000.00 * Cos(GetUnitFacing(caster) * bj_DEGTORAD)
    local real endfly_y = GetUnitY(caster) + 2000.00 * Sin(GetUnitFacing(caster) * bj_DEGTORAD)
    call SaveUnitHandle(udg_Hash,GetHandleId(t),1,caster)
    call SaveUnitHandle(udg_Hash,GetHandleId(t),2,suriken)
    call SaveReal(udg_Hash,GetHandleId(t),3,endfly_x)
    call SaveReal(udg_Hash,GetHandleId(t),4,endfly_x)
    call TimerStart(t,0.02,true,function Flyin)
    call TriggerSleepAction(1.7)
    call SaveUnitHandle(udg_Hash,GetHandleId(t),1,caster)
    call SaveUnitHandle(udg_Hash,GetHandleId(t),2,suriken)
    call SaveReal(udg_Hash,GetHandleId(t),3,endfly_x)
    call SaveReal(udg_Hash,GetHandleId(t),4,endfly_x)
    call TimerStart(t,0.02,true,function Flyout)
    call TriggerSleepAction(3.0)
    call DestroyTimer(t)
    set caster = null
    set suriken = null
    set endfly_x = 0
    set endfly_y = 0
    set t = null
endfunction

//===========================================================================
    function InitTrig_Suriken takes nothing returns nothing
        set gg_trg_Suriken = CreateTrigger( )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Suriken, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Suriken, Condition( function Trig_Suriken_Conditions ) )
        call TriggerAddAction( gg_trg_Suriken, function Trig_Suriken_Actions )
        
        set udg_Hash = InitHashtableBJ( )
    endfunction
Карта:
З.Ы. Если кто может помочь с вопросами на чистом энтузиазме - могу скинуть DS.
З.Ы.Ы. Дабы не дергать форум много раз, а то уже 4 темы создал))

Принятый ответ

range * Cos(a * bj_DEGTORAD)
должно получится так:
a = Atan2(endfly_y - GetUnitY(suriken), endfly_x - GetUnitX(suriken))
SetUnitX(suriken, GetUnitX(suriken) + 20.00 * Cos(a))
SetUnitY(suriken, GetUnitY(suriken) + 20.00 * Sin(a))
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
5
6 лет назад
Отредактирован Lillikon
0
UrsaBoss:
Там где ты уничтожаешь таймер в Flyin - можно заного запустить таймер и уже юзать Flyout
И ещё ты во Flyin используешь "location endfly" которая там просто висит, наверное ты забыл поменять на endfly_x/y
Вместо многократного использования GetHandleId(t) - занеси всё в одну integer и используй её
Обнулять нужно только указатели на игровой объект, обнулять real/integer/boolean/string не нужно.
Есть исключения, если игровой объект в игре будет всю игру (к примеру игрок) - то указатель на него не обязательно обнулять
Я уже переписываю код, исключая все замечания, которые учел и которые мне подсказали. Сейчас проблема только в том, как в формулу :
a = угол направления
x + range * Cos(a * bj_DEGTORAD)
y + range * Sin(a * bj_DEGTORAD)
добавить джижение 20 единиц. Я это не ферштейн и объяснить никто пока не смог.
0
26
6 лет назад
0
PT153:
Не все BJ функции зло. Злом являются те, кто использует локации, группы, кланы, делают вызов 1-й функции без доп. аргументов.
практически все бж функции - оберточные, а значит их можно раскрыть и избежать двойных а то и тройных вызовов функций
2
18
6 лет назад
Отредактирован Hodor
2
range * Cos(a * bj_DEGTORAD)
должно получится так:
a = Atan2(endfly_y - GetUnitY(suriken), endfly_x - GetUnitX(suriken))
SetUnitX(suriken, GetUnitX(suriken) + 20.00 * Cos(a))
SetUnitY(suriken, GetUnitY(suriken) + 20.00 * Sin(a))
Принятый ответ
0
5
6 лет назад
0
Borodach:
триггеры
каст способности
движение часть 1
движение часть 2
Хоспади, добрый человек, спасибо! Хоть кто-то мне на пальцах объяснил! Меня это реально добивало)))) Сижу тут как "умный" и думаю интенсивно)
PT153:
Не все BJ функции зло. Злом являются те, кто использует локации, группы, кланы, делают вызов 1-й функции без доп. аргументов.
Конкретно в моем скилле при одном касте из-за этих BJ где-то 1к утечек на каст) Так что убрать их - маст хев.
0
13
6 лет назад
0
И если нужен каст между целью и кастером, а не куда кастер смотрит,
то угол в SaveReal(h, id, 5, Atan2(GetSpellTargetY() - y, GetSpellTargetX() - x))
2
21
6 лет назад
2

//===========================================================================
function Trig_Suriken_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A01G'
endfunction

//===========================================================================
function Move takes nothing returns nothing
    local timer    t        = GetExpiredTimer()
    local integer  id       = GetHandleId( t )
    
    local unit     caster   = LoadUnitHandle( udg_Hash, id, 1 )
    local unit     suriken  = LoadUnitHandle( udg_Hash, id, 2 )
    local real     surikenX = LoadReal( udg_Hash, id, 7 )
    local real     surikenY = LoadReal( udg_Hash, id, 8 )
    
    local real     targetX  = LoadReal( udg_Hash, id, 3 )
    local real     targetY  = LoadReal( udg_Hash, id, 4 )

    local real     time     = LoadReal   ( udg_Hash, id, 6 )

    local real     dx       = targetX - surikenX
    local real     dy       = targetY - surikenY
    local real     dist     = SquareRoot( dx * dx + dy * dy )
    
    local group    pool     = CreateGroup( )
    local unit     g        = null

    call SaveReal( udg_Hash, id, 6, time + 0.02 )
    
    call GroupEnumUnitsInRange( pool, surikenX, surikenY, 150.00, null )
    loop
        set g = FirstOfGroup( pool )
        exitwhen ( g == null )
        if IsUnitEnemy( g, GetOwningPlayer( caster ) ) then
            call UnitDamageTarget( caster, g, 40.00, false, false, null, null, null )
        endif
        call GroupRemoveUnit( pool, g )
    endloop


    if ( time <= 1.7 ) and ( dist > 16.0 ) then
        set surikenX = ( surikenX + 20.0 * ( dx / dist ) )
        set surikenY = ( surikenY + 20.0 * ( dy / dist ) )

        call SetUnitPosition( suriken, surikenX, surikenY )
        call SaveReal      ( udg_Hash, id, 7, surikenX )
        call SaveReal      ( udg_Hash, id, 8, surikenY )

    elseif ( dist < 16.0 ) and ( time <= 3.4 ) then
        call DestroyTimer( t )
        call KillUnit( suriken )
        call RemoveUnit(suriken)
        call FlushChildHashtable( udg_Hash, id )

    elseif ( time <= 3.4 ) or ( dist > 16.0 ) then
        set surikenX = ( surikenX + 20.0 * ( dx / dist ) )
        set surikenY = ( surikenY + 20.0 * ( dy / dist ) )

        call SetUnitPosition( suriken, surikenX, surikenY )
        call SaveReal      ( udg_Hash, id, 3, GetUnitX( caster ) )
        call SaveReal      ( udg_Hash, id, 4, GetUnitY( caster ) )
        call SaveReal      ( udg_Hash, id, 7, surikenX           )
        call SaveReal      ( udg_Hash, id, 8, surikenY           )

    else
        call DestroyTimer( t )
        call KillUnit( suriken )
        call RemoveUnit(suriken)
        call FlushChildHashtable( udg_Hash, id )
    endif

    call DestroyGroup( pool )
    
    set t       = null
    set caster  = null
    set suriken = null
    set pool    = null
endfunction

//===========================================================================
function Trig_Suriken_Actions takes nothing returns nothing
    local timer   t        = CreateTimer( )
    local integer id       = GetHandleId( t )
    
    local unit    caster   = GetSpellAbilityUnit( )
    local real    casterX  = GetUnitX( caster )
    local real    casterY  = GetUnitY( caster )
    
    local real    targetX  = GetSpellTargetX( )
    local real    targetY  = GetSpellTargetY( )

    local unit    suriken  = CreateUnit( GetOwningPlayer( caster ), 'u001', casterX, casterY, 0.0 )
    
    local real    angle    = Atan2( targetY - casterY, targetX - casterX )

    set targetX = GetUnitX( caster ) + 2000.0 * Cos( angle )
    set targetY = GetUnitY( caster ) + 2000.0 * Sin( angle )

    call SaveUnitHandle( udg_Hash, id, 1, caster  )
    call SaveUnitHandle( udg_Hash, id, 2, suriken )
    call SaveReal      ( udg_Hash, id, 3, targetX )
    call SaveReal      ( udg_Hash, id, 4, targetY )
    call SaveReal      ( udg_Hash, id, 6, 0.0     )
    call SaveReal      ( udg_Hash, id, 7, casterX )
    call SaveReal      ( udg_Hash, id, 8, casterY )

    call TimerStart( t, 0.02, true, function Move )

    set t       = null
    set caster  = null
    set suriken = null
endfunction

//===========================================================================
function InitTrig_Suriken_2 takes nothing returns nothing
    set gg_trg_Suriken_2 = CreateTrigger( )
    set udg_Hash = InitHashtable( )
        
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Suriken_2, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Suriken_2, Condition( function Trig_Suriken_Conditions ) )
    call TriggerAddAction( gg_trg_Suriken_2, function Trig_Suriken_Actions )
endfunction
1
28
6 лет назад
1
UrsaBoss, нафига тут вообще углы?
float dx = endfly_x - GetUnitX(suriken);
float dy = endfly_y - GetUnitY(suriken);
float r = SquareRoot(dx*dx + dy*dy);
SetUnitX(suriken, GetUnitX(suriken) + 20.00 * (dx/r))
SetUnitY(suriken, GetUnitY(suriken) + 20.00 * (dy/r))
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.