Одну не знаю как удалить, а вторую не могу найти, подробности на скрине.

Alexey103, посмотрел карту которую ты скинул
отключая по строчке выяснил что утечка возникает при установке переменной playergroup
т.е. утекает группа игроков
это происходит из за не обнулённой переменной в бж функции
чтобы исправить надо не использовать эту бж функцию
желательно перейти на джасс
`
ОЖИДАНИЕ РЕКЛАМЫ...
22
код этой гуишной функции которая поворачивает юнита к точке (отключенная на скрине под коментом "тут утечка как удалить")
как видно на скрине не обнуляется локалка
как исправить - заменить на установку угла поворота равным углу между точками вместо этой функции
как всегда не редактируются вложения ну почините уже плиз
Загруженные файлы
30
Переведите всё в JASS и раскройте BJ функции, всёравно там один Custom Script.
23
Само событие утекает. Оно реагирует абсолютно на всех юнитов, которые "отдают" приказ в цель (даже если поставить условие). Для этих событий желательно устанавливать конкретного юнита, это меньшее зло.
30
Obelick:
Само событие утекает. Оно реагирует абсолютно на всех юнитов, которые "отдают" приказ в цель (даже если поставить условие). Для этих событий желательно устанавливать конкретного юнита, это меньшее зло.
Как событие может утекать то? Событие происходит и дёргает всех "слушателей" которые на него повешены. И чем больше "слушателей", тем хуже.
Мне вот интересно, когда нейтрально пассивный Order("smart") отдаёт?
12
biridius:
код этой гуишной функции которая поворачивает юнита к точке (отключенная на скрине под коментом "тут утечка как удалить")
как видно на скрине не обнуляется локалка
как исправить - заменить на установку угла поворота равным углу между точками вместо этой функции
как всегда не редактируются вложения ну почините уже плиз
Еще надо не забыть удалить оба эти Position of (unit), т.к. они тоже точки создают. На ГУИ проще всего будет сперва записать их в переменные типа Temp_Loc1, Temp_Loc2, произвести действия триггера, а затем их удалить.
17
Sergarr, Это очевидно, и не нужно создавать переменных, они у меня уже там созданы
NazarPunk, Там же нейтрально пассивный цель отданного приказа.
29
впервые такое слышу..
    private function init takes nothing returns nothing
     local trigger t=CreateTrigger()
        call TriggerAddCondition(t, Condition( function spellIdMatch) )
        call TriggerAddAction(t,    function onSpellCast)
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )

     set t=null
    endfunction
Возможно он имел ввиду триггер, который висит в памяти, после регистрации событий и условий с действиями соответственно. Код выше его обнуляет, чего в гуи нет.
17
Obelick, Ты не прав, я проверил заменив детектор расстояния между юнитами сообщением в чат, события и условия не утекают.
biridius, NazarPunk, Obelick, ScopteRectuS, Sergarr, Msey,
Путём исключения безутечных частей триггера удалось локализовать область поиска утечек до вот такого маленького участка, кто-нибудь может теперь понять что там не так, или просто написать джасс замену этого участка без утечек, хотя там и так всё на кастом скрипте. Я вообще удивляюсь, у меня такая-же проблема была в аналогичном триггере только в системе генерации мобов для карты, и там тоже никто толком не помог. Видимо гет енам юнитс нифига не безутечный, судя по хендл каунтеру. Или я не знаю как обьяснить его рост.
Загруженные файлы
30
Alexey103:
Obelick, Ты не прав, я проверил заменив детектор расстояния между юнитами сообщением в чат, события и условия не утекают.
biridius, NazarPunk, Obelick, ScopteRectuS, Sergarr, Msey,
Путём исключения безутечных частей триггера удалось локализовать область поиска утечек до вот такого маленького участка, кто-нибудь может теперь понять что там не так, или просто написать джасс замену этого участка без утечек, хотя там и так всё на кастом скрипте. Я вообще удивляюсь, у меня такая-же проблема была в аналогичном триггере только в системе генерации мобов для карты, и там тоже никто толком не помог. Видимо гет енам юнитс нифига не безутечный, судя по хендл каунтеру. Или я не знаю как обьяснить его рост.
Внесите проблемный триггер в отдельную карту и прикрепите сообщение. Сложно разбираться по картинкам.
NazarPunk, Там же нейтрально пассивный цель отданного приказа.
Что-то недоглядел.
21
Msey, эту локальную переменную можно не обнулять, она ссылается на статичный триггер, который будет висеть в памяти до конца игры. Другое дело, если бы это был динамичный триггер...
30
ScopteRectuS:
Msey, эту локальную переменную можно не обнулять, она ссылается на статичный триггер, который будет висеть в памяти до конца игры. Другое дело, если бы это был динамичный триггер...
И зачем вам лишний handle, который вы не сможете дальше использовать?
21
NazarPunk, ну так set t = null не освободит handle. Handle освободится, когда объект будет удалён и всё ссылки на него стёрты. А так как триггер статичный, он будет висеть в памяти до конца игры.
28
Alexey103, в редакторе триггеров вверху нажми правка --> конвертировать в текст
твой триггер преобразуется в джасс код
кинь этот код сюда
так же не забудь использовать форматирование код при вставке кода в комментарий
30
Вот, набросал библиотеку. Под себя заточить несложно
zinc
//! zinc
library NeutralPassiveTalk {
    /* настройки */
    constant real FontSize = 8.;
    constant real FontTime = 1.5;
    constant real Range = 500.;
    constant string Effect = "Abilities\\Spells\\Human\\InnerFire\\InnerFireTarget.mdl";
    
    //функция спецэффекта
    function Eff(player p, unit u) {
        string e = "";
        if (p == GetLocalPlayer()) {
            e = Effect;
        }
		DestroyEffect(AddSpecialEffectTarget(Effect, u, "overhead"));
    }
    
    // функция текстага
    function TextTag(player p, unit u, string s){
        texttag tt = CreateTextTag();
        SetTextTagText(tt,s,FontSize*.0023);
        SetTextTagPosUnit(tt, u, 20.);
        SetTextTagVelocity(tt, .05325 * Cos(1.570795), .05325 * Sin(1.570795));
        SetTextTagPermanent(tt, false);
        SetTextTagLifespan(tt, FontTime);
        SetTextTagFadepoint(tt, 0.);
        
        //скрываем от всех
        SetTextTagVisibility(tt, false);
        
        //показываем локальному игроку
        if (p == GetLocalPlayer()){
            SetTextTagVisibility(tt, true);
        }
        
        //утечки
        tt = null;
    }
    
    // применяем действия
    function Actions(player p, unit u1, unit u2,real angle){
        integer id = GetUnitTypeId(u2);
        string s = null;
        
        //проверяем юнитов
        if (id == 'hfoo'){
            s = "я бью";
        } else if (id == 'hsor') {
            s = "я колдую";
        } else if (id == 'hrif') {
            s = "у меня ружжо";
        } else if (id == 'earc') {
            s = "я стреляю";
        } else if (id == 'ugho') {
            KillUnit(u2);
        }
        
        // создаём текстаг, поворачиваем юнита и накидываем спецэффеты 
        if (s != null){
            // поворачиваем юнита
            SetUnitFacingTimed( u2, angle, 0. );
            
            // показываем текстаг
            TextTag(p, u2, s);
            
            // аттачим эффект
            Eff(p, u2);
            
            // шаманим с LocalPlayer
            if (p == GetLocalPlayer()){
                //говорим от юнита, возможен десинк, нужно проверить!
                SetCinematicScene(id, GetPlayerColor(GetOwningPlayer(u2)), GetUnitName(u2), s, I2R(StringLength(s)) * .3, .0);
                //мигаем индикатор, возможен десинк, нужно проверить!
                AddIndicator(u2, 255, 255, 255, 255);
            }
        }
    }
    
    // условия триггера
    function Cond() -> boolean {
        return (GetOwningPlayer(GetOrderTargetUnit()) == Player(PLAYER_NEUTRAL_PASSIVE) && GetIssuedOrderId() == 851971);
    }

    // инициализация
    function onInit(){
        trigger t = CreateTrigger();
        integer i;
        
        // вешаем событие только играющим людям
        for (0 <= i < 12) {
            if (GetPlayerController(Player(i)) == MAP_CONTROL_USER && GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) {
                TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null);
            }
        }
        
        // вешаем условие
        TriggerAddCondition( t, Condition( function Cond));
        
        // вешаем действие
        TriggerAddAction( t, function(){
            unit u1 = GetTriggerUnit(); //юнит отдавший приказ
            unit u2 = GetOrderTargetUnit(); // юнит - цель приказа
            real x1 = GetUnitX(u1);
            real y1 = GetUnitY(u1);
            real x2 = GetUnitX(u2);
            real y2 = GetUnitY(u2);
            real dx = x2 - x1;
            real dy = y2 - y1;
            real angle = bj_RADTODEG * Atan2(y1 - y2, x1 - x2);
            real distance = SquareRoot(dx * dx + dy * dy);
            player p = GetOwningPlayer(u1);
            
            // применяем действия
            if (distance <= Range) {
                Actions(p,u1,u2,angle);
            }
                        
            // утечки
            u1 = null;
            u2 = null;
        });
    }
}
//! endzinc
Загруженные файлы
17
NazarPunk, Круто вроде, но ошибку выдаёт при проверке.
function Trig_speak_system_____________________u_Func001Func001Func006C takes nothing returns boolean
    if ( not ( IsUnitInGroup(GetOrderedUnit(), udg_units) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_speak_system_____________________u_Func001Func001C takes nothing returns boolean
    return true
endfunction

function Trig_speak_system_____________________u_Func001C takes nothing returns boolean
    if ( not ( GetIssuedOrderIdBJ() == String2OrderIdBJ("smart") ) ) then
        return false
    endif
    if ( not ( GetOwningPlayer(GetOrderTargetUnit()) == Player(PLAYER_NEUTRAL_PASSIVE) ) ) then
        return false
    endif
    return true
endfunction

function Trig_speak_system_____________________u_Actions takes nothing returns nothing
    if ( Trig_speak_system_____________________u_Func001C() ) then
        if ( Trig_speak_system_____________________u_Func001Func001C() ) then
            set udg_playergroup = GetPlayersByMapControl(GetPlayerController(GetOwningPlayer(GetOrderedUnit())))
            set udg_speak = GetUnitLoc(GetOrderTargetUnit())
            set udg_speak2 = GetUnitLoc(GetOrderedUnit())
            set udg_units = CreateGroup()
            call GroupEnumUnitsInRangeOfLoc(udg_units, udg_speak, 500., null)
            if ( Trig_speak_system_____________________u_Func001Func001Func006C() ) then
                // Если расстояние от юнита до цели меньше 500 то цель поворачивается и говорит в чат с подсветкой кружка
                call SetUnitFacingTimed( GetOrderTargetUnit(), AngleBetweenPoints(udg_speak, udg_speak2), 0.30 )
                call TransmissionFromUnitWithNameBJ( udg_playergroup, GetOrderTargetUnit(), "", null, "", bj_TIMETYPE_SET, 1.00, true )
                call UnitAddIndicatorBJ( GetOrderTargetUnit(), 100, 100, 100, 0 )
                call DisplayTextToForce( udg_playergroup, udg_strings[GetRandomInt(0, udg_count)] )
            else
            endif
            call RemoveLocation(udg_speak)
            call RemoveLocation(udg_speak2)
            call DestroyGroup(udg_units)
            call DestroyForce(udg_playergroup)
        else
        endif
    else
    endif
endfunction

//===========================================================================
function InitTrig_speak_system_____________________u takes nothing returns nothing
    set gg_trg_speak_system_____________________u = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_speak_system_____________________u, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
    call TriggerAddAction( gg_trg_speak_system_____________________u, function Trig_speak_system_____________________u_Actions )
endfunction 
nvc123, Ну и гайд по форматированию, только по примеру понял как его сделать. Вот текст уже только с одной утечкой и удалённым лишним кодом. Хорошо бы устранить утечку так чтоб не полностью перейти на джасс, но если нельзя то нельзя.
Загруженные файлы
21
А зачем через группу проверять расстояние? Есть же функция IsUnitInRange( ).
30
но ошибку выдаёт при проверке.
Попробуйте обновить JGNP и pjass и выключить Adic Parser и Adic Optimizer в cjass
чтоб не полностью перейти на джасс
Что вы так JASS'а боитесь то? Если юзать его с препроцессорами, то с разрастанием карты не потеряешься в куче глобальных переменных и триггеров.
ScopteRectuS:
А зачем через группу проверять расстояние? Есть же функция IsUnitInRange( ).
Это наследие GUI, всё через глобалки сделано же.
JASS
function SpeakSystem_Actions takes nothing returns nothing
    local force f = GetPlayersByMapControl(GetPlayerController(GetOwningPlayer(GetOrderedUnit())))
    local location loc1 = GetUnitLoc(GetOrderTargetUnit())
    local location loc2 = GetUnitLoc(GetOrderedUnit())
    /* 851971 это id приказа smart, ненужно лишний раз конвертить из строки */
    if GetOwningPlayer(GetOrderTargetUnit()) == Player(PLAYER_NEUTRAL_PASSIVE)  and GetIssuedOrderId() == 851971 and  IsUnitInRange(GetOrderTargetUnit(),GetOrderedUnit(),500.) then
        // Если расстояние от юнита до цели меньше 500 то цель поворачивается и говорит в чат с подсветкой кружка
        call SetUnitFacingTimed( GetOrderTargetUnit(), AngleBetweenPoints(loc1, loc2), 0.30 )
        call TransmissionFromUnitWithNameBJ( f, GetOrderTargetUnit(), "", null, "", bj_TIMETYPE_SET, 1.00, true )
        call UnitAddIndicatorBJ( GetOrderTargetUnit(), 100, 100, 100, 0 )
        call DisplayTextToForce( f, udg_strings[GetRandomInt(0, udg_count)] )
    endif
    call ForceClear(f)
    call DestroyForce(f)
    set f = null
    call RemoveLocation(loc1)
    call RemoveLocation(loc2)
endfunction

function SpeakSystem takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0

    //вешаем только играющим
    loop
        exitwhen i > 12
        if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, null)
        endif
        set i = i + 1
    endloop
    call TriggerAddAction(t, function SpeakSystem_Actions)
    set t = null
endfunction 
29
Adic Parser и Adic Optimizer
Достаточно просто отключить парсер. Оптимизация без него не будет работать.
30
Msey:
Adic Parser и Adic Optimizer
Достаточно просто отключить парсер. Оптимизация без него не будет работать.
То во что превращает код Adic сложно назвать оптимизацией, да и при сохранении карты он тормозит и частенько вылетает.
Мне вот пригдянулся zinc из-за простоты реализации и удобства отладки.
JASS
function Temp takes string s returns boolean r
..
return true
endfunction
против
zinc
function Temp (string s) -> boolean {
...
return true;
}
28
NazarPunk, cjass
bool Temp(string s){
	return true;
}
Alexey103, да что там понимать?
>> кат "" тут находится джасс код "" <<
получается:
кат
тут находится джасс код

при беглом просмотре утечек не заметил
убери группу и используй простую проверку расстояния между точками:
"если расстояние между точками speak и speak2 меньше чем 500 то"
всеравно ведь точки используешь
так же проверь утечки при многократном повторении этого триггера
т.е. последовательно запусти этот триггер раз 20 и посмотри на показатель счётчика
29
То во что превращает код Adic сложно назвать оптимизацией
Есть такой момент. Хоть он и деликатен в написании, суммарное количество времени на компиляцию и возню с ошибками затрачивается при 500+ запусках для отладки значительно больше.
28
NazarPunk, Msey, оптимизация с точки зрения человека и с точки зрения машины разные вещи
код оптимизированный для машины плохо понятен человеку
а красивый и понятный код как правило дольше обрабатывается машиной
хотя существуют уникумы которые могут писать медленно работающий непонятный код
по сути задача любого препроцессора и компилятора превратить красивый и удобный код в нечитаемое говно которое устраивает машину
Чтобы оставить комментарий, пожалуйста, войдите на сайт.