![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
![]()
Сообщение
#1
|
|
Level 11 ![]() Класс: Вор Характер: Neutral Evil Раса: Эльф NWN: Скриптинг [PW] Validor2 ![]() |
возможно где-то такое уже предлагалось, но я, честно говоря, такие вещи искать не привык - проще самому написать (IMG:style_emoticons/kolobok_light/smile.gif)
в общем в процессе переписывания старых скриптов под нужны нового модуля обратил внимание на убогость своей системы очищения шарда от ненужного шмота (а вместе с ним и лишних лагов (IMG:style_emoticons/kolobok_light/smile.gif) )... суть задачи: на шарде по локам появляются вещи (лут из мобов и игроков, просто выкинутые шмотки), которые нужно удалять... у каждой шмотки есть параметр - время через которое она должна быть удалена... нужно написать скрипт и засунуть его в такое место, чтобы результат и время выполнения скрипта были наиболее оптимальными... как пример, я рассматривал такой вариант: харбит локи, который собирает итемы + отдельные харбиты на каждом лутбеге... хотелось лучше (IMG:style_emoticons/kolobok_light/smile.gif) придумал я вот что... при создании каждого лутбега или в момент выкидывания игроком шмотки на землю на эти объекты создается своего рода ссылка... а именно - вейпоинты в отдельной локации, на которых хранитятся данные по этому объекту... само собой в локе есть харбит, которые по очереди эти вейпоинты чекает... т.е. в итоге вместо кучи харбитов получаем один... с одной стороны, за одним харбитом и следить проще... да к тому же время у меня из внешней бд запрашивается - а одно обращение в 10 сек к БД, это все таки не 100... с другой, время выполнения скрипта понятно что дольше, да и не понятно вообще насколько все это оптимальней получается (IMG:style_emoticons/kolobok_light/smile.gif) если кто что может подсказать по сути вопроса - буду рад... ну или может кто свои системы писал... собственно скрипты: процедура, которая создает вейпоинт-ссылку Neverwinter Script Source void CreateGarbageLink( object oObject, int nDestroyTime ) { object oItem = CreateObject( OBJECT_TYPE_WAYPOINT, GARBAGE_WP, GetLocation( GetObjectByTag( GARBAGE_LOCATION )) ); SetLocalObject( oObject, "oGarbageLink", oItem ); SetLocalObject( oItem, "oGarbageItem", oObject ); if( nDestroyTime>235900 ) nDestroyTime = 235900; // новый день SetLocalInt( oItem, "nDestroyTime", nDestroyTime ); } харбит локи Neverwinter Script Source void main( ) { int nCurrentTime = GetTime( ); int nDestroyTime; object oGarbageItem; int nDebugI = 0; object oWP = GetFirstObjectInArea( ); while( oWP!=OBJECT_INVALID && nDebugI<300 ){ nDestroyTime = GetLocalInt( oWP, "nDestroyTime" ); if( nDestroyTime>=0 ){ // если нет переменной nDestroyTime, значит это не GARBAGE_WP if( nDebugI>250 ){ // если мусора больше 250 вещей - удаляем все подряд oGarbageItem = GetLocalObject( oWP, "oGarbageItem" ); DeleteLocalObject( oGarbageItem, "oGarbageLink" ); DestroyObject( oGarbageItem ); DeleteLocalObject( oWP, "oGarbageItem" ); DeleteLocalInt( oWP, "nDestroyTime" ); DestroyObject( oWP ); }else if( nDebugI>150 ){ // если мусора больше 150 вещей - удаляем итемы ( лутпаки не трогаем ) oGarbageItem = GetLocalObject( oWP, "oGarbageItem" ); if( GetObjectType( oGarbageItem )==OBJECT_TYPE_ITEM ){ DeleteLocalObject( oGarbageItem, "oGarbageLink" ); DestroyObject( oGarbageItem ); DeleteLocalObject( oWP, "oGarbageItem" ); DeleteLocalInt( oWP, "nDestroyTime" ); DestroyObject( oWP ); } }else if( nDestroyTime<=nCurrentTime ){ oGarbageItem = GetLocalObject( oWP, "oGarbageItem" ); DeleteLocalObject( oGarbageItem, "oGarbageLink" ); DestroyObject( oGarbageItem ); DeleteLocalObject( oWP, "oGarbageItem" ); DeleteLocalInt( oWP, "nDestroyTime" ); DestroyObject( oWP ); } } oWP = GetNextObjectInArea( ); nDebugI++; } } скрипт на OnUnacquire модуля Neverwinter Script Source void main( ) { object oItem = GetModuleItemLost( ); object oPC = GetModuleItemLostBy( ); object oNewOwner = GetItemPossessor( oItem ); // проверяем только вещи игроков + вещь должна быть именно выложена, а не удалена if( GetIsPC( oPC ) && oItem!=OBJECT_INVALID && oNewOwner==OBJECT_INVALID ){ int nCurrentTime = GetTime( ); CreateGarbageLink( oItem, nCurrentTime+GARBAGE_DESTROY_DELAY ); } } скрипт на Acquire модуля (ну и по сути теже команды выполняются на скрипте OnDisturb лутбега, когда из него вытаскивают последнюю шмотку) Neverwinter Script Source void main( ) { object oItem = GetModuleItemAcquired( ); object oGarbageLink = GetLocalObject( oItem, "oGarbageLink" ); if( oGarbageLink!=OBJECT_INVALID ){ DeleteLocalObject( oItem, "oGarbageLink" ); DeleteLocalObject( oGarbageLink, "oGarbageItem" ); DeleteLocalInt( oGarbageLink, "nDestroyTime" ); DestroyObject( oGarbageLink ); } } |
![]() |
![]()
Сообщение
#2
|
|
Level 3 ![]() Класс: Обыватель Характер: Chaotic Evil Раса: Человек ![]() |
Я не видел нвн 2-3 года, предупреждаю.
Но как мне кажется все это излишне. Сделать можно намного проще. Создаем очередь FIFO через simply linked lists. При падении обьекта, добавляем в очередь поинтер на обьект. Задаем максимальную длинну очереди либо константу (скажем 50-70) в зависимости от популярности шарда, либо делаем длинну динамичной, прямопропорциональной кол-ву игроков онлайн (скажем 5-20 лежащих объектов на 1го игрока, ну и тогда меняем длинну на онЕнтер игроков или как там...) Соответственно когда упавших объектов на шарде становится больше заданого числа, самые старые объекты которые лежат уже несколько минут мы начинаем удалять. Что бы моментально доставать последний элемент, можно все это закодить через doubly linked circular lists, если хочешь. Если обьект вовремя подобран - находим в очереди и удаляем поинтер. Чаще всего он будет в самом начале листа. Все просто. Кодится немножко дольше, зато оптимальнее, на мой взгляд, раз в сто. Сообщение отредактировал Edwin - Jan 5 2008, 04:24 |
![]() ![]() |
Текстовая версия | Сейчас: 31st July 2025 - 15:14 |