![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#76
|
|||
Level 3 ![]() Класс: Паладин Характер: Chaotic Evil Раса: Человек ![]() |
Нет проблем. Итак, вот он, скрипт:
Спасибо, Aiwan. Этот скрипт и вправду лучше - не загружает систему и более обширней в применении. Ставить на OnHeartbeat локации или триггера. ЗЫ: Сорри за опечатки |
||
![]()
Сообщение
#77
|
|||||||
Level 9 ![]() Класс: Вор Характер: True Neutral Раса: Эльф NWN: Скриптинг [PW] ![]() |
альтернатива стандартному отдыху с возможностью ставить свою анимацию, выставлять время реста, проверки до/после/во время реста и т.п.
в модульный onEnter:
Добавлено в 15:18 позволяет получать разницу во времени между действиями..
Сообщение отредактировал 2_advanced - Aug 30 2005, 15:24 |
||||||
![]()
Сообщение
#78
|
|||
Миловидный Бегрюссунг ![]() Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
Скрипт запрещает классы в модуле. Годится для сингла. Для шардов надо придумать как описать РС. Ставится это добро на OnPlayerLevelUp модуля.
|
||
![]()
Сообщение
#79
|
|||
Level 9 ![]() Класс: Вор Характер: True Neutral Раса: Эльф NWN: Скриптинг [PW] ![]() |
скрипт, усаживающий на стулья и т.п., не запарывает стул после выхода сидящего из игры (хоть это и древняя недоработанная бетка, однако работает) зы. необходим неразрушимый невидимый объект sittingsurface
для доработки: выкидывать игрока с *объекта посадки* при уничтожении стула, профиксить баг с высотой посадки для разных расс (было такое на 1.29 о_О), сделать возможным усаживаться нескольким персонажам на 1 большой объект (диван =)) с автораспределением свободных сидячих мест.
<сделаю позже :swoon: > |
||
![]()
Сообщение
#80
|
|||
Миловидный Бегрюссунг ![]() Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
Скрипт вешается на строку диалога НПС. Если он загородил нам проход, просим отойти в сторону. Очень актуально для сингла. Когда НПС стоит поперек выхода и нет сил его обойти...
|
||
![]()
Сообщение
#81
|
|||||
Миловидный Бегрюссунг ![]() Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
Скрипт активирует на локации енкаучеры ночные и дневные. Соответсвенно одни выключает, другие включает. Все работает как часы и оптимизировано Лексом. За шо ему гранд респект. :good:
Добавлено в [mergetime]1131452068[/mergetime] А, забыл! :scratch: Первый на хертбит арены. Второй на юзерДеф ей же. |
||||
![]()
Сообщение
#82
|
|||||||||||
Миловидный Бегрюссунг ![]() Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
Выкладываю скрипт+заготовку ERF триггера, что бы вы не мучались с настройкой. Давно я использую на триггерах три своих темповых скрипта, для присвоения каких-нибудь локалок на игрока, для проверки того или иного диалога, строки, действия и прочее. Очень меня задолбало это. Писать каждый раз новый скрипт и я написал триггер для теста. Что он делает? Он присваивает до 5 уникальных локалок на игрока и НПС, может отправить НПС в точку которую вы укажите. Например, НПС в другой локе, вы наступили на триггер, он спавнился рядом и повесили на него три локалки, повесили на РС две локалки и можно быть в середине вашего сюжета. Еще он (скрипт) может запускать другие скрипты на НПС, РС и OBJECT_SEL, соответсвенно. Как он настраивается: DEACTIVATED == 1 отключает триггер после первого раза. Например, вы насупили раз, прошли одну ветку диалога. Подошли, наступили второй, прошли заново диалог и т.д. Надо? Ставьте 0 и будет бесконечно приваивать ваши локалки. LOCAL_NPC_01 - Присваивает переменную на НПС. Пример: ПЕРЕМЕННАЯ_01
LOCAL_PC_01 - Присваивает переменную на PС. Пример: ПЕРЕМЕННАЯ_01
RUN_SCRIPT - ИМЯ_СКРИПТА - запускает на OBJECT_SELF
RUN_SCRIPT_ON_NPC - ИМЯ_СКРИПТА - запускает на oNpc
На игрока понятное дело так же. TAG_NPC - Таг нашего НПС. TAG_WP_TO_JUMP - ТАГ нашего вейпоинта. НПС прыгнет на него, если только вы укажете ТАГ точки. Ну вот и все. Все локалки работают до пяти штук на РС и НПС.
|
||||||||||
![]()
Сообщение
#83
|
|||||||
Level 19 ![]() Класс: Воин Характер: Lawful Good Раса: Человек NWN: Скриптинг [Sn] ![]() |
Вот тут решил написать скрипты, которые может кому, пригодятся, но лично мне они пока не нужны. Зачем написал? Просто так. :crazy: Что эти скрипты делают? Они дают процент экспы за убийство/разрушение объекта равное проценту нанесенного ущерба. Пример: Есть бочка, у нее 10 хитов. За разрушение назначено 100 опыта. Если вы снимите 100% хитов(10), то получите 100% опыта(100). Если вы снимете 50% хитов(5), то получите 50% опыта(50). Остальной опыт либо пропадет (если кроме вас объект лупили только НПС), либо поделится между другими ПС лупившими объект, либо поделится между всеми ПС и часть пропадет, от лупивших НПС. ХМ, надеюсь, идея ясна. Приступим к скриптам. Для реализации нам нужно два скрипта: один на OnDamaged объекта, другой на OnDeath объекта. Скрипты универсальные и ограничений по атакующим у них нет. Дома я проверил, как смог, но так как шарда у меня дома нет, то данный аспект проверить не смог. Но по идее все работает нормально, если заметите баг, обязательно сообщите. Еще, на шарде ни когда не играл, поэтому может это и не идеальный код для него, но думаю, что знающим людям поправить будет не сложно. :) И так, сами скрипты. На OnDamaged объекта
Второй скрипт ставется на OnDeath объекта. Этот скрипт раздает опыт.
Ну и еще их маленький брат - скрипт считающий отдельно урон ПС и урон всех остальных. Иногда бывает очень нужно узнать урон нанесенный объекту ПС. Скрипт для сингла.
З.Ы Сорри, что порвал страницу :oops: Aiwan: вообще-то некоторые строки можно делить и переносить. :this: -fenix-: просто мне как-то неудобно так ориентироваться %) Но впредь, на форуме, буду строки делить и переносить:yes: Сообщение отредактировал -fenix- - Nov 17 2005, 13:09 |
||||||
![]()
Сообщение
#84
|
|||
Level 5 ![]() Класс: Обыватель Характер: Lawful Neutral Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
|
||
![]()
Сообщение
#85
|
|||
Level 4 ![]() ![]() Класс: Маг Характер: Chaotic Evil Раса: Человек ![]() |
Скрипт мой, все совпадения с другими скриптами случайны. Скрипт для управления группой NPC в реальном времени, без создания waypoint-ов. Позволяет группировать NPC в любые построения(к примеру в Каре, Свинью, Шеренгу,Полк и т д.и т п на Ваш вкус) и перемещать их в таком построении. Можно использовать при построении масштабных баталий с участием большого количества неписей(причем под управлением игрока)
Построение можно регулировать с помощью двух параметров a и b. a отвечает за то как удален будет NPC от игрока, а b - за смещение NPC вправо или влево. Для использования необходимо: 1) Создать предмет со свойством "активировать предмет:дальнее расстояние" и тагом "panel" 2)Поставить группу из семи NPC с тагоми:NPC1 , NPC2 , NPC3 , NPC4 , NPC5 , NPC6 , NPC7 При желании количество неписей и их построение можно поменять произвольным образом Сообщение отредактировал justshurik - Feb 4 2006, 01:52 |
||
![]()
Сообщение
#86
|
|
Level 12 ![]() Класс: Оборотень Характер: Chaotic Neutral Раса: Нежить NWN: Скриптинг [Sn] ![]() |
Библиотечка нескольких функций для работы со строками, фактически написана ради одной функции. Насколько оптимален алгоритм не знаю, но годится для обычных проверок на нужные тэги.
NSS // name: i_string // type: Библиотека // desc: Строковые функции // autor: Nightwalker Sorcerer // date: 4.01.2006 // modified: 11.01.2006 //////////////////////////////////////////////////////////////////////////////// // INFO //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* Contains: int FindFirstOf(string sString, string sPattern, int nFrom = 0, int bSymbols = TRUE); int FindLastSubString(string sString, string sSubString); int FindSubStringFrom(string sString, string sSubString, int nCount = 0); int Match(string sString, string sPattern); */ //////////////////////////////////////////////////////////////////////////////// // CONSTANTS /////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// const string ANY_SYMBOL = "?"; const string ANY_SEQUENCE = "*"; const string P_BEGIN = "["; // открывающая скобка (1 символ) const string P_END = "]"; // закрывающая скобка (1 символ) const string P_OR = "|"; // ИЛИ выражение внутри скобок (1 символ) const string SYMBOL_NOT = "!"; //////////////////////////////////////////////////////////////////////////////// // FUNCTION DEFINITIONS //////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Нахождение первого вхождение в строку sString символов из набора sPattern. // - sString: строка для поиска; // - sPattern: набор символов; // - nFrom: позиция символа, с которого начинается поиск; // - bSymbols: Зарезервировано, используйте умолчание, чтобы в следующих // версиях библиотеки функция работала как предполагалось. // * Возвращает позицию в строке или отрицательное значение, если // позиция не найдена. // --> Например: // > FindFirstOf("a", "abc") - возвращает 0; // > FindFirstOf("word", "ro") - возвращает 1; // > FindFirstOf("word", " _[](),.-") - возвращает отрицательное значение; // > FindFirstOf("wоw", "w", 1) - возвращает 2; // > FindFirstOf("string", "some", 1) - возвращает отрицательное значение. int FindFirstOf(string sString, string sPattern, int nFrom = 0, int bSymbols = TRUE); // Нахождение последнего вхождения строки sSubString в строку sString. // - sString: строка для поиска; // - sSubString: искомая подстрока. // * Возвращает позицию в строке или отрицательное значение, если позиция // не найдена. int FindLastSubString(string sString, string sSubString); // Нахождение позиции подстроки sSubstring внутри строки sString, // начиная поиск с позиции nCount. // - sString: строка, в которой ищем; // - sSubString: что ищем; // - nCount: ищем начиная с этой позиции. // * Возвращает позицию подстроки или отрицательное значение, если подстрока // не найдена. int FindSubStringFrom(string sString, string sSubString, int nCount = 0); // Провека совпадения сторки sString с шаблоном sPattern: // '?' считается любым символом; // '*' cчитается любой последовательностью символов, // в том числе пустой (без символов); // '!' совпадение считается, если остаток строки не подходит к шаблону, // испольйте только в начале шаблона или скобочного выражения, // иначе за результат не ручаюсь; // [..|..|..] один из вариантов, допускается вложенность. // - sString: строка для проверки; // - sPattern: правильная палитра. // * Возвращает TRUE, если строки совпадают, и FALSE, если нет. // --> Например: // > "?*" - любая непустая последовательность; // > "itm_*" - все строки, начинающиеся с "itm_"; // > "i_*_gold" - строки вида "i_25_gold", "i_pi_gold", а также "i__gold"; // > "*a*" - строки, в которых есть хоть одна буква а; // > "[X|N]*" - тэги всех стандарнтых вещей NWN и дополнений; // > "[|?[|?]]" - пустая строка или 1-2 символа; // > "!wrong" - любая строка, кроме "wrong". int Match(string sString, string sPattern); //////////////////////////////////////////////////////////////////////////////// // IMPLEMENTATION ////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int FindFirstOf(string sString, string sPattern, int nFrom = 0, int bSymbols = TRUE) { int nResult = -1; int nCounter, nPosition, nLengthPattern = GetStringLength(sPattern); for (nCounter = 0; nCounter < nLengthPattern; nCounter++) { nPosition = FindSubStringFrom(sString, GetSubString(sPattern, nCounter, 1), nFrom); if (nResult < 0) nResult = nPosition; else if ((nPosition >= 0) && (nResult > nPosition)) nResult = nPosition; } return nResult; } int FindLastSubString(string sString, string sSubString) { int nSubStrLength, nResult, nNext; if ((nSubStrLength = GetStringLength(sSubString)) == 0) return -1; if ((nNext = (nResult = FindSubString(sString, sSubString))) < 0) return nResult; while ((nNext = FindSubString((sString = GetStringRight(sString, GetStringLength(sString) - nNext - nSubStrLength)), sSubString)) >= 0) { nResult += (nNext + nSubStrLength); } return nResult; } int FindSubStringFrom(string sString, string sSubString, int nCount = 0) { int nResult = FindSubString(GetStringRight(sString, GetStringLength(sString) - nCount) , sSubString); if (nResult < 0) return nResult; return (nResult + nCount); } int Match(string sString, string sPattern) { // DEBUG //SendMessageToPC(GetFirstPC(), "Сравнение '"+sString+"' с '"+sPattern+"'."); int nS, nPhB, nPhE; int nLengthString = GetStringLength(sString); int nLengthPattern = GetStringLength(sPattern); if (GetStringLeft(sPattern, 1) == SYMBOL_NOT) { return (!Match(sString, GetStringRight(sPattern, nLengthPattern - 1))); } if ((nPhE = (nPhB = FindSubString(sPattern, P_BEGIN))) >= 0) // обработка ИЛИ выражений { int nNest = 1; // текущая вложенность while ((nPhE >= 0) && (nNest > 0)) { nPhE = FindFirstOf(sPattern, P_BEGIN + P_END, nPhE + 1); if (GetSubString(sPattern, nPhE, 1) == P_BEGIN) nNest++; else nNest--; } if (nNest != 0) return FALSE; // неправильно расставлены скобки int nPhS, nPhF = nPhB; // начало и конец подстроки string sSymbol = ""; while ((sSymbol != P_END) && (nPhF >= 0)) { nPhS = nPhF + 1; sSymbol = ""; while ((((sSymbol != P_OR) || (nNest > 0)) && ((sSymbol != P_END) || (nNest >= 0))) && (nPhF >= 0)) { nPhF = FindFirstOf(sPattern, P_BEGIN + P_OR + P_END, nPhF + 1); sSymbol = GetSubString(sPattern, nPhF, 1); if (sSymbol == P_BEGIN) nNest++; else if (sSymbol == P_END) nNest--; } if (Match(sString, GetStringLeft(sPattern, nPhB) + GetSubString(sPattern, nPhS, nPhF - nPhS) + GetStringRight(sPattern, nLengthPattern - nPhE - 1))) return TRUE; } return FALSE; } if ((nS = FindSubString(sPattern, ANY_SEQUENCE)) > 0) // строки, содержащие ANY_SEQUENCE, но не вначале { if (!Match(GetStringLeft(sString, nS), GetStringLeft(sPattern, nS))) return FALSE; // упрощаем в "*..." return Match(GetStringRight(sString, nLengthString - nS), GetStringRight(sPattern, nLengthPattern - nS)); } if (nS == 0) // теперь ANY_SEQUENCE вначале { string sPattern2 = GetStringRight(sPattern, nLengthPattern - 1); if ((nS = (FindLastSubString(sPattern2, ANY_SEQUENCE) + 1)) > 0) // есть второй ANY_SEQUENCE { // конечные кусочки после последнего ANY_SEQUENCE должны "совпадать" string sPatternAfterSeq = GetStringRight(sPattern, GetStringLength(sPattern) - nS - 1); int nLengthAfterSeq = GetStringLength(sPatternAfterSeq); if (!Match(GetStringRight(sString, nLengthAfterSeq), sPatternAfterSeq)) return FALSE; // упрощаем в "*...*" nLengthString = GetStringLength(sString = GetStringLeft(sString, nLengthString - nLengthAfterSeq)); nLengthPattern = GetStringLength(sPattern = GetStringLeft(sPattern, nS + 1)); // DEBUG: //SendMessageToPC(GetFirstPC(), "тупой подбор '"+sString+"' к '"+sPattern+"'"); int nCounter1, nCounter2; for (nCounter1 = 1; (nCounter1 < nLengthString); nCounter1++) { for (nCounter2 = 1; (nCounter2 < nLengthPattern); nCounter2++) { if (Match(GetStringLeft(sString, nCounter1), GetStringLeft(sPattern, nCounter2))) if (Match(GetStringRight(sString, nLengthString - nCounter1), GetStringRight(sPattern, nLengthPattern - nCounter2))) return TRUE; } } return FALSE; } // только один ANY_SEQUENCE вначале; осталось сравнить конец строки с палитрой return Match(GetStringRight(sString, GetStringLength(sPattern2)), sPattern2); } // теперь строка и палитра должны быть одинакового размера if (nLengthString != nLengthPattern) return FALSE; if ((nS = FindSubString(sPattern, ANY_SYMBOL)) >= 0) // в палитре присутствует ANY_SYMBOL { return Match(GetStringLeft(sString, nS), GetStringLeft(sPattern, nS)) && Match(GetStringRight(sString, nLengthString - nS - 1), GetStringRight(sPattern, nLengthPattern - nS - 1)); } return (sString == sPattern); } //void main(){} Библиотека функций для работы с инвентарем, используя предыдущий инклюд. Основные функции: CreateItemList HasItemList и RemoveItemList, остальные функции тоже полезны в тех или иных ситуациях. NSS // name: i_inv // type: Библиотека // desc: Функции для работы с инвентарем. // autor: Nightwalker Sorcerer // date: 11.01.2005 // modified: 13.01.2005 //////////////////////////////////////////////////////////////////////////////// // INFO //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* Contains: void CreateItemList(string sList, object oTarget = OBJECT_SELF); int GetNumItems(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE); int GetNumItemsInInventory(object oInventory = OBJECT_SELF, string sTag = "*"); int GetNumItemsInSlot(object oTarget, int nSlot, string sTag = "*"); int HasItemList(object oTarget, string sList, int bCreatureSlots = FALSE); void RemoveItemList(object oTarget, string sList, int bCreatureSlots = FALSE); int RemoveItemsFromInventory(object oInventory = OBJECT_SELF, string sTag = "*", int nNum = -1); int RemoveItemsFromSlot(object oTarget, int nSlot, string sTag = "*", int nNum = -1); int RemoveItemsFromSlots(object oTarget = OBJECT_SELF, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE) */ //////////////////////////////////////////////////////////////////////////////// // INCLUDES //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// #include "i_string" //////////////////////////////////////////////////////////////////////////////// // CONSTANTS /////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// const string SYMBOL_AND = "&"; const string SYMBOL_EQU = "="; //////////////////////////////////////////////////////////////////////////////// // FUNCTION DEFINITIONS //////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Создание вещей из заданого списка в инвентаре oTarget // - sList: список вещей в виде "вещь1=кол-во1&вещь2=кол-во2&вещь3=кол-во3", // при опускании "=колво", количество считается 1; // - oTarget: в чьем инвентаре создаем? // --> Например: // > CreateItemList("single_item"); // > CreateItemList("first_item&second_item&one_arrow=99", oTreasure); // ? Примечание: если символ '&' плохо видно в списке, можно использовать '&&'. void CreateItemList(string sList, object oTarget = OBJECT_SELF); // Нахождение количества вещей с тэгом sTag у персонажа oTarget (в инвентаре // и слотах) // - oInventory: персонаж, в имуществе которого ищем; // - sTag: палитра для проверки тэга; // - bCreatureSlots: искать ли в невидимых слотах? // * Возвращает количество найденых вещей. int GetNumItems(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE); // Нахождение количества вещей с заданым тэгом sTag в инвентаре oInventory, // предметы в слотах не учитываются. // - oInventory: целевой инвентарь // - sTag: палитра для проверки тэга // * Возвращает количество найденых вещей, тэг которых подходит под палитру // --> Например: // > GetNumItemsInInventory(oChest, "itm_sword*") - количество вещей с тэгом, // начинающимся с "itm_sword" у объекта oChest; // > GetNumItemsInInventory(oPC, "eda") - количество вещей с тэгом "eda" у oPC. int GetNumItemsInInventory(object oInventory = OBJECT_SELF, string sTag = "*"); // Нахождение количества вещей с заданым тегом sTag в слоте инвентаря nSlot // существа oTarget. // - oTarget: существо, у которого ищем; // - nSlot: слот инвентаря; // - sTag: тэг. // * Возвращает количество найденых вещей. int GetNumItemsInSlot(object oTarget, int nSlot, string sTag = "*"); // Нахождение количества вещей с заданым тегом sTag в слотах инвентаря // существа oTarget. // - oTarget: существо, у которого ищем; // - sTag: тэг; // - bCreatureSlots: считать ли вещи в невидимых слотах? // * Возвращает количество найденых вещей. int GetNumItemsInSlots(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE); // Проверка, имеет ли oTarget cписок вещей sList. // - sList: список вещей в виде "вещь1=кол-во1&вещь2=кол-во2&вещь3=кол-во3", // при опускании "=колво", количество считается 1; // - oTarget: у кого проверяем; // - bCreatureSlots: проверять ли вещи в невидимых слотах? // * Возвращеет TRUE, если объект имеет вещи из списка, иначе FALSE. // --> Например: // > НasItemList(oPC, "quest&gem[1|2]=6") - проверка, есть ли у персонажа вещь // c тэгом "quest" и шесть вещей с тэгом gem1 или gem2 // ? Примечание: если символ '&' плохо видно, можно использовать '&&'. int HasItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE); // Удаление у оTarget списка вещей sList. // - sList: список вещей в виде "вещь1=кол-во1&вещь2=кол-во2&вещь3=кол-во3", // при опускании "=колво", количество считается 1; // - oTarget: у кого удаляем; // - bCreatureSlots: удалять ли вещи из невидимых ячеек? // --> Например: // > RemoveItemList(oPC, "fragile=-1&extra") - удаление всех вещей с // тэгом "fragile" и одной вещи с тэгом "extra". // ? Примечание: если символ '&' плохо видно, можно использовать '&&'. void RemoveItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE); // Удаление заданого количества вещей с тэгом sTag у персонажа. // - oTarget: персонаж; // - sTag: палитра для проверки тэга; // - nNum: количество вещей, коророе нужно удалить, при отрицательном // значении будут удалены все вещи; // - bCreatureSlots: удалять ли вещи из невидимых ячеек? // * Возвращает количество вещей, коророе осталось удалить. // --> Например: // > RemoveItems(oTarget) - удалить все вещи у цели; // > RemoveItems(oPC, "flower", 2) - удалить у oPC две вещи с тэгом "flower". int RemoveItems(object oTarget, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE); // Удаление вещей из инвентаря с заданым тэгом, вещи в слотах не удаляются // - oInventory: целевой инвентарь // - sTag: палитра для проверки тэга // - nNum: количество удаляемых вещей, при -1 удалятся все вещи, // подходящие под палитру // * Возвращает количество вещей, которые осталось удалить, т.е 0, если удалено // столько вещей, сколько указано или большее число, если найдено меньше вещей, // c подходящим тэгом. Возвращает -1, если указано удалять все вещи. // Количество удаленных вещей можно получить = nNum - RemoveItemsFromInventory(,, nNum) // --> Например: // > int nNoFood = RemoveItemsFromInventory(oPC, "itm_food", 1) - удаляет 1 еду, // nNoFood = 1, если у oPC нет еды; // > RemoveItemsFromInventory(oPC, "x*") - удаляет из вещмешка oPC вещи из дополнений. int RemoveItemsFromInventory(object oInventory = OBJECT_SELF, string sTag = "*", int nNum = -1); // Удалить nNum вещей из слота nSlot существа oTarget, // если тэг вещи подходит к sTag. // - oTarget: существо, у которого удаляем вещи; // - nSlot: ячейка, из которой удаляем; // - sTag: палитра тэга; // - nNum: количество вещей, которое нужно удалить, при отрицательном значении // удалять все вещи. // * Возвращает количество вещей, которые осталось удалить, или отрицательное // значение, если указано удалять все вещи. int RemoveItemsFromSlot(object oTarget, int nSlot, string sTag = "*", int nNum = -1); // Удалить nNum вещей из ячеек инвентаря существа oTarget с заданным тэгом. // - oTarget: цель; // - sTag: палитра тэга; // - nNum: количество вещей, которое нужно удалить, при отрицательном значении // удалять все вещи; // - bCreatureSlots: удалять ли вещи из невидимых ячеек. // * Возвращает количество вещей, которые осталось удалить, или отрицательное // значение, если указано удалять все вещи. int RemoveItemsFromSlots(object oTarget = OBJECT_SELF, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE); //////////////////////////////////////////////////////////////////////////////// // IMPLEMENTATION ////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void CreateItemList(string sList, object oTarget = OBJECT_SELF) { int nDiv, nNum; string sResRef; while (sList != "") { if ((nDiv = FindSubString(sList, SYMBOL_AND)) < 0) { nDiv = GetStringLength(sList); } sResRef = GetStringLeft(sList, nDiv); sList = GetStringRight(sList, GetStringLength(sList) - nDiv - 1); nNum = 1; if ((nDiv = FindSubString(sResRef, SYMBOL_EQU)) >= 0) { nNum = StringToInt(GetStringRight(sResRef, GetStringLength(sResRef) - nDiv - 1)); sResRef = GetStringLeft(sResRef, nDiv); } for ( ; nNum > 0; nNum--) CreateItemOnObject(sResRef, oTarget); // лучше ничего не придумал } } int GetNumItems(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE) { return GetNumItemsInInventory(oTarget, sTag) + GetNumItemsInSlots(oTarget, sTag, bCreatureSlots); } 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 GetNumItemsInSlot(object oTarget, int nSlot, string sTag = "*") { object oItem = GetItemInSlot(nSlot, oTarget); if (Match(GetTag(oItem), sTag)) return GetItemStackSize(oItem); return 0; } int GetNumItemsInSlots(object oTarget = OBJECT_SELF, string sTag = "*", int bCreatureSlots = FALSE) { int nNum = 0; nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_ARMS, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_ARROWS, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BELT, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BOLTS, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BOOTS, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_BULLETS, sTag); //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CARMOUR, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CHEST, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CLOAK, sTag); //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag); //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag); //nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_HEAD, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_LEFTHAND, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_LEFTRING, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_NECK, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_RIGHTHAND, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_RIGHTRING, sTag); if (bCreatureSlots) { nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CARMOUR, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag); nNum += GetNumItemsInSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag); } return nNum; } int HasItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE) { int nDiv, nNum; string sTag; while (sList != "") { if ((nDiv = FindSubString(sList, SYMBOL_AND)) < 0) { nDiv = GetStringLength(sList); } sTag = GetStringLeft(sList, nDiv); sList = GetStringRight(sList, GetStringLength(sList) - nDiv - 1); if ((nDiv = FindSubString(sTag, SYMBOL_EQU)) >= 0) { nNum = StringToInt(GetStringRight(sTag, GetStringLength(sTag) - nDiv - 1)); sTag = GetStringLeft(sTag, nDiv); } else { nNum = 1; } if (sTag != "") if (GetNumItems(oTarget, sTag, bCreatureSlots) < nNum) return FALSE; } return TRUE; } void RemoveItemList(string sList, object oTarget = OBJECT_SELF, int bCreatureSlots = FALSE) { int nDiv, nNum; string sTag; while (sList != "") { if ((nDiv = FindSubString(sList, SYMBOL_AND)) < 0) { nDiv = GetStringLength(sList); } sTag = GetStringLeft(sList, nDiv); sList = GetStringRight(sList, GetStringLength(sList) - nDiv - 1); if ((nDiv = FindSubString(sTag, SYMBOL_EQU)) >= 0) { nNum = StringToInt(GetStringRight(sTag, GetStringLength(sTag) - nDiv - 1)); sTag = GetStringLeft(sTag, nDiv); } else { nNum = 1; } RemoveItems(oTarget, sTag, nNum, bCreatureSlots); } } int RemoveItems(object oTarget, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE) { nNum = RemoveItemsFromInventory(oTarget, sTag, nNum); return RemoveItemsFromSlots(oTarget, sTag, nNum, bCreatureSlots); } 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; } int RemoveItemsFromSlot(object oTarget, int nSlot, string sTag = "*", int nNum = -1) { if (nNum == 0) return nNum; object oItem = GetItemInSlot(nSlot, oTarget); if (GetIsObjectValid(oItem)) if (Match(GetTag(oItem), sTag)) { int nStack; if (nNum < 0) DestroyObject(oItem); else if ((nStack = GetItemStackSize(oItem)) > nNum) { SetItemStackSize(oItem, nStack - nNum); return 0; } else { DestroyObject(oItem); nNum -= nStack; } } return nNum; } int RemoveItemsFromSlots(object oTarget = OBJECT_SELF, string sTag = "*", int nNum = -1, int bCreatureSlots = FALSE) { nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_ARMS, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_ARROWS, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BELT, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BOLTS, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BOOTS, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_BULLETS, sTag, nNum); //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CARMOUR, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CHEST, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CLOAK, sTag, nNum); //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag, nNum); //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag, nNum); //nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_HEAD, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_LEFTHAND, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_LEFTRING, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_NECK, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_RIGHTHAND, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_RIGHTRING, sTag, nNum); if (bCreatureSlots) { nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CARMOUR, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_B, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_L, sTag, nNum); nNum = RemoveItemsFromSlot(oTarget, INVENTORY_SLOT_CWEAPON_R, sTag, nNum); } return nNum; } //void main(){} Примеры использования (судя по всему маст би): - Проверка в диалоге на наличие у персонажа игрока необходимого количества (пусть 3) предметов с заданым тэгом (пусть "quest_item") NSS #include "i_inv" int StartingConditional() { object oPC = GetPCSpeaker(); int n = GetNumItems(oPC, "quest_item"); return (n >= 3); } - Забрать необходимое кол-во предметов у игрока (пусть те же 3 "quest_item") NSS #include "i_inv"
void main() { object oPC = GetPCSpeaker(); RemoveItems(oPC, "quest_item", 3); } Сообщение отредактировал azathoth - Jul 9 2006, 02:47 |
![]()
Сообщение
#87
|
|
Миловидный Бегрюссунг ![]() Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
Эта функция копирует инвентарь объекта, если необходимо, то и все надетые вещи на существо.
NSS // // КОПИРУЕТ ВЕСЬ ИНВЕНТАРЬ oMaster=OBJECT_SELF В ИНВЕНТАРЬ oNewMaster // iDel = TRUE - удаляет копируемый объект из инвентаря хозяина, FALSE - нет // iUnequip = TRUE - раздевает объект, снимая с него все в инвентарь void CopyInventory(object oNewMaster, object oMaster=OBJECT_SELF, int iDel=TRUE, int iUnequip=FALSE); void CopyInventory(object oNewMaster, object oMaster=OBJECT_SELF, int iDel=TRUE, int iUnequip=FALSE) { if(iUnequip==TRUE) { int i=0; while(i<14) { if(GetItemInSlot(i, oMaster)!= OBJECT_INVALID) CopyItem(GetItemInSlot(i, oMaster), oNewMaster, TRUE); if(iDel==TRUE) DestroyObject(GetItemInSlot(i, oMaster)); i++; } } object oItem = GetFirstItemInInventory(oMaster); while(GetIsObjectValid(oItem)) { if(GetBaseItemType(oItem) == BASE_ITEM_LARGEBOX) { CreateItemOnObject(GetResRef(oItem), oNewMaster, 1); if(iDel==TRUE) DestroyObject(oItem, 0.5); } else { CopyItem(oItem, oNewMaster, TRUE); if(iDel==TRUE) DestroyObject(oItem); } oItem = GetNextItemInInventory(oMaster); } } Тут все просто. Имеем 25 бутылочек, удаляем из них 3 или одну. NSS // ВОЗВРАЩАЕТ КОЛИЧЕСТВО ПРЕДМЕТОВ В СТЕКЕ В ИНВЕНТАРЕ ОБЪЕКТА int GetItemStackNumber(string sTagItem, object oTarget=OBJECT_SELF); // УДАЛЯЕТ iNum КОЛИЧЕСТВО ПРЕДМЕТОВ В СТЕКЕ В ИНВЕНТАРЕ ОБЪЕКТА void RemoveItemStackNumber(string sTagItem, int iNum = 1, object oTarget=OBJECT_SELF); //------------------------------------------------------------------------------ int GetItemStackNumber(string sTagItem, object oTarget=OBJECT_SELF) { object oItem = GetFirstItemInInventory(oTarget); int iNum = 0; while (GetIsObjectValid(oItem)) { if (GetTag(oItem) == sTagItem) { iNum = iNum+GetItemStackSize(oItem); } oItem = GetNextItemInInventory(oTarget); } return iNum; } //------------------------------------------------------------------------------ void RemoveItemStackNumber(string sTagItem, int iNum = 1, object oTarget=OBJECT_SELF) { object oItem = GetFirstItemInInventory(oTarget); while (GetIsObjectValid(oItem) && (iNum != 0)) { if (GetTag(oItem) == sTagItem) { int i = GetItemStackSize(oItem); if (i > iNum) { SetItemStackSize(oItem, GetItemStackSize(oItem)-iNum); iNum = 0; } else { DestroyObject(oItem); iNum = iNum-i; } } oItem = GetNextItemInInventory(oTarget); } } Определяем лучший класс мультикласса. NSS //
// ЛУЧШИЙ КЛАСС МУЛЬТИКЛАССОВОГО СОЗДАНИЯ int GetCreatureBestClass(object oCr=OBJECT_SELF); int GetCreatureBestClass(object oCr) { int class1 = GetClassByPosition(1, oCr); int class2 = GetClassByPosition(2, oCr); int class3 = GetClassByPosition(3, oCr); int classlev1, classlev2, classlev3; classlev1 = GetLevelByClass(class1, oCr); if (class2 != CLASS_TYPE_INVALID) classlev2 = GetLevelByClass(class2, oCr); if (class3 != CLASS_TYPE_INVALID) classlev3 = GetLevelByClass(class3, oCr); int BestClass = class1; if (classlev1 < classlev2) BestClass = class2; if (classlev2 < classlev3) BestClass = class3; return BestClass; } |
![]()
Сообщение
#88
|
|
Level 8 ![]() Класс: Некромант Характер: Chaotic Evil Раса: Дракон NWN: Скриптинг [PW] ![]() |
Скрипт "резервирования" нескольких мест на сервере под DM'ов
Бывает, что сервер полностью забит и зайти DM'ом не получается. Теперь несколько мест будут забиты для ДМов P.S. Возможно где-то уже есть, если так то сорри onClientEnter NSS int nMaxPlayers = 30; // Макс. число игроков в настройке сервера минус число зарезервированных мест void main() { object oPC = GetEnteringObject(); object oMod = GetModule(); int nCurrPC = GetLocalInt(oMod, "CurrPC"); if(nCurrPC >= nMaxPlayers && !GetIsDM(oPC)) { BootPC(oPC); return; } SetLocalInt(oMod, "CurrPC", nCurrPC+1); // нормальный oncliententer // ... OnClientExit NSS void main() {
object oMod = GetModule(); SetLocalInt(oMod, "CurrPC", GetLocalInt(oMod, "CurrPC")-1); // нормальный onclientexit // ... |
![]()
Сообщение
#89
|
|
Level 9 ![]() Класс: Друид Характер: True Neutral Раса: Эльф NWN: Скриптинг [PW] Амен ![]() |
Скрипт резервирования мест для ДМ-ов.
Аналогичный скрипт. Только чуть эффективней и проще. В момент входа игрока, а не ДМ-а, пересчитывается количество игроков, и если их больше указанной цифры, то входящий игрок бутится. В скрипте, что выше, есть недостатки. Если клиент "отвалится" от сервера, т.е. у него произойдет дисконнект, то скрипт изменения переменной не выполнится. Далее, ДМ-ы занимают места игроков. Это не очень хорошо. Учитывая то, что максимально клиентов может быть только 30. В настройках сервера надо сделать 35 мест, а игроков ограничить 30-ю местами, используя подобный скрипт. Т.е. изменение переменной необходимо включить в условие, которое игнорирует Дм. И соответственно на выходе с модуля тоже ограничить условие игроком. NSS void main() { object oMod = GetModule(); //--------------------------------------------------// // Данные записываются в отдельный скрипт, а потом // // считываются во время загрузки модуля через // // действие 'OnModuleLoad'. // int DMRESERVE = 30; // Для примера - 30 человек SetLocalInt(oMod, "DMRESERVE", DMRESERVE); //--------------------------------------------------// object oClient = GetEnteringObject(); if (GetIsDM(oClient) == FALSE) { int nReserve = GetLocalInt(oMod, "DMRESERVE"); if (nReserve == TRUE) { int nPlayer; object oPlayer = GetFirstPC(); while (GetIsObjectValid(oPlayer)) { nPlayer++; oPlayer = GetNextPC(); } if (nPlayer > nReserve) { BootPC(oClient); return; } } } } З.Ы. kreon, если не сложно, доработай скрипт. |
![]()
Сообщение
#90
|
|
Level 2 ![]() Класс: Обыватель Характер: Lawful Good Раса: Человек ![]() |
Вообщем я хотела вот что,у меня была такая идея...нужно было разделить отдых и процесс подготовки заклинаний кастующем классом. Это все нужно было все, чтобы клерик мог молиться Богу о заклинаниях только в определенные часы времени суток....ну перепало и магу конечно.(IMG:style_emoticons/kolobok_light/smile.gif) )
NSS ////////////////////////////////////////////////////////////////////////////////
/////Эта функция каждые 3 секунды проверяет подготавливает ли персонаж магию./// //////////////////////////////////////////////////////////////////////////////// void Examen(object oPC = OBJECT_SELF) { if(!GetLocalInt(oPC,"Rest")) { ForceRest(oPC);//востановление магии ActionMoveToLocation(GetLocation(oPC));//встаем FloatingTextStringOnCreature( "Вы успешно подготовили магию.",oPC); //удаление локалок if(GetIsObjectValid(GetLocalObject(oPC,"GodLay"))) { DestroyObject(GetLocalObject(oPC,"GodLay")); DeleteLocalObject(oPC,"GodLay"); } DeleteLocalLocation(oPC, "RestLocation"); return; } if(GetLocation(oPC) != GetLocalLocation(oPC, "RestLocation")) { ActionMoveToLocation(GetLocation(oPC)); FloatingTextStringOnCreature("Вам неудалось подготовить магию.",oPC); //удаление локалок if(GetIsObjectValid(GetLocalObject(oPC,"GodLay"))) { DestroyObject(GetLocalObject(oPC,"GodLay")); DeleteLocalObject(oPC,"GodLay"); } DeleteLocalInt(oPC,"Rest"); DeleteLocalLocation(oPC, "RestLocation"); return; } else { AssignCommand(oPC, DelayCommand(3.0f, Examen(oPC))); AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,3.0)); } } //////////////////////////////////////////////////////////////////////////////// ///Это начало подготовки заклинаний для божественных заклинателей/////////////// //////////////////////////////////////////////////////////////////////////////// void BeginGodMagic(object oPC =OBJECT_SELF) { object oLay;//тут я сделала луч, с неба как бы, впрочем необязательно. Так что можно убрать(IMG:style_emoticons/kolobok_light/smile.gif) //проверка айламента if(GetAlignmentGoodEvil(oPC)==ALIGNMENT_EVIL) {oLay = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_solred",GetLocation(oPC));} else if (GetAlignmentGoodEvil(oPC)==ALIGNMENT_NEUTRAL) {oLay = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_solblue",GetLocation(oPC));} else oLay = CreateObject(OBJECT_TYPE_PLACEABLE,"plc_solwhite",GetLocation(oPC)); //вешаем нужные локалки на Чара и плэйсебл SetLocalLocation(oPC, "RestLocation", GetLocation(oPC)); SetLocalInt(oPC,"Rest",TRUE); SetLocalObject(oPC,"GodLay",oLay); AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,3.0)); AssignCommand(oPC, DelayCommand(3.0, Examen())); DelayCommand(1.0,FloatingTextStringOnCreature("Подготовка магии.",oPC)); DelayCommand(30.0,DeleteLocalInt(oPC,"Rest")); } //////////////////////////////////////////////////////////////////////////////// //Это проверка у божественных заклинателей наличия бога///////////////////////// //если есть, то все нормально,нет-не подготовить заклинаний.//////////////////// //и времени, в которое можно помолиться этому богу.///////////////////////////// //Закоментировала.////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /*void ExsamenGod(object oPC = OBJECT_SELF) { object oGodLatander,oGodMysrta; int nTime = GetTimeHour(); oGodLatander = GetItemPossessedBy(oPC,"i_latander_sign"); oGodMysrta = GetItemPossessedBy(oPC,"i_mystra_sign"); // Latander if(GetIsObjectValid(oGodLatander)) { if((nTime>=6)&&(nTime<13)){BeginGodMagic(oPC);return;} else return; } //Mystra else if(GetIsObjectValid(oGodMysrta)) { if((nTime>=23)&&(nTime<4)){BeginGodMagic(oPC);return;} else return; } else{FloatingTextStringOnCreature("Вам не кому молитьсЯ относительно заклинаний.",oPC);} }*/ //////////////////////////////////////////////////////////////////////////////// /// Это начало подготовки заклинаний для арканных заклинателей ///////////////// //////////////////////////////////////////////////////////////////////////////// void BeginArcaneMagic(object oPC =OBJECT_SELF) { SetLocalLocation(oPC, "RestLocation", GetLocation(oPC)); SetLocalInt(oPC,"Rest",TRUE); AssignCommand(oPC,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,3.0)); DelayCommand(3.0,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_FIREFORGET_READ,1.0,10.0))); AssignCommand(oPC, DelayCommand(3.0, Examen())); DelayCommand(1.0,FloatingTextStringOnCreature("Подготовка магии.",oPC)); DelayCommand(30.0,DeleteLocalInt(oPC,"Rest")); } //////////////////////////////////////////////////////////////////////////////// ///// Проверка. Есть ли у персонажа кастующий класс? ////////////////////////// //////////////////////////////////////////////////////////////////////////////// void ExamenCastClass(object oPC = OBJECT_SELF) { int iu = 1,iClass; while(iu <=3) { iClass=GetClassByPosition(iu,oPC); if(iClass == CLASS_TYPE_CLERIC){BeginGodMagic(oPC);return;} else if(iClass == CLASS_TYPE_DRUID){BeginGodMagic(oPC);return;} else if(iClass == CLASS_TYPE_PALADIN){BeginGodMagic(oPC);return;} else if(iClass == CLASS_TYPE_RANGER){BeginGodMagic(oPC);return;} else if(iClass == CLASS_TYPE_WIZARD){BeginArcaneMagic(oPC);return;} else if(iClass == CLASS_TYPE_SORCERER){BeginArcaneMagic(oPC);return;} else if(iClass == CLASS_TYPE_BARD){BeginArcaneMagic(oPC);return;} iu++ ; } } //////////////////////////////////////////////////////////////////////////////// /// Удаление восстановленных при отдыхе заклинаний ///////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SpellDelete(object oPC = OBJECT_SELF) { int nSpell, nKSpell; for (nSpell = 0; nSpell < 1000; nSpell++) { nKSpell = GetHasSpell(nSpell, oPC); if (nKSpell) { while (nKSpell > 0) { DecrementRemainingSpellUses(oPC, nSpell); nKSpell--; } } } } //////////////////////////////////////////////////////////////////////////////// ////////////////// Отдых /////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void main() { object oPC = GetLastPCRested(); object oItem,oItem1; switch(GetLastRestEventType()) { case REST_EVENTTYPE_REST_STARTED: { //Необходимые эффекты,проверки и тд.. break; } case REST_EVENTTYPE_REST_CANCELLED: { break; } case REST_EVENTTYPE_REST_FINISHED: { SpellDelete(oPC); DelayCommand(1.5,ExamenCastClass(oPC)); break; } } } |
![]()
Сообщение
#91
|
|
Level 8 ![]() Класс: Некромант Характер: Chaotic Evil Раса: Дракон NWN: Скриптинг [PW] ![]() |
Не знаю, было или нет... Раскидывание заходящих игроков по точкам (например для автоматического раскидывания игроков по камерам в тюрьме)
jail_include.nss NSS int WP_COUNT = 5; // кол-во вейпойнтов int PC_PER_WP = 1; // скольо игроков в 1н вейпойнт string WP_SUFFIX = "_jail_wp"; // суффикс для переменной jail_on_enter.nss NSS #include "jail_include" void main() { object oPC = GetEnteringObject(); if(!GetIsPC(oPC) || GetIsDM(oPC)) return; int i, count; string sWTag; object oWP; for(i=0;i<WP_COUNT;i++) { oWP = GetObjectByTag("wp_"+IntToString(i)+WP_SUFFIX); count = GetLocalInt(oWP, "pc_count"); if(count < PC_PER_WP) { SetLocalInt(oWP, "pc_count", count+1); SetLocalObject(oPC, "wp"+WP_SUFFIX, oWP); AssignCommand(oPC, ActionJumpToObject(oWP)); return; } } oWP = GetObjectByTag("wp_all"+WP_SUFFIX); AssignCommand(oPC, ActionJumpToObject(oWP)); } jail_on_exit.nss NSS #include "jail_include" void main() { object oPC = GetExitingObject(); if(!GetIsPC(oPC) || GetIsDM(oPC)) return; object oWP = GetLocalObject(oPC, "wp"+WP_SUFFIX); int count = GetLocalInt(oWP, "pc_count"); SetLocalInt(oWP, "pc_count", count-1); DeleteLocalObject(oPC, "wp"+WP_SUFFIX); } соотв. ставим вейпойнты с тегами "wp_"+id+WP_SUFFIX, и 1н с тегом "wp_all"+WP_SUFFIX Думаю остальное все ясно (IMG:style_emoticons/kolobok_light/smile.gif) Сообщение отредактировал kreon - May 10 2006, 22:18 |
![]()
Сообщение
#92
|
|
Level 12 ![]() Класс: Оборотень Характер: Chaotic Neutral Раса: Нежить NWN: Скриптинг [Sn] ![]() |
Функция, определяющая лучшее оружие ближнего боя для указаного персонажа. Учитываются не только фокусы, если они есть (им отдается преимущество), но и специализации. Упор на схему щит+меч. Впрочем нисколько не претендую на полноту, тем более нет учета фита "Weapon Finesse" для предпочтения легкого оружия и полной поддержки дистанционного (необходим фокус, чтобы оно появилось). Метательное вообще не стал включать (не лублу его), если нужно -- раскомментируйте первые три строки.
Опробовано и работает, в своем модуле я использовал эту функцию для создания рандомного оружия у спавнов монстров - если НВН беден на модели, то хотя бы разное оружие у противников смотрится куда лучше. Функция возвращает константу типа BASE_ITEM_*, по которой нужно создавать необходимую экипировку. NSS int GetWeaponBestBaseType(object oFor)
{ //if (GetHasFeat(FEAT_WEAPON_FOCUS_DART, oFor)) return BASE_ITEM_DART; //if (GetHasFeat(FEAT_WEAPON_FOCUS_SHURIKEN, oFor)) return = BASE_ITEM_SHURIKEN; //if (GetHasFeat(FEAT_WEAPON_FOCUS_THROWING_AXE, oFor)) return THROWINGAXE; if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_BASTARD_SWORD, oFor)) return BASE_ITEM_BASTARDSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_KATANA, oFor)) return BASE_ITEM_KATANA; if (GetHasFeat(FEAT_WEAPON_FOCUS_DWAXE, oFor)) return BASE_ITEM_DWARVENWARAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_KUKRI, oFor)) return BASE_ITEM_KUKRI; if (GetHasFeat(FEAT_WEAPON_FOCUS_SCYTHE, oFor)) return BASE_ITEM_SCYTHE; if (GetHasFeat(FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD, oFor)) return BASE_ITEM_TWOBLADEDSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_DIRE_MACE, oFor)) return BASE_ITEM_DIREMACE; if (GetHasFeat(FEAT_WEAPON_FOCUS_DOUBLE_AXE, oFor)) return BASE_ITEM_DOUBLEAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_KAMA, oFor)) return BASE_ITEM_KAMA; if (GetHasFeat(FEAT_WEAPON_FOCUS_WHIP, oFor)) return BASE_ITEM_WHIP; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_BATTLE_AXE, oFor)) return BASE_ITEM_BATTLEAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_AXE, oFor)) return BASE_ITEM_GREATAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_SWORD, oFor)) return BASE_ITEM_GREATSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_HALBERD, oFor)) return BASE_ITEM_HALBERD; if (GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oFor)) return BASE_ITEM_HANDAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_FLAIL, oFor)) return BASE_ITEM_HEAVYFLAIL; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_FLAIL, oFor)) return BASE_ITEM_LIGHTFLAIL; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_HAMMER, oFor)) return BASE_ITEM_LIGHTHAMMER; if (GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD, oFor)) return BASE_ITEM_LONGSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oFor)) return BASE_ITEM_LONGBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oFor)) return BASE_ITEM_RAPIER; if (GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR, oFor)) return BASE_ITEM_SCIMITAR; if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD, oFor)) return BASE_ITEM_SHORTSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oFor)) return BASE_ITEM_SHORTBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_WAR_HAMMER, oFor)) return BASE_ITEM_WARHAMMER; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD, oFor)) return BASE_ITEM_LONGSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oFor)) return BASE_ITEM_LONGBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oFor)) return BASE_ITEM_RAPIER; if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oFor)) return BASE_ITEM_SHORTBOW; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB; if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER; if (GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oFor)) return BASE_ITEM_HANDAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE, oFor)) return BASE_ITEM_LIGHTMACE; if (GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR, oFor)) return BASE_ITEM_MORNINGSTAR; if (GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oFor)) return BASE_ITEM_RAPIER; if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD, oFor)) return BASE_ITEM_SHORTSWORD; if (GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oFor)) return BASE_ITEM_SHORTBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB; if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER; if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE, oFor)) return BASE_ITEM_LIGHTMACE; if (GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR, oFor)) return BASE_ITEM_MORNINGSTAR; if (GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE, oFor)) return BASE_ITEM_SICKLE; if (GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oFor)) return BASE_ITEM_SLING; if (GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR, oFor)) return BASE_ITEM_SHORTSPEAR; if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB; if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER; if (GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR, oFor)) return BASE_ITEM_SCIMITAR; if (GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE, oFor)) return BASE_ITEM_SICKLE; if (GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oFor)) return BASE_ITEM_SLING; if (GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR, oFor)) return BASE_ITEM_SHORTSPEAR; if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_KAMA, oFor)) return BASE_ITEM_KAMA; if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB; if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER; if (GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oFor)) return BASE_ITEM_HANDAXE; if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oFor)) return BASE_ITEM_SLING; if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oFor)) { if (GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oFor)) return BASE_ITEM_CLUB; if (GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oFor)) return BASE_ITEM_DAGGER; if (GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oFor)) return BASE_ITEM_HEAVYCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oFor)) return BASE_ITEM_LIGHTCROSSBOW; if (GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oFor)) return BASE_ITEM_QUARTERSTAFF; } int nSize = GetCreatureSize(oFor); if (GetHasFeat(FEAT_POINT_BLANK_SHOT, oFor)) { // TODO: range weapons } if (GetHasFeat(FEAT_WEAPON_FINESSE, oFor)) { // TODO: fine weapons } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MONK, oFor)) { return BASE_ITEM_KAMA; } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_EXOTIC, oFor)) { // double weapons if has two-weapon fighting feats if (GetHasFeat(FEAT_AMBIDEXTERITY, oFor) && GetHasFeat(FEAT_IMPROVED_TWO_WEAPON_FIGHTING, oFor) && (nSize >= CREATURE_SIZE_MEDIUM)) { switch (Random(3)) { case 0: return BASE_ITEM_DIREMACE; case 1: return BASE_ITEM_DOUBLEAXE; case 2: return BASE_ITEM_TWOBLADEDSWORD; } } // two-handed weapon if can't use shield if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor)) { switch(nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: case CREATURE_SIZE_MEDIUM: return BASE_ITEM_SCYTHE; case CREATURE_SIZE_SMALL: switch (Random(3)) { case 0: return BASE_ITEM_BASTARDSWORD; case 1: return BASE_ITEM_KATANA; case 2: return BASE_ITEM_DWARVENWARAXE; } case CREATURE_SIZE_TINY: switch (Random(3)) { case 0: return BASE_ITEM_KAMA; case 1: return BASE_ITEM_WHIP; case 2: return BASE_ITEM_KUKRI; } } } // one-handed weapon switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: return BASE_ITEM_SCYTHE; case CREATURE_SIZE_MEDIUM: switch (Random(3)) { case 0: return BASE_ITEM_BASTARDSWORD; case 1: return BASE_ITEM_KATANA; case 2: return BASE_ITEM_DWARVENWARAXE; } case CREATURE_SIZE_SMALL: switch (Random(3)) { case 0: return BASE_ITEM_KAMA; case 1: return BASE_ITEM_KUKRI; case 2: return BASE_ITEM_WHIP; } case CREATURE_SIZE_TINY: } } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oFor)) { if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor)) { // two-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: case CREATURE_SIZE_MEDIUM: switch (Random(4)) { case 0: return BASE_ITEM_HALBERD; case 1: return BASE_ITEM_GREATSWORD; case 2: return BASE_ITEM_GREATAXE; case 3: return BASE_ITEM_HEAVYFLAIL; } case CREATURE_SIZE_SMALL: switch (Random(6)) { case 0: return BASE_ITEM_LONGSWORD; case 1: return BASE_ITEM_RAPIER; case 2: return BASE_ITEM_SCIMITAR; case 3: return BASE_ITEM_BATTLEAXE; case 4: return BASE_ITEM_LIGHTFLAIL; case 5: return BASE_ITEM_WARHAMMER; } case CREATURE_SIZE_TINY: switch (Random(3)) { case 0: return BASE_ITEM_SHORTSWORD; case 1: return BASE_ITEM_HANDAXE; case 2: return BASE_ITEM_LIGHTHAMMER; } } } // one-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: switch (Random(4)) { case 0: return BASE_ITEM_HALBERD; case 1: return BASE_ITEM_GREATSWORD; case 2: return BASE_ITEM_GREATAXE; case 3: return BASE_ITEM_HEAVYFLAIL; } case CREATURE_SIZE_MEDIUM: switch (Random(6)) { case 0: return BASE_ITEM_LONGSWORD; case 1: return BASE_ITEM_RAPIER; case 2: return BASE_ITEM_SCIMITAR; case 3: return BASE_ITEM_BATTLEAXE; case 4: return BASE_ITEM_LIGHTFLAIL; case 5: return BASE_ITEM_WARHAMMER; } case CREATURE_SIZE_SMALL: switch (Random(3)) { case 0: return BASE_ITEM_SHORTSWORD; case 1: return BASE_ITEM_HANDAXE; case 2: return BASE_ITEM_LIGHTHAMMER; } case CREATURE_SIZE_TINY: } } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ELF, oFor)) { switch (Random(2)) { case 0: return BASE_ITEM_LONGSWORD; case 1: return BASE_ITEM_RAPIER; } } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oFor)) { if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor)) { // two-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: case CREATURE_SIZE_MEDIUM: return BASE_ITEM_QUARTERSTAFF; case CREATURE_SIZE_SMALL: switch (Random(3)) { case 0: return BASE_ITEM_CLUB; case 1: return BASE_ITEM_RAPIER; case 2: return BASE_ITEM_MORNINGSTAR; } case CREATURE_SIZE_TINY: switch (Random(3)) { case 0: return BASE_ITEM_HANDAXE; case 1: return BASE_ITEM_LIGHTMACE; case 2: return BASE_ITEM_SHORTSWORD; } } } // one-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: return BASE_ITEM_QUARTERSTAFF; case CREATURE_SIZE_MEDIUM: switch (Random(3)) { case 0: return BASE_ITEM_CLUB; case 1: return BASE_ITEM_RAPIER; case 2: return BASE_ITEM_MORNINGSTAR; } case CREATURE_SIZE_SMALL: switch (Random(2)) { case 0: return BASE_ITEM_HANDAXE; case 1: return BASE_ITEM_LIGHTMACE; case 2: return BASE_ITEM_SHORTSWORD; } case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER; } } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oFor)) { if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor)) { // two-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: case CREATURE_SIZE_MEDIUM: switch (Random(2)) { case 0: return BASE_ITEM_SHORTSPEAR; case 1: return BASE_ITEM_QUARTERSTAFF; } case CREATURE_SIZE_SMALL: switch (Random(2)) { case 0: return BASE_ITEM_CLUB; case 1: return BASE_ITEM_MORNINGSTAR; } case CREATURE_SIZE_TINY: switch (Random(2)) { case 0: return BASE_ITEM_LIGHTMACE; case 1: return BASE_ITEM_SICKLE; } } } // one-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: switch (Random(2)) { case 0: return BASE_ITEM_SHORTSPEAR; case 1: return BASE_ITEM_QUARTERSTAFF; } case CREATURE_SIZE_MEDIUM: switch (Random(2)) { case 0: return BASE_ITEM_CLUB; case 1: return BASE_ITEM_MORNINGSTAR; } case CREATURE_SIZE_SMALL: switch (Random(2)) { case 0: return BASE_ITEM_LIGHTMACE; case 1: return BASE_ITEM_SICKLE; } case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER; } } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oFor)) { if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor)) { // two-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: case CREATURE_SIZE_MEDIUM: switch (Random(2)) { case 0: return BASE_ITEM_SHORTSPEAR; case 1: return BASE_ITEM_QUARTERSTAFF; } case CREATURE_SIZE_SMALL: switch (Random(2)) { case 0: return BASE_ITEM_CLUB; case 1: return BASE_ITEM_SCIMITAR; } case CREATURE_SIZE_TINY: return BASE_ITEM_SICKLE; } } // one-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: switch (Random(2)) { case 0: return BASE_ITEM_SHORTSPEAR; case 1: return BASE_ITEM_QUARTERSTAFF; } case CREATURE_SIZE_MEDIUM: switch (Random(2)) { case 0: return BASE_ITEM_CLUB; case 1: return BASE_ITEM_SCIMITAR; } case CREATURE_SIZE_SMALL: return BASE_ITEM_SICKLE; case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER; } } if (GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oFor)) { if (!GetHasFeat(FEAT_SHIELD_PROFICIENCY, oFor)) { // two-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: case CREATURE_SIZE_MEDIUM: return BASE_ITEM_QUARTERSTAFF; case CREATURE_SIZE_SMALL: return BASE_ITEM_CLUB; case CREATURE_SIZE_TINY: } } // one-handed switch (nSize) { case CREATURE_SIZE_HUGE: case CREATURE_SIZE_LARGE: return BASE_ITEM_QUARTERSTAFF; case CREATURE_SIZE_MEDIUM: return BASE_ITEM_CLUB; case CREATURE_SIZE_SMALL: case CREATURE_SIZE_TINY: return BASE_ITEM_DAGGER; } } return BASE_ITEM_INVALID; } |
![]()
Сообщение
#93
|
|
Level 4 ![]() ![]() Класс: Некромант Характер: Chaotic Evil Раса: Нежить ![]() |
Не знаю было, нет что то подобное.
Скрипт, после смерти непися создает невидимый объект в который перекладываются все вещи моба, через минуту все уничтожается. Синьки: plc_сorpse - невидимый объект, plc_blood - пятно крови, появляется если на мобе весит локалка - no_blood. Переменные: no_blood - отвечает за появление пятна крови, если переменная TRUE - крови не будет. 1. onDeath, NPC: NSS void ClearInventory(object oTarget) { object oFirstItem = GetFirstItemInInventory(oTarget); while (GetIsObjectValid(oFirstItem)) { DestroyObject(oFirstItem); oFirstItem = GetNextItemInInventory(oTarget); } } void main() { SetIsDestroyable(FALSE, FALSE); object oCorpse = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_сorpse",GetLocation(OBJECT_SELF)); if (!GetLocalInt(OBJECT_SELF, "no_blood")) { object oBlood = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_blood", GetLocation(OBJECT_SELF)); DestroyObject(oBlood, 120.0f); } DestroyObject(oCorpse, 60.0f); DestroyObject(OBJECT_SELF, 60.0f); DelayCommand(59.0f, ClearInventory(oCorpse)); DelayCommand(60.0f, SetIsDestroyable(TRUE, FALSE)); object oItem = GetFirstItemInInventory(); while (GetIsObjectValid(oItem)) { if(GetBaseItemType(oItem) == BASE_ITEM_LARGEBOX) { CreateItemOnObject(GetResRef(oItem), oCorpse, 1); DestroyObject(oItem, 0.5); } else { CopyItem(oItem, oCorpse, TRUE); DestroyObject(oItem); } oItem = GetNextItemInInventory(); } int i; for (i=0; i<14; i++) { CopyItem(GetItemInSlot(i), oCorpse, TRUE); } } 2. На оnClose, oCorpse: NSS void main()
{ if (!GetIsObjectValid(GetFirstItemInInventory())) { DestroyObject(OBJECT_SELF, 0.5); } } Сообщение отредактировал Waromon - Aug 10 2006, 19:30 |
![]() ![]()
Сообщение
#94
|
|
Level 1 Класс: Тайный Лучник Характер: True Neutral Раса: Полуэльф ![]() |
Это мой скрипт для разных таверн.Официантка ходит по таверне подходит к разнам клиентам ,спрашивает заказ
идет к стойке берерт заказ идет назад к тому же клиенту отдает ему заказ и берет плату.Время от времени отдыхает и жалуется на жизнь.Реплики впишете сами не хотелось париться. Что бы скрипты правильно работали следует создать следущие вай поинты: Bar1-сюда приходят за напитками Rest1-здесь отдыхает wt_return1-ставиться возле бара WP_TavernPatronXX_01-ставится возле клиентов у каждого клиент должен быть свой номер ХХ Zone1-ставится где нибудь не подалеку от клиентов Этот скрипт ставится на оnUserDef NSS //////////////////////////////////////////////////////////////////////////////// // Written by Angelelf 24.03.06 // Скрипт придаю щий реальную атмосферу таверне // требуются следующие вай поинты // WP_WTCommon_Bar - место где берутся заказы.Бар // WP_Rest1 - Здесь она будет отдыхать // ZoneX - этот вай поинт обозначает зону обслуживания // X это номер зоны обслуживания начинается с 1 //////////////////////////////////////////////////////////////////////////////// void DrinkOrderKid(); // Заказ ребенка void DrinkOrder(); // Заказ посетителей string CountPatrons(); // Счетчик посетителей void GetQueryString(); // void TakeBreak(); // перерыв void GetMyPay(); // получение пллаты int StartingConditional() { return TRUE; } void DrinkOrderKid() // Заказ ребенка { int nOrder= -1; string sOrder; // реплика официанта string sAmount; // Реплика при передаче заказа string sBarkeepR;// Реплика бармена nOrder= d4(); switch(nOrder) { case 1: sOrder = "Бармен,стакан молока для ребенка."; sAmount = "Вот твое молоко."; sBarkeepR = "Один стакан свежего молока готов."; break; case 2: sOrder = "Один стакан воды пожалуйста"; sAmount = "Вот вода которую вы заказывали"; sBarkeepR = "Держи."; break; case 3: sOrder = "Можешь себе представить ребенок попросил водки"; sAmount = "Простите мы не продаем водку лицам моложе 18 лет"; sBarkeepR = "Когда они поймут что водка это вредно."; break; case 4: sOrder = "________"; sAmount = "________"; sBarkeepR = "_______."; break; } SetLocalString(OBJECT_SELF, "WG_ORDER", sOrder); SetLocalString(OBJECT_SELF, "WG_AMOUNT", sAmount); SetLocalString(OBJECT_SELF, "WG_BARKEEP", sBarkeepR); } void DrinkOrder() // заказы посетителей { int nOrder= -1; string sOrder; string sAmount; string patronOrder; string sBarkeepR; nOrder= d8(); switch(nOrder) { case 1: patronOrder = "Принеси мне эля."; // заказ sOrder = ""; //реплика официанта sAmount = ""; //реплика при передачи заказа sBarkeepR = ""; //реплика бармена break; case 2: patronOrder = ""; sOrder = ""; sAmount = ""; sBarkeepR = ""; break; case 3: patronOrder = ""; sOrder = ""; sAmount = ""; sBarkeepR = ""; break; case 4: patronOrder = ""; sOrder = ""; sAmount = ""; sBarkeepR = ""; break; case 5: patronOrder = ""; sOrder = ""; sAmount = ""; sBarkeepR = ""; break; case 6: patronOrder = ""; sOrder = ""; sAmount = ""; sBarkeepR = ""; break; case 7: patronOrder = ""; sOrder = ""; sAmount = ""; sBarkeepR = ""; break; case 8: patronOrder = ""; sOrder = ""; sBarkeepR = ""; sAmount = ""; break; } SetLocalString(OBJECT_SELF, "PATRON_ORDER", patronOrder); SetLocalString(OBJECT_SELF, "WG_ORDER", sOrder); SetLocalString(OBJECT_SELF, "WG_AMOUNT", sAmount); SetLocalString(OBJECT_SELF, "WG_BARKEEP", sBarkeepR); } string CountPatrons() { int i=-1; int j=-1; int myZone = GetLocalInt(OBJECT_SELF,"MyZone"); float size; switch(myZone) { // Изменяйте величену size чтоб официант обслуживал разных клиентов за круг это увеличит реальность case 1: size=15.0; break; case 2: size=15.0; break; case 3: size=21.0; break; case 4: size=7.0; break; } string myTag = "Zone" + IntToString(myZone); string patronTag; object oJunk = GetFirstObjectInShape(SHAPE_CUBE, size, GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); if ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF)) { oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); } while (oJunk != OBJECT_INVALID) { while ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF)) { oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); } i++; oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); } int bla=Random(i); oJunk = GetFirstObjectInShape(SHAPE_CUBE, size, GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); if ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF)) { oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); } while (oJunk != OBJECT_INVALID) { while ((GetIsPC(oJunk) == TRUE) || (oJunk == OBJECT_SELF)) { oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); } j++; if (j == bla) { patronTag = GetTag(oJunk); } oJunk=GetNextObjectInShape(SHAPE_CUBE, size,GetLocation(GetWaypointByTag(myTag)), TRUE, CREATURE_TYPE_PLAYER_CHAR); } return patronTag; } void GetQueryString() // Спрашивает заказ у PC { switch(Random(4)) { case 0: ActionSpeakString ("",TALKVOLUME_TALK); break; case 1: ActionSpeakString ("",TALKVOLUME_TALK); break; case 2: ActionSpeakString ("",TALKVOLUME_TALK); break; case 3: ActionSpeakString ("",TALKVOLUME_TALK); break; } } void TakeBreak() // реплики во время перерыва { switch(Random(4)) { case 0: ActionSpeakString ("",TALKVOLUME_TALK); break; case 1: ActionSpeakString ("",TALKVOLUME_TALK); break; case 2: ActionSpeakString ("I",TALKVOLUME_TALK); break; case 3: ActionSpeakString ("",TALKVOLUME_TALK); break; } } void GetMyPay() // gjctnbntkb jnlf.n gkfne { string payAmount; switch(d4()) { case 1: payAmount = "Вот твои деньги сдачи не надо"; break; case 2: payAmount = ""; break; case 3: payAmount = ""; break; case 4: payAmount = ""; break; } SetLocalString(OBJECT_SELF,"PAY_AMOUNT",payAmount); } void main() { int nUser = GetUserDefinedEventNumber(); string sQuery; string sOrder; int myZone = GetLocalInt(OBJECT_SELF,"MyZone"); string myPatron=CountPatrons(); string sAmount; string payAmount; string patronOrder; string sBarkeepR; int isKid; object oCustomer = GetLocalObject(OBJECT_SELF, "CUSTOMER"); object oBar; object oBar2; switch(myZone) { // Добавляйте или убирайте кол-во case в зависимости от того сколько зон вам надо обслуживать case 1: oBar = GetWaypointByTag("WP_WTCommon_Bar"); //Здесь официантка берет напитки oBar2 = GetWaypointByTag("Rest1"); //Сюда она возвращается когда разнесет напитки break; } if (nUser == 1001) { if (!GetIsObjectValid(oCustomer) && (GetLocalInt(OBJECT_SELF, "BARMAID_STATE") < 1)) { // идет к своему клиенту не игроку oCustomer = GetObjectByTag(myPatron); if (oCustomer != GetObjectByTag("Barkeeper") && oCustomer != OBJECT_SELF && GetIsObjectValid(oCustomer)) { // подходит к клиенту и спрашивает чего он хочет SetLocalInt (OBJECT_SELF, "BARMAID_STATE", 1); SetLocalObject (OBJECT_SELF, "CUSTOMER", oCustomer); ActionForceMoveToObject(oCustomer, FALSE, 0.5, 60.0); GetQueryString(); isKid = GetLocalInt(oCustomer,"IAmAKid"); if (isKid == 1) { DrinkOrderKid(); } else { DrinkOrder(); } ActionWait(1.0); patronOrder = GetLocalString(OBJECT_SELF,"PATRON_ORDER"); ActionDoCommand(AssignCommand(oCustomer,SpeakString(patronOrder,TALKVOLUME_TALK))); ActionWait(3.0); //ждет 3 сек // идет к бару за напитками ActionDoCommand (SetLocalInt(OBJECT_SELF, "BARMAID_STATE", 2)); ActionForceMoveToObject(oBar, FALSE, 0.5, 60.0); sOrder = GetLocalString(OBJECT_SELF,"WG_ORDER"); sBarkeepR = GetLocalString(OBJECT_SELF, "WG_BARKEEP"); ActionSpeakString (sOrder); ActionWait(3.0); // проверяет к тому ли бару она идет if(myZone == 1) { ActionDoCommand(AssignCommand(GetObjectByTag("wt_Barkeeper1"), ActionSpeakString (sBarkeepR,TALKVOLUME_TALK))); } else { ActionDoCommand(AssignCommand(GetObjectByTag("wt_Barkeeper2"), ActionSpeakString (sBarkeepR,TALKVOLUME_TALK))); } ActionWait(3.0); // возвращается к клиенту и отдает напитки ActionDoCommand (SetLocalInt(OBJECT_SELF, "BARMAID_STATE", 3)); ActionForceMoveToObject (oCustomer, FALSE, 0.5, 60.0); sAmount = GetLocalString(OBJECT_SELF,"WG_AMOUNT"); GetMyPay(); payAmount = GetLocalString(OBJECT_SELF,"PAY_AMOUNT"); if (sAmount == "**") // реакция на выражения { PlaySound("cb_ht_critical"); //звук payAmount = ""; // фраза } ActionSpeakString (sAmount); ActionWait(2.0); ActionDoCommand(AssignCommand(oCustomer,SpeakString(payAmount,TALKVOLUME_TALK))); ActionDoCommand (SetLocalObject(OBJECT_SELF, "CUSTOMER", OBJECT_INVALID)); // возвращается к бару и берет перерыв ActionForceMoveToObject(oBar2, FALSE, 0.5, 60.0); ActionWait(1.0); TakeBreak(); ActionWait(2.0); ActionDoCommand (SetLocalInt(OBJECT_SELF, "BARMAID_STATE", 0)); } } } if (nUser == 1004) { SetLocalObject (OBJECT_SELF, "CUSTOMER", OBJECT_INVALID); SetLocalInt (OBJECT_SELF, "BARMAID_STATE", 0); } } Этот на onSpawn официанта NSS //:://///////////////////////////////////////////// //:: Default: On Spawn In //:: NW_C2_DEFAULT9 //:: Copyright © 2001 Bioware Corp. //::////////////////////////////////////////////// /* Determines the course of action to be taken after having just been spawned in */ //::////////////////////////////////////////////// //:: Created By: Preston Watamaniuk //:: Created On: Oct 25, 2001 //::////////////////////////////////////////////// #include "NW_O2_CONINCLUDE" #include "NW_I0_GENERIC" void main() { SetLocalInt(OBJECT_SELF,"MyZone",1); // это значит что данный официант будет обслуживать зону 1.Создать вай поинт Zone1 // OPTIONAL BEHAVIORS (Comment In or Out to Activate ) **************************************************************************** //SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION); //SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION); // This causes the creature to say a special greeting in their conversation file // upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired // greeting in order to designate it. As the creature is actually saying this to // himself, don't attach any player responses to the greeting. //SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET); // This will set the listening pattern on the NPC to attack when allies call //SetSpawnInCondition(NW_FLAG_STEALTH); // If the NPC has stealth and they are a rogue go into stealth mode //SetSpawnInCondition(NW_FLAG_SEARCH); // If the NPC has Search go into Search Mode //SetSpawnInCondition(NW_FLAG_SET_WARNINGS); // This will set the NPC to give a warning to non-enemies before attacking //SetSpawnInCondition(NW_FLAG_SLEEP); //Creatures that spawn in during the night will be asleep. //SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING); //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION); //SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS); //SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS); //This will play Ambient Animations until the NPC sees an enemy or is cleared. //NOTE that these animations will play automatically for Encounter Creatures. // NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME. //SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.) //SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.) //SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.) //SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.) // CUSTOM USER DEFINED EVENTS /* The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined events user 1000 - 1010 */ SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001 //SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002 //SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005 //SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006 //SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008 //SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003 SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004 //SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007 // DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) ***************************************************************************************** SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to. WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0) // 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them // 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after // combat. // GenerateNPCTreasure(); //* Use this to create a small amount of treasure on the creature } Этот на onConvercation NSS //:://///////////////////////////////////////////// //:: SetListeningPatterns //:: NW_C2_DEFAULT4 //:: Copyright © 2001 Bioware Corp. //::////////////////////////////////////////////// /* Determines the course of action to be taken by the generic script after dialogue or a shout is initiated. */ //::////////////////////////////////////////////// //:: Created By: Preston Watamaniuk //:: Created On: Oct 24, 2001 //::////////////////////////////////////////////// #include "NW_I0_GENERIC" void main() { int nMatch = GetListenPatternNumber(); object oShouter = GetLastSpeaker(); object oIntruder; if (nMatch == -1 && GetCommandable(OBJECT_SELF)) { ClearAllActions(); BeginConversation(); ActionWait(8.0); } else if(nMatch != -1 && GetIsObjectValid(oShouter) && !GetIsPC(oShouter) && GetIsFriend(oShouter)) { if(nMatch == 4) { oIntruder = GetLocalObject(oShouter, "NW_BLOCKER_INTRUDER"); } else if (nMatch == 5) { oIntruder = GetLastHostileActor(oShouter); if(!GetIsObjectValid(oIntruder)) { oIntruder = GetAttemptedAttackTarget(); if(!GetIsObjectValid(oIntruder)) { oIntruder = GetAttemptedSpellTarget(); if(!GetIsObjectValid(oIntruder)) { oIntruder = OBJECT_INVALID; } } } } RespondToShout(oShouter, nMatch, oIntruder); } if(GetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT)) { SignalEvent(OBJECT_SELF, EventUserDefined(1004)); } } Этот на onDistr NSS //:://///////////////////////////////////////////// //:: Default: On Disturbed //:: NW_C2_DEFAULT8 //:: Copyright © 2001 Bioware Corp. //::////////////////////////////////////////////// /* Calls the end of combat script every round */ //::////////////////////////////////////////////// //:: Created By: Preston Watamaniuk //:: Created On: Oct 16, 2001 //:://///////////////////////////////////////// // * Make me hostile the faction of my last attacker (TEMP) // AdjustReputation(OBJECT_SELF,GetFaction(GetLastAttacker()),-100); // * Determined Combat Round #include "NW_I0_GENERIC" void main() { object oTarget = GetLastDisturbed(); if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget())) { if(GetIsObjectValid(oTarget)) { DetermineCombatRound(oTarget); } } if(GetSpawnInCondition(NW_FLAG_DISTURBED_EVENT)) { ActionWait(8.0); } } Этот сиавится на onSpawn клиента таверны NSS //:://///////////////////////////////////////////// //:: Default: On Spawn In //:: NW_C2_DEFAULT9 //:: Copyright © 2001 Bioware Corp. //::////////////////////////////////////////////// /* Determines the course of action to be taken after having just been spawned in */ //::////////////////////////////////////////////// //:: Created By: Preston Watamaniuk //:: Created On: Oct 25, 2001 //::////////////////////////////////////////////// #include "NW_O2_CONINCLUDE" #include "NW_I0_GENERIC" void main() { // OPTIONAL BEHAVIORS (Comment In or Out to Activate ) **************************************************************************** //SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION); //SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION); // This causes the creature to say a special greeting in their conversation file // upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired // greeting in order to designate it. As the creature is actually saying this to // himself, don't attach any player responses to the greeting. //SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET); // This will set the listening pattern on the NPC to attack when allies call //SetSpawnInCondition(NW_FLAG_STEALTH); // If the NPC has stealth and they are a rogue go into stealth mode //SetSpawnInCondition(NW_FLAG_SEARCH); // If the NPC has Search go into Search Mode //SetSpawnInCondition(NW_FLAG_SET_WARNINGS); // This will set the NPC to give a warning to non-enemies before attacking //SetSpawnInCondition(NW_FLAG_SLEEP); //Creatures that spawn in during the night will be asleep. //SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING); //SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION); //SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS); //SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS); //This will play Ambient Animations until the NPC sees an enemy or is cleared. //NOTE that these animations will play automatically for Encounter Creatures. // NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME. //SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.) //SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.) //SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.) //SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.) // CUSTOM USER DEFINED EVENTS /* Вот и все вроде бы скрипт работает без багов но если такие найдутся попытаесь разобраться в чем дело. |
![]()
Сообщение
#95
|
|
Level 5 ![]() Класс: Обыватель Характер: Lawful Neutral Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени ![]() |
Название: Рубка железных деревьев.
Описание: Дерево, которое можно рубить только специальным топором и после некоторых мучений отрубить таки сук. Другое оружие тупится об это дерево. скрипты: NSS // lx_pus_irontree // ставится на слот onUsed дерева void main() { object oPC = GetLastUsedBy(); object oTree = OBJECT_SELF; // если мы сук уже срубили - выдаем сообщение if (GetLocalInt(OBJECT_SELF,"CUTTED")) { FloatingTextStringOnCreature("**Нет ни одного подходящего сука, который можно было бы отрубить**",oPC); } else // если еще не срубили, тоже сообщение { FloatingTextStringOnCreature("**У дерева есть сук, котороый вполне можно отрубить**",oPC); // и начинаем рубить DelayCommand(0.8,AssignCommand(oPC,ClearAllActions())); DelayCommand(1.0,AssignCommand(oPC,ActionAttack(oTree))); } } NSS // lx_pat_irontree // скрипт на слот onAttacked дерева void main() { object oPC = GetLastAttacker(); // если рубить нечего - сообщение и выход (можно добавить сброс рубки, по желанию) if (GetLocalInt(OBJECT_SELF,"CUTTED")) { FloatingTextStringOnCreature("**Нет ни одного подходящего сука, который можно было бы отрубить**",oPC); return; } // оружие, которым ведется рубка object oW = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC); // если это особый топор (он у меня двуручный, поэтому проверяю только правую руку) if (GetTag(oW)=="ITM_GAXE_FORIRON") { // снимаем плот с дерева, теперь его можно дамажить (а до этого плот стоял по умочанию) SetPlotFlag(OBJECT_SELF,FALSE); } else // если же мы пытаемся рубить не нужным топором { // ставим плот SetPlotFlag(OBJECT_SELF,TRUE); // если оружие есть, то одно сообщение if (GetIsObjectValid(oW)) FloatingTextStringOnCreature("**Я только испорчу "+GetName(oW)+ " об это железное дерево**",oPC); // если нет - другое else FloatingTextStringOnCreature("**Я только себе руки в кровь разобью об это железное дерево**",oPC); } } NSS // lx_pdm_irontree // скрипт на слот onDamage дерева void main() { object oPC = GetLastDamager(); // если уже отрезано - чистим действия (сообщение было в *_pat_*) if (GetLocalInt(OBJECT_SELF,"CUTTED")) { AssignCommand(oPC,ClearAllActions(TRUE)); return; } // оружие, которым рубим object oW = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC); // если нужное - все ок if (GetTag(oW)=="ITM_GAXE_FORIRON") { // как только у дерева меньше 100 хп, значит сук мы срубили (у меня вначале стоит 150 хп) if (GetCurrentHitPoints()<100) { // отмечаем, что сук срублен SetLocalInt(OBJECT_SELF,"CUTTED",TRUE); // даем срубленный сук игроку CreateItemOnObject("ITM_IRONWOOD",oPC); // чистим действия и даем сообщение AssignCommand(oPC,ClearAllActions(TRUE)); FloatingTextStringOnCreature("**Вы срубили сук железного дерева**",oPC); } } else { // если рубим "левым" оружием SetPlotFlag(OBJECT_SELF,TRUE); if (GetIsObjectValid(oW)) { // то на оружии накапливается повреждение int SPL = GetLocalInt(oW,"SPOILING"); // и после 5 ударов по дереву if (SPL == 5) { // оружие тупится FloatingTextStringOnCreature("**Ваш "+GetName(oW)+ " затупился**",oPC); AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAttackPenalty(2),oW); AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamagePenalty(2),oW); SetLocalInt(oW,"SPOILING",6); } else { SetLocalInt(oW,"SPOILING",SPL+1); } } } } установка: - ставим в локации дерево, даем ему 150-200 хитов, ставим плот, настраиваем (я Hardness ставлю около 10) - ставим с слоты вышеуказанные скрипты - создаем в палитре предмет ITM_IRONWOOD ps: тут есть пара моментов, которые я упустил (ну мне они не очень актуальны) 1. не учитывается магия.. а надо бы (IMG:style_emoticons/kolobok_light/smile.gif) Думаю простого плота на onSpellCast будет достаточно 2. не учитывается вариант атаки дерева дальнобойным оружием. В этом случае не должно оно тупиться. Но это так же легко проверить, немного дописав скрит lx_pdm_irontree (IMG:style_emoticons/kolobok_light/smile.gif) |
![]()
Сообщение
#96
|
|
Level 17 ![]() Класс: Волшебник Характер: Neutral Good Раса: Человек NWN: Скриптинг [PW] Axistown SR 1.9 NWNX ![]() |
Пара скриптов посадки на стул:
NSS void main() { object oPC = GetLastUsedBy(); object oChair = OBJECT_SELF; if (!GetIsObjectValid (GetSittingCreature(oChair))) { AssignCommand(oPC, ActionSit(oChair)); } } NSS void main()
{ object oPlayer = GetLastUsedBy (); object oChair = OBJECT_SELF; object oSitter=GetSittingCreature(oChair); if (GetIsPC (oPlayer)) { if (GetIsObjectValid(oChair) && !GetIsObjectValid (oSitter)) { AssignCommand (oPlayer, ActionSit (oChair)); } } else if(!GetIsObjectValid(oSitter)) { AssignCommand(oPlayer, ActionSit(oChair)); } } |
![]()
Сообщение
#97
|
|
Level 9 ![]() Класс: Вор Характер: True Neutral Раса: Эльф NWN: Скриптинг [PW] ![]() |
но не для шардов :-)
|
![]()
Сообщение
#98
|
|
Level 17 ![]() Класс: Волшебник Характер: Neutral Good Раса: Человек NWN: Скриптинг [PW] Axistown SR 1.9 NWNX ![]() |
QUOTE(2_advanced @ Jan 29 2007, 13:44) [snapback]103439[/snapback] но не для шардов :-) Работало без проблем более 3 лет.
|
![]()
Сообщение
#99
|
|
Level 9 ![]() Класс: Вор Характер: True Neutral Раса: Эльф NWN: Скриптинг [PW] ![]() |
если сидячий персонаж выйдет из игры / перезайдет, уйдет в другую локу, то стульчик накроется:
GetSittingCreature на стуле останется до рестарта => проверять нужно GetSittingCreature не с запоротого стула, а с объекта, на который перс садится + место где он находится =) может уже в другой локе, а не рядом со стулом древний извращенский метод: NSS void main()
{ object oPC = GetLastUsedBy(); object oChair = OBJECT_SELF; if(GetIsObjectValid(oChair) && GetIsObjectValid(oPC)) { object oSurf = GetLocalObject(oChair, "surf"); // +очистка if(GetIsObjectValid(oSurf)) { object oSitter = GetSittingCreature(oSurf); if(!GetIsObjectValid(oSitter) || GetArea(oSitter) != GetArea(oChair)) DestroyObject(oSurf); else return; } vector vSurf = GetPosition(oChair); // сабж усаживал много персов на 1 скамейку (IMG:style_emoticons/kolobok_light/smile.gif) найду- выложу //vector vSurf = GenerateNewSurfPos(oChair, GetSubRace(oPC), GetGender(oPC)); location lSurf = Location(GetArea(oChair), vSurf, GetFacing(oChair)); object oNewSurf = CreateObject(OBJECT_TYPE_PLACEABLE, "sittingsurface", lSurf, FALSE); SetLocalObject(oChair, "surf", oNewSurf); AssignCommand(oPC, ActionSit(oNewSurf)); } } Сообщение отредактировал 2_advanced - Jan 30 2007, 08:44 |
![]()
Сообщение
#100
|
|
Level 17 ![]() Класс: Волшебник Характер: Neutral Good Раса: Человек NWN: Скриптинг [PW] Axistown SR 1.9 NWNX ![]() |
О глюках при перезаходе ни разу не слышал.
Может, это уже давно пофиксили в 1.67? Lex: QUOTE(virusman @ Jan 30 2007, 08:57) [snapback]103489[/snapback] О глюках при перезаходе ни разу не слышал. на Аксисе такие "запоротые" стулья были сто пудов, сам видел. А вот фиксено это на 1.67 или нет - мне не ведомо. Сообщение отредактировал Lex - Jan 31 2007, 19:40 |
![]() ![]() |
Текстовая версия | Сейчас: 26th April 2025 - 20:11 |