Город Мастеров
IPB

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> Вендоры, Как очистить товары вендоров ?
Raven
сообщение Oct 24 2004, 12:19
Сообщение #1


Level 8
***

Класс: Фея
Характер: Chaotic Evil
Раса: Фея



Дарова всем...

Возник трабл - через некоторое время товары вендоров забиваются всяким гэ и сервак начинает жутко лагать... Как можно очистить товары вендоров от вещей игроков ?

Или может ... есть мысля создать вендора "Старьёвщик" - который бы покупал все вещи у игроков, а остальным вендорам запретить покупать вещи. Тогда какой скрипт нада написать, чтобы через некоторое время все товары этого старьёвщика очищались ?
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
balrog
сообщение Oct 24 2004, 12:27
Сообщение #2


Великий хранитель фотоальбома
Иконки Групп

Класс: Оборотень
Характер: Chaotic Neutral
Раса: Тварь
МАСТЕР Кисти



QUOTE
Скрипт для магазинов. Проверяет наличие такого товара в магазине, если уже есть - то после продажи удаляет. Нужен на шардах, где мазагины со временем забиваются ловушками, камнями и т.п. - при наличии более 10 страниц ассортимента в магазине начинаются заметные торможения сервера, проверенно.
Только одно требования к самим магазинам. В теге должно содержаться слово "_SHOP" (//Иначе нельзя узнать, магазин это или нет). - Вру ведь и никто не видит %)
Есть функция узнать тип объекта GetObjectType();
Вызывать из события модуля OnUnAcquireItem
Проще всего добавить в уже существующий обработчки строку:
ExecuteScript("at_check_dupe",OBJECT_SELF);

Сам скрипт:

Neverwinter Script Source
at_check_dupe


CODE

void main()
{
object oLostItem = GetModuleItemLost();
object oLostBy = GetModuleItemLostBy();
object oNewPosessor = GetItemPossessor(oLostItem);

if (FindSubString(GetStringUpperCase(GetTag(oNewPosessor)),"_SHOP"))
   {
    int n = 0;
    object oItem = GetFirstItemInInventory(oNewPosessor);
    while (GetIsObjectValid(oItem))
        {
          if (GetTag(oLostItem) == GetTag(oItem)) n++;
          if (n>1)
               {
                 DestroyObject(oLostItem);
                 break;
               }
          oItem = GetNextItemInInventory(oNewPosessor);
        }
   }
}


Я тут где-то на форуме видал такой .... он удоляет все повторные вещи ... по мне так даже лучше, а магазины делай шоб ничего не покупали, можешь какой нить ламбард сделать - шоб тока там скупалась всакая х***я :D
******************************************
Я конечно сам не проверял, сегодня вечерокм тэстить буду =)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Raven
сообщение Oct 24 2004, 15:43
Сообщение #3


Level 8
***

Класс: Фея
Характер: Chaotic Evil
Раса: Фея



Сделал немного проще - вещь сразу удаляется после продажи, но возникает мелкая проблемка.. Получается что игрок продает вещь, она оседает у вендора и удаляется - и получается, что между вещами, которые были у вендора появляется пустое место, которое раньше занимала удаленная вещь... можно ли как-то удалять вещь до попадания ее в инвентарь вендора или какой-то командой отсортировать вещи сразу после удаления ее из инвентаря вендора ?

Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Lex
сообщение Oct 24 2004, 20:05
Сообщение #4


Level 5
Иконки Групп

Класс: Обыватель
Характер: Lawful Neutral
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



сделай просто скупщика, у него после закрытия вендора чистится все. А с тем, с чем сталкнулся ты я встречался раньше...хз как это правильно делать, у меня были дырки, но я на них забил.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
_kaa_
сообщение Oct 25 2004, 12:28
Сообщение #5


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



Это старый и не совсем правильный вариант. Приставка _SHOP - не обязательна, можно просто проверять тип объекта.
Надо заменить первую проверку
Neverwinter Script Source
if (FindSubString(GetStringUpperCase(GetTag(oNewPosessor)),"_SHOP"))

на
Neverwinter Script Source
if (GetObjectType(oNewPosessor) == OBJECT_TYPE_STORE)


Так же помогают новые возможности SoU, т.е. ограничение денег у продовца, перечисление типов покупаемых\непокупаемых товаров и т.д.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Raven
сообщение Oct 25 2004, 12:43
Сообщение #6


Level 8
***

Класс: Фея
Характер: Chaotic Evil
Раса: Фея



QUOTE
if (GetObjectType(oNewPosessor) == OBJECT_TYPE_STORE)


Так и сделал :yes:

Вопросец - мона ли сделать так, чтобы юзерские вещи у вендора очищались через некоторое время ?

Можно в принципе на OnAcquireItem и на OnClientEnter дописать в скриптах, чтобы всем игроцким вещам давалась локальная переменная, чтобы отличить вещи вендоров от игроцких... Ну и потом на OnStoreClose DelayCommand , чтобы понаходить все вещи игроков и уничтожить... Вопрос вот в чем - возможно ли на OnStoreClose в скрипте DelayCommand прописать и не вызовет ли это лаги сервера ?
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
_kaa_
сообщение Oct 25 2004, 12:49
Сообщение #7


Level 9
Иконки Групп

Класс: Волшебник
Характер: Chaotic Good
Раса: Дракон
NWN: Скриптинг [PW]



DB одно время говорил, что если очередь превышает 75 команд - начинаются траблы. Не знаю, как обстоит дело сейчас, но в любом случае перегружать очередь не нужно.
Можно повесить скрипт очистки на какое-нибудь переодическое событие (раз в час, в день и т.д.)
По поводу "вешать переменную" - можешь делать это прямо в скрипте этом. Он как раз срабатывает в момент получения вещи магазином.
Только одно "НО". Когда такой итем снова купит игрок - переменную надо удалять, иначе она останется на предмете и сохраниться в .bic файл игрока. Зачем тебе лишние несколько килобайт на каждом игроке? :)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Twin
сообщение Nov 24 2004, 08:38
Сообщение #8


Level 5
**

Класс: Некромант
Характер: Neutral Evil
Раса: Нежить
NWN: Скриптинг [PW]



У меня получилось решить проблему дырок от DestroyObject(). Если после этого мы делаем CreateItemOnObject() в инвентаре торговца, то эти дырки пропадают, происходит пересортировка ассортимента. Так вот, как теперь избавится от дырок, но и чтобы не оставалось предмета от CreateItemOnObject()? Довольно просто... Создает в синьке ОЧЕНЬ дорогой предмет, дороже любой вещи на шарде. И просто для убирания дырок влепливаем его в CreateItemOnObject(), а потом спокойно удаляем. Т.к. этот дорогой предмет будет в са-а-амом конце ассортимента, то и дырки после него уж точно не останется. Имхо. ;) :ww:
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Twin
сообщение Nov 24 2004, 10:35
Сообщение #9


Level 5
**

Класс: Некромант
Характер: Neutral Evil
Раса: Нежить
NWN: Скриптинг [PW]



Скриптик для шардов, где не хотят по простому удалять продаваемые игроком предметы и в тоже время очень не нужен спам одинаковых товаров на несколько страниц, который способствует лагам всего шарда.

Сохраняем под именем "tw_inc_shoplist" следующее:
Neverwinter Script Source
//:://////////////////////////////////////////////
//:: Created By: Twin
//:: Communication:
//::  E-mail: twin_quad@hotmail.com
//::  IRC: Twin@irc.rinet.ru:6669
//::
//:: Created On: 2004.11.24
//:://////////////////////////////////////////////
//:: Description:
//::  Скрипт в момент продажи игроком в магазин, проверzет,
//::  есть ли уже данный товар в ассортименте. Если есть,
//::  то копиz удалzетсz, а в базе магазина записываетсz,
//::  что данного товара теперь на единицу больше.
//::
//::  В момент покупки из магазина, скрипт создает еще одну
//::  копию купленного предмета, если в базе есть запись о том,
//::  что данный товар не закончилсz.
//:://////////////////////////////////////////////

// Declarations
void SpecSL_Sell();
void SpecSL_Buy();
void SpecSL_UpdateList(object oVendor, object oDisturbedItem, int nSellStack);
void SpecSL_CreateItem(string sResRef, object oVendor, int nStackSize);
string SpecSL_Variable (string sResRef, string sTag);

/*
** Игрок продает товар в магазин.
** Если в магазине данный предмет уже существует и он бесконечен,
** то этот триггер вообще не срабатывает.
*/

void SpecSL_Sell()
{
    object oLostItem = GetModuleItemLost();
    object oNewPosessor = GetItemPossessor(oLostItem);

    if (
        !GetIsObjectValid(oNewPosessor) ||
        GetObjectType(oNewPosessor) != OBJECT_TYPE_STORE ||
        !GetLocalInt(oNewPosessor, "SPECIAL_SHOP_LIST")
    )
        return;

    SpecSL_UpdateList(oNewPosessor, oLostItem, GetNumStackedItems(oLostItem));
}

/*
** Игрок покупает товар в магазине.
** Триггер срабатывае даже если этот предмет бессконечен.
*/

void SpecSL_Buy()
{
    object oLostBy = GetModuleItemAcquiredFrom();

    if (
        !GetIsObjectValid(oLostBy) ||
        GetObjectType(oLostBy) != OBJECT_TYPE_STORE ||
        !GetLocalInt(oLostBy, "SPECIAL_SHOP_LIST")
    )
        return;

    object oLostItem = GetModuleItemAcquired();

    // Флаг длz того чтобы определить купленную в данном магазине вещь,
    // если будут баги в этой системе. После удачного бета-теста нужно удалить.
    //SetLocalInt(oLostItem, "SSL_FLAG", 1);

    SpecSL_UpdateList(oLostBy, oLostItem, 0);
}

string SpecSL_Variable(string sResRef, string sTag)
{
    return "SSL_"+ sResRef +"!"+ sTag;
}

/*
** Удаление всех вещей, эквивалентных проданной/купленной
** и создание единственного экземплzра.
*/

void SpecSL_UpdateList(object oVendor, object oDisturbedItem, int nSellStack)
{
    string sResRef = GetResRef(oDisturbedItem);
    string sTag = GetTag(oDisturbedItem);

    int nCountItems = 0, nStackSize = 1;

    object oItem = GetFirstItemInInventory(oVendor);

    while (GetIsObjectValid(oItem))
    {
        if (
            sResRef == GetResRef(oItem) &&
            sTag == GetTag(oItem)
        ) {
            nCountItems = nCountItems + GetNumStackedItems(oItem);

            // Если игрок продает вещь, то уничтожаем её и все такие же.
            if (nSellStack)
                DestroyObject(oItem);
        }

        oItem = GetNextItemInInventory(oVendor);
    }

    // Это, возможно, бесконечный предмет.
    if (!nSellStack && nCountItems) {
        //SendMessageToPC(GetFirstPC(), "Infinite");
        return;
    }

    nCountItems += GetLocalInt(oVendor, SpecSL_Variable(sResRef, sTag));

    //SendMessageToPC(GetFirstPC(), "NEW nCountItems == "+ IntToString(nCountItems));

    // Берем из 2da размер стеков длz стандартной амуниции к оружию.
    if (GetBaseItemType(oDisturbedItem) == BASE_ITEM_ARROW)
        nStackSize = StringToInt(Get2DAString("baseitems", "Stacking", 20));
    if (GetBaseItemType(oDisturbedItem) == BASE_ITEM_BOLT)
        nStackSize = StringToInt(Get2DAString("baseitems", "Stacking", 25));
    if (GetBaseItemType(oDisturbedItem) == BASE_ITEM_BULLET)
        nStackSize = StringToInt(Get2DAString("baseitems", "Stacking", 27));
    if (GetBaseItemType(oDisturbedItem) == BASE_ITEM_DART)
        nStackSize = StringToInt(Get2DAString("baseitems", "Stacking", 31));
    if (GetBaseItemType(oDisturbedItem) == BASE_ITEM_SHURIKEN)
        nStackSize = StringToInt(Get2DAString("baseitems", "Stacking", 59));
    if (GetBaseItemType(oDisturbedItem) == BASE_ITEM_THROWINGAXE)
        nStackSize = StringToInt(Get2DAString("baseitems", "Stacking", 63));

    if (nStackSize > nCountItems)
        nStackSize = nCountItems;

    //SendMessageToPC(GetFirstPC(), "nStackSize == "+ IntToString(nStackSize));

    nCountItems -= nStackSize;
    if (!nCountItems)
        DeleteLocalInt(oVendor, SpecSL_Variable(sResRef, sTag));
    else
        SetLocalInt(oVendor, SpecSL_Variable(sResRef, sTag), nCountItems);

    //SendMessageToPC(GetFirstPC(), "NEW2 nCountItems == "+ IntToString(nCountItems));

    if (!nStackSize)
        return;

    DelayCommand(0.04f,
        SpecSL_CreateItem(sResRef, oVendor, nStackSize)
    );
}

void SpecSL_CreateItem(string sResRef, object oVendor, int nStackSize)
{
    CreateItemOnObject(sResRef, oVendor, nStackSize);
}

Нужно:
в OnItemAcquire и в OnItemUnAcquire наверху дописать
Neverwinter Script Source
#include "tw_inc_shoplist"

в OnItemAcquire вниз дописать
Neverwinter Script Source
SpecSL_Buy();

в OnItemUnAcquire вниз дописать
Neverwinter Script Source
SpecSL_Sell();

На мерчанта в тулсете нужно вешать LocalInt "SPECIAL_SHOP_LIST" со значением 1.

Также нужно соблюдать следующее условие: нельзя делать в магазине один и тот же предмет несколько раз. Можно сделать 5 бутылок в стеке, но не 5 раз по одной бутылке. Имеется в виду, нельзя этого делать во время создания модуля, т.е. через тулсет. Это вынужденная мера, из-за того что тулсет не даёт возможности определить бесконечен ли данный товар в магазине или нет.

Всё! ;)

Хотелось бы, чтобы кто-нибудь протестил работу в полевых условиях, т.е. непосредственно на каком-нибудь шарде... Хотя если у меня одного работало, то должно и на шарде нормально... Т.к. глючить нечему особо. :)

Сообщение отредактировал Twin - Nov 24 2004, 10:57
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 24th April 2024 - 09:03