Имеется два кода для разных способностей, каждая из них движет юнита вокруг героя, но один код работает исправно, а другой притягивает юнитов к герою, хотя код и механика одинакова. В чём проблема?
Работает
function circlemotionsoul takes nothing returns nothing
    local timer SoulMooveCircleTimer = GetExpiredTimer()
    local integer id = GetHandleId(SoulMooveCircleTimer)
    local unit Soul = LoadUnitHandle(H, id, 1)
    local unit DeathKnight = LoadUnitHandle(H, id, 2)
    local real SoulX = GetUnitX(Soul)
    local real SoulY = GetUnitY(Soul)
    local real SoulStealerX = GetUnitX(DeathKnight)
    local real SoulStealerY = GetUnitY(DeathKnight)
    local integer ds = LoadInteger(H, id, 3)
    local real a
    
    if Soul != null then
    
        set a = bj_RADTODEG * Atan2(SoulStealerY + 250 * Sin((6 * ds) * bj_DEGTORAD) - SoulY, SoulStealerX + 250 * Cos((6 * ds) * bj_DEGTORAD) - SoulX)
        call SetUnitPosition(Soul, SoulX + 10 * Cos(a * bj_DEGTORAD), SoulY + 10 * Sin(a * bj_DEGTORAD))
        if ds == 60 then
            set ds = 0
        else
            set ds = ds + 1
        endif
        
        call SaveInteger(H, id, 3, ds)
        
    else
        call DestroyTimer(SoulMooveCircleTimer)
        call FlushChildHashtable(H, id)
    endif
    
    set SoulMooveCircleTimer = null
    set Soul = null
    set DeathKnight = null
endfunction

function motionsoul takes nothing returns nothing
    local timer SoulMooveTimer = GetExpiredTimer()
    local integer id = GetHandleId(SoulMooveTimer)
    local unit Soul = LoadUnitHandle(H, id, 1)
    local unit DeathKnight = LoadUnitHandle(H, id, 2)
    local real SoulX = GetUnitX(Soul)
    local real SoulY = GetUnitY(Soul)
    local real SoulStealerX = GetUnitX(DeathKnight)
    local real SoulStealerY = GetUnitY(DeathKnight)
    local real a 
    local timer SoulMooveCircleTimer = CreateTimer()
    local integer idt = GetHandleId(SoulMooveCircleTimer)

    if SquareRoot((SoulStealerX - SoulX) * (SoulStealerX - SoulX) + (SoulStealerY - SoulY) * (SoulStealerY - SoulY)) >= 200 then
        set a = bj_RADTODEG * Atan2(SoulStealerY - SoulY, SoulStealerX - SoulX)
        call SetUnitPosition(Soul, SoulX + 25 * Cos(a * bj_DEGTORAD), SoulY + 25 * Sin(a * bj_DEGTORAD))
    else
        call DestroyTimer(SoulMooveTimer)
        call FlushChildHashtable(H, id)
        call TimerStart( SoulMooveCircleTimer, 0.04, true, function circlemotionsoul)
        call SaveUnitHandle(H, idt, 1, Soul)
        call SaveUnitHandle(H, idt, 2, DeathKnight)
        call GroupAddUnit(KnifeGroup, Soul)
    endif

    set SoulMooveTimer = null
    set Soul = null
    set DeathKnight = null
    set SoulMooveCircleTimer = null
endfunction
Не работает
function BladeDanceMoveAround2 takes nothing returns nothing
    local unit Knife = GetEnumUnit()
    local integer tid = GetHandleId(KnifeGroup)
    local integer ds = LoadInteger(H, tid, 'Arnd')
    local real Distance = LoadReal(H, tid, 'Dist')
    local real CasterX = GetUnitX(Kolamana)
    local real CasterY = GetUnitY(Kolamana)
    local real KnifeX = GetUnitX(Knife)
    local real KnifeY = GetUnitY(Knife)
    local real a
        
    set a = bj_RADTODEG * Atan2(CasterY + Distance * Sin(6 * ds * bj_DEGTORAD) - KnifeY, CasterX + Distance * Cos(6 * ds * bj_DEGTORAD) - KnifeX)
    call SetUnitPosition(Knife, KnifeX + 10 * Cos(a * bj_DEGTORAD), KnifeY + 10 * Sin(a * bj_DEGTORAD))
    
    call BJDebugMsg("Angle: " + R2S(a) + ". NewX " + R2S(KnifeX + 10 * Cos(a * bj_DEGTORAD)) + ". NewY " + R2S(KnifeY + 10 * Sin(a * bj_DEGTORAD)) + ". Ds " + R2S(ds))
    
    if ds == 60 then
        set ds = 0
    else
        set ds = ds + 1
    endif
    
    call SaveInteger(H, tid, 'Arnd', ds)
    
    set Knife = null
endfunction

function BladeDanceMoveAround1 takes nothing returns nothing
    call ForGroup(KnifeGroup, function BladeDanceMoveAround2)
endfunction

function Trig_BladeDance_Actions takes nothing returns nothing
    local integer ingex = 0
    local unit KnifeU
    local player Owner = GetOwningPlayer(Kolamana)
    local integer lvl = 3 + 2 * GetUnitAbilityLevel(Kolamana, BladeDance)
    local real X = GetUnitX(Kolamana)
    local real Y = GetUnitY(Kolamana)
    local real NewX
    local real NewY
    local real angle = 0.00
    local real Distance = 200.00
    local timer Timer = CreateTimer()
    
    loop
        set KnifeU = FirstOfGroup(KnifeGroup)
        exitwhen KnifeU == null
        call GroupRemoveUnit(KnifeGroup, KnifeU)
        call RemoveUnit(KnifeU)
    endloop
    
    call GroupClear(KnifeGroup)

    loop
        set angle = angle + 360.00 / lvl
        set NewX = X + Distance * Cos(angle  * bj_DEGTORAD)
        set NewY = Y + Distance * Sin(angle  * bj_DEGTORAD)
        
        set KnifeU = CreateUnit(Owner, KnifeMoveId, NewX, NewY, angle)
        call GroupAddUnit(KnifeGroup, KnifeU)
        
        set ingex = ingex + 1
        exitwhen ingex == lvl
    endloop
    
    call TimerStart(Timer, 0.04, true, function BladeDanceMoveAround1)
    
    call SaveReal(H, GetHandleId(KnifeGroup), 'Dist', Distance)
    call SaveTimerHandle(H, GetHandleId(KnifeGroup), 'BDMA', Timer)
    
    set KnifeU = null
    set Owner = null
    set Timer = null
endfunction

function BladeDance_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == BladeDance
endfunction

//===========================================================================
function InitTrig_BladeDance takes nothing returns nothing
    local integer index
    local trigger T1 = CreateTrigger()
    
    set index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(T1, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddCondition(T1,function BladeDance_Conditions)
    call TriggerAddAction(T1, function Trig_BladeDance_Actions)
    
    set T1 = null
endfunction

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

вот немного переделанная но вышло норм
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
19
3 года назад
0
Похожие вопросы:

ответ
Ну вообще, такое делается с помощью алгоритма Грэхема по построению выпуклой оболочки.
ответ
проверил, все работает, всем спасибо)
в коде будет примерно такой вид:
function getTrajectoryRadius takes real speed, real rotationSpeed returns real
	local real  N = 360 / rotationSpeed		// количество сторон вписанного многоугольника
		return speed / (2 * (Sin (PI / N)))
endfunction
ответ
Я пробовал каналом с заданным приказом patrol. Когда отдаем приказ patrol, то получается что юнит не патрулирует, а бежит кастовать в точку, игноря всех. Я забил на этот способ. Потом пришла новая идея, а вдруг можно абузить этим способом. Представьте, сначала бежит патрулировать в одну точку, а когда дойдет, он же побежит обратно - получит другой приказ, и тут канал срабатывает, и мы узнаем завершение. Короче, не работает. Канал тоже не видит приказы patrol, только в начале
SomeFire, ну это понятно. Но мне хочется свою систему патрулирования иметь. Но чекать поиском весь маршрут на наличие противников и прочее, не хочется. Проще отловить начальные приказы patrol, далее ловим завершение приказа, и в завершении готовый patrol отдать в точку, дошел - отдаем новый patrol в точку. дело - отследить.
пока самый оптимальный вариант - это таймером чекать изменилось ли положение маршрута, там нужно интервал таймера сделать больше. И пока работает хорошо, но насколько хорошо - неизвестно. Но я еще забываю, что юниты могут драться, и в патруле могут остановиться и подраться. Ну придется заигнорить патрулирование.
patrol => заменить на attack - тут визуальные эффекты портят все. рамку как найти. можно кое-что сделать))

0
14
3 года назад
0
пиши в лс помогу
0
27
3 года назад
Отредактирован rsfghd
0
какой-то знакомый код, неужели Анашина?

Гуванч, почему ты не хочешь помочь человеку тут? все смогут увидеть решение проблемы
0
14
3 года назад
Отредактирован Гуванч
0
if SquareRoot(a2 * a2 + a1 * a1) >= Distance + 50 then
        call SetUnitPosition(Knife, KnifeX + 10 * Cos(a * bj_DEGTORAD), KnifeY + 10 * Sin(a * bj_DEGTORAD))
    else
        call SetUnitPosition(Knife, KnifeX + 10 * Cos(a * bj_DEGTORAD), KnifeY + 10 * Sin(a * bj_DEGTORAD))
    endif
я не понял зачем этот блок
почему в обих случаях притягивает или отдоляет
и скидывай карту пример что бы помогли одним кодом не всегда можно обойтись
0
27
3 года назад
Отредактирован rsfghd
0
в карте для конкурса Crusader есть светляк ночью, вот его код движения
function Wisp_Actions takes nothing returns nothing
    local real x1 = GetUnitX( Wisp )
    local real y1 = GetUnitY( Wisp )
    local real x  = GetUnitX( MainUnit ) + Distance * Cos( CircleA )
    local real y  = GetUnitY( MainUnit ) + Distance * Sin( CircleA )
    local real a  = Atan2( y - y1, x - x1 )
    local real d  = SquareRoot( ( x1 - x ) * ( x1 - x ) + ( y1 - y ) * ( y1 - y ) ) * 0.01
    
    set CircleA = CircleA + 1 * bj_DEGTORAD

    call SetUnitX( Wisp, x1 + d * Cos( a ) )
    call SetUnitY( Wisp, y1 + d * Sin( a ) )
    if WispExplodeB then
        call SetUnitFlyHeight( Wisp, GetUnitFlyHeight( MainUnit ) + 90, 0 )
    endif
endfunction
ничего сложного, MainUnit вокруг которого движется висп, CircleA, угол для движения в точку вокруг юнита, Distance - расстояние движения от юнита, чтобы постепенно оно влетало в юнита можно просто уменьшать эту дистанцию, но у меня оно было фиксированным

хотя код и механика одинакова
код не одинаков же
2
12
3 года назад
Отредактирован Стас Орлов
2
rsfghd, Да), удивлён, что кто-то вспомнил

rsfghd, не помогло, они всё равно движутся к герою, а не вокруг него

Я прикрепил карту и вернул всё к тому, как изначально написал
0
14
3 года назад
0
вот сделал теперь крутятся в дистанции 200 без приближения
Загруженные файлы
0
27
3 года назад
0
Гуванч, чёт кривовато вышло

ну.. наверное так надо, хз

впрочем, если автору нужно было такое простое движение, как скинули выше, то даже на ютубе уже делали подобные вещи, в виде подробного гайда и даже на гуи

у Анашина движение совсем по другому реализовано, покрасивее но механически похоже не подошло автору
Загруженные файлы
0
14
3 года назад
0
вот немного переделанная но вышло норм
Загруженные файлы
Принятый ответ
0
12
3 года назад
0
Нашёл причину, ломает триггер таймер и группа
0
14
3 года назад
0
Стас Орлов:
Нашёл причину, ломает триггер таймер и группа
нет ты изначально создаешь в радиусе 200 ед. а потом добавляя 10 ед. двигаешь к герою вот и все причина того что лезвии идут к герою
Чтобы оставить комментарий, пожалуйста, войдите на сайт.