Библиотечка нескольких функций для работы со строками, фактически написана ради одной функции. Насколько оптимален алгоритм не знаю, но годится для обычных проверок на нужные тэги.
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);
}