Помощь - Поиск - Пользователи - Календарь
Полная версия: Бесконечный цикл
Город Мастеров > РЕДАКТОРЫ > Neverwinter Nights Aurora Toolset
virusman
Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
                }
            }

Выполнение этого куска скрипта приводит к многократному созданию плейсебла в одной точке + подвисанию и таймауту скрипта. ГДЕ здесь бесконечный цикл создания объекта?! swoon.gif
Lukas Addon
Возможно надо сделать так чтобы этот скрипт выполнялся 1 раз
то есть добавить переменную
Lex
ВИРЬ, ну ты даешь!!

Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                }
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
            }


надеюсь, объяснять не надо, почему так, а не так, как ты написал? (примерно неделю назад ТОЧНО ТАКОЙ ЖЕ случай зацикливания кто-то выложил. Я там расписал, почему так, а не иначе. )
2GoDoom
И что не понятного?
пока oTemp = GetFirstObjectInArea(OBJECT_SELF); - будет "совпадать" - будет выполняться условие...
может стоит сделать for (правда не помню я - есть ли он в НВНе) pardon.gif
Ну или в While вписать другие условия...

А вообще - что требуется от скрипта?
virusman
Брр. Опять не тот исходник выложил.
У меня и:
Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                }
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
            }

Действовал абсолютно аналогично.
Lex
Эх..ладно, что-то меня совесть замучила. Сейчас объясню для тех, кто не понял еще раз и тему закрою. (Твин, можно это в ФАК занести потом будет)

Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
                }
            }

Идея скрипта такова: замещение одного объекта другим. Те цикл, который перебирает все объекты локации, и если тэг объекта совпадает с тэгом заменяемого объекта (тут это "vir_dw_snow") то мы создаем новый объект, а старый удаляем.

А теперь что НА САМОМ деле тут происходит.
Первый же объект в локации, который будет иметь тэг не "vir_dw_snow" повесит скрипт. ТАК КАК ПЕРЕОБОЗНАЧЕНИЕ ПЕРЕМЕННОЙ oTemp ПРОИСХОДИТ ВНУТРИ УСЛОВИЯ ПРОВЕРКИ ТЭГА. Другими словами, если тэг не "vir_dw_snow" то этот объект и будет вечно бегать по циклу, другой не берется.

Что делать?
Правильно, перенести переобозначение объекта (oTemp = GetNextObjectInArea(OBJECT_SELF)wink.gif в тело цикла. Те получаем вот это:
Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                }
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
            }

Добавлено в [mergetime]1104690570[/mergetime]
Вирь, да не может такого быть. У меня такие скрипты работают как часы.
virusman
Да я знаю, в чем баг скрипта, который в первом посте. Это я просто криво его восстановил после различных безуспешных попыток что-то другое намудрить. Первоначальный вариант был как у тебя. И он виснет. swoon.gif
Comper
Такая же проблема и у меня сегодня возникла. Но я только создаю объекты в таком цикле.
Причина возможно кроется в том что, в цикле по всем объекта в локе нельзя создавать и, возможно, удалять объекты, находящиеся в этой же локе. Похоже меняются указатели на след. объект.
Lex
я писал скрипты отчистки локации от мусора. Все работает. А это удаление объектов в цикле.
virusman
QUOTE
Такая же проблема и у меня сегодня возникла. Но я только создаю объекты в таком цикле.
Причина возможно кроется в том что, в цикле по всем объекта в локе нельзя создавать и, возможно, удалять объекты, находящиеся в этой же локе. Похоже меняются указатели на след. объект.

Я пробовал так:

Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                    oTemp = GetFirstObjectInArea(OBJECT_SELF);
                }
                else
                {
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
                }
            }

Результат: игра уже не виснет, но при каждом вызове создается куча плейсеблов в одной точке, после чего скрипт вылетает с таймаутом (при след. вызове скрипт все-таки переходит на другую точку).
Lex
Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                    oTemp = GetFirstObjectInArea(OBJECT_SELF);
                    // может сюда надо oTemp = GetNextObjectInArea(OBJECT_SELF); smile.gif
                }
                else
                {
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
                }
            }
virusman
QUOTE
я писал скрипты отчистки локации от мусора. Все работает. А это удаление объектов в цикле.

Да у меня тоже.. Даже отложенные вызовы и вложенные циклы в некоторых местах применялись. Но именно в этом скрипте почему-то все виснет. Может, потому что он висит на heartbeat локации? Я с этим уже не в первый раз сталкиваюсь: чуть раньше у меня один модуль вообще вызывал синий экран и зависание всего компа, когда heartbeat локации посылал команды NPC.
virusman
QUOTE (Lex @ Jan 2 2005, 22:35)
Neverwinter Script Source
oTemp = GetFirstObjectInArea(OBJECT_SELF);
            while(GetIsObjectValid(oTemp))
            {
                if(GetTag(oTemp)=="vir_dw_snow")
                {
                    CreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", GetLocation(oTemp));
                    DestroyObject(oTemp);
                    oTemp = GetFirstObjectInArea(OBJECT_SELF);
                    // может сюда надо oTemp = GetNextObjectInArea(OBJECT_SELF); smile.gif
                }
                else
                {
                    oTemp = GetNextObjectInArea(OBJECT_SELF);
                }
            }

Результат тот же. Виснет.
Comper
Neverwinter Script Source
string sName, sTag;
int nNum = 0;

object oTemp = GetFirstObjectInArea(OBJECT_SELF);
while (oTemp != OBJECT_INVALID)
{
    sName = GetName(oTemp);
    if (GetStringLeft(sName, 2) == "SP")
    {
        nNum++;
        SetLocalObject(OBJECT_SELF,"SP"+IntToString(nNum),oTemp);
    }
    oTemp = GetNextObjectInArea(OBJECT_SELF);
}

int i;
for (i=1; i <= nNum; i++)
{
    oTemp = GetLocalObject(OBJECT_SELF, "SP"+IntToString(i));
    if (oTemp != OBJECT_INVALID)
    {
        CreateObject(OBJECT_TYPE_CREATURE, GetTag(oTemp), GetLocation(oTemp), FALSE, GetTag(oTemp));
    }
}

Сделал в 2 этапа. Первый цикл проходит, но при включении 2го - повисание. Этот скрипт висит на OnEnter локи. Или у меня во втором цикле ошибка?
Lex
я не работаю с for в скриптах почти никогда.
i=1;
while (i<=nNum)
{
....
i++;
}
Comper
Эффект тот же.
virusman
Кстати, юзайте Script Debugger. smile.gif Завтра гляну, что он напишет про мой скрипт.
Lex
что за дебагер?
Twin
Вариант рабочий:
Neverwinter Script Source
void main()
{
    int nCount = 0;
    location lTemp;

    object oTemp = GetFirstObjectInArea(GetObjectByTag("AREA001"));

    while ( GetIsObjectValid(oTemp) ) {
        if ( GetTag(oTemp) == "StatueDefaced" ) {
            SetLocalLocation(OBJECT_SELF,
                "TEMP_CreDelItems_"+ IntToString(nCount), GetLocation(oTemp)
            );
            nCount++;

            DestroyObject(oTemp);
        }

        oTemp = GetNextObjectInArea(GetObjectByTag("AREA001"));
    }

    for ( ; nCount >= 0; nCount-- ) {
        lTemp = GetLocalLocation(OBJECT_SELF,
            "TEMP_CreDelItems_"+ IntToString(nCount)
        );
        DeleteLocalLocation(OBJECT_SELF,
            "TEMP_CreDelItems_"+ IntToString(nCount)
        );

        CreateObject(OBJECT_TYPE_PLACEABLE, "plc_impledcrpse1", lTemp);
    }
}

OBJECT_SELF - в данном случае это модуль.

Остается только проблема с созданием новых плейсов на месте старых статичных. Статичеые плейсы не удаляются и в _первом_ цикле участвуют (но потом куда-то из цикла пропадают, странно dntknw.gif). В общем, если девелоппер гарантирует, что все плейсы, заменяемые в цикле будут не статичными, то всё окей. Имхо. yes.gif
DBColl
Да, Твин верно заметил, что для уничтожаемых плэйсов надо ОБЯЗАТЕЛЬНО снимать галку Static. Не забывайте!
Vanes
Neverwinter Script Source
void VoidCreateObject(int nType, string sResRef, location lLoc)
{
    CreateObject(nType, sResRef, lLoc);
}

void main()
{
    object oTemp = GetFirstObjectInArea(OBJECT_SELF);
    location lLoc;
    while(GetIsObjectValid(oTemp))
    {
        if(GetTag(oTemp)=="vir_dw_snow")
        {
            lLoc = GetLocation(oTemp);
            ActionDoCommand(DestroyObject(oTemp)); // вот так правильнее wink.gif
            ActionDoCommand(VoidCreateObject(OBJECT_TYPE_PLACEABLE, "x0_snowdrift", lLoc));
        }
        oTemp = GetNextObjectInArea(OBJECT_SELF);
    }
}

вот это должно работать...

DBColl: Чуток исправлю...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Invision Power Board © 2001-2024 Invision Power Services, Inc.