Помощь - Поиск - Пользователи - Календарь
Полная версия: Скрипты
Город Мастеров > РЕДАКТОРЫ > 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
[MoF]Darth_Nick
в OnConversation нпс есть абзац:
NSS
if (GetCommandable(OBJECT_SELF))
{
ClearActions(CLEAR_NW_C2_DEFAULT4_29);
BeginConversation();
}

ставиш проверку на локалки и изменяеш аргументы ф-ции..к примеру:
NSS
if (GetCommandable(OBJECT_SELF))
        {
            ClearActions(CLEAR_NW_C2_DEFAULT4_29);
            if(GetLocalInt(OBJECT_SELF,"SSS") == 1)
                BeginConversation("dlg1",oShouter);
            else
                BeginConversation("dlg2",oShouter);
        }


еще надо прикрутить проверку на таг или индивидуальный скрипт для нпс
Elf-Drow
Благодарим, еще вопрос, я пытался сделать генерацию книг, как в Проклятии Левора, как описывал Айван, но ничего не вышло. Пытался долго и муторно, по-моему это довольно непростой скрипт. И еще, локалка это LocalInt в переменных?
Aiwan
Там надо сделать одну книгу и потом копу/едит делать все остальные. Все там работает.
Aiwan
Вот работающий скрипт из моего мода ПВ.
Создаешь предмет с тагом и РесРефом AM_ITM_BOOK001. Потом Копу/едит делаешь себе сколько надо, например 25 штук. Дальше. Открываешь свойства модуля и в адвансед, присваиваешь локальную переменную ALL_BOOKS_IN_MODULES равную 25. На шкафу вешай переменную BOOKS равную столько, сколько тебе нужно книг в шкафу при открытии. Не повесишь будет одна. И все.

NSS
//:://////////////////////////////////////////////
//:: OnOpen  am_pop_bookshelf
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
  Скрипт генирирует книги в инвентарь шкафа.
  Локальная переменная "BOOKS" на объекте
  означает количество генерируемых книг.
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 23.07.2005
//:://///////////////////////////////////////////
void main()
{
    //-------------------------------------------------------------------------
    // Количество книг в палитре. Присваиваем на модуль "ALL_BOOKS_IN_MODULES"
    //-------------------------------------------------------------------------
    int iBook = GetLocalInt(GetModule(), "ALL_BOOKS_IN_MODULES");
    int iNum = GetLocalInt(OBJECT_SELF, "BOOKS"); // Сколько создаем в шкафу
    if (GetLocalInt(OBJECT_SELF, "HAS_OPERATED")) // Сработает один раз
      {
        return;
      }
      while(iNum >= 1) // Пока количество создаваемых книг больше или равно 1.
          {
    //-------------------------------------------------------------------------
    // Кстати... У меня ResRef-ы  am_itm_book001 ... am_itm_book021, поэтому
    // я извратился немного, лень было переделать книги... Но так проще создать
    // много одинаковых книг, цифры сами генерятся редактором, вы только
    // создаете первую, а дальше Изменить/Сохранить и все.
    //-------------------------------------------------------------------------
            int i = Random(iBook)+1; // Гененрируем случайную унигу
            string sN = "0";
            string sNN = "0";
            if (i >=100) {sNN ="";}
            if (i >=10) {sN ="";}
            object oBook = CreateItemOnObject("am_it_book"+sNN+sN+IntToString(i));
            iNum--; //Создали одну книгу. Отняли от количества еденичку...
          }
          SetLocalInt(OBJECT_SELF,"HAS_OPERATED",TRUE); // Запомним что уже сработал
}


QUOTE(Elf-Drow @ Mar 30 2006, 17:49) [snapback]75275[/snapback]
И еще, локалка это LocalInt в переменных?

Да.
Aiwan
Еще раз увижу ПРЕВЕД или КРАСАВЧЕГИ - влеплю пред. Юзверей с одним сообщением забаню.
JCDenton
Суть:

Есть N обьектов с одинаковыми тэгами. и есть обьект с тегом в конце "00". Нужно сделать:
1) на месте обьекта появляется костерчик, обьет исчезает. (первый 00)
2) загорается ближайший к нему из N обьектов, обьет исчезает.
3) загорается следующий и так далее..

КОД:
NSS
void main()
{
    int iN;
    location lLoc;
    object oFire = GetObjectByTag("PLC_DRM_F00");
      if (GetLocalInt(OBJECT_SELF, "Counter") == 1)
      return;
      else
            SetLocalInt(OBJECT_SELF, "Counter", 2);
            while (oFire != OBJECT_INVALID || iN < 10)
              {
              lLoc = GetLocation(oFire);
              DestroyObject(oFire, 0.0f);
              oFire = GetNearestObjectByTag("PLC_DRM_F01", GetNearestObjectByTag("PLC_DRM_FR", OBJECT_SELF));
              CreateObject(OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lLoc, FALSE, "PLC_DRM_FR");
              iN ++;
              }
}

! Счетчик юзания триггера отключен специально!
Результаты работы:
при первом нахождении на триггер:
1) загорается обьект "..00" 1 костром.
2) загорается соседний 9 кострами. конец.
при повторном нахождении горит соседний 10 кострами..

Спрашивается.. "Какого **ра?" biggrin.gif

Elf-Drow
Пара вопросов по скриптам, приведенным в Проклятии Левора.
1 - Какой скрипт нужен и куда его ставить, чтобы НПС говорили фразы, то есть названия вейпоинтов, находящихся вокруг них ( Говорящие НПС в Проклятии)
2 - Как ваша команда создала такой шедевр как карта? Создание моделей в 3D-MAX, а затем вставка в игру?
Диалог, а затем скрипт с появляющейся картинкой и отправление к месту назначения? И как вы сделали, что бой по дороге может быть на случайной миле, т.е. Там на 11, 23, хоть на какой?
Заранее благодарю.
Aiwan
1. Строка дожна быть в диалоге всегда ОДНА и содержать токен <CUSTOM220>. А содержание = имя вейпоинта. Я опускаю разные ньюансы, стринге на поинте, ответы РС локалки на расстояния и прочее. Даю обрезанный рабочий код. Вставляй и работай.
NSS
//:://////////////////////////////////////////////
//:: Выдает стринг, если НПС рядом с поинтом
//:: Copyright © 2006 WRG!
//:://////////////////////////////////////////////
/*
    Таг нашего поинта. WP_STRING
    <CUSTOM220> - [Имя поинта - строка НПС]
*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 17.01.2006
//:://////////////////////////////////////////////
int StartingConditional()
{
  object oWp = GetNearestObjectByTag("WP_STRING"); // Берем ближайший объект с тагом "WP_STRING"
  float fDist = 20.0f; // Расстояние реакции, дальше 20 метров строки не будет
  float fZone = GetDistanceBetween(OBJECT_SELF, oWp); // Дистанция срабатывания
//-------------------------------------------------------
  if(GetIsObjectValid(oWp)) // Если такой объект существует
  {
    if (fDist < fZone) // Если дистанция между Нпс и Поинтом больше установленной 20 м.
      return FALSE; // Строка не появится
      else // в противном случае (ЕЩЕ)
      {
          string sMessage = GetName(oWp); // Стринг sMessage равен имени поинту
          SetCustomToken(220, sMessage); // Установим токен 220 равный этому стрингу
          return TRUE; // Вернем строку функции StartingConditional(). Она покажет ее игроку
      }
    }
    else return FALSE; // Если такого объекта oWp нет, то нечего не появится
}


2. Карта и ее скрипты очень сложны. Не берись пока за это. Созреешь до сложных скриптов поговорим.
Aiwan
А чего ты хотел? БЕРЕМ БЛИЖАЙШИЙ и насилуем его девять раз. smile.gif Тебе надо брать все объекты и перебирать по параметрам свои костры.
Нужен скрипт на факела-костры-жаровние? Вот мой скрипт запускается ExecuteScript на локацию.
Суть такая. Создаешь два объекта один горящий, другой потухший. На этих объектах в палитре вешаешь стриги ResRef-ы объектов что создаем вместо существующего. Например на плейсе AM_PLS_TORCH_ON стринг NEW_ResRef будет равен am_pls_torchoff. И на оборот. Годится скрипт для чего хошь. Днем объект создается, ночью дестроится. Вешай на вход в локацию. Или на хертбит с проверкой в локации ли РС.
NSS
//:://////////////////////////////////////////////
//:: OnEnter  am_exe_torch_del
//:: Copyright © 2005 WRG!
//:://////////////////////////////////////////////
/*
    ВКЛЮЧАЕМ ОГОНЬ ФАКЕЛОВ И ЗВУК К НИМ НОЧЬЮ.

Таг факела = "AM_PLS_TORCH_OFF". Он должен быть с
в палитре с моделью факела без амбиент анимации.
Именно его и надо расставить в локации. Иначе будет
свет от факела гореть над ним. Его ResRef "am_pls_torchoff"
Таг горящего факела = "AM_PLS_TORCH_ON" ResRef "am_pls_torchon"
Звуковой объект ставим рядом с факелом, помните его таг
ДОЛЖЕН БЫТЬ УНИКАЛЬНЫМ ВО ВСЕМ МОДУЛЕ. Иначе не
сработает. К примеру таг моего звука, равен тагу
триггера плюс порядковый номер, начиная с еденицы:
AM_SOUND_TORTCH_(порядковый номер = i). Расставляйте
на локации факела и звуки рядом.
"NEW_ResRef" Локальный стринг ResRef-а объекта, который
создаем на месте этого. Все готово!

LocalInt "AREA_TORCH_ON_OFF" - запускает на локацию.

*/

//:://////////////////////////////////////////////
//:: Created By: Aiwan
//:: Created On: 08.06.2005
//:://///////////////////////////////////////////
void main()
{
  int i=1; // Первый порядковый номер тага звука
  float f=0.5; // Задержка дестроя
  string sSound = GetTag(OBJECT_SELF); // Приравнял таг Локации к звуовому
  object oTorch = GetFirstObjectInArea(OBJECT_SELF);
  object oSound = GetObjectByTag(sSound+IntToString(i)); // Звуковой объект
  effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_20); // Свет факела
  int nEvent = GetUserDefinedEventNumber();
//======================= USERDEINE EVENT 1000 =================================
if (GetIsDay() || GetIsDawn())
//---------------------------------- ДЕНЬ --------------------------------------
  {
  while (GetIsObjectValid(oTorch))
      {
      if (GetTag(oTorch) == "AM_PLS_TORCH_ON" && !GetLocalInt(oTorch, "DO"))
        /* Проверяем все объекты на локации, берем с нужным тегом и без
            локальной переменной, что с объектом уже выключен. */

          {
          string sResRef = GetLocalString(oTorch, "NEW_ResRef");
          SetLocalInt(oTorch, "DO", TRUE);
          DestroyObject(oTorch, f);
          CreateObject(OBJECT_TYPE_PLACEABLE,sResRef, GetLocation(oTorch));
          f=f+0.2; // Сделай паузу!
          }
          if (GetIsObjectValid(oSound))
            {
            DebugObject(oSound);
            SoundObjectStop(oSound); // Выключаем звук
            i++;  // Присвоим объекту звука таг на единицу больше
            }
      oSound = GetObjectByTag(sSound+IntToString(i));
      oTorch = GetNextObjectInArea(OBJECT_SELF);
      }
    return;
  }
//======================= USERDEINE EVENT 3000 =================================
  else if (GetIsNight() || GetIsDusk())
//----------------------------- НОЧЬ -------------------------------------------
  {
  while (GetIsObjectValid(oTorch))
      {
      if (GetTag(oTorch) == "AM_PLS_TORCH_OFF" && !GetLocalInt(oTorch, "DO"))
        {
          string sResRef = GetLocalString(oTorch, "NEW_ResRef");
          SetLocalInt(oTorch, "DO", TRUE);
          DestroyObject(oTorch, f);
          object oTorchNew = CreateObject(OBJECT_TYPE_PLACEABLE,sResRef, GetLocation(oTorch));
          DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLight, oTorchNew));
          f=f+0.2; // Сделай паузу!
          }
          if (GetIsObjectValid(oSound))
            {
            DebugObject(oSound);
            SoundObjectPlay(oSound); // Включаем звук
            i++; // Присвоим объекту звука таг на единицу больше
            }
      oSound = GetObjectByTag(sSound+IntToString(i));
      oTorch = GetNextObjectInArea(OBJECT_SELF);
      }
  }
}
Elf-Drow
Знаешь, Айван, вроде вы в Проклятии сделали так, чтобы Геркан был с героем одной расы, то есть ты гном он гном, ты эльф он эльф. Но это не работает! Я играю за эльфа, но Геркан у меня гном!
-fenix-
Elf-Drow, ты баг описываешь, предполагаешь или вопрос какой есть по реалезации?

Если первые два, то это не сюда.
Lex
В скриптинге карты в принципе нет ничего сложного. (текущая версия карты для ПВ это небольшая библиотечка в ~800 строк, там ~50 функций описано).
А вот моделинг самой карты, плейсов для нее и всякие вспомогательные штуки, это скриптами не сделать.

QUOTE(Elf-Drow @ Mar 31 2006, 11:10) [snapback]75488[/snapback]
Знаешь, Айван, вроде вы в Проклятии сделали так, чтобы Геркан был с героем одной расы, то есть ты гном он гном, ты эльф он эльф. Но это не работает! Я играю за эльфа, но Геркан у меня гном!

баг.. хотя странны. А делается просто - в палитре Герканы всех расс, при старте модуля создаем нужного, согласно расе игрока. Хоть полуорка smile.gif
Lanilor
2[MoF]Darth_Nick: спасибо.
У меня еще один вопрос: как сделать, чтобы npc (хенч) уходил назад в свою область (дом) для будущего использования, как только он становится ненужным. Никак не сделать, чтобы нпс бежал на вейпоинт, находящийся в другой области? Может можно его туда телепортировать?
Lex
QUOTE(Lanilor @ Mar 31 2006, 19:17) [snapback]75560[/snapback]
Никак не сделать, чтобы нпс бежал на вейпоинт, находящийся в другой области? Может можно его туда телепортировать?

Делай темный экран на пару секунд и телепортируй. С бегатней меж локами гемороя много всякого.
отследить событие отсоединения можно в библиотеке x0_inc_henai. Строка 866.
там ниже вставь, что если хенч с тэгом таким-то, то джампается туда-то.
Не забудь билдануть скрипты потом, особено onConversation для хенчей.
JCDenton
Нафик мне факелы? :-) Мне надо спалить кучу обьектов..
в скрипте.. то как я это вижу..

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

и по новой..

а работает хз как

а тупой перебор тагов (если их разными сделать) я тоже как бы сам соображу..
суть не в скрипте а в причине его не работоспособности.. вникнуть может ктонить? просто интересно.
Lex
работает хз как, потому что написан хз как.
oFire = GetNearestObjectByTag("PLC_DRM_F01", GetNearestObjectByTag("PLC_DRM_FR", OBJECT_SELF));
это тебе все время одно и тоже давать будет: ближайший к твоей конструкции (Так как удаление не происходит мгновенно. Создание тоже не мгновенное.).
NSS
void main()
{
object oFire  = GetObjectByTag("PLC_DRM_F00");
location lLoc = GetLocation(oFire);
if (GetLocalInt(OBJECT_SELF, "Counter") == 1return;
SetLocalInt(OBJECT_SELF, "Counter", 2);
DestroyObject(oFire);
// центр, относительно которого берем ближайший объект на удаление
object oCenter = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lLoc, FALSE, "PLC_DRM_FR");
// берем следующую кучу дров
oFire = GetNearestObjectByTag("PLC_DRM_F01", oCenter);
// пока есть дрова в локации.. тут бы лучше добавить проверки дистанции.
while (GetIsObjectValid(oFire))
    {
    lLoc = GetLocation(oFire);
    DestroyObject(oFire, 0.0f);
    // новый центр поиска - костерок на месте дров
    oCenter = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lLoc, FALSE, "PLC_DRM_FR");
    // следующие дрова
    oFire  = GetNearestObjectByTag("PLC_DRM_F01", oCenter);
    }
}

Так примерно, не тестировал..

QUOTE(JCDenton @ Mar 31 2006, 19:52) [snapback]75570[/snapback]
а тупой перебор тагов (если их разными сделать) я тоже как бы сам соображу..

не заметно как-то, что сообразишь. тут самый, что ни наесть, тупой перебор.
JCDenton
Ну Куда нам нубам до мудрого Лекса... smile.gif))
Твой скрипт вешает невервинтер к чертям.. т.к. получается бесконечный цикл. Почему он там получается? потому что скрипт написан ХЗ как =)

Сеня первое апреля но я тя не прикалываю.. проверь сам =)
Кстати потому я и ввел второе условие в цикл.. чтобы не atl-ctrl-delete =)
Lex
ну раз не получилось так (все из-за того же, создание и удаление + взятие одних и тех же по несколько раз)
делаем простейшую рекурсию

lx_fire_start
NSS
void main()
{
if (GetLocalInt(OBJECT_SELF, "Counter") == 1return;
SetLocalInt(OBJECT_SELF, "Counter", 2);
object oFire  = GetObjectByTag("PLC_DRM_F00");
location lLoc = GetLocation(oFire);
CreateObject(OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lLoc, FALSE, "PLC_DRM_FR");
ExecuteScript("lx_fire_main",oFire);
DestroyObject(oFire,0.5);
}


lx_fire_main
NSS
void main()
{
SetLocalInt(OBJECT_SELF,"USED",TRUE);
location lLoc = GetLocation(OBJECT_SELF);
int i = 1;
CreateObject(OBJECT_TYPE_PLACEABLE, "plc_flamelarge", lLoc, FALSE, "PLC_DRM_FR");
object oFire = GetNearestObjectByTag("PLC_DRM_F01", OBJECT_SELF,i);
while (GetLocalInt(oFire,"USED"))
    {
    i++;
    oFire = GetNearestObjectByTag("PLC_DRM_F01", OBJECT_SELF,i);
    }
if (GetIsObjectValid(oFire))
    DelayCommand(0.4,ExecuteScript("lx_fire_main",oFire));

DestroyObject(OBJECT_SELF, 0.5f);
}


--
вместо того, чтоб панику поднимать, товарищ нуб, лучше бы подумали маленько smile.gif
А не списывали начисто у мудрого Лекса.
JCDenton
Во, терь Лекс молодец, терь работает yahoo.gif
Вопросыsmile.gif
1) Что такое рекурсия? ссылка на другой скрипт?
2) тот скрипт не работал изза того что "удаление/создание" проходят медленее чем остальная часть скрипта?



3) object GetNearestObjectByTag(string sTag, object oTarget=OBJECT_SELF, int nNth=1)

что обозначает "int nNth"?
как я понял из твоего скрипта.. Берется ближайший, потом 2-й ближайший.. 3-й и т.п. Так?
Lex
1. рекурсия это в общем когда функция вызывает саму себя. В данном случае скрипт вызывает сам себя до определенного момента.

2. скорее всего. если там расставить задержки, которые бы потихоньку росли, поменять систему поиска следующего элемента, то мб все было бы ок.

3. это номер ближайшего объекта. по умолчанию 1, те ближайший. А можно брать второй, третий и Хый по удаленности. это все описано в лексиконе.
dumbo
изначально скрипт не работал именно из-за того, что не был указан третий параметр в функции GetNearestObjectByTag. так как фактическое удаление объекта происходит после окончания работы скрипта, то циклилось все на первом объекте. рекурсии-фигурсии... crazy.gif
JCDenton
Значит в принципе операции удаления происходят после выполнения Большей части скрипта?
Короче не юзать удаление обьектов в циклах, если с них таким методом снимаем координаты.. biggrin.gif

Насчет карты в Проклятии..
Щелкаешь правой на тсурлаголе, выбераешь "рубануть". Слышешь вопли ПС "My weapon is not effect.." Ржешь.. Делаешь Alt-Ctrl-Delete. Закрываешь нвн. Заходшь аново и загружаешься с последней савы.. я такое сделал в момент прохождения половины первого мода.. а сохраняться я люблю только перед тем как вырубить камп.. :-)

Но тем не менее карта это прикол, надо только сделать, чтобы в случае закрытия диалога - он появлялся снова.
-fenix-
У меня, такой вопрос.
Можно ли восстановить хиты игроку кроме как регенерациями и EffectHeal?
В общем, есть что-то, что не пишет в панель сообщений, кто и скока хитов восстановил?
2_advanced
ForceRest()
EffectDamage crazy.gif

можно временные хиты добавлять еще..
-fenix-
QUOTE(2_advanced @ Apr 3 2006, 20:18) [snapback]76072[/snapback]
ForceRest()
EffectDamage

Иными словами - НЕТ! А жаль.
Zirrex
-fenix-, как ты себе это представляешь? Игра основана на спасбросках и т.п. вещах, и поэтому все действия, которые осуществляются с персонажем, отображаются в логах. Не совсем понимаю, зачем тебе это нужно?
2_advanced
QUOTE(-fenix- @ Apr 3 2006, 18:22) [snapback]76076[/snapback]

Иными словами - НЕТ! А жаль.
QUOTE
можно временные хиты добавлять еще..
Elf-Drow
Подмогите со скриптом, чтобы в модуль можно было играть к примеру только мужским полом...
2_advanced
а поиск на что?

О_о
Elf-Drow
Благодарствую...

Но также, знаете, не получилось заставить непися, к примеру подбегать к двери и бежать в другую локацию или просто исчезать, помогитеее...
Aiwan
Слушай, это есть в разделе новичков. Давай ка ты читай что есть. Нечего спрашивать что спрашивали сто раз.
Nashman
Привет,
Возникла идея, или лутше назвать "потребность", что бы когда ПС садился то у него с рук снимались перчатки smile.gif, с головы шлем, убирался меч и щит. А когда он вставал, ето под красивую анимацию надевалось все обратно.

ПС: Может я и написал бы, но я не сталкивался с тем, как снимать или надевать что-то...
azathoth
NSS
// Unequip oItem from whatever slot it is currently in.
void ActionUnequipItem(object oItem)

NSS
// Equip oItem into nInventorySlot.
// - nInventorySlot: INVENTORY_SLOT_*
// * No return value, but if an error occurs the log file will contain
//  "ActionEquipItem failed."
//
// Note:
//      If the creature already has an item equipped in the slot specified, it will be
//      unequipped automatically by the call to ActionEquipItem.
//
//      In order for ActionEquipItem to succeed the creature must be able to equip the
//      item oItem normally. This means that:
//      1) The item is in the creature's inventory.
//      2) The item must already be identified (if magical).
//      3) The creature has the level required to equip the item (if magical and ILR is on).
//      4) The creature possesses the required feats to equip the item (such as weapon proficiencies).
void ActionEquipItem(object oItem, int nInventorySlot)
NSS
// Get the object which is in oCreature's specified inventory slot
// - nInventorySlot: INVENTORY_SLOT_*
// - oCreature
// * Returns OBJECT_INVALID if oCreature is not a valid creature or there is no
//  item in nInventorySlot.
object GetItemInSlot(int nInventorySlot, object oCreature=OBJECT_SELF)


В скрипте, сажающим на стул добавь действия снятия вещей до того, как усаживать персонажа. Снятые вещи запомни в локальных переменных и пусти цикл, проверяющий, допустим, каждые 3 сек. сидит ли еще персонаж на стуле или нет.
Zirrex
Проверять через цикл не самая лучшая идея. Гонять циклы для всех сидящих персонажей, причем постоянно, только лишняя нагрузка на процессор. Лучше рядом посадить невидимое существо, которое будет слушать команды игрока или же составить список команд, которые можно будет запускать с быстрой панели. Например, решил он выполнить команду, сесть на стул, нажимаем на определенное действие в быстрой панели, решил встать, нажимаем другое действие. А там и соответствующие действия по раздеванию smile.gif

Кстати, интересная идея, надо поэкспериментировать. Есть что-то подобное у скриптов DMFI, но там вроде бы все команды видны в чате.
2_advanced
хертбиты у мобов на АИ работают и нормально..
процессор спалили пока только один crazy.gif
ни какая микро проверялка с АИ не сравнится

offtopic.gif
Lanilor
Привет,
У PC есть пиво "ss_pivo" (n бутылочек). Как сделать, чтобы в диалоге отдать пиво НПС. Нужно отдать заявленное количество бутылочек. И как определить, сколько бутылочек есть у PC?
Dik Morris
С помощью фун-ций:
NSS
// Sets stack size of an item.
// - oItem: item to change
// - nSize: new size of stack.  Will be restricted to be between 1 and the
//  maximum stack size for the item type.  If a value less than 1 is passed it
//  will set the stack to 1.  If a value greater than the max is passed
//  then it will set the stack to the maximum size
void SetItemStackSize(object oItem, int nSize)

NSS
// Returns stack size of an item
// - oItem: item to query
int GetItemStackSize(object oItem)

NSS
// Destroy oObject (irrevocably).
// This will not work on modules and areas.
void DestroyObject(object oDestroy, float fDelay=0.0f)

azathoth
QUOTE(Lanilor @ Apr 7 2006, 06:26) [snapback]76679[/snapback]
И как определить, сколько бутылочек есть у PC?
к примеру вот скрипт, показывающий строку в диалоге, если у персонажа игрока есть больше, чем N бутылочек:
NSS
int Match(string s1, string s2)
{
    return (s1 == s2);
}

int GetNumItemsInInventory(object oInventory = OBJECT_SELF, string sTag = "*")
{
    int nNum = 0;
    object oItem = GetFirstItemInInventory(oInventory);
    while (GetIsObjectValid(oItem))
    {
        if (Match(GetTag(oItem), sTag))
        {
            nNum += GetItemStackSize(oItem);
        }

        oItem = GetNextItemInInventory(oInventory);
    }

    return nNum;
}

int StartingConditional()
{
    return (GetNumItemsInInventory(GetPCSpeaker(), "ss_pivo") >= 3);
}
забирающий N бутылочек (тоже в диалоге):
NSS
int Match(string s1, string s2)
{
    return (s1 == s2);
}

int RemoveItemsFromInventory(object oInventory = OBJECT_SELF, string sTag = "*", int nNum = -1)
{
    int nStack;
    object oItem = GetFirstItemInInventory(oInventory);
    while (GetIsObjectValid(oItem) && (nNum != 0))
    {
        if (Match(GetTag(oItem), sTag))
        {
                if (nNum < 0) DestroyObject(oItem);
            else if ((nStack = GetItemStackSize(oItem)) > nNum)
            {
                SetItemStackSize(oItem, nStack - nNum);
                return 0;
            }
            else
            {
                DestroyObject(oItem);
                nNum -= nStack;
            }
        }

        oItem = GetNextItemInInventory(oInventory);
    }

    return nNum;
}

void main()
{
    RemoveItemsFromInventory(GetPCSpeaker(), "ss_pivo", N);
}
только не забудь залепить такую дыру в диалогах NWN: во время разговора можно положить предметы на землю, а при этом скрипт может уже постчитать, что предметы в инвентаре. Лечится легко:
-- Непись: Ну и где ж пиво-то?
---- Игрок: Вот тебе твое пиво, как заказывал, все *N* штук! (провека на наличие предметов)
------ Непись: О-о-о... давай-давай, теперь в кружку лей... (проверка на наличие предметов)
------ Непить: Ну-ну молодец, молодец. А теперь подними с пола и поставь на стол. Я сказал подними и поставь!
---- Игрок: Сейчас принесу...
Zirrex
А можно еще так:

NSS
void DestroyItem(object oOwner, string sComponent, int nNumItems)
{
    int nStackSize;

    object oItem = GetFirstItemInInventory(oOwner);

    while (GetIsObjectValid(oItem) == TRUE)
    {
        if (GetTag(oItem) == sComponent)
        {
            nStackSize = GetItemStackSize(oItem);

            if (nStackSize > nNumItems)
            {
                SetItemStackSize(oItem, nStackSize - nNumItems);
                return;
            }
            else if (nStackSize == nNumItems)
            {
                DestroyObject(oItem, 0.1);
                return;
            }
            else if (nStackSize < nNumItems)
            {
                nNumItems = nNumItems - nStackSize;
                DestroyObject(oItem, 0.1);
            }
        }
        oItem = GetNextItemInInventory(oOwner);
    }
}

void main()
{
    object oPC = GetPCSpeaker();

    string sGhead = "am_it_goblinhead";

    if (IsInInventory(oPC, sGhead))
    {
        int nFound = 0;

        object oItem = GetFirstItemInInventory(oPC);

        while (GetIsObjectValid(oItem) == TRUE)
        {
            if (GetTag(oItem) == sGhead)
            {
                nFound = nFound + GetNumStackedItems(oItem);
            }
            oItem = GetNextItemInInventory(oPC);
        }

        GiveGoldToCreature(oPC, 100 * nFound);
        DestroyItem(oPC, sGhead, nFound);
    }
    else
    {
        SpeakString("Не понял, а где же трофеи? Вы решили меня надуть?");
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectKnockdown(), oPC, 15.0f);
    }
}

Взял скрипт из своего модуля. НПС отдаются головы гоблинов. Если их нет, но игрок желает на халяву получить деньги (а проверка на деньги уже была), ставится на второе условие сей мелкий скриптик.
Aiwan
А чего в базу не кинуть код? Я вот на днях тоже писал сам, а мог бы не париться... pardon.gif
azathoth
А база закрыта =)

Lex: открыл
Zirrex
Я тогда подберу коллекцию разнообразных скриптов, которые будут полезны каждому, кто занимается разработкой модулей. Только вначале их нужно соответствующе оформить smile.gif

Lex: от это будет отлично
Lanilor
2azathoth: сенькс, очень удобный код.
2Zirrex: а зачем в DestroyObject() указан fDelay?
Zirrex
Lanilor, а, это я делал для одного скрипта своего, чтобы вначале выводилось сообщение, а потом удалялась сама вещь. Можешь задержку убрать, она не принципиальна.
Fortesso
Уважаемые мастера, очень сомневаюсь, что это возможно, но вопрос всё же задам:
Допустим PC и два хенчмена доходят до финала какой-нить локации, а дальше их, по сценарию, разбрасывает по разным локациям. Появляется какая-нить фея и говорит - "А теперь выбираем сценарий!" (помните FF6?) И после прохождения одного, сразу же переходить к прохождению второго и т.д. Короче - Отдельно за хенчей, без PC, можно играть? И как энто буит выглядеть в скриптах???
-fenix-
Люди, ни кто не сталкивался с ситуацией, когда нужно снять эффект яда?
Сам-то эффект снимается, но с каждым эффектом яда накладывается еще и эффект понижения статов, для каждого яда понижается свой стат и для каждого кидается свой кубик.
Так вот, как отличить эффект понижающий статы, который был наложен вместе с ядом, от того, который был просто когда-то наложен?
Aiwan
QUOTE(-fenix- @ Apr 11 2006, 06:12) [snapback]77271[/snapback]
Так вот, как отличить эффект понижающий статы, который был наложен вместе с ядом, от того, который был просто когда-то наложен?

Поиск эффекта от имени того, кто его наложил не выхоит?
NSS
void RemoveEffectCreator(object oCreature, object oCreator = OBJECT_SELF)
{
    effect eEffect = GetFirstEffect(oCreature);
    while(GetIsEffectValid(eEffect))
    {
    if (GetEffectCreator(eEffect) == oCreator)
      {
        RemoveEffect(oCreature, eEffect);
      }
        eEffect = GetNextEffect(oCreature);
    }
}
-fenix-
QUOTE(Aiwan @ Apr 11 2006, 10:02) [snapback]77290[/snapback]
Поиск эффекта от имени того, кто его наложил не выхоит?

Хм, ну да, можно для начало найти яд, узнать кто его наложил, снять его, а потом поискать EffectAbilityDecrease, который повесил этот же объект.

Сенькс. yes3.gif
Lex
Fortesso, я так и не понял, что тебе нужно.
gennady
-fenix-, а если просто кинуть спел лечения от яда?
NSS
void main()
{
  object oPC = GetFirstPC();
  AssignCommand(oPC,ActionCastSpellAtObject(SPELL_LESSER_RESTORATION,oPC,METAMAGIC_QUICKEN,TRUE));
}

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