Утечки
Обнулял всё, что только в голову взбрело, даже то, что не нужно, и всё равно они есть.. Как же оно задолбало. Может что-то пропустил, не обнулил, не удалил, я хз.
Научите нуба, пожалуйста, избавляться от этой саранчи. Практически среди всех способностей похожего типа присутствуют эти 1-3 утечки, которые растут при быстром касте абилок
Прикладываю карту

Лучший ответ:
quq_CCCP скинул карту с нормальным кодом.
Спасибо большое)
» Код:
globals
    hashtable H = InitHashtable()
    real x
    real y
    group g = CreateGroup()
    real MaxX
    real MinX
    real MaxY
    real MinY
    unit bj_lastFilterUnit = null
endglobals

function GetCorX takes real x returns real
    if ( x < MinX ) then
        return MinX
    endif
    if ( x > MaxX ) then
        return MaxY
    endif
    return x
endfunction

function GetCorY takes real y returns real
    if ( y < MinY ) then
        return MinY
    endif
    if ( y > MaxY ) then
        return MaxY
    endif
    return y
endfunction

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

function Enemy_Filter takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit( )
    return IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and GetWidgetLife(bj_lastFilterUnit) > 0.405 and not IsUnitType( bj_lastFilterUnit, UNIT_TYPE_STRUCTURE ) 
endfunction

function Group_Damage_Enemy_Enum takes nothing returns nothing
    local unit enemy = GetEnumUnit()
    call UnitDamageTarget( bj_lastReplacedUnit, enemy, 100.00,  true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS )
    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl", enemy, "chest" ) )
    set enemy = null
endfunction

function Timer_Dummy_Move_Expires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit cast = LoadUnitHandle( H, id, 0 )
    local unit dummy = LoadUnitHandle( H, id, 1 )
    local real facing = LoadReal( H, id, 2 )
    local real dist = LoadReal( H, id, 3 ) + 32.00

    set x = GetCorX( GetUnitX(dummy) + 32.00 * Cos( facing ) )
    set y = GetCorY( GetUnitY(dummy) + 32.00 * Sin( facing ) )
    call SetUnitX( dummy, x )
    call SetUnitY( dummy, y )
    call GroupClear( g )
    set bj_groupEnumOwningPlayer = GetOwningPlayer( cast )
    call GroupEnumUnitsInRange( g, x, y, 125.00, Condition( function Enemy_Filter ) )  
    if dist < 1500.00 and FirstOfGroup( g ) == null then
        call SaveReal( H, id, 3, dist )
    else
        call GroupClear( g )
        set bj_groupEnumOwningPlayer = GetOwningPlayer( cast )
        call GroupEnumUnitsInRange( g, x, y, 225.00, Condition( function Enemy_Filter ) ) 
        set bj_lastReplacedUnit = cast
        call ForGroup( g, function Group_Damage_Enemy_Enum )
        call FlushChildHashtable( H, id )
        call PauseTimer(t)
        call DestroyTimer(t)
        call KillUnit(dummy)
    endif

    set t = null
    set cast = null
    set dummy = null
endfunction

function Trig_Frost_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local unit cast = GetSpellAbilityUnit()
    local real dx = GetUnitX(cast)
    local real dy = GetUnitY(cast)
    local real facing = Atan2(GetSpellTargetY() - dy, GetSpellTargetX() - dx)
    local unit dummy = CreateUnit( GetOwningPlayer(cast), 'u000', GetCorX( dx + 64.00 * Cos(facing) ), GetCorY( dy + 64.00 * Sin(facing) ), facing * bj_DEGTORAD )
    
    call SetUnitPathing( dummy, false )
    call UnitApplyTimedLife( dummy, 'BTLF', 0.00 )
    
    call SaveUnitHandle( H, id, 0, cast )
    call SaveUnitHandle( H, id, 1, dummy )
    call SaveReal( H, id, 2, facing )
    call SaveReal( H, id, 3, 0.00 )
    call TimerStart( t, 0.03125, true, function Timer_Dummy_Move_Expires )
    
    set cast = null
    set dummy = null
    set t = null
endfunction

//===========================================================================
function InitTrig_Frost takes nothing returns nothing
    set gg_trg_Frost = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Frost, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Frost, Condition( function Trig_Frost_Conditions ) )
    call TriggerAddAction( gg_trg_Frost, function Trig_Frost_Actions )
endfunction


Views: 167

» Лучшие комментарии


XGM Bot #1 - 1 month ago 0
Голосов: +0 / -0
Похожие вопросы:

» ответ
Какой ужас
Делай вот так.
» бронепоезд
создать.
направить на 128 точек наверх(90)
сделать неперманентным
текст удалится через 3 секунды
текст затухнет до 100% прозрачности через 3 секунды
Вот чёрт. не успел приплюснуть к посту.
» ответ
Есть системы, для автоматического удаления локейшенов и групп прям на гуи в 126. Так же можно подгрузить автоочистуюку на луа, для последнего патча.
Пример автоочистки на гуи есть вот тут
Не скажу где, делал мега давно, но точно где то вначале
» ответ
AllChosen, строки
TrigSpell = 0
TrigPlayer = null

EnumPlayer = null
EnumUnitType = 0
Строка
EnumUnit = null
тоже лишняя, так как условием выхода из цикла loop является
exitwhen EnumUnit == null
Старайтесь использовать координаты вместо локаций:
GetSpellTargetLoc() -> GetSpellTargetX(), GetSpellTargetY()
GroupEnumUnitsInRangeOfLoc() -> GroupEnumUnitsInRange()
CreateUnitAtLoc() -> CreateUnit()
» ответ
думаю из за loop где то цикл не может закончиться...
после этого скилла герой не возрождается

ой я нуб блин гуй триггерщик который писал этот спелл поставил этому скиллу скорость снаряда 0 конечно будет лагать все вопрос закрыт))

Vlod #2 - 1 month ago 0
Голосов: +0 / -0
Утечки происходят если снаряды улетают за пределы карты. Если попадают по целям, то все норм
quq_CCCP #3 - 1 month ago (изм. ) 0
Голосов: +0 / -0
Че это за ахинея?
    local trigger t = CreateTrigger()
    local integer index = 0
    local playerunitevent e = null
    local code c = function Frost_Conditions
    local player p = null
    local boolexpr b = null
    
    loop
    set p = Player(index)
    set e = EVENT_PLAYER_UNIT_SPELL_EFFECT
    call TriggerRegisterPlayerUnitEvent(t,p,e,b)
    set index = index + 1
    exitwhen index == bj_MAX_PLAYER_SLOTS
    set e = null
    set p = null
    endloop
    
    set b = Condition(c)
    call TriggerAddCondition(t,b)
    set c = null
    set c = function Frost_Actions
    call TriggerAddAction(t,c)
    
    set b = null
    set c = null
    set t = null
Ну сами и наплодили непойми чего.

Потом волну силы то не пробовали а?
Тут спелл примитив примитивом, но сделан отвратно, зачем то SteUnitPos - вместо нормального движения по осям, как таймер бредовый 0.01, ну ладно уж 0.02, или 0.03125.
Куда 0.01? Нет никакой обьективной нужды в таких таймерах, как и в прочих вещях вроде SetIUnitPosition.

Vlod, они там улететь немогут, т.к SetUnitPos не выпустит.

Но тут почему то нормально не пострена дальность полета, тупая проверка группой что кто то попалася, а если никто - то оно и дальше тикает....

Полная ахинея, уж блин триггер бы взяли и событие UnitsInRange и вручали его всем даммиками, а триггер был бы 1, если уж дофига оптимизацию охото.
1 point от : 1.1 (ненормативная лексика)
Vlod #4 - 1 month ago 1
Голосов: +1 / -0
quq_CCCP, да ладно, он элементарно написал свою систему создания триггера
rsfghd, добавь ограничение по дальности, а то сейчас дамми умирают только если попадают по врагу
rsfghd #5 - 1 month ago (изм. ) 0
Голосов: +0 / -0
Та не в дальности дело, господи. Я на дальность плевать хотел, главное что при попадании все равно есть утечки (быстро кастуем спелл)
Насчёт таймера в 0.01, та бл, там изначально было 0.03, мне пофигу на таймер, если оно в любом случае криво работает

quq_CCCP, чем ужасен SetUnitPosition? Оно просто совместимо в себе 2 команды SetUnitX и SetUnitY, разве нет?
они там улететь немогут, т.к SetUnitPos не выпустит.
За карту юниты спокойно улетают (ну или за пределы камеры, хз)

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

Было 230, стало 233

Тут спелл примитив примитивом, но сделан отвратно, зачем то SteUnitPos - вместо нормального движения по осям, как таймер бредовый 0.01, ну ладно уж 0.02, или 0.03125. Куда 0.01? Нет никакой обьективной нужды в таких таймерах, как и в прочих вещях вроде SetIUnitPosition.
Ну окей, поставил таймер 0.03 обратно, движение по осям. А толку? Всё так же, как и было до этого, вообще ничего не изменилось.
Полная ахинея, уж блин триггер бы взяли и событие UnitsInRange и вручали его всем даммиками, а триггер был бы 1, если уж дофига оптимизацию охото.
Мне охота не оптимизация, а избавление от утечек
Прикрепленные файлы
quq_CCCP #6 - 1 month ago 0
Голосов: +0 / -0
rsfghd,
1)SetUnitPosition - значительно более ресурсоемка чем движение по осям, для проверки границ карты проверяйете кординаты на корректность, это элементарно.
  1. Нет никакой надобности юзать таймеры с таким малым периодом, типа 100 раз в сек, 50 или 23 более чем достаточно.
  2. Ты скорее наделал утечики с переменными чем сделал лучше, подобный код бесполезен, уж лучше обынчый БЖ код юзай.

Далее неверный алгоритм, нет иного завершения кроме как попадания. Если у тебя планируется тонны снарядом - то мб не делать как ты для каждого снаряда 1 таймер, еще и переборы группой ?
ScorpioT1000 #7 - 1 month ago (изм. ) 0
Голосов: +0 / -0
Нет никакой обьективной нужды в таких таймерах
240гц передает тебе привет)
хотя в классике действительно нет смысла , хотя интерес к классике остался у полутора землекопов
quq_CCCP #8 - 1 month ago 0
Голосов: +0 / -0
ScorpioT1000, причем тут 240 герц монитор и прочее? Вот причем?
rsfghd #9 - 1 month ago (изм. ) 0
Голосов: +0 / -0
Так, спокойно, дыши ровно.. Когда-нибудь мне да помогут с этими утечками
Вот карта с вашим ограничением полёта, господи
Вот карта без моей "ахинеи" и ограничением полёта, раз уж оно так раздражает
Почему нельзя было просто сказать как сделать так, чтобы число хэндлов возвращалось на своё изначальное место? Ладно придрались к коду, что-то там плохо, что-то тут не так, но изменение этого не решает проблему
Камон, мне просто нужна помощь, пожалуйста
Прикрепленные файлы
NazarPunk #10 - 1 month ago 0
Голосов: +0 / -0
Вот карта с вашим ограничением полёта, господи
Вот карта со снарядом без утечек.
Камон, мне просто нужна помощь, пожалуйста
Не у всех варкрафт установлен, а без него код не глянуть.
rsfghd #11 - 1 month ago (изм. ) -1
Голосов: +0 / -1
NazarPunk, я не знаю cJass и vJass, я этим даже воспользоваться не смогу

За отсутствие кода извиняюсь
» Код
globals
    hashtable H = InitHashtable()
    real x
    real y
    group g = CreateGroup()
endglobals

function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = LoadUnitHandle(H,GetHandleId(t),1)
    local unit u1 = null
    local effect e = null
    local string s = null
    local real a = GetUnitFacing(u)
    local real x1 = LoadReal(H,GetHandleId(t),2)
    local real y1 = LoadReal(H,GetHandleId(t),3)
    local real dx
    local real dy
    
    call SetUnitX(u,GetUnitX(u)+15*Cos(a*bj_DEGTORAD))
    call SetUnitY(u,GetUnitY(u)+15*Sin(a*bj_DEGTORAD))
    set x = GetUnitX(u)
    set y = GetUnitY(u)
    set dx = x1-x
    set dy = y1-y
    
    if SquareRoot(dx*dx+dy*dy) >= 900 then
        call GroupEnumUnitsInRange(g,x,y,300,null)
        
        loop
            set u1 = FirstOfGroup(g)
            exitwhen u1 == null
            if IsUnitType(u1,UNIT_TYPE_DEAD) != true and IsUnitEnemy(u1,GetOwningPlayer(u)) == true then
                call UnitDamageTarget(u,u1,10,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
            endif
            call GroupRemoveUnit(g,u1)
            set u1 = null
        endloop
        
        set s = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
        set e = AddSpecialEffect(s,x,y)
        call DestroyEffect(e)
        set e = null
        set s = null
        
        call KillUnit(u)
        call PauseTimer(t)
        call FlushChildHashtable(H,GetHandleId(t))
        call DestroyTimer(t)
    else
        call GroupEnumUnitsInRange(g,x,y,100,null)
        loop
            set u1 = FirstOfGroup(g)
            exitwhen u1 == null
            if IsUnitType(u1,UNIT_TYPE_DEAD) != true and IsUnitEnemy(u1,GetOwningPlayer(u)) == true then
                call GroupClear(g)
                call GroupEnumUnitsInRange(g,x,y,300,null)
                
                loop
                    set u1 = FirstOfGroup(g)
                    exitwhen u1 == null
                    if IsUnitType(u1,UNIT_TYPE_DEAD) != true and IsUnitEnemy(u1,GetOwningPlayer(u)) == true then
                        call UnitDamageTarget(u,u1,10,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
                    endif
                    call GroupRemoveUnit(g,u1)
                    set u1 = null
                endloop
                
                set s = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
                set e = AddSpecialEffect(s,x,y)
                call DestroyEffect(e)
                set e = null
                set s = null
                
                call KillUnit(u)
                call PauseTimer(t)
                call FlushChildHashtable(H,GetHandleId(t))
                call DestroyTimer(t)
            endif
            call GroupRemoveUnit(g,u1)
            set u1 = null
        endloop
    endif
    
    call GroupClear(g)
    set t = null
    set u = null
endfunction

function Frost_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local code c = function move
    local unit u1 = GetSpellAbilityUnit()
    local real x1 = GetUnitX(u1)
    local real y1 = GetUnitY(u1)
    local unit u = CreateUnit(GetOwningPlayer(u1),'u000',x1,y1,bj_RADTODEG*Atan2(GetSpellTargetY()-y1,GetSpellTargetX()​-x1))
    
    call SaveUnitHandle(H,GetHandleId(t),1,u)
    call SaveReal(H,GetHandleId(t),2,x1)
    call SaveReal(H,GetHandleId(t),3,y1)
    call TimerStart(t,.03,true,c)
    
    set c = null
    set t = null
    set u1 = null
    set u = null
endfunction

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

function InitTrig_Frost takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index = 0
    local playerunitevent e = null
    local code c = function Frost_Conditions
    local player p = null
    local boolexpr b = null
    
    loop
    set p = Player(index)
    set e = EVENT_PLAYER_UNIT_SPELL_EFFECT
    call TriggerRegisterPlayerUnitEvent(t,p,e,b)
    set index = index + 1
    exitwhen index == bj_MAX_PLAYER_SLOTS
    set e = null
    set p = null
    endloop
    
    set b = Condition(c)
    call TriggerAddCondition(t,b)
    set c = null
    set c = function Frost_Actions
    call TriggerAddAction(t,c)
    
    set b = null
    set c = null
    set t = null
endfunction 
ScorpioT1000 #12 - 1 month ago 0
Голосов: +0 / -0
quq_CCCP, даже при 120 фпс период движения 0.01 уже будет заметен
Zetox #13 - 1 month ago 0
Голосов: +0 / -0
0,0069 для моего монитора оптимально. Но это отступление.
Почему call KillUnit(u) а не RemoveUnit() ?
Запустил твою карту, поставил условие выхода снаряда за пределы карты и remove unit, лагов не было, запускал по 200 снарядов.
Или ты судил по GetHandleId ? Так она не покажет количество хендлов в карте, у тебя хендл с более большим значением может освободиться позже.
rsfghd #14 - 1 month ago 0
Голосов: +0 / -0
Zetox, убийство юнита из-за его красивой анимации. Если ремувнуть его, то не будет взрыва и след от юнита внезапно исчезнет, это не красиво. В любом случае юнит после разложения удаляется. Да, я судил по кол-ву хэндлов. Выше кидали норм карту. Там хэндлы возвращаются на своё изначальное место, сколько бы ты не юзал эту абилку. Но там слишком много новых для меня функций принцип действия которых я не понимаю от слова совсем. Да и структура не очень комфортная для меня, это же c/vJass, что-то могу понять, но не всё
DracoL1ch #16 - 1 month ago 3
Голосов: +3 / -0
о, люди с частотой глаза 360 герц в треде
Zetox #17 - 1 month ago 0
Голосов: +0 / -0
Там хэндлы возвращаются на своё изначальное место
Ну он возвращает так сказать id последнего созданного хендла, имей ввиду, что у тебя могут быть пропуски, к примеру возвращает 0x100300, а с 0x100150 по 0x100200 может и не быть объектов с такими хендлами. Если создавать больше объектов, он будет забирать из стека свободные номера.

DracoL1ch:
о, люди с частотой глаза 360 герц в треде
В глазу, в отличие от камер, нет никого таймера обновления кадров. Разница между 144 гц и 60 существенная, между 144 и 360 я не знаю, но думаю что она тоже есть.
quq_CCCP #18 - 1 month ago 0
Голосов: +0 / -0
Zetox, в варкарвте лок 60 фпс, который надо еще и снимать, а обновление анимации там и того реже бывает, так что не обманывайте себя что там вы чето лучше сделали, или плавнее - нет.

rsfghd, внезапно юниту можно время жизни поставить и он разложится как суммон, сразу после времени смерти.
Zetox #19 - 1 month ago (изм. ) 1
Голосов: +1 / -0
Какой лок в 60 ? написано 298 фпс. (правда монитор 144гц)
Двигать можно и более мелким таймером, а обрабатывать встречу с юнитом с более большим интервалом.
Прикрепленные файлы
Proshel_Doty #20 - 1 month ago (изм. ) 0
Голосов: +0 / -0
quq_CCCP, и чё такого в таймере 0.01? Почему бы не заюзать его для движения снаряда, который будет лететь от силы сек 3, что в этом такого
Или ты волнуешься за чьи-то калькуляторы? Пусть за них волнуются их обладатели

NazarPunk, я не знаю cJass и vJass, я этим даже воспользоваться не смогу
в той наработке вроде Zinc, если я не путаю с какой-то другой )
quq_CCCP #21 - 1 month ago 0
Голосов: +0 / -0
Proshel_Doty, нет никакой надобности в подобном, о чем я пытаюсь донести - но кто бы слушал. Да и вовсе рализация не лучшая.
Proshel_Doty #22 - 1 month ago 0
Голосов: +0 / -0
Было 230, стало 233
Правильно, потому что объекты всё ещё присутствуют в игре, хоть их не видно

quq_CCCP, ещё как есть. Попробуй прицепить текст за курсором на 0.02 сек или хп бар у юнита на 0.02 сек, и посмотришь как он будет подёргиваться
ScorpioT1000 #23 - 1 month ago 0
Голосов: +1 / -1
quq_CCCP, Тем не менее предлагаешь обновлять 32 раза в секунду)
беды с олдовостью
quq_CCCP #24 - 1 month ago 0
Голосов: +0 / -0
ScorpioT1000,на 300 мс делать 100 раз все, ок, понятно все с вами.
DracoL1ch #26 - 1 month ago (изм. ) 3
Голосов: +3 / -0
Разницу между 60 и 144 видно, между 144 и 240 - нет, ни один участник исследований не смог определить где какой, с достоверной точностью.
Проблема таймеров 0.01 в высокой нагрузке при нулевом смысле в этой самой скорости. Пару снарядов сделать так можно, но для активно используемых вещей 002 более чем хорошо, даже 0.325 терпимо для не чётких моделей
Proshel_Doty #27 - 1 month ago 0
Голосов: +0 / -0
Проблема таймеров 0.01 в высокой нагрузке при нулевом смысле в этой самой скорости. Пару снарядов сделать так можно, но для активно используемых вещей 002 более чем хорошо, даже 0.325 терпимо для не чётких моделей
верняк
ScorpioT1000 #28 - 1 month ago (изм. ) 0
Голосов: +0 / -0
32 фпс... на снарядах, карл
терпимо
действительно, остаётся только терпеть)
Proshel_Doty #29 - 1 month ago 0
Голосов: +0 / -0
ScorpioT1000, ты за 0.01? )
Zetox #30 - 1 month ago 0
Голосов: +0 / -0
Может тогда изменить подход ? пулять снаряд до юнита (который находится на краю карты), отрисовка будет будет ровна кол-во фпс, а в цикле мы просто меняем точку снаряда и делаем проверки (интервал хоть 0.05).
А автору, чтобы ускорить код, лучше не высчитывать 15*Cos(a*bj_DEGTORAD) каждый раз, если у тебя угол снаряда не меняется.

И не высчитывать каждый раз это: if SquareRoot(dx*dx+dy*dy) >= 900 then у тебя скорость постоянная.
Это сообщение удалено
ScorpioT1000 #32 - 1 month ago 0
Голосов: +0 / -0
Можно интерполировать анимацию как взрослые дяди, но всем лень
rsfghd #33 - 1 month ago (изм. ) 0
Голосов: +0 / -0
Значит всё сводится к тому, что у меня просто ужасная структуризация кода и есть некоторые недочёты? В статусе написано, что я криво структуризирую триггеры
Утечек нет или что?
Zetox #34 - 1 month ago 0
Голосов: +0 / -0
Утечек нет. У там у тебя хендлы освобождаются не в том порядке, когда был запущен снаряд, а до встречи юнитов, поэтому нумерация так себя введет. Если на 1.26 работаешь, используй vJass и векторы. Хотя до 50 одновременных снарядов, у меня практически нет просадок фпс, если на карте планируется 60 и более одновременных снарядов, то стоит оптимизировать, Если 0-20 одновременно, то даже трогать ничего не стоит.
rsfghd #35 - 1 month ago (изм. ) 0
Голосов: +0 / -0

quq_CCCP скинул карту с нормальным кодом.
Спасибо большое)
» Код:
globals
    hashtable H = InitHashtable()
    real x
    real y
    group g = CreateGroup()
    real MaxX
    real MinX
    real MaxY
    real MinY
    unit bj_lastFilterUnit = null
endglobals

function GetCorX takes real x returns real
    if ( x < MinX ) then
        return MinX
    endif
    if ( x > MaxX ) then
        return MaxY
    endif
    return x
endfunction

function GetCorY takes real y returns real
    if ( y < MinY ) then
        return MinY
    endif
    if ( y > MaxY ) then
        return MaxY
    endif
    return y
endfunction

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

function Enemy_Filter takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit( )
    return IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and GetWidgetLife(bj_lastFilterUnit) > 0.405 and not IsUnitType( bj_lastFilterUnit, UNIT_TYPE_STRUCTURE ) 
endfunction

function Group_Damage_Enemy_Enum takes nothing returns nothing
    local unit enemy = GetEnumUnit()
    call UnitDamageTarget( bj_lastReplacedUnit, enemy, 100.00,  true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS )
    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl", enemy, "chest" ) )
    set enemy = null
endfunction

function Timer_Dummy_Move_Expires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit cast = LoadUnitHandle( H, id, 0 )
    local unit dummy = LoadUnitHandle( H, id, 1 )
    local real facing = LoadReal( H, id, 2 )
    local real dist = LoadReal( H, id, 3 ) + 32.00

    set x = GetCorX( GetUnitX(dummy) + 32.00 * Cos( facing ) )
    set y = GetCorY( GetUnitY(dummy) + 32.00 * Sin( facing ) )
    call SetUnitX( dummy, x )
    call SetUnitY( dummy, y )
    call GroupClear( g )
    set bj_groupEnumOwningPlayer = GetOwningPlayer( cast )
    call GroupEnumUnitsInRange( g, x, y, 125.00, Condition( function Enemy_Filter ) )  
    if dist < 1500.00 and FirstOfGroup( g ) == null then
        call SaveReal( H, id, 3, dist )
    else
        call GroupClear( g )
        set bj_groupEnumOwningPlayer = GetOwningPlayer( cast )
        call GroupEnumUnitsInRange( g, x, y, 225.00, Condition( function Enemy_Filter ) ) 
        set bj_lastReplacedUnit = cast
        call ForGroup( g, function Group_Damage_Enemy_Enum )
        call FlushChildHashtable( H, id )
        call PauseTimer(t)
        call DestroyTimer(t)
        call KillUnit(dummy)
    endif

    set t = null
    set cast = null
    set dummy = null
endfunction

function Trig_Frost_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local unit cast = GetSpellAbilityUnit()
    local real dx = GetUnitX(cast)
    local real dy = GetUnitY(cast)
    local real facing = Atan2(GetSpellTargetY() - dy, GetSpellTargetX() - dx)
    local unit dummy = CreateUnit( GetOwningPlayer(cast), 'u000', GetCorX( dx + 64.00 * Cos(facing) ), GetCorY( dy + 64.00 * Sin(facing) ), facing * bj_DEGTORAD )
    
    call SetUnitPathing( dummy, false )
    call UnitApplyTimedLife( dummy, 'BTLF', 0.00 )
    
    call SaveUnitHandle( H, id, 0, cast )
    call SaveUnitHandle( H, id, 1, dummy )
    call SaveReal( H, id, 2, facing )
    call SaveReal( H, id, 3, 0.00 )
    call TimerStart( t, 0.03125, true, function Timer_Dummy_Move_Expires )
    
    set cast = null
    set dummy = null
    set t = null
endfunction

//===========================================================================
function InitTrig_Frost takes nothing returns nothing
    set gg_trg_Frost = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Frost, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Frost, Condition( function Trig_Frost_Conditions ) )
    call TriggerAddAction( gg_trg_Frost, function Trig_Frost_Actions )
endfunction
Прикрепленные файлы
NazarPunk #36 - 1 month ago 0
Голосов: +0 / -0
я не знаю cJass и vJass, я этим даже воспользоваться не смогу
Если не собираетешься переходить на Reforged, то ИМХО лучше разобраться с zinc, он реально удобен.
в той наработке вроде Zinc, если я не путаю с какой-то другой )
Для 1.26 у меня все наработки на zinc. Который по сути есть vJass.
Если на 1.26 работаешь, используй vJass и векторы
В чём удобство векторов на простых снарядах?
МрачныйВорон #37 - 1 month ago (изм. ) 0
Голосов: +0 / -0
NazarPunk, векторы удобны тем что код упрощают. разве не так?: просто x и y запара писать. хоть не использую структуры векторов, но на jass это дико неудобно, но терпимо. хотя многие действия с векторами непонятны к примеру деление, умножение итд не понятно где они применимы
но видел системы, где все кратко и красиво написано
NazarPunk #38 - 1 month ago 0
Голосов: +1 / -1
векторы удобны тем что код упрощают. разве не так?
Многие вещи с векторами становится делать проще, но вот для простого движения по параболе зачем они нужны?
this.l = this.l + BarrelSpeedAdd;
this.x = this.x + BarrelSpeedAdd * this.cos;
this.y = this.y + BarrelSpeedAdd * this.sin;
this.z = ParabolaZ2(this.zs, this.ze, this.h, this.d, this.l);
                
SetUnitX(this.barrel, this.x);
SetUnitY(this.barrel, this.y);
SetUnitZ(this.barrel, this.z);