Помощь - Поиск - Пользователи - Календарь
Полная версия: Скрипты
Город Мастеров > РЕДАКТОРЫ > Neverwinter Nights Aurora Toolset
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74
Waromon
http://www.city-of-masters.ru/forums/index...p;p=89858&#


ЗЫ: Тяжелый случай...
Артём
Мне нужен скрипт, который ставится на область, а не на непися.
Waromon
QUOTE
У меня вопрос, какой нужен скрипт чтобы после смерти непися заработал новый скрипт.


И:

QUOTE
Мне нужен скрипт, который ставится на область, а не на непися.


shok.gif swoon.gif shok.gif


http://www.city-of-masters.ru/forums/index...p;p=88758&# (Сообщение #2415)


ЗЫ: http://www.city-of-masters.ru/forums/index...=Search&f=5
Артём
Упс.. scratch_one-s_head.gif
Aiwan
Увижу спам в этой теме, головы поотрываю. big_boss.gif Касается молодежи... Отвечать не надо.
Zirrex
Меня этот скрипт уже бесит. Не желает он работать правильно. Вроде все верно, но значение репутации меняться по отношению к игроку не желает. Сразу обмолвлюсь, пытаюсь восстановить отношение своей (не стандартной) фракции к игроку. Скрипт:

NSS
void AdjustFactionReputation(object oPC, object oFaction, int nCurRep, int nSetRep)
{
    object oMember = GetFirstFactionMember(oFaction, FALSE);

    while (oMember != OBJECT_INVALID)
    {
        AdjustReputation(oPC, oMember, nCurRep + nSetRep);
        oMember = GetNextFactionMember(oFaction, FALSE);
    }
}

void main()
{
    object oPC = OBJECT_SELF;
    location lPC = GetLocation(oPC);
    object oNeutral = GetObjectByTag("npc_faction");

    int nCurRep, nNeutral = 50;
    object oNPC = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, lPC, FALSE, OBJECT_TYPE_CREATURE);

    while (oNPC != OBJECT_INVALID)
    {
        if (GetFactionEqual(oNPC, oNeutral))
        {
            nCurRep = GetReputation(oNPC, oPC);

            if (nCurRep != nNeutral)
            {
                AdjustFactionReputation(oPC, oNPC, nCurRep, nNeutral);
            }
        }
        oNPC = GetNextObjectInShape(SHAPE_SPHERE, 20.0, lPC, FALSE, OBJECT_TYPE_CREATURE);
    }
}

Пробовал по-разному, работает нормально, если только "AdjustReputation" вытащить из цикла, а вместо него внести "SetIsTemporaryNeutral". Почему значение не хочет устанавливаться без второй функции, я не понимаю.

Краткое описание работы скрипта, как я его вижу. В сфере, радиусом 20 метров, ищу любых существ. Внутреннее условие проверки фракции отсекает существ, которые не подпадают под него. Значение во время смерти игрока по отношению к НПС, на которого игрок напал, равно 0. Проверяю, неравно ли полученное значение 50, если неравно, продолжаю выполнение скрипта. С помощью кастомной функции через цикл проверяю, сколько у НПС было существ в партии. Всем пытаюсь установить значение 50 по отношению к игроку.

В итоге значение как было 0, так и остается 0. Фракция не имеет глобального эффекта. Обижается только то существо, на которое напали.

Кстати, во время мучений со скриптом, заметил некоторую странность в логих. Иногда не пишут, кто же именно убил игрока. Просто фраза "Someone killed Player". Шутку не понимаю, учитывая то, что предыдущая строчка четко показывает, что игрока ударил такой-то. Баг?

Из-за этой пакости невозможно вычислить убийцу.
Aiwan
AdjustFactionReputation - лишнее. Или по крайней мере она не в том направлении работает.
Тебе не надо искать каждого НПС этой фракции и устанавливать значение общее. Тебе надо установить лидеру фракции репу в 50 у других участников фракции сделать ClearPersonalReputation(oPC,oMember); К тому же, если у твоей фракции не стоит ГЛОБАЛЬНЫЙ эффект, то ничего менять не надо в репе. Только почистить у всех и они забудут старые грешки. Не надо глобально править репутацию у всей фракции. К примеру, если у фракции стоит глобальное отслеживание репы, то меняй у главаря на 50 и чисти у тех, кто видим и все. Вот такой функцией: (примерно...)

NSS
void ClearFactionReputation(object oPC, object oFaction=OBJECT_SELF)
{
    object oMember = GetFirstFactionMember(oFaction, FALSE);

    while (oMember != OBJECT_INVALID)
    {
        ClearPersonalReputation(oPC, oMember);
        oMember = GetNextFactionMember(oFaction, FALSE);
    }
}
Zirrex
Aiwan, спасибо, то, что нужно было smile.gif Я как раз подумывал использовать эту функцию, тем более, когда искал на форуме что-нибудь про фракции, натолкнулся на нее в твоем скрипте, но решил вначале добить все же ту функцию, которую использовал изначально. Видимо, работает она нормально только тогда, когда эффект у фракции глобальный.

Немного усовершенствовал общий скрипт, добавить перечисление всех своих фракций с помощью цикла, а то писать объект такой-то, и впихивать их все под условие, все же не очень весело, да и лишние проверки для цикла. Получился следующий скрипт, если кому нужен на вооружение, можно использовать, я не буду против smile.gif

NSS
void ClearFactionReputation(object oPC, object oFaction=OBJECT_SELF)
{
    object oMember = GetFirstFactionMember(oFaction, FALSE);

    while (oMember != OBJECT_INVALID)
    {
        ClearPersonalReputation(oPC, oMember);
        oMember = GetNextFactionMember(oFaction, FALSE);
    }
}

void main()
{
    object oPC = OBJECT_SELF, oFaction, oNPC;
    location lPC = GetLocation(oPC);
    int i, nCurRep, nNeutral = 50;

    for (i = 1; i <= 7; i++) // значение зависит от количества своих фракций
    {
        oFaction = GetObjectByTag("factionnpc_" + IntToString(i));

        oNPC = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, lPC, FALSE, OBJECT_TYPE_CREATURE);

        while (oNPC != OBJECT_INVALID)
        {
            if (GetFactionEqual(oNPC, oFaction))
            {
                nCurRep = GetReputation(oNPC, oPC);

                if (nCurRep != nNeutral)
                {
                    ClearFactionReputation(oPC, oNPC);
                }
            }
            oNPC = GetNextObjectInShape(SHAPE_SPHERE, 20.0, lPC, FALSE, OBJECT_TYPE_CREATURE);
        }
    }
}
Don_Beavis
Люди, помогите! Кинте ктонить хороший скриптик AI с описанием. Заранее спасибо! smile.gif
Waromon
2 Don_Beavis

Посмотри здесь.
Noah
Получился следующий скрипт, если кому нужен на вооружение, можно использовать, я не буду против :)

а куда скрипт ставить?На персептион модуля?
Zirrex
Нет, причем тут модуль? Тебе же скрипт не всегда необходим. Скрипт ставится на эвент смерти модуля (OnPlayerDeath), и обрабатывается только тогда, когда умирает персонаж. Чтобы после смерти фракции для персонажа не были злыми, их необходимо обновить. Не забудь сделать куклы с фракциями, которые необходимо разместить где-нибудь в модуле, чтобы скрипт мог к ним обращаться.
Elf-Drow
Так как скриптера у меня *хлюп-хлюп* нету, прошу помочь бедному дроу написать скрипт на исчезновение челов из области на полдня-день в случайное время, но не слишком часто...
Dik Morris
Опиши ситуацию ПОДРОБНО. Как и при каких обстоятельствах NPC должен исчезать (в диалоге, просто так), в какое время суток (если это критично) и т.д. Здесь нужна конкретика. wink3.gif
Elf-Drow
Исчезать должны просто так, вне зависимости от времени суток.
windhover
Доброго времени суток.
Возникла следующая проблема:
Изменил стандартный скрипт заклинания лечения к проверке на андед добавил проверку на субрасу но проверка не срабатывает. Ошибок вроде нет пробовал в отдельном скрипте - работает.
Ткните, пожалуйста носом что не так делаю, подозреваю что проблема в руках =)
Пробовал просто вносить изменения в тулсете в стандартный скрипт, пробовал вносить изменения в .nss выдраный из .bif'a и ложил его в оверрайд..
Или нужно обязательно делать отдельный скрипт и прописывать его в spells.2da?

И еще вопрос теоретический:
Какой приоритет использования ресурсов игрой? По моим предположениям: сначала в оверриде смотрит, потом
ресурсы хаков и в последнюю очередь использует стандартные ресурсы?
Aiwan
QUOTE(windhover @ Sep 6 2006, 03:07) [snapback]91142[/snapback]
сначала в оверриде смотрит, потом
ресурсы хаков и в последнюю очередь использует стандартные ресурсы

Верно.
Если отредактировать стандартный скрипт, то будет работать он. Никуда его класть не надо. Если удалить его из модуля то будет пахать дефолтный с таком же именем от Биовар.
windhover
Спасибо, разобрался в чем проблема:
Я вносил изменения в скрипт nw_i0_spells - инклюд. Почитал в лексиконе, что для того чтобы изменения внесенные в инклюд вступили в силу нужно перекомпилировать ВСЕ скрипты которые ссылаються на данный инклюд. Возможно это можно какимто образом обойти? А то слишком много скриптов надо перекомпиливать. sad.gif Покачто я решил проблему так: написал свой инклюд и дал ссылку на него в тех скриптах заклинаний, которые мне нужны, перекомпилил все это дело - заработало.

Возможно есть решение данной проблемы попроще?

Lex
QUOTE(windhover @ Sep 7 2006, 19:15) [snapback]91245[/snapback]
Возможно это можно какимто образом обойти?

нет, но это можно сделать за пару минут.
ВТулсете Build - Build Module.
Если нужна только копмиляция, ставь галочку в Compile и в Scripts, остальные галочки снимай.
windhover
QUOTE(Lex @ Sep 7 2006, 18:29) [snapback]91246[/snapback]

нет, но это можно сделать за пару минут.
ВТулсете Build - Build Module.
Если нужна только копмиляция, ставь галочку в Compile и в Scripts, остальные галочки снимай.


Эм.. Дело в том, что в лексиконе билд модуля тоже описывается как панацея.. но не помогло. unsure.gif
Я так понял, что стандартные скрипты в которые не вносят изменений не компилируются при билде модуля.
Хотя может это у меня глюк, проверял на 1.68.
Lex
да, стандартные не билдаются, поэтому если ты вносишь изменения в стандартную библу, которая влияет на заклы, тебе еще скрипты этих заклов надо у себя в модуле пересохранить. Вродь только так.
virusman
Стандартные инклюды типа nw_i0_spells, nwscript очень нежелательно изменять. Ещё раз подумай, надо ли тебе это.
windhover
QUOTE(virusman @ Sep 7 2006, 21:54) [snapback]91271[/snapback]

Стандартные инклюды типа nw_i0_spells, nwscript очень нежелательно изменять. Ещё раз подумай, надо ли тебе это.


Да я просто скопировал этот инклюд, внес в него нужные изменения, сохранил с другим названием, прописал его в нужных заклинаниях и все откомпилил.. так вроде проще всего и безопастнее, наверно smile.gif
Всем спасибо за советы.
Milfes
У меня проблема. Надо что бы когда игрок наступал на тригер к нему подбегал хенчь и начинал разговор, но если хенчь далеко то он подбегает но разговор не начинает.
Вот скрипт на он энтаре тригера:
NSS
void main()
{
object oPC = GetEnteringObject();
if (!GetIsPC(oPC)) return;
if (GetLocalInt(OBJECT_SELF,"ACTIVATED")) return;
object oIlirin = GetHenchman(oPC);
if (GetTag(oIlirin)!="ilirin01") return;
SetLocalInt(oIlirin,"D_LINE",GetLocalInt(OBJECT_SELF,"CONVERSATION_LINE"));
SetLocalInt(OBJECT_SELF,"ACTIVATED",TRUE);
DestroyObject(OBJECT_SELF,5.0);
AssignCommand(oIlirin, ClearAllActions(TRUE));
AssignCommand(oPC, ClearAllActions(TRUE));
SetCutsceneMode(oPC,TRUE);
AssignCommand(oIlirin, ActionStartConversation(oPC,"plot_ilitrin01"));
}

Может кто знает в чём ошибка.
ЗЫ так же пробовал что бы хенчь сначала подбегал при момощи ActionMoveToObjecy, а только потом начинал разговор, но всё равно не получается.
Lex
Знакомый код smile.gif))
У мну работало. Правда на большой дальности не проверял. Довольно странно, что не работает, если далеко.
-fenix-
Milfes, ну если он по команде ActionStartConversation подбегает, а диалог не начинает, то ведать проблема в диалоге. У него точно такой таг?

Хм, а зачем дестрой через 5 секуд?
Batkom
Обьект дестроится, действие остается.
-fenix-
Зачем его вообще дестроить и почему именно через пять секунд?
В скрипте есть проверка переменной, чтобы он второй раз не запускался.
Dik Morris
-fenix-, уничтожение конечно не критично, но триггер то больше не нужен, он свое дело сделал. pleasantry.gif

Milfes, самое простое - хенчмана по пути могут задержать. (Враги, другие команды и т.д...)
Поэтому лучше подстраховаться и забить стек команд помощника.


PS: (ИМХО) разумнее сначала подойти к игроку, а только потом начинать диалог.
(Кстати вот тебе и решение - ActionForceMoveToObject)
Lex
Фен, триггер одноразовый, я такие обычно удаляю через пару секунд. Чтоб не мешался.
Milfes
Dik Morris, не помогает.
Кстати если хенчу приказать стоять на месте, то он спокойно подбегает и начинает разговор не зависимо от расстояния.
-fenix-
Milfes, тоесть приказать стоять, когда?
Milfes
Нажимаешь на хенча правой кнопкой мышки и отдаёшь приказ стоять на месте. И вот в этом случае при наступление на тригер хенч начинает разговор.
-fenix-
Хм, что-то странное, такое ощущение, что у тебя хенч в каком-то возбужденном состоянии, так как он подбегает, а говорить у него не получается. Но такое состояние не снимается приказом стоять (или снимается?).
У тебя хенч что-нить делает или просто стоит ждет команды?

Попробуй хенча пересоздать. Еще почитать в Лексиконе про функцию ActionStartConversation, мож там что интересное есть. Чет хз пока что. Домой прийду, постараюсь пасмотреть.
Milfes
В том то и дело что ничего не делает.
Lex
Хенч там криво получился хз почему. При переходах между локациями ему надо переприказывать, чтобы шел за тобой. Я хз почему.
Aiwan
QUOTE(Milfes @ Sep 15 2006, 16:28) [snapback]91739[/snapback]

У меня проблема. Надо что бы когда игрок наступал на тригер к нему подбегал хенчь и начинал разговор, но если хенчь далеко то он подбегает но разговор не начинает.
Вот скрипт на он энтаре тригера:
NSS
void main()
{
object oPC = GetEnteringObject();
if (!GetIsPC(oPC)) return;
if (GetLocalInt(OBJECT_SELF,"ACTIVATED")) return;
object oIlirin = GetHenchman(oPC);
if (GetTag(oIlirin)!="ilirin01") return;
SetLocalInt(oIlirin,"D_LINE",GetLocalInt(OBJECT_SELF,"CONVERSATION_LINE"));
SetLocalInt(OBJECT_SELF,"ACTIVATED",TRUE);
DestroyObject(OBJECT_SELF,5.0);
AssignCommand(oIlirin, ClearAllActions(TRUE));
AssignCommand(oPC, ClearAllActions(TRUE));
SetCutsceneMode(oPC,TRUE);
AssignCommand(oIlirin, ActionStartConversation(oPC,"plot_ilitrin01"));
}

Может кто знает в чём ошибка.
ЗЫ так же пробовал что бы хенчь сначала подбегал при момощи ActionMoveToObjecy, а только потом начинал разговор, но всё равно не получается.

NSS
//:://////////////////////////////////////////////
//:: OnEnter  am_ten_convr_npc
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
  Старт диалога с РС. Текст над РС - Name триггера
  KeyTag - если больше 0, то непись ПОДБЕЖИТ.
  TR_CONV_[ТАГ_НПС_ДЛЯ_ДИАЛОГА]
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Original idea By: DBColl
//:: Created On: 22.04.2005
//:://////////////////////////////////////////////

void main()
{
    object oPC = GetEnteringObject();
    object oTrig = OBJECT_SELF;
    string sTag = GetTag(oTrig); // Таг триггера
    string sNPC = GetStringRight(sTag, (GetStringLength(sTag)- 8)); // Таг НПС
    object oNPC = GetNearestObjectByTag(sNPC);
    string sSpeak = GetName(oTrig); // Фраза
    vector vD = GetPosition(oNPC) - GetPosition(oPC);
    float fDir = VectorToAngle(vD);
    int bRun = StringToInt(GetLockKeyTag(oTrig));
    if (!GetIsPC(oPC)) return;
    if (GetLocalInt(oTrig, "HAS_OPERATED")) return;
    if (!GetIsObjectValid(oNPC)) return;
    if (GetArea(OBJECT_SELF)!=GetArea(oNPC)) return;
    if (GetIsEnemy(oNPC, oPC)) return;
    if (GetObjectType(oNPC)!=OBJECT_TYPE_CREATURE) return;

    FadeToBlack(oPC, FADE_SPEED_FASTEST);
    AssignCommand(oPC, ClearAllActions());
    AssignCommand(oNPC, ClearAllActions());
    SetCutsceneMode(oPC);
    DelayCommand(0.8, AssignCommand(oPC, SetCameraFacing(fDir, 25.0, 60.0, CAMERA_TRANSITION_TYPE_SNAP)));
    AssignCommand(oNPC, ActionDoCommand(SetFacingPoint(GetPosition(oPC))));
    DelayCommand(1.2, FadeFromBlack(oPC, FADE_SPEED_FAST));
    DelayCommand(2.0, AssignCommand(oPC, SetCameraFacing(fDir+35.0, 8.0, 50.0, CAMERA_TRANSITION_TYPE_SLOW)));
    AssignCommand(oPC, ActionDoCommand(SetFacingPoint(GetPosition(oNPC))));
    if (GetDeity(oNPC)!="")
      {
        int iAnim = StringToInt(GetDeity(oNPC));
        DelayCommand(3.0, AssignCommand(oNPC, ActionPlayAnimation(iAnim, 0.8, 2.0)));
      }
    DelayCommand(3.5, AssignCommand(oNPC, SpeakString(sSpeak)));
    DelayCommand(4.5, AssignCommand(oNPC, ActionForceMoveToObject(oPC, bRun)));
    DelayCommand(5.5, AssignCommand(oNPC, ActionDoCommand(SetCutsceneMode(oPC, FALSE))));
    DelayCommand(6.0, AssignCommand(oNPC, ActionStartConversation(oPC)));
    //-------------------------------------------------------
    SetLocalInt(oTrig, "HAS_OPERATED", TRUE);
}

Работает уже пару лет.

Зайди в раздел хеньчмана, там есть заготовка диалога и стрингов. Все бегает все подбегает и прочее. Хеньч сложная системаскриптов. там постоянно чистят акции и прочее, сканит врагов и друзей.

NSS
//:://////////////////////////////////////////////
//:: Name: am_ten_evt_alish
//:: Copyright © 2006 WRG! Team
//:://////////////////////////////////////////////
/*
  Скрипт персональных триггеров Алишан
  Основан на скрипте X2_EVT_TRIGGER
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 02.08.2006
//:://////////////////////////////////////////////
#include "x0_i0_common"
#include "x2_inc_banter"


void main()
{
    object oSelf = OBJECT_SELF;
    object oTrigger = GetEnteringObject();
    object oAlishan = GetObjectByTag("AM_HEN_ALISHAN");
    string sLl = GetLocalString(oSelf, "LOCAL_PC_01");
    string sL2 = GetLocalString(oSelf, "LOCAL_PC_02");

    if(GetMaster(oAlishan) == oTrigger)
    {
      // Если РС длаьше 20 метров то возврат. Иначе у BioWare тупо удаляется триггер...
    if(GetDistanceBetweenLocations(GetLocation(oTrigger), GetLocation(oAlishan)) > 20.0)
      return;

      // Локальные переменные на РС при каторых триггер не сработает
      if(GetLocalInt(oTrigger, sLl) || GetLocalInt(oTrigger, sL2))
      {
        DestroyObject(oSelf);
        return;
      }
      string sTag = GetTag(OBJECT_SELF);
      AttemptInterjectionOrPopup(OBJECT_SELF, sTag, oTrigger, 0, oAlishan);
    }
}
Milfes
Тут дело не в самом скрипте похоже, а в чём-то другом. По идее и скрипт Lеха должен работать.
-fenix-
Milfes, ну вроде сказали уже, что похоже дело в хенче, глюкнуло там что-то.
Aiwan
QUOTE(Milfes @ Sep 16 2006, 00:43) [snapback]91780[/snapback]
Тут дело не в самом скрипте похоже, а в чём-то другом. По идее и скрипт Lеха должен работать.

Надо делать вот что: повесить все команды на хеньчмана акциями. Через 0.1 секунду закрыть стек команд, а в конце всех команд повесить ActionDoCommand(Открываем стек команд Хеньчману) и все будет пахать как часы. проверено на разных НПС делающих что-то по скриптам. Ходящих по вейпам, стоящих на поинтах. У них сбиваются акции. Или с рандомно бродящими НПС.
Milfes
Огромное спасибо. thank_you.gif Помогло.
2_advanced
я сей сабж делал через OnUserDefined o_O
Diamond
Всем добрый вечер. Я в скриптах почти ноль, и поэтому помучавшесь чуть чуть решил написать сюда. В общем мысль такая - есть триггер, игрок на него наступает, NPC говорит фразу (это я сделал сам...) Но после того как игрок сходит с триггера меняется переменная и в следующий раз NPC говорит уже другую фразу. Вот то, что я сам наваял, что то работает, что то нет...

NSS
void main()
{
   SetLocalInt(GetPCSpeaker(), "Int_1", 0);
   object oNPC=GetObjectByTag("SHIP_KONTR");
   string sString_1="Текст_1!";
   string sString_2="Текст_2!";
   if(!(GetLocalInt(GetPCSpeaker(), "Int_1") == 1))
     return ActionDoCommand(AssignCommand(oNPC,ActionSpeakString(sString_1)));

   return ActionDoCommand(AssignCommand(oNPC,ActionSpeakString(sString_2)));
}


Это на OnEnter триггера

NSS
void main()
{
SetLocalInt(GetPCSpeaker(), "Int_1", 1;
}


Это на OnExit
Lex
эм.. я ничего не понял, если честно...
вот тот скрипт, который ты по идее должен был бы написать:
OnEnter триггера
NSS
void main()
{
// берем того, кто наступил на триггер (у тебя тут GetPCSpeaker был.. совсем не в тему)
object oPC = GetEnteringObject();
// если наступил на триггер не игрок (что более чем реально)
if (!GetIsPC(oPC)) return; // выходим из скрипта
// теперь берем НПС, который говорит фразу
// чтобы унифицировать, тэг НПС храним в локальной переменной NPC_TAG, которая записана на триггере
object oNPC = GetNearestObjectByTag(GetLocalString(OBJECT_SELF,"NPC_TAG"));
// теперь берем номер строки, которую нам надо сказать (нумерация идет с 0)
int nNumber = GetLocalInt(OBJECT_SELF,"NUMBER");
// если номер текущей строки -1 (это означает, что кончились строки)
if (nNumber == -1) return; // мы выходим из скрипта
// теперь берем саму строчку.. строки это локальные строковые переменные на триггере STRING_0, STRING_1 и тд
string sString = GetLocalString(OBJECT_SELF,"STRING_"+IntToString(nNumber));
// увеличивем указатель номера строки на 1. (чтоб в след. раз взять следующую строку)
SetLocalInt(OBJECT_SELF,"NUMBER",nNumber++);
// если строка не пустая, говорим ее
if (sString!="")
     AssignCommand(oNPC,SpeakString(sString));
// а если пустая, значит строки кончились. Тады ставим указатель на -1
else SetLocalInt(OBJECT_SELF,"NUMBER",-1);
}

__
таким образом получаем:
- ставишь триггер
- ставишь в onEnter этот скрипт
- в локальную строковую переменную NPC_TAG пишешь тэг нпс (в данном случае у тебя это SHIP_KONTR)
- в локальные строковые переменные STRING_0, STRING_1 и тд (скока хочешь, хоть STRING_10000) пишешь нужные тебе фразы.

готово.

вопросы?
Diamond
Всё отлично работает! Спасибо. Еще один маленький вопрос - как сделать задержку между появлениями фраз, а то если ходить по комнате они слишком часто появляются.
Lex
DelayCommand ставь.. например так:
AssignCommand(oNPC,DelayCommand(SpeakString(sString)));

или ты про то, чтобы он не постоянно говорил, а скажем в след. раз не раньше, чем через 2 минуты.
если да, то тут придется скрипт модернизировать.
Aiwan
NSS
/* ЭТО В НАЧАЛО СКРИПТА */

if(GetLocalInt(OBJECT_SELF, "DELAY") == 1) return;
// Если есть локалка DELAY на триггере то он не сработает.

/* ЭТО В КОНЕЦ */

SetLocalInt(OBJECT_SELF,"DELAY", 1);
// присвоим локалку ожидания
float f = IntToFloat(Random(15)+5);
// Сделаем плавающей время ожидания сгенерировав случайное число и конвертнув его в float
// при этом мы прибавили 5 секунд что бы точно не скзал фразу сразу при выпадении 1 или 0
DelayCommand(f,SetLocalInt(OBJECT_SELF,"DELAY", 0));
// Получаем искомое случайное время задержки. Присваиваем 0 локалке триггер опять работает.
Diamond
QUOTE
чтобы он не постоянно говорил, а скажем в след. раз не раньше, чем через 2 минуты.


Ну в общем то да, чтобы прошло секуд 25.
Lex
тады самое эффективное, это временно делать триггер неактивным.
NSS
void main()
{
// если заблокирован - выходим
if (GetLocalInt(OBECT_SELF,"STOP")) return;
// берем того, кто наступил на триггер (у тебя тут GetPCSpeaker был.. совсем не в тему)
object oPC = GetEnteringObject();
// если наступил на триггер не игрок (что более чем реально)
if (!GetIsPC(oPC)) return; // выходим из скрипта
// теперь берем НПС, который говорит фразу
// чтобы унифицировать, тэг НПС храним в локальной переменной NPC_TAG, которая записана на триггере
object oNPC = GetNearestObjectByTag(GetLocalString(OBJECT_SELF,"NPC_TAG"));
// теперь берем номер строки, которую нам надо сказать (нумерация идет с 0)
int nNumber = GetLocalInt(OBJECT_SELF,"NUMBER");
// если номер текущей строки -1 (это означает, что кончились строки)
if (nNumber == -1) return; // мы выходим из скрипта
// теперь берем саму строчку.. строки это локальные строковые переменные на триггере STRING_0, STRING_1 и тд
string sString = GetLocalString(OBJECT_SELF,"STRING_"+IntToString(nNumber));
// увеличивем указатель номера строки на 1. (чтоб в след. раз взять следующую строку)
SetLocalInt(OBJECT_SELF,"NUMBER",nNumber++);
// если строка не пустая, говорим ее
if (sString!="")
     {
     AssignCommand(oNPC,SpeakString(sString));
    // блокируем триггер
     SetLocalInt(OBJECT_SELF,"STOP",1);
    // снимаем блокировку через 25с.
     DelayCommand(25.0,SetLocalInt(OBJECT_SELF,"STOP",0));
     }
// а если пустая, значит строки кончились. Тады ставим указатель на -1
else SetLocalInt(OBJECT_SELF,"NUMBER",-1);
}
Diamond
Теперь всё совсем как нужно! Ура!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Invision Power Board © 2001-2024 Invision Power Services, Inc.