Помощь - Поиск - Пользователи - Календарь
Полная версия: Вопросы новичков
Город Мастеров > РЕДАКТОРЫ > 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, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103
retriever
У меня такой вопрос.
Есть, грубо говоря, модуль. Модуль для РП, т.е. там может быть все, что угодно.
Допустим, я захотел одним НПСом напасть на другого через ДМку. Очень хорошо, два НПСа дерутся. Что происходит потом?
Если два нпса имели одну фракцию, то атакуемый будет стоять смирно, и ждать, пока его убьют. А вот если они имели разные фракции, то почему-то иногда начинается "гражданская война".

Все неписи фракции 1 начинают нападать на всех неписей фракции 2, полисмен бьет проститутку, негр-рабочий насилует повара кувалдой и т.п. У меня такое подозрение, что при атаке одной фракцией на другую происходит смена отношений между ними, и они, скажем, из нейтральных становятся враждебными. Есть какие-то способы это прекратить? То есть чтобы дрались только выбранные мною НПС а остальные стояли бы и смотрели?

З.Ы. Модуль использует хаки д20 модерн+СЕР2.4.

Melisse
Фракции вообще настроить правильно надо, насколько я помню в стандартных фракциях Защитник защищает Простолюдинов и Торговцев, т.е. там 100 единиц стоит (это типа дружба и при нападении защита), если 50 единиц - то до фени между фракциями.
При редактировании фракций там есть такая галочка Глобальный эффект, если навредить одному из нпс то все сразу становятся врагами, независимо от того видели или нет.
Можно еще таблицу 2да подредактировать и убрать понижение репутации при ударе/смерти и тех кто видел, слышал и тд. потом в овверрайд ее или хаком подрубить к модулю.

П.С. Милые собачки.
retriever
Возникла еще такая проблема: играем с друганом в модуль, через ДМ-аккаунты. Бои тока по роллу (без механики, как в настолке). Для смены музыки на боевую используем Slyn's Music changer. Так вот, работает этот мюзик чейнджер криво: если залезть дмом в нпс-а, поставить батл музыку, затем вылезти и вселиться в еще кого-нибудь, то музыка снова становится обычной. Если музон поставить за дм-а, то вроде бы вообще музыка слетит при вселении в кого-либо.

Код, вызывающий смену музыки, выглядит так:
Код
void main()
{
    object oPC = GetPCSpeaker();
    object oArea = GetArea(oPC);

    MusicBattlePlay(oArea);
}

Т.е. это тупо стандартная функция нвна, как я понимаю. Я пробовал вставлять эти скрипты в диалоги DMFI, но все так же музон слетает при выселении из непися и вселения еще в кого-то. Возможно, дмфи-шные скрипты тоже не без греха (и в них что-то тоже откатывается), но в общем и целом у меня складывается впечатление, что это баг самой функции MusicBattlePlay(oArea).

Вопросы:
1) Есть ли какое-то решение для этой проблемы (чтобы батл музыка играла всегда, вне зависимости от действий ДМ-а)
2) Как сделать "говорящий" предмет (т.е. такой предмет, при использовании которого вылезал бы диалог)? Меня интересует конкретно процесс привязки предмета к скриптам и диалогам.

Flaristan
Это, видимо, особенность движка НВН - играть надо игроками, а не ДМами. smile.gif
1) Поставь вот так:..
Neverwinter Script
void main()
{
object oPC = GetPCChatSpeaker();
object oArea = GetArea(oPC);

if (GetPCChatMessage()=="fight")
MusicBattlePlay(oArea);
}
Вот сюда:..

...тогда музыка будет меняться на музыку боя когда кто-нибудь напишет в чате fight (или любое другое слово/комбинацию слов, которая будет определена в скрипте).
Кстати, таким же образом можно назначить кучу полезных заскриптованных действий на команды чата, раз уж вам нужны таковые - их удобно в случае частого употребления выносить на панели быстрых слотов в качестве "Макро Команд" и вызывать одним нажатием кнопки.

2) Поставь вот так:..
Neverwinter Script
void main()
{
object oItem = GetItemActivated();

if (GetTag(oItem)=="tag_of_item")
  {
  object oPC = GetItemActivator();

  AssignCommand(oPC, ActionStartConversation(oPC, "dialog_resref", FALSE, FALSE));
  }
}
Вот сюда:..

Потом сделай так:..

+

+

...и да прибудет с тобой сила! smile.gif
Taniati
Подскажите пожалуйста, если есть кто живые, почему могут не отображаться в игре визульные эффекты, звук идет, а вот самого эффекта нет sad.gif
Flaristan
Дай угадаю – речь идет про эффект «EffectBeam»? smile.gif
Melisse
Варианты почему могут быть проблемы в игре:
1. Проблема видеокарты ATI
1.1 Проблема драйверов.
2. Проблемы "нового железа" и "новых ОС", комбинация этих проблем. Игра без проблем идет только на ХП и Висте
3. Урезанная (пиратская) версия nwn. Хотя такое вообще сложно представить сейчас.
Flaristan
Если речь идет про модульмейкинг и неудавшееся скриптование эффектов при котором есть звук эффекта, но нету визуализации, то:
1. Эффект может не визуализироваться, если была применена функция не подходящая выбранному типу эффекта (например если эффект может быть наложен только на объект, а в скрипте его накладывают на локацию и наоборот).
2. Конкретно эффекты типа «EffectBeam» в НВНе несколько багнуты и если их накладывать не «инстантно», а «временно» или «перманентно» - анимация пропадает и остается только звук (если речь про них – могу поделиться своими логическими «заплатками» для таковых в режимах «временно» и «перманентно» smile.gif).
warringlamer
Так как "Абсолютные глупости", то вопрос следующий
Как и откуда добавить в палитру, для последующего редактирования и использования, различные предметы которых в ней нет, а в игре присутствуют ?
Например доспех Арибет или говорящий меч Энсерика
Flaristan
1. Заходим в папку с НВН и находим в ней папку NWM (если нас интересуют модули компании – иначе пропускаем этот шаг и шаг «2», сразу переходя к шагу «3», в котором открываем в тулсете интересующий нас модуль).
2. Копируем из нее в папку MODULES скажем 1 эпизод компании Chapter1.nwm, но переименовываем его при этом в Chapter1.mod.
3. Открываем тулсетом Chapter1 (или тот модуль который нас интересует).
4. Ищем область в которой должен находиться интересующий нас объект (Арибет к примеру стоит в 1 эпизоде в «Центр города: Здание суда»).
5. Ищем сам интересующий нас предмет (у Арибет нет никакого доспеха – облом biggrin.gif; да и вообще все оригинальные предметы в компаниях добавлены в основную или настраиваемую палитру и можно найти их там по категории и названию – вещи героев идут категорией «Предметы созданий»). В крайнем случае нам поможет опция меню «Редактировать -> Найти экземпляр» ищущая объекты в модуле по тагу (если мы нашли его в инвентаре, например, и не можем отредактировать там же, правда если предмет есть в инвентаре у кого-то, то он обязательно должен быть где-то в палитре).
6. Выделяем интересующий нас предмет (где бы он ни был) и кликаем по предмету правой кнопкой мыши – выбираем пункт «Добавить к Палитре» (если нашли предмет там где этого сделать нельзя – продолжаем искать его там, где это сделать можно, или размещаем/копипастим его любым способом на полу в локации, при этом его точно можно добавить к палитре). При добавлении в палитру указываем предмету новый уникальный резреф в соответствующем поле (ResRef) и жмем «ok» (с новым резрефом проще будет избежать путаницы и обломов при поиске).
7. В меню тулсета жмем «Файл -> Экспорт…» + «Добавить Ресурсы…» + «Тип ресурса: Чертеж для Предметов» (если это предмет). Ищем наш резреф в списке и жмем «Экспорт». Видим его в списке экспортируемых ресурсов – жмем «ok». Вводим имя файла экспорта и жмем «Сохранить» (по умолчанию все файлы экспорта отправляются/берутся в папке игры под именем ERF).
8. Открываем в тулсете модуль, в который мы бы хотели перенести этот предмет.
9. В меню тулсета жмем «Файл -> Импорт…» + выбираем имя нашего файла экспорта и жмем «Открыть». Читаем комментарии файла (если они есть) и жмем «ok».
10. Теперь в этом модуле есть этот предмет (в том же месте в палитре в каком он был там, откуда мы его экспортировали). smile.gif

P.S.: Вещи вроде Энсерика - это не единичный итем, а комплекс ресурсов (скриптов как минимум иногда еще диалогов и т.д.); соответственно переносить их при необходимости придется так же комплексно.
Melisse
Цитата
Ищем сам интересующий нас предмет (у Арибет нет никакого доспеха – облом; да и вообще все оригинальные предметы в компаниях добавлены в основную или настраиваемую палитру и можно найти их там по категории и названию – вещи героев идут категорией «Предметы созданий»).

Вообще он есть просто недоступен обычному пользователю, но люди не долго думая вскрыли бифы (файлы игры) и вытащили его. Правда использовать его можно лишь хак-паком. Взять на ваулте
В бифах очень много скрытых от тулсета видов брони, даже некоторые плэйсеблы.
Flaristan
Арибет, насколько я знаю, в тулсете юзается аппеаренсом (моделька доспеха накладывается на объект только вместе с моделькой самой Арибет). Понадергать модельки конечно из игры в хаки можно какие угодно – не раз видел новые модели сделанные из стандартных путем передела или доработки. wacko.gif
Про модели плейсеблов знаю, что в 1.69 версии не все новые модели есть в палитре в виде готовых объектов – полный список всех моделек можно просмотреть, если открыть свойство объекта и полистать список доступных ему моделей в соответствующем окошке напрямую.
Так же дело обстоит и с визуальными эффектами – в игре их, если правильно помню, чуть более полутысячи; и просмотреть все можно, последовательно накладывая их не по string названию, а по int порядковому номеру эффекта.
Melisse
Цитата
Арибет, насколько я знаю, в тулсете юзается аппеаренсом (моделька доспеха накладывается на объект только вместе с моделькой самой Арибет). Понадергать модельки конечно из игры в хаки можно какие угодно – не раз видел новые модели сделанные из стандартных путем передела или доработки.

Та просто их не стали делать доступными для игроков. Лень под все фенотипы делать. По сути создавать шкурки для моделей обратный вариант проделанной работы с доспехами арибет. Разнообразные виды мобов на ваулте делали из частей и в том числе - брони. Так что тут собственно ничего такого.
Да там много всяких еще - например одежда главы милиции (в русском переводе) в райне полуострова, она представлена женской только вариацией, но на ваулте так же лежит для ПС, ну и много из 1.69 есть так же.
Собственно, броня то состоит из частей, их только отдельно сохранить в максе надо из шкурки и прописать в 2да и всего-то делов.
Aiwan
Интересно, автор вопроса еще раз в тему зайдет? smile.gif
warringlamer
Цитата(Aiwan @ Dec 11 2013, 09:35) *
Интересно, автор вопроса еще раз в тему зайдет? smile.gif


Если Вы про меня, то зашел.
Всем спасибо.
Heather
Всем доброго времени суток. Я опять со своими глупостями.
Делаю Арену (да-да, банально, но что же поделать? pardon.gif ). Суть такова: убиваем 3- противников, идет затемнение и на их месте появляются новые 3 противника. Я вроде как понимаю, что надо на этих мобов вешать на OnDeath что-то вроде, "переменная+1" и делать if then, но никак не могу все это скомпоновать в своей голове в четкий скрипт. К тому же, может быть я усложняю и все можно сделать проще?
Надеюсь, что кто-нибудь подскажет, как все это сделать или хотя бы даст направление.
Flaristan
Ну да – так и сделай, об чем там вопросы?
При «ОнДэф» скрипт считывает переменную скажем с локации и увиличивает ее на +1; затем смотрит получившееся значение и если оно = 3, то скидывает его в «0» и спавнит 3 противников в заданных точках:..
Neverwinter Script
void main()
{
int iInt = GetLocalInt(GetArea(OBJECT_SELF), "3DEATH");
location lTarget;
object oSpawn;

if (iInt < 3)
  {
  iInt++;
  SetLocalInt(GetArea(OBJECT_SELF), "3DEATH", iInt);
  }
if (iInt == 3)
  {
  SetLocalInt(GetArea(OBJECT_SELF), "3DEATH", FALSE);
  lTarget = GetLocation(GetWaypointByTag("tag_of_spawn_waypoint_1"));
  oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "resref_of_creature_1", lTarget);
  lTarget = GetLocation(GetWaypointByTag("tag_of_spawn_waypoint_2"));
  oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "resref_of_creature_2", lTarget);
  lTarget = GetLocation(GetWaypointByTag("tag_of_spawn_waypoint_3"));
  oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "resref_of_creature_3", lTarget);
  }
}
retriever
Добрый день.
Как и в старые добрые времена, иногда играю в РП-модуль НВН. Использую хакпаки d20 modern и CEP 2.4.
СЕР 2.3 был совместим с д20 модерном, СЕР 2.4 - частично накладывается.
Решил изготовить хакпак (а точнее- пока что набор отдельных хакпаков), в которых выносится часть "пересекающегося" материала.
Среди всего материала есть головы (heads).

Вопрос: какой .2da файл отвечает за головы? К примеру, в хакпаке mdrn20_head.hak нету .2da вообще - только модели и текстуры.
Откуда он тогда берется? Или его совсем нет, что ли?
Melisse
Я думаю, его нет. Во всяком случае я не встречала.
Модели просто идут по счету. Если те, что в бифах имеют одинаковый номер с теми что в хаках -происходит овверайд модели в пользу последних и клиент видит модели из хаков.

Для редактирования PLT текстур тебе надо поставить gimp. Это бесплатная рисовальная программа, к ней есть плагин на новом ваулте. Думаю там разберешься.
Heather
Уважаемые мастера! Объясните мне, пожалуйста, если не трудно, как делаются глобальные переменные? На форуме нашла лишь то, что "глобальные переменные лучше не использовать". =)
Мне хотелось бы, что бы игра запомнила пару выборов, кот. мы сделали в первой главе, и в 3-ей главе в этом же городе мы бы увидели последствия нашего выбора. (Банально - помогли мужику, в 3-ей части он нас благодарит и рассказывает как хорошо живет, а не помогли, то дохлый в канаве валяется).
Единственное, что выбор переносится не в следующий модуль, а через несколько модулей. (хотя если это вообще возможно, то можно в каждом модуле раз за разом проверять их).
Через предметы проверять нет возможности, по-крайней мере, в некоторых случаях.

Как всегда заранее благодарю за ответ и опять же, заранее извиняюсь, если это обсуждалось где-то и не раз.
NumberOne
Ребят... что за ересь? У меня НПС не удаляются с помощью DestroyObject diablo.gif


Скрипт

Код
#include "nw_i0_2q4luskan"

void main()
{
object oPC = GetEnteringObject();
object oOrt = GetObjectByTag("ortai1");
object oTr1 = GetObjectByTag("tr1");
object oTr2 = GetObjectByTag("tr2");
object oTr3 = GetObjectByTag("tr3");
object oTarget = GetWaypointByTag("wp_spawn_ort");
object oCoster = GetWaypointByTag("wp_koster");

location lTarget = GetLocation(oTarget);
location lCoster = GetLocation(oCoster);

if (!GetIsPC(oPC)) return;
    {
     DestroyObject(oOrt);
     CreateObjectVoid(OBJECT_TYPE_CREATURE, "creature", lTarget);
     CreateObject(OBJECT_TYPE_PLACEABLE, "koster_lager", lCoster);
     DelayCommand(1.0, DestroyObject(oTr1));
     DelayCommand(1.0, DestroyObject(oTr3));
     DelayCommand(1.0, DestroyObject(oTr2));
    }
}
Melisse
if (!GetIsPC(oPC)) return;
тут у тебя возвращает остальное не идет
NumberOne
Все остальное как раз идет нормально, кроме DestroyObject...
denis0k
Недостаточно данных. Пробуй сам, к примеру, проверять валидность или выводить имя после каждого GetObject, мб объекты не цепляет. Фигурные скобки кстати не нужны в скрипте вообще, мб это выносит мозг компилятору. А "if (!GetIsPC(oPC)) return;" стоит поставить первой строкой.
NumberOne
Учту, благодарю все за ответы.
Melisse
Есть еще момент, проверь:
1. Если ты тэги созданий пишешь верхним регистром в них, а в скрипте нижним - то это разные тэги.
2. Попробуй поставить AssignCommand(oTr1, SetDestroyable (TRUE, FALSE, FALSE)); А потом удалять через DestroyObject(oTr1);
3. DelayCommand(1.0, DestroyObject(oTr1)); Лучше не использовать так, оно так может потеряться по ряду причин. Попробуй DestroyObject(oTr1, 1.0f); или если делаешь вешай на модуль через AssignCommand(GetModule(), DelayCommand(1.0, DestroyObject(oTr1)));
NumberOne
Нужна помощь. Цель такая: я использую набор целителя на существе с уникальным тегом и запускается скрипт. У кого есть какие идеи?

Пытался написать скрипт в слот модуля на OnActivateItem

Код
void main()
{
object oTarget = GetItemActivatedTarget();
object oItem = GetItemActivated();

string sTagItem = GetTag(oItem);
string sTagTarget = GetTag(oTarget);

if (sTagItem == "NW_IT_MEDKIT001")
    {
     if (sTagTarget == "wolfica")
        {
         Действия
        }
    }
}


Но он не работает(
Fimko
Фунецией GetItemActivated() вызывается только свойством Cast Spell: Unique Power. (или Unique Power SelfOnly). Могу посоветовать скриптом менять свойство Healer's Kit на свойство уникальной силы. Только для этого надо будет в itemprops.2da "открыть" доступ к свойству "Cast Spell" для данного типа вещей. Гемор короче smile.gif

Второй способ - теоретический - сам не пробовал. Попробовать отловить использования хилер кита через SignalEvent и EventSpellCastAt. По идеи должно получится, так как свойство Healer's Kit находится в spells.2da и по сути является спеллом.
greye
Цитата(Fimko @ Feb 26 2015, 16:56) *
Второй способ - теоретический - сам не пробовал. Попробовать отловить использования хилер кита через SignalEvent и EventSpellCastAt. По идеи должно получится, так как свойство Healer's Kit находится в spells.2da и по сути является спеллом.

Не помню, занимался ли аптечками, но зелья через спеллхук отлавливать можно совершенно точно.
NumberOne
Fimko, благодарю тебя! Твой пост навел меня на замечательную мысль, за счет которой я добился нужного результата.

Цитата(NumberOne @ Feb 26 2015, 18:12) *
Не помню, занимался ли аптечками, но зелья через спеллхук отлавливать можно совершенно точно.


И про зелья теперь учту, глядишь пригодится...
denis0k
Аптечка в 2да вроде как есть, но все поля там - "****", это больше похоже на свойство-заглушку для тулсета. Они вообще вне механики, например, ими можно хилиться по нескольку раз в раунд или в минусах. Собсно поэтому на шардах их часто выпиливают.
StasMokos
Приветствую!
Не подскажете, можно ли сделать так, чтобы нельзя было исключить хенча из группы?

Через секунду ответ нашелся сам, уже не надо, прошу прощения.
Heather
StasMokos, а можно мне решение? Тоже интересно, и думаю, что может пригодиться.
Aztec2012
Доброго времени суток!

Известно что после установки дополнения Hordes of the Underdark в тулсете появляется опция по установке времени исчезновения трупов существ. Значение по умолчанию 5 секунд.

Через NWN Explorer решил покопаться в 2da файлах игры и найти это значение и поставить своё, но не могу найти файл который отвечает за это. Есть всё (существа, классы, расы, заклинания т .п.) кроме этого.

Прошу знающих подсказать в каком файле искать этот параметр. Заранее спасибо.
greye
Цитата(Aztec2012 @ May 12 2015, 14:24) *
Доброго времени суток!

Известно что после установки дополнения Hordes of the Underdark в тулсете появляется опция по установке времени исчезновения трупов существ. Значение по умолчанию 5 секунд.

Через NWN Explorer решил покопаться в 2da файлах игры и найти это значение и поставить своё, но не могу найти файл который отвечает за это. Есть всё (существа, классы, расы, заклинания т .п.) кроме этого.

Прошу знающих подсказать в каком файле искать этот параметр. Заранее спасибо.

В 2да этого нет, насколько мне известно. Для каждого существа время определяется записью DecayTime в соответствующем GFF файле.
Aztec2012
Цитата
В 2да этого нет, насколько мне известно. Для каждого существа время определяется записью DecayTime в соответствующем GFF файле.


Спасибо за ответ. Так а GFF файлы где?

Нашёл utc файлы существ в них есть DecayTime, но он есть только у существ из второго аддона. У существ из первого аддона и основой игры такого пункта нет. Хотя в тулсете он есть у всех.
Flaristan
Цитата(Aztec2012 @ May 12 2015, 12:24) *
Значение по умолчанию 5 секунд.
Гхм.
Melisse
Так смени значение на другое. Если тебе нужно чтобы труп не исчезал, нужно сделать скриптами тело не удаляемое. SetDestroyable (FALSE, FALSE , FALSE);
Aztec2012
Цитата
Так смени значение на другое. Если тебе нужно чтобы труп не исчезал, нужно сделать скриптами тело не удаляемое. SetDestroyable (FALSE, FALSE , FALSE);


Спасибо. Но мне нужно чтобы это значение распространилось на все существа всех модулей игры, а в ручную каждое редактировать довольно долго. А скрипт врядли будет работать с теми существа у которых не стандартный скрипт смерти, типа Маугрима или Мораг.
ud4ever
Прошу помочь со скриптом проверки наличия игрока враждебной фракции в локации. Необходимо для того, чтобы добавить эту проверку в скрипт при активации телепорта.

Melisse
Neverwinter Script
//Смотря как у тебя активируется телепорт - игрок, активирующий, будет определятся для диалога через функцию = GetPCSpeaker();
//или если на юз = GetObjectLastUsedBy();
object oPC =  // Игрок тут выбрать того как определяется игрок, активирующий телепорт

object oNearestPCEnemy = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oPC, 1, CREATURE_TYPE_REPUTATION,  REPUTATION_TYPE_ENEMY);

if (GetIsObjectValid (oNearestPCEnemy)) // проверка наличия. Сюда можно еще проверку расстояния вставить
{

// Тут то что тебе нужно

}


О функции GetNearestCreature можно почитать тут
ud4ever
Спасибо за подробный ответ)
Flaristan
Цитата(Melisse @ May 19 2015, 13:11) *
Neverwinter Script
object oNearestPCEnemy = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oPC, 1, CREATURE_TYPE_REPUTATION,  REPUTATION_TYPE_ENEMY);

if (GetIsObjectValid (oNearestPCEnemy)) // проверка наличия. Сюда можно еще проверку расстояния вставить
{
}
И вот тут мы сразу ловим баг, который делает нашу проверку всегда TRUE, если в модуле присутствует хотя бы 1 враждебный игрок. biggrin.gif
На сколько я успел наобщаться со скриптами НВН, если мне не изменяет сей опыт - GetNearestCreature вполне успешно считает расстояние между объектами в разных локациях и оно равно -1. И в этом случае GetIsObjectValid будет совершенно валиден, если он будет где-то (не важно где) в модуле, а исходная задача была сделать проверку по конкретной локации.
Итого, чтоб это было без подобного бага - сделать нужно вот так:..
Neverwinter Script
object oPC = GetObjectLastUsedByGetLastUsedBy(); //к примеру для варианта на OnUse

object oNearestPCEnemy = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oPC, 1, CREATURE_TYPE_REPUTATION,  REPUTATION_TYPE_ENEMY);

if ((GetIsObjectValid (oNearestPCEnemy))
    &&(GetArea(oPC)== GetArea(oNearestPCEnemy))) //приклеиваем чудную проверочку, что наш oNearestPCEnemy находится в той же локации, что и oPC
    {
    //тыры-пыры
    }
...Вот так будет работать без сбоев. rolleyes.gif
ud4ever
Цитата(Flaristan @ May 20 2015, 06:04) *
И вот тут мы сразу ловим баг, который делает нашу проверку всегда TRUE, если в модуле присутствует хотя бы 1 враждебный игрок. biggrin.gif
На сколько я успел наобщаться со скриптами НВН, если мне не изменяет сей опыт - GetNearestCreature вполне успешно считает расстояние между объектами в разных локациях и оно равно -1. И в этом случае GetIsObjectValid будет совершенно валиден, если он будет где-то (не важно где) в модуле, а исходная задача была сделать проверку по конкретной локации.
Итого, чтоб это было без подобного бага - сделать нужно вот так:..
Neverwinter Script
object oPC =  = GetObjectLastUsedBy(); //к примеру для варианта на OnUse

object oNearestPCEnemy = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oPC, 1, CREATURE_TYPE_REPUTATION,  REPUTATION_TYPE_ENEMY);

if ((GetIsObjectValid (oNearestPCEnemy))
    &&(GetArea(oPC)== GetArea(oNearestPCEnemy))) //приклеиваем чудную проверочку, что наш oNearestPCEnemy находится в той же локации, что и oPC
    {
    //тыры-пыры
    }
...Вот так будет работать без сбоев. rolleyes.gif


Спасибо за дополнение) скорее всего оно сэкономило ощутимый отрезок времени)
Melisse
Цитата
И вот тут мы сразу ловим баг, который делает нашу проверку всегда TRUE, если в модуле присутствует хотя бы 1 враждебный игрок.

Вообще-то приставка Nearest говорит о поиске по списку объектов в локации, а не в модуле в целом. Чтобы объекты искались в модуле используется, для игроков - GetFirstPC() с GetNextPC(), в цикле while, а для других объектов по тегу - GetObjectByTag().

Вот тут я ведь не просто так дала ссылку на lexicon, чтобы человек почитал
Цитата
О функции GetNearestCreature можно почитать тут


Цитата
На сколько я успел наобщаться со скриптами НВН, если мне не изменяет сей опыт - GetNearestCreature вполне успешно считает расстояние между объектами в разных локациях и оно равно -1.

Изменяет. GetNearestCreature не считывает расстояние, он просто берет самый близкий к субъекту объект в локации из которой его запускают.
Расстояние считывает GetDistanceToObject() и вот именно у него в описании сказано что
Цитата
Note that it of course can be invalid (-1.0) if they are in different areas, one object is not something that has a distance (Area's, module's), although items probably return the distance to the person that possess it (if it is possessed by a creature).

Поэтому когда мы после поиска по функции GetNearestCreature() делаем проверку через if (GetIsObjecValid()) то при возвращении TRUE это утверждает что объект находиться в одной локации с тем, от которого происходит поиск.
Flaristan
Цитата(Melisse @ May 20 2015, 13:29) *
Вообще-то приставка Nearest говорит о поиске по списку объектов в локации, а не в модуле в целом.
Вот тут я ведь не просто так дала ссылку на lexicon, чтобы человек почитал
Вообще-то не говорит. Во всяком случае как раз в лексиконе нигде не упоминается, что поиск происходит в пределах одной локации.
Цитата(Melisse @ May 20 2015, 13:29) *
GetNearestCreature не считывает расстояние, он просто берет самый близкий к субъекту объект в локации из которой его запускают.
Считает расстояние не в смысле как GetDistanceToObject - в метрах, а в значениях (и не в локации, в которой его запускают, а в локации, в которой находится указанный объект, по умолчанию объект запускающий скрипт).
Цитата(Melisse @ May 20 2015, 13:29) *
Поэтому когда мы после поиска по функции GetNearestCreature() делаем проверку через if (GetIsObjecValid()) то при возвращении TRUE это утверждает что объект находиться в одной локации с тем, от которого происходит поиск.
Ну - это хорошо тогда (не -1 значит считает а OBJECT_INVALID, наверное это 0), спс - буду знать, но все равно кашу маслом не испортишь, а то знаем мы эти скрипты...
Цитата(Melisse @ May 19 2015, 13:11) *
Neverwinter Script
//Смотря как у тебя активируется телепорт - игрок, активирующий, будет определятся для диалога через функцию = GetPCSpeaker();
//или если на юз = GetObjectLastUsedBy();
А еще нет такой функции "GetObjectLastUsedBy" - есть только "GetLastUsedBy". biggrin.gif
denis0k
Цитата
Вообще-то не говорит. Во всяком случае как раз в лексиконе нигде не упоминается, что поиск происходит в пределах одной локации.
Потому что этот поиск за пределами локации абсолютно бессмысленен. Во-первых, чисто логически. Во-вторых, например, потому, что эта функция возвращает энный объект, а за пределами локации сортировка невозможна, т.к. внутренние координаты разных локаций связать нельзя никак. Биовари, конечно, славятся своими кривыми руками, но не настолько же smile.gif
Flaristan
Цитата(denis0k @ May 20 2015, 20:04) *
Потому что этот поиск за пределами локации абсолютно бессмысленен. Во-первых, чисто логически. Во-вторых, например, потому, что эта функция возвращает энный объект, а за пределами локации сортировка невозможна, т.к. внутренние координаты разных локаций связать нельзя никак. Биовари, конечно, славятся своими кривыми руками, но не настолько же smile.gif
Ну почему же - он был бы очень полезен для динамического АИ неписей. Ну например задать алгоритм его перемещения по модулю...

Ну например создаем локацию/ии леса и размещаем в них грибочки, которые можно собирать; рядом делаем деревню и размещаем в ней непися девочку, которая каждый день в определенное время начинает двигаться к ближайшему грибочку, дабы их собрать в лукошко и принести домой; тут нам понадобится искать ближайший грибочек и разумеется он не будет в одной локации с девочкой, а чтоб АИ было пластичным (ну например грибочки у нас тоже не деревянные, а имеют скрипт эмуляции роста и могут появиться в определенные дни годичных сезонов в произвольной локации с тайлом леса в произвольной точке), нужно чтоб поиск производился не по установленному списку локаций, а по всему модулю.
Внутренние координаты локаций связать можно - тут главное просто задать логику связки. Ну например перед измерением расстояния - проложить маршрут от НПС к требуемому объекту: делаем цикл, прокладываем от НПС маршрут к ближайшему триггеру перехода, отмечаем стартовую локацию и вычеркиваем ее из списка локаций модуля, далее повторяем операцию с нахождением ближайшего триггера и вычеркиванием локации (чтоб не прокладывать маршрут через 1 локацию дважды), повторяем, пока не кончатся не вычеркнутые локации модуля или пока мы не обнаруживаем в локаци с проверяемым триггером целевой объект, в случае последнего - суммируем расстояния от НПС до триггира, от триггеров до триггеров, от триггера до целевого объекта, получаем расстояние до ближайшего объекта в модуле, прогоняем цикл для следующего триггера в стартовой локации и далее для каждого триггера в каждой следующей локации маршрута, пока не находим кратчайший маршрут... ППЦки громоздко, но теоретически вполне возможно. ph34r.gif
denis0k
Ну грибочки через GetNearestCreature ты всё равно не найдёшь smile.gif

Но если это просто грубый пример, то возможности нвскрипта всё равно не позволят сделать такой поиск пути адекватным. Даже в сингле можно было заставить ИИ тупить, если для прохода в соседнюю комнату персонажу приходилось делать крюк через пол-локации. Поиск пути автоматически проваливался, и персонаж утыкался носом в стену.

Единственный работающий вариант, который я нашёл, - натыкать везде вейпоинтов, связать их локалками (а-ля podbot для cs) и ходить по ним, привязывая к ним все прочие объекты. Нужен гриб? Ищем ближайшие к грибу и неписю вейпоинты и прокладываем кратчайший путь по какому-нить A* или Дейкстре. Правда на вложенных циклах нвскрипт стопудово вылетит в тми, поэтому часть логики придётся вынести наружу, я считал это в mysql, очень удобно - сразу и кэшировать можно. Со временем при неизменных вейпоинтах база данных наполняется маршрутами, и даже считать не надо.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Invision Power Board © 2001-2024 Invision Power Services, Inc.