XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
оптимизация
Прочитал статью сергея про полярные координаты, и возник такой вопрос. Будет ли данный триггер засорять память?

Код:
MotherLink
    Events
        Time - Every 0.50 seconds of game time
    Conditions
        (Number of units in (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to Ancient Protector))) Greater than 0
    Actions
        Unit Group - Pick every unit in (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to Ancient Protector)) and do (Actions)
            Loop - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Number of units in (Units within 10000.00 of (Position of (Picked unit)) matching ((Unit-type of (Matching unit)) Equal to Ancient Protector))) Greater then 0
                    Then - Actions
                        Unit - Set level of Mother Link for (Picked unit) to 10
                    Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Number of units in (Units within 9000.00 of (Position of (Picked unit)) matching ((Unit-type of (Matching unit)) Equal to Ancient Protector))) Greater then 0
                    Then - Actions
                        Unit - Set level of Mother Link for (Picked unit) to 9
                    Else - Actions


Конкретно меня интересует действие

(Number of units in (Units within 10000.00 of (Position of (Picked unit)) matching ((Unit-type of (Matching unit)) Equal to Ancient Protector))) Greater then 0

Если да - то как от этого вылечить?
Старый 14.01.2006, 22:55
Медведь
ФффыррфррфффФФфф!
offline
Опыт: 21,702
Активность:
Цитата:
Конкретно меня интересует действие

(Number of units in (Units within 10000.00 of (Position of (Picked unit)) matching ((Unit-type of (Matching unit)) Equal to Ancient Protector))) Greater then 0

Если да - то как от этого вылечить?


Да, будет. А как лечить было в статье сергея про оптимизацию :D
Пишем перед этим условием: Set bj_wantDestroyGroup = true
Старый 14.01.2006, 23:22
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
Про способ сергея читал, но как его применить в данном случае - ума не приложу =\
bj_wantDestroyGroup прописал при старте карты
Кстати, нашел такой баг. Как вы поняли, триггер должен понижать\повышать уровень заклинание (аура барабанов )при удалении\приблиижении юнита к другому. При повышении уровня все идет нормально, а при понижении, эффект ауры на какое-то время пропадает. Может кто знает, почему и можно ли это исправить?
Старый 14.01.2006, 23:49
Медведь
ФффыррфррфффФФфф!
offline
Опыт: 21,702
Активность:
Нее, насчёт этого не знаю.. надо у "отцов" спросить.
Старый 15.01.2006, 00:02
zibada

offline
Опыт: отключен
Pick every.... - это вообще зло, тем более в таких количествах.
для действенной оптимизации (можно от всех "Pick every" вообще избавиться =)) там надо на джассе все переписывать...
идея такая - где-то храним список всех юнитов нужного типа на карте, раз в 0.5 секунды для каждого юнита из этого списка проверяем, сколько юнитов из этого же списка находятся на нужном расстоянии, в зависимости от этого что-то делаем.
список юнитов обновляем при событиях типа "юнит создан"/"юнит помер", ну и инициализируем один раз - при запуске карты (один Pick every... все-таки тут понадобится)
наверное, это можно даже на обычных триггерах сделать..
Старый 15.01.2006, 01:59
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
ок, а с точками что делать?
Старый 15.01.2006, 12:57
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Units within 10000.00 of (Position of (Picked unit)) - создаст сорный объект типа группа
Position of (Picked unit) - создаст сорный объект типа точка
Как лечится:
на GUI пишешь
set p = Position of (Picked unit)
set gr = Units within 10000.00 of <p>
Pick every unit in gr...
...
Когда группа и точка станут ненужными
CustomScript: call DestroyGroup(udg_gr)
CustomScript: call RemoveLocation(udg_p)
Старый 15.01.2006, 13:34
zibada

offline
Опыт: отключен
если делать не через группы, а как я предложил, точки вообще нафиг не нужны, т.к. можно считать расстояние по формуле:
SquareRoot((GetUnitX(u1) - GetUnitX(u2))*(GetUnitX(u1) - GetUnitX(u2)) + (GetUnitY(u1) - GetUnitY(u2))*(GetUnitY(u1) - GetUnitY(u2))
чистая арифметика, никаких левых объектов не создается.
Старый 15.01.2006, 13:58
NETRAT

offline
Опыт: 83,712
Активность:
Гм, вопросы по теме
  1. Любые функции, которые возвращают в качестве результата тип Location по сути создают регион, который кушает память - верно?
  2. Аналогично и для ret type Group - создается группа(причем глобальная) и пока не удалим, память будет кушать - верно?
  3. При этом ret type Point таким образом память не кушает - верно?
Старый 15.01.2006, 15:02
Toadcop

offline
Опыт: 54,313
Активность:
DimonT группы лутче чем аррай !
Старый 15.01.2006, 15:21
exploder
iOS zealot
offline
Опыт: 19,394
Активность:
Функции объявленные как native, и возврашающие handle, тоже жрут память? Или это зло только чисто jass функций?
Цитата:
1. Любые функции, которые возвращают в качестве результата тип Location по сути создают регион, который кушает память - верно?

Причем тут регион, если существует тип location?
Старый 15.01.2006, 15:32
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
Господи, как я близзов за всю эту фигню ненавижу =\
Старый 15.01.2006, 15:49
NETRAT

offline
Опыт: 83,712
Активность:
exploder я не имел ввиду ничего конкретного, создает точку, не в этом суть

NETRAT добавил:
тип Location - два Real'a, тип Region - четыре Real'a
Старый 15.01.2006, 16:00
exploder
iOS zealot
offline
Опыт: 19,394
Активность:
NETRAT
А понял что ты имел в виду...

Как насчет native функций?
Старый 15.01.2006, 16:06
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
DimonT ты точно формулу правильно написал? что-ты числа больно астрономические получаются
Старый 15.01.2006, 17:13
NETRAT

offline
Опыт: 83,712
Активность:
Точно - Sqrt((X1-X2)^2+(Y1-Y2)^2)
Старый 15.01.2006, 17:27
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
да, правильно. я в другом месте ступил

Mefist добавил:
вот что получилось, в млем случае вышло еще проще - у меня на карте может быть максимум 32 юнита обоих типов и 10 уровней абилки. надо еще что-то делать? (кроме переписывания условий)
Код:
function Trig_MotherLink_Copy_Copy_Func002001001002 takes nothing returns boolean
    return ( GetUnitTypeId(GetFilterUnit()) == 'hgry' )
endfunction

function Trig_MotherLink_Copy_Copy_Conditions takes nothing returns boolean
    if ( not ( CountUnitsInGroup(GetUnitsInRectMatching(GetPlayableMapRect(), Condition(function Trig_MotherLink_Copy_Copy_Func002001001002))) > 0 ) ) then
        return false
    endif
    return true
endfunction

function Trig_MotherLink_Copy_Copy_Actions takes nothing returns nothing
    local unit u1
    local unit u2
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 32
    loop
        set u1 = udg_NatureTowers[GetForLoopIndexA()]
        set u2 = udg_AncientProtectors[GetForLoopIndexA()]
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set bj_forLoopBIndex = 1
        set bj_forLoopBIndexEnd = 10
        loop
            exitwhen bj_forLoopBIndex > bj_forLoopBIndexEnd
            if (SquareRoot((GetUnitX(u1) - GetUnitX(u2))*(GetUnitX(u1) - GetUnitX(u2)) + (GetUnitY(u1) - GetUnitY(u2))*(GetUnitY(u1) - GetUnitY(u2))) <= 11000 - GetForLoopIndexB()*1000) then
              call SetUnitAbilityLevelSwapped( 'Aakb', udg_AncientProtectors[GetForLoopIndexA()], 11 - GetForLoopIndexB() )
            endif
            set bj_forLoopBIndex = bj_forLoopBIndex + 1
        endloop
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction

//===========================================================================
function InitTrig_MotherLink takes nothing returns nothing
    set gg_trg_MotherLink = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_MotherLink, 0.05 )
    call TriggerAddCondition( gg_trg_MotherLink, Condition( function Trig_MotherLink_Copy_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_MotherLink, function Trig_MotherLink_Copy_Copy_Actions )
endfunction
Старый 15.01.2006, 18:09
zibada

offline
Опыт: отключен
Цитата:
тип Location - два Real'a, тип Region - четыре Real'a

фиг там, это полновесные игровые объекты, которые надо создавать/удалять, которые кушают отдельный хэндл и т п..

имхо, в мало-мальски продвинутых скриптах лучше такие левые типы юзать по минимуму, а хранить пары чисел в явном виде.

например, чтобы в периодическом цикле перемещать точку равномерно, что проще:
set x = x + dx
set y = y + dy
или извращения типа MoveLocation(loc, GetLocationX(loc) + dx, GetLocationY(loc) + dy)?

но это уже малость оффтоп..
Старый 15.01.2006, 18:34
Sergey
Старейший
offline
Опыт: 44,363
Активность:
2NETRAT, location - в jass это точка, а не регион. В осальном - все верно. Когда вы вместо конкретной точке или группы указываете ФУНКЦИЮ (такую как "позиция такого-то юнита") всегда происходит создание объекта. И поскольку никакая переменная на него не ссылается, его невозможно удалить из памяти.
Что касается методов работы с группами... Кажется я когда-то тестировал, влияет ли какой-то способ на быстродействие - и особой разницы не было. Во всяком случае это точно несущественно для триггеров, если только они не на малых периодах. Поэтому и заморачиваться особо не надо. Если есть возможность все упростить и свести к GUI - так и надо сделать.
Хотя Димон прав - в jass есть команда для заполнения группы вообще без участия точки - при помощи координат.
Старый 15.01.2006, 21:47
NETRAT

offline
Опыт: 83,712
Активность:
DimonT глянь три вопроса которые я задавал - все ли верно. Мда, мне не очень понятно зачем структуру переделывать в обьект...

NETRAT добавил:
Sergey да, я поправился, не в этом дело - разница незначительная

весьма фигово что в варкрафте такие заморочки с глобальными обьектами, по видимому это было сделано для более удобной работы с триггерами, однако, в основном это как-то не по-людски
Старый 15.01.2006, 21:58
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 20:04.