При вылетах по invalid vertex, отсутствующих путях, при ругани restrictor на отсутствие объекта, в других игровых ситуациях возникает необходимость удалить "мешающий" объект. Замечание: удаляйте объекты, будучи в полной уверенности, что они больше не нужны.
1. В файле gamedata\scripts\bind_stalker.script найти закомментированный блок кода:
Код
--[[local bad_object_names = {"wpn_lr30053522", "wpn_lr30058409" } --"wpn_lr30025601", "wpn_lr30028817","wpn_lr30033589" local i, se_name, se_obj
for i, se_name in ipairs(bad_object_names) do se_obj = alife():object(se_name) if se_obj then news_manager.send_tip(db.actor,"Удалили глючный ствол:"..se_name,nil,nil,1000) alife():release(se_obj, true) end end]]
2. Убрать комментарии --[[ в начале перед local и ]] в конце после end.
3. В bad_object_names вместо указанных для примера наименований стволов вписать названия объектов, которые имеется необходимость удалить. Каждое наименование заключается в "", наименования, если их более одного, следует перечислять через запятую.
Пример 1. Удаление рестриктора удаления Седого (АТП, мобильный торговец)
Код
local bad_object_names = {"atp_sedoy_delete_restrictor"}
Пример 2. Удаление вечно глючных зомбиков (Саркофаг, к примеру их 2)
Код
local bad_object_names = {"sarc_arhara_zombied_respawn_154797", "sarc_arhara_zombied_respawn_149048"}
4. Сохранить скрипт и загрузить нужный сэйв. Удаление будет выполнено во время загрузки, ГГ получит соответствующее сообщение. Удаленный один раз объект более раз удалять не нужно.
Лечение: достаточно дописать в файл gamedata\scripts\se_respawn.script следующую строку:
Код
get_console():execute("load ~ Spawn now ["..tostring(self:name()).."] -> ["..obj:name().."]")
перед строкой amk.on_REspawn(obj,self). Примечание: то, что в консоль будет выводится красным текст типа такого: ! Cannot find saved game ~ spawn now [amk_embankment_soldat_respawn] -> [esc_soldier_respawn_specnaz21604] - не ошибка, просто информация.
Иногда могут возникнуть спонтанные вылеты без вменяемого лога. Например это было замечено в лаборатории Х-10 или на Дикой территории. В некоторых случаях помогает временно уменьшить онлайн-зону ГГ до маленьких значений. Это позволит, скорее всего пройти проблемный участок. Чтобы уменьшить/увеличить switch_distance надо: 1. Выйти из игры. 2. Найти файл gamedata\config\alife.ltx. 3. В нем найти строчку switch_distance. 4. И изменить значение параметра на другое число, в данном случае нам надо уменьшить. Ставим ноль. Должно получится так: switch_distance = 0. 5. Сохраняем файл. 6. После прохождения проблемного места, выходим из игры и возвращаем значение назад. После чего играем дальше.
Дополнительно:
Лог - это файл в котором фиксируется вся работа движка S.T.A.L.K.E.R. во время игры, а также сохраняются сведения об обычных некритичных ошибках и ошибках, приводящих к вылету. В большинстве случаев важна сама ошибка (т.е. последние строчки лога).
Где искать файл с логом: В Windows XP (По умолчанию) - C:\Documents and Settings\All Users\STALKER-SHOC\logs\xray_<ваше_имя_пользователя>.log В Windows Vista (По умолчанию) - C:\Users\Public\Documents\STALKER-SHOC\logs\xray_<ваше_имя_пользователя>.log B Windows 7 (По умолчанию) - C:\Users\Public\Documents\STALKER-SHOC\logs\xray_<ваше_имя_пользователя>.log
Можно ещё поступить так: 1. После вылета создать текстовый документ. 2. Правой кнопкой мыши на свободном месте нажать Вставить и появится ошибка.
После открытия файла с ошибкой видим много всего, пролистываем все это и в самом низу будет лог ошибки. Он начинается с FATAL ERROR. Еще бывают вылеты безголовые, в которых файл лога пустой. Здесь скорее всего проблемы с железом, либо со скачанными файлами.
Информация от Верховного Шамана мода OGSE KamikaZze (инфа сталкерам для понимания что и из-за чего происходит вылет) + дополнения
1) Вылеты при нехватке памяти:
Симптом: любой вылет со ссылкой на "out of memory" или аналогично "insufficient resources available" или "no more data is available". Кроме того, некоторые вылеты с "Can't open section" тоже могут быть связаны с нехваткой памяти.
Причина: STALKER – игра крайне требовательная к ресурсам, она перегружена даже в чистом виде, и в особенности некоторые карты – Кордон, Тёмная Долина, Армейские Склады, Припять. При этом совершенно НЕ ИМЕЕТ ЗНАЧЕНИЯ сколько у вас оперативной памяти! Для процессов 32-битной версии Виндовс доступная память ограничена 2 Гб и не больше.
Лечение: снизьте качество текстур, или в особо тяжких случаях, перейдите на статичное освещение. Кроме того, можно попробовать играть с опцией командной строки " -noprefetch". Эту опцию без кавычек можно вбить в свойства ярлыка сталкера через пробел сразу за ссылкой на экзешник игры. Если же вы играете на Висте, можно попробовать играть, запустив сначала команду "bcdedit /SetIncreaseUserVA 2700", залогинившись с административными правами.
2) Вылеты рендера:
Симптом:
Код
stack trace:
001B:0188B3B6 xrRender_R1.dll or 001B:02C09EE6 xrRender_R2.dll
Причина: это проблема с видеодрайвером, связанная с тем, что игра передала функции драйвера неверные данные или возможно подвисшим потоком обработки видеоданных...
Лечение: хорошо в этом вылете то, что он обычно только временная проблема, и лечится простой загрузкой с последнего сейва. Основная локация таких вылетов – Янтарь, они часто случаются к северо-востоку от бункера экологов.
3) Вылеты с потерянным игрой или уничтоженным оружием
Scheduler tried to update object lvl_community_respawn_xxxxx (e.g., esc_soldier_respawn_11350)
Причина: этот вылет обычно возникает когда оружие свежеубитого непися уничтожено или покинуло уровень (провалилось сквозь землю) в тот момент когда его хотел подобрать другой непись или главгерой
Лечение: обычно достаточно просто загрузить последний сейв и вылет пропадает.
4) Вылеты с боем сейвов – большей частью исправлены в патче 1.0004, но могут возникать и в 1.0005
Симптом примерно такой:
Код
stack trace:
xrGame.dll xrGame.dll
или ошибка "Can't open section"
Причина: Сейвгейм повреждён. Это например может произойти в том случае, когда игра уничтожила труп, но не очистила точку на карте, привязанную к нему. Вы также получите эту проблему если увидели в логе строку вида:
Код
"- Critical: SMapLocation binded to non-existent object id=xxxxx"
Её, впрочем очень легко пропустить, так как она обычно пролетает в логе намного, намного раньше того момента, как вы попробуете загрузить побитый в результате сейв. Пропадания трупов такого рода часты в модах или на Арене, однако не менее часто они происходят когда аномалия, например сильная Гравии разрывает труп.
Лечение: в этом случае придётся искать более раннее сохранение, где эта проблема ещё не возникла.
5) Некорректное место спавна:
Симптом примерно такой:
Код
! Cannot build GAME path! (object m_tushkano_normal21511) ! CURRENT LEVEL : l10_radar ! CURRENT game point position : [376.978180][-51.199860][29.992897]
FATAL ERROR
[error]Expression : I != levels().end() [error]Function : GameGraph::CHeader::level [error]File : e:\stalker\patch_1_0004\xr_3da\xrgame\game_graph_inline.h [error]Line : 171 [error]Description : there is no specified level in the game graph : 96
stack trace:
Scheduler tried to update object m_tushkano_normal21511
... или что-то вроде вот этого ...
Код
FATAL ERROR
[error]Expression : false [error]Function : CGameGraph::distance [error]File : e:\stalker\patch_1_0004\xr_3da\xrgame\game_graph_inline.h [error]Line : 96 [error]Description : There is no proper graph point neighbour!
stack trace:
Причина: некий мутант или непись заспавнился в некорректном месте. Причина этого в том, что А-лайф спавнит их в некотором произвольном радиусе от точки спавна, что позволяет каждый раз спавн разнообразить. К сожалению, иногда он умудряется поместить живность в точку снаружи уровня – под землю или в стену, или заспавненый объект проваливается под уровень.
Лечение: обычно достаточно просто загрузить последний сейв и вылет пропадает. В особо тяжких случаях, когда вы умудрились сохранится рядом с уже застрявшим так неписем или монстром вам придётся убежать на другую локацию, чтобы эта животина в оффлайне ушла в нормальное место.
6) Некорректное место спавна – второй вариант:
Симптом примерно такой:
Код
! DetailPathManager has failed : from [142.099976,-4.614447,445.899963] to [142.099976,-5.792273,443.799988] ! DetailPathManager has failed : from [142.099976,-4.614447,445.899963] to [142.099976,-5.792273,443.799988] ! DetailPathManager has failed : from [142.099976,-4.614447,445.899963] to [142.099976,-5.792273,443.799988]
Причина: непись или мутант перешёл в онлайн в неудачном месте, и не может найти выход чтобы пойти в точку назначения. Игра использует для навигации существ сеть квадратов, соединённых между собой, однако некоторые из них изолированы друг от друга. Например камни на границе карты, или места на другой высоте чем точка назначения.
Лечение: обычно достаточно просто загрузить последний сейв и вылет пропадает. В особо тяжких случаях, когда вы умудрились сохранится рядом с уже застрявшим так неписем или монстром вам придётся убежать на другую локацию, чтобы эта животина в оффлайне ушла в нормальное место.
7) Вылеты вида «Bad argument #2 to 'format'» или аналогичные
Причина: обычная причина этих вылетов – передача некорректных значений родным функциям игры. Эти ошибки обычно возникают когда произошёл какой-то серьёзный сбой, и о таких вылетах желательно сообщать разработчикам. Если такой вылет случился желательно так же сбросить текст выше строки FATAL ERROR из лога.
Лечение: обычно достаточно просто загрузить последний сейв и вылет пропадает. Если же этот вылет у вас происходит при загрузке сейва – сбросьте его разработчикам мода с логом вылета.
Причина: обычно связан с отработкой физики и анимации. Если происходит стабильно на каком-то специфичном персонаже – сообщите разработчикам.
Лечение: обычно достаточно просто загрузить последний сейв.
10) Редкий родной вылет 3: ParticleManager
Симптом:
Любой вылет со ссылкой на ParticleManager.
Причина: обычно происходит при воспроиведении частиц – дыма костров, огня, стрельбы и т.д.
Лечение: во многих случаях помогает обновление драйверов видеокарты
11) Две или более ошибки друг за другом
Симптом:
Код
[error][183] : Cannot create a file when that file already exists.
Причина: обычно это просто две одинаковых ошибки, произошедших одновременно
Лечение: в логе обычно есть и первая ошибка из серии. Разбирайтесь с ней так, как описано выше для ошибок этого вида.
12) Ошибки пути или маршрутов
Симптом примерно такой:
Код
Expression : ai().level_graph().valid_vertex_id(vertex->data().level_vertex_id()) Function : CPatrolPathManager::select_point File : E:/stalker/patch_1_0004/xr_3da/xrGame/patrol_path_manager.cpp Line : 164 Description : patrol path[mil_mercs_walker_3_walk], point on path [name07],object [ros_killer_respawn_230016]
Причина: в игре даже пропатченной до версии 1.0005 всё ещё есть проблемы с маршрутами.
Лечение: обычно достаточно просто загрузить последний сейв и не сохраняться рядом с местами, где происходят такие вылеты.
13) Вылеты типа:
Код
Expression : error handler is invoked! Function : invalid_parameter_handler File : E:\stalker\sources\trunk\xrCore\xrDebugNew.cpp Line : 800 Description :
Expression : error handler is invoked! Function : invalid_parameter_handler File : E:\stalker\sources\trunk\xrCore\xrDebugNew.cpp Line : 804 Description :
Причина: подобный вылет говорит о том, что в игре инициализируется некий объект у которого в параметрах присутствует некорректное значение (например нулевое).
Лечение: искать в конфигах некорректно прописанную строку. Ошибка очень редка и без рабочего сейва, на котором эта ошибка воспроизводится, устранить ее не представляется возможным.
14) Ошибки типа:
Код
Line : 12 Description : e_parent && e_entity
или
Line : 804 Expression : error handler is invoked!
Они известны, но корни которых уходят в движок, конфиги, текстуры... Такие ошибки встречаются в любом моде и в оригинале и не воспроизводятся.
15) Ошибки типа "_g.script:22": - это только факт вызова принудительного прерывания из-за возникновения ошибки/проблемы в каком-то из скриптов и вызывается искусственно! - если этот флаг-ошибка возникла (т.е. вылет игры по _g.script) то следует не "мазать зеленкой" нарыв а лечить! Т.е. смотреть строки над секцией [FATAL ERROR], в которых как правило указан источник и причина ошибки, и искать/исправлять/...
16) Ошибка: xr_logic:pstor_load_all:not_registered_type_N=[ХХХ]_encountered - следствие того, что какой-то объект при запуске игры/сэйва не был до конца инициализирован и при следующей записи сэйва не были записаны его данные. При чтении этого же сэйва этот непрописанный предмет все одно начинает читаться и ... считываются данные не предназначенные для него. Это приводит к некорректным значениям и соответственно прерыванию игры. Если такие сейвы есть и они с игры начатой на новых фиксах - стОит их дать в разработку. Такие объекты нужно искать и искать причины их недоинициализации.
17) Прямо над строкой в логе: "ВНИМАНИЕ!_Игра_принудительно_прерывается!" При данном типе ошибок всегда присутствует строка типа:
В которой указан и конкретный 'виновник" (в данном случае: obj=[prapor_mafon]) и явно странная 'кракозяба': var[)=[] и странная запись: type=[244] на которую в нижних строках у ссылается причина прерывания. Все это говорит о запорченной информации, которую игра пытается загрузить.
18) Вылет типа:
Код
FATAL ERROR
[error]Expression : false [error]Function : CGameObject::ef_detector_type [error]File : E:\stalker\sources\trunk\xr_3da\xrGame\GameObject.cpp [error]Line : 857 [error]Description : Invalid detector type request, virtual function is not properly overridden! [error]Arguments : C_HLCP_S
stack trace:
Пояснение: 'C_HLCP_S' - это что-то вертушка заплуталась в Темной долине... Встречается подобное, хотя о-о-чень редко, поэтому до сих пор не отловлено.
19) Вылет типа:
Код
Expression : e_entity Function : xrServer::Process_event_reject File : E:\stalker\patch_1_0004\xr_3da\xrGame\xrServer_process_event_reject.cpp Line : 12 Description : entity not found.
Пояснение: ошибка 1.0004 патча. Исправляется установкой более новой версии патча для ТЧ.
Лечение: не сохраняйтесь с нестандартными подствольными гранатами в подствольниках автоматов и в Бульдоге + не оставляйте в нычках/рюкзаках/ящиках оружие с заряженными в подствольники гранатами.
21) Вылет по вертексам:
Код
FATAL ERROR
[error]Expression : vertex || show_restrictions(m_object) [error]Function : CPatrolPathManager::select_point [error]File : E:\stalker\sources\trunk\xr_3da\xrGame\patrol_path_manager.cpp [error]Line : 155 [error]Description : any vertex in patrol path [rostok_sniper_3_walk] in inaccessible for object [rostok_stalker_0002]
Проблемы самой игры. Мод не причем. Это конечная точка пути какого-то НПС или монстра совпадает с точкой появившейся аномалии (одна логика наложилась на другую логику, вот и вылет из-за этого). Такая ошибка будет возникать все чаще и чаще с вводом динамических аномалий.
Решение банальное - или перезайти на локацию (загрузить автоматическую запись по заходу на локацию) или сделать запись и опять загрузиться, возможно аномалия образуется в другом месте и тогда ошибок наложения точек логики не будет.
22) Вылет типа:
Код
FATAL ERROR
[error]Expression : fatal error [error]Function : CScriptEngine::lua_error [error]File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp [error]Line : 73 [error]Description : <no expression> [error]Arguments : LUA error: ...обыля\s.t.a.l.k.e.r\gamedata\scripts\xr_gulag.script:1190: attempt to index field 'gulag' (a nil value)
Редкий, но противный вылет. Чаще всего появляется на Дикой Территории.
Лечение: загрузить сейв до проблемного захода на локацию. --------------------------------------------
На самом деле это не ошибка, а предупреждение движка или отладочное сообщение. Никаких проблем это не вызывает.
Перед тем как писать о вылете обязательно прочитайте информацию выше - вполне возможно, решение уже есть.
1. Пост без лога вылета\без полного игрового набора или с явными намеками на вмешательство в ресурсы мода, в лучшем случае будет просто игнорироваться. С уже вылеченными вылетами - аналогично. 2. Также, перед тем как написать пост о вылете, используйте поиск на форуме. 3. Даже не пытайтесь писать, что после установки мода игра не работает, за последствия неумелой установки я не отвечаю.
Demetrix, Чтобы убрать кровавый туман после попадания нужно в файле gamedata/config/ui/ui_custom_msgs.xml найти <hud_blood1 x="0" y="0" width="1024" height="768" stretch="1"> и перед 1024 поставить минус <hud_blood1 x="0" y="0" width="-1024" height="768" stretch="1"> вот так И сделать это нужно для всех hud_blood их там пять. Мутант из тумана☻
Всем привет и заранее спасибо за помощь! У меня на Радаре после х-10 по пути к переходу в припять сталкеры свободы и долга затеивают стычку. В самом начале стычки у меня происходит вылет [error]Expression : fatal error [error]Function : _out_of_memory [error]File : E:\stalker\patch_1_0004\xrCore\xrDebugNew.cpp [error]Line : 359 [error]Description : <no expression> [error]Arguments : Out of memory. Memory request: 114688 K
причем Out of memory. Memory request: 114688 K всегда одинаковый! Пробовал и переигрывать, и копался в файлах пробуя перепрыгнуть эту зону. Но всегда происходит вылет. Один-в-один! Если нет другого решения, подскажите, как убрать эту стычку сталкеров догла и свободы из игры? Где что закомментировать? Если можно, подробнее, опыта в "ковыряниях" пока мало. Машина слабо-средняя, раньше вылеты по Out of memory тоже имели место быть, но не настолько настойчиво-втупую в одном месте. Всегда помогала переигровка с сейва. Качать новую версию Солянки с дмх не имею возможности-живу в закрытом воинском городке, пользуюсь инетом через телефон. Внизу главного меню игры описана такая конфигурация AMK 1.4.1 + народная солянка от 19.04.10 + дополнение 14.08.10 + патч 3.09.10 + DMX 1.3.4 + ставил фикс по вылету при получении переходов dmx_mod_fix_lc Простите, что так много написано и не спрятано в спойлер-инет с телефона имеет свои минусы ( Прошу снисхождения и сострадания админов и модераторов... ВСС Винторез: один выстрел - один труп! Добрым словом и револьвером можно добиться большего, чем просто добрым словом! Вот так и шли мы с отмычкой: то он впереди, то я сзади... Ударили по правой щеке-подставь левую...А сам поднырни под руку врага,левым боковым сбей его с ног, и по почкам,по почкам с носака!
kapitanDemo,Вылет по нехватке памяти. Попробуй : "в alife.ltx в папке gamedata\config, находим строчку switch_distance и ставим значение =0 Прошли проблемный участок - верните прежнее значение обратно." А в общем нужно оптимизировать систему . Посмотри эту тему http://dmx-mod.ucoz.com/forum/6-11-1 Кто людям помогает-тот тратит время зря. Хорошими делами прославиться нельзя...
Железо: AMD Athlon II X3 450 3.2 ГГц, 8Гб ОЗУ,GF GTS250 1Гб, Win7 64bit домашняя базовая файл подкачки 8-16 ГГб , ОС и игра на SSD
Спасибо за подсказку обязательно попробую. На всякий случай вопрос: В ДМХ эта стычка долга и свободы не является каким-то ключевым моментом игры? Если поставить switch_distance = 0, то как я понял, стычки не будет? Это ни на что в дальнейшем не повлияет? Пока эти две группы просто стоят-игра не вылетает. Как только звучит первый выстрел (фактически начало стычки)-на-те вам вылет. Так что я думаю, что вылет не по памяти, хоть и лог с характерными признаками этого... ВСС Винторез: один выстрел - один труп! Добрым словом и револьвером можно добиться большего, чем просто добрым словом! Вот так и шли мы с отмычкой: то он впереди, то я сзади... Ударили по правой щеке-подставь левую...А сам поднырни под руку врага,левым боковым сбей его с ног, и по почкам,по почкам с носака!
kapitanDemo, После этой стычки появляется торговец Сяк на Радаре . Он дает ряд квестов (не сюжетных). И у него отличный выбор оружия. Ты выйди с Радара .А потом пережди Выброс и снова зайди . Может всё поправится и стычка пройдет без вылета. Кто людям помогает-тот тратит время зря. Хорошими делами прославиться нельзя...
Железо: AMD Athlon II X3 450 3.2 ГГц, 8Гб ОЗУ,GF GTS250 1Гб, Win7 64bit домашняя базовая файл подкачки 8-16 ГГб , ОС и игра на SSD
Пробовал. Выходил с Радара не через эту "стычку", а через переход на Янтарь. Потом по кругу снова на Радар, мимо застывших в готовности долга и свободы в сторону х-10, затем разворачивался и опять к забиякам. И снова с первым выстрелом-вылет! Пробовал специально провоцировать выброс с помощью сна и пройти это место во время или после выброса. То же самое. Пробовал даже такую подлость, как уменьшение популяции обеих групп из снайперки из-за угла, чтоб не заметили меня )) Доходило до того, что их становилось не по 5 с каждой стороны, а по три. И всё равно вылет! Я понял, что БЕЗ стычки никак не появится Сяк. А уменьшить количество "конфронтантов" можно? Сделать не по 5, а по 3 или одному? Может поможет? Если может, то где и что-на-что поменять? ВСС Винторез: один выстрел - один труп! Добрым словом и револьвером можно добиться большего, чем просто добрым словом! Вот так и шли мы с отмычкой: то он впереди, то я сзади... Ударили по правой щеке-подставь левую...А сам поднырни под руку врага,левым боковым сбей его с ног, и по почкам,по почкам с носака!
kapitanDemo, если у тебя виндовс 7 смотри это мне очень помогло с тех пор незнаю что такое вылеты по памяти. Считай оперативки добавил. В свойствах флешки найдешь, как включить. Щелкнешь правой кнопкой мыши/свойства/ReadyBoost/Использовать это устройство. Ковырялка DMX
Сообщение отредактировал KADAR - Пятница, 13.04.2012, 22:00
kapitanDemo, сяк появится когда дойдешь до перехода в припять, в припять можешь даже при этом не ходить AMD Athlon II X3 435, 2900 MHz (14.5 x 200),DDR2-800 (400 МГц) 2гига,Microsoft Windows 7 Home Premium 64бит, nVIDIA GeForce 9800 GT 512Мб
А по стычке у меня тоже самое было. Я пока время было подбежал поближе-вылет, загрузился, подбежал поближе-вылет, загрузился, и постепенно пробежал мимо, а они себя на ноль помножили и все, больше не выкидывало. Это вылет по переполнению стека, если не ошибаюсь. А если по памяти, то играй с флешкой. Я тогда еще не знал про ReadyBoost Ковырялка DMX
Сообщение отредактировал KADAR - Пятница, 13.04.2012, 22:32
Увы, XP SP3... У меня даже ближе подбежать не получается ))) Только первый выстрел-и виснет иногда так, что через RESET компа приходится выходить. Даже старые добрые "три веселых клавиши" не помогают. И что делать с этим вылетом по переполнению стека? И как все-таки уменьшить количество забияк? Или убрать эту стычку совсем, если она все-таки ни на что не влияет программно?
Добавлено (13.04.2012, 22:46) --------------------------------------------- Забыл сказать, обычно играю на минимальных требованиях, которые стандартно предложила игра. ЭТОТ участок не могу пройти на мизерных требованиях. Все соответствующие движки в левый угол.
Добавлено (13.04.2012, 22:49) --------------------------------------------- И еще: респект и уважение всем, кто пытается помочь! Был на другом сайте, так там кроме тычков в сторону правил форума, высокопарных реплик и хвастовства умением выразиться по пижонски никакого результата. Спасибо! ВСС Винторез: один выстрел - один труп! Добрым словом и револьвером можно добиться большего, чем просто добрым словом! Вот так и шли мы с отмычкой: то он впереди, то я сзади... Ударили по правой щеке-подставь левую...А сам поднырни под руку врага,левым боковым сбей его с ног, и по почкам,по почкам с носака!
Сообщение отредактировал kapitanDemo - Пятница, 13.04.2012, 22:51
kapitanDemo, за всю игру у меня был тоже такой баг.В Х-10 вис комп. Три клавиши не помогало,только принудительная перезагрузка.Эту проблему я обошел переигрыванием,пошел в Х-10 с Генераторов другим путём.Почему не вис потом не знаю.Но saruman_ten, тогда мне подсказал что сделать что б комп не вис, сделать следующее:
Лечение: достаточно дописать одну строку в файл gamedata\scripts\se_respawn.script Code get_console():execute("load ~ Spawn now ["..tostring(self:name()).."] -> ["..obj:name().."]")
Насколько я знаю, XP SP 3 64-х битная (по крайней мере когда советовался какую ось лучше поставить для моего железа, сказали, что эта XP SP3 64-х битная). И процессор Атлон х64, хоть и одноядерный.
Добавлено (13.04.2012, 23:20) --------------------------------------------- Эсминец, я у себя такого не нашел в указанном файле. свою версию файла прикладываю:
--[[------------------------------------------------------------------------------------------------------------------ Respawner. Схема обновления популяции всего всего всего в симуляции. by Stohe (Диденко Руслан) --------------------------------------------------------------------------------------------------------------------]]
--function printf() --end
local section_name = "respawn" local i,k,v = 0,0,0
local idle_spawn_preset = { seldom = 60*60*96, medium = 60*60*48, often = 60*60*24, --seldom = 60*60*6, --medium = 60*60*3, --often = 60*60, once = -100000 }
-- Список респавнеров, для сбора статистики local respawners = {} local respawners_by_parent = {} ---------------------------------------------------------------------------------------------------------------------- -- Разные полезные функции ---------------------------------------------------------------------------------------------------------------------- function r_bool( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_bool( section, line ) else return default end end
function r_str( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_string( section, line ) else return default end end
function r_num( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_float( section, line ) else return default end end
function r_2nums( spawn_ini, section, line, def1, def2 ) if spawn_ini:line_exist( section, line ) then -- если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini local t = parse_names( spawn_ini:r_string( section, line ) ) local n = #t
if n == 0 then return def1, def2 elseif n == 1 then return t[1], def2 else return t[1], t[2] end else return def1, def2 end end
function parse_names( s ) local t = {} for name in string.gfind( s, "([%w_%-.\\]+)%p*" ) do table.insert( t, name ) end return t end
function r_spawns( spawn_ini, section, line, sectSpawnProps) if spawn_ini:line_exist( section, line ) then --' если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini local t = parse_names( spawn_ini:r_string( section, line ) ) local n = #t
local ret_table = {} local k = 1 while k <= n do local spawn = {} spawn.section = t[k] -- Проверяем что это не последняя запись if t[k+1] ~= nil then local p = tonumber(t[k+1]) -- проверяем что вторым числом задана вероятность, а не другая секция спавну if p then -- забиваем число spawn.prob = p k = k + 2 else -- забиваем дефолт 1 spawn.prob = 1 k = k + 1 end else spawn.prob = 1 k = k + 1 end table.insert(ret_table, spawn)
-- Вычитываем настройки секций респавна и кешируем их. if sectSpawnProps[spawn.section] == nil then local respawn_ini = system_ini()
local community = r_str(respawn_ini, spawn.section, "community", "nil") local rank = r_str(respawn_ini, spawn.section, "spec_rank", "nil") local check = true local custom_data = r_str(respawn_ini, spawn.section, "custom_data") if custom_data ~= nil then local custom_data_ltx = ini_file(custom_data) if custom_data_ltx:section_exist("smart_terrains") then if custom_data_ltx:line_exist("smart_terrains", "none") then if r_str(custom_data_ltx, "smart_terrains", "none") == "true" then check = false end end if custom_data_ltx:line_exist("smart_terrains", "respawn_check") then if r_str(custom_data_ltx, "smart_terrains", "respawn_check") == "false" then check = false end end end end
end return ret_table end return nil end ---------------------------------------------------------------------------------------------------------------------- -- Серверный объект спавнера ---------------------------------------------------------------------------------------------------------------------- class "se_respawn" ( cse_alife_smart_zone ) function se_respawn:__init( section ) super( section ) self.spawned_obj = {} -- Таблица для кеширования свойств секций респавна. self.sectSpawnProps = {} self.rt_read = false self.proxy_initialized = false end -- сохранение function se_respawn:STATE_Write( packet ) cse_alife_smart_zone.STATE_Write( self, packet )
local table_size = #self.spawned_obj -- printf("SPAWNER SAVE table_size[%d]", table_size) -- print_table(self.spawned_obj)
packet:w_u8(table_size) for i=1,table_size do packet:w_u16(self.spawned_obj[i]) end
utils.w_CTime(packet, self.respawn_time)
if self.respawn_time == nil then self.respawn_time = game.CTime() end --sak.dbglog("%s write respawn_time %s %s", tostring(self:name()), self.respawn_time:dateToString(0), self.respawn_time:timeToString(1)) end -- восстановление function se_respawn:STATE_Read( packet, size ) cse_alife_smart_zone.STATE_Read( self, packet, size )
if editor() then return end
local table_size = packet:r_u8() for i=1,table_size do table.insert(self.spawned_obj, packet:r_u16()) end
if not packet:r_eof() then self.respawn_time = utils.r_CTime(packet) self.rt_read = true --sak.dbglog("%s read respawn_time %s %s", tostring(self:name()), self.respawn_time:dateToString(0), self.respawn_time:timeToString(1)) end end -- инициализация объекта. -- вызывается симулятором. function se_respawn:on_register() cse_alife_smart_zone.on_register( self ) --printf("RESPAWN: [%s] se_respawn on_register", tostring(self:name())) init_respawn_params(self) end -- Создаем объект function se_respawn:create(prob) if tostring(prob)=="true" then prob=80 elseif tostring(prob)=="false" then prob=0 end if tonumber(prob) == nil then print_table(self.conditions) abort("RESPAWN[%s]spawn probability doesn't set", tostring(self:name())) prob = 0 return false end
if math.random(100) <= tonumber(prob) then local spawn_section = "" local sum = 0 -- Производим рандомную взвешенную выборку -- с учетом уже заспавленного количества человек. for k,v in pairs(self.respawn_section) do --' local tt = self.sectSpawnProps[v.section] --' local community_rank = tt.community.."_"..tt.rank --' local s_count = simMaxCount[community_rank] --' if s_count == nil then --' s_count = 0 --' end --' if tt.check == false or --' self.item_spawn == true or --' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count --' then sum = sum + v.prob --' end end sum = math.random(0, sum) for k,v in pairs(self.respawn_section) do --' local tt = self.sectSpawnProps[v.section] --' local community_rank = tt.community.."_"..tt.rank --' local s_count = simMaxCount[community_rank] --' if s_count == nil then --' s_count = 0 --' end --' if tt.check == false or --' self.item_spawn == true or --' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count --' then sum = sum - v.prob if sum <= 0 then spawn_section = v.section break end --' end end
if spawn_section == "" then -- printf("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name())) --sak.dbglog("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name())) return false end
local parent_id = nil if self.parent ~= nil then local s_obj = alife():story_object(self.parent) if s_obj == nil then abort("SPAWNING [%s], cant find parent with SID [%s]", self:name(), self.parent) return end parent_id = s_obj.id end
local obj if parent_id == nil then obj = alife():create(spawn_section, self.position, self.m_level_vertex_id, self.m_game_vertex_id) else obj = alife():create(spawn_section, self.position, self.m_level_vertex_id, self.m_game_vertex_id, parent_id) end
amk.on_REspawn(obj,self) local tt = self.sectSpawnProps[spawn_section]
--sak.dbglog("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section) -- printf("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section) return false end end end table.insert(self.spawned_obj ,obj.id) return true end end -- Попытка спаунить объекты. Анализируется сколько уже заспавнено и выбирается один из механизмов - либо -- мы доспавниваем до минимального количества, либо спавним с заданной вероятностью function se_respawn:spawn() -- printf("RESPAWN: [%s] spawn execute", tostring(self:name())) --sak.dbglog("RESPAWN: [%s] spawn execute", tostring(self:name())) if not self.spawn_once then -- Пробегаемся по списку уже заспавненных объектов и удаляем из них мертвые либо уничтоженные. for k,v in pairs(self.spawned_obj) do local obj = level.object_by_id(v) if obj == nil then obj = alife():object(v) end
if obj ~= nil then if (IAmAStalker[obj:clsid()] or IAmAMonster[obj:clsid()]) and obj:alive() ~= true then table.remove(self.spawned_obj, k) end else table.remove(self.spawned_obj, k) end end end if xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions) == "0" then -- printf("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name())) --sak.dbglog("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name())) sim_statistic.respawn_enabled(self, false) return end sim_statistic.respawn_enabled(self, true)
if self.spawn_once and not self.already_once_spawned then self.already_once_spawned = true end -- экстренный спаун минимального количества объектов if #self.spawned_obj < self.min_count then while #self.spawned_obj < self.min_count do --sak.dbglog("RESPAWN: [%s] very small object", tostring(self:name())) if self:create(100) == false then return end end return end
-- делаем несколько попыток заспаунить объект. for i=1,self.max_spawn do if self.max_count ~= -1 and #self.spawned_obj >= self.max_count then --sak.dbglog("RESPAWN: [%s] max count reached", tostring(self:name()))
-- printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(self:name())) return end if self:create(xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions)) == false then return end end end --' Удаляем уже заспавненный объект из списка заспавненных --' Используется только для ящиком со шмотками в смарттеррейнах function se_respawn:remove_spawned(id) for k,v in pairs(self.spawned_obj) do if id == v then table.remove(self.spawned_obj, k) end end end -- Обновление респавнера. В зависимости от настроек обновляется либо только в офлайне, либо и там и там. function se_respawn:execute() -- printf("RESPAWN: [%s] se_respawn execute", tostring(self:name())) if self.already_once_spawned==true then return end --' Выходим, если у нас установлен событийный спавн. if self.idle_spawn_min == -1 then return end
if self.respawn_time < game.get_game_time() then -- if not self.proxy_initialized then -- db.actor_proxy:init() -- self.proxy_initialized = true -- end local idle_time = game.CTime() local now = game.get_game_time()
-- printf("spawn_count = %s", table.getn(self.spawned_obj)) end end -- Обновление в офлайне function se_respawn:update() cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_offline", tostring(self:name())) self:execute() end -- Обновление в онлайне function se_respawn:update_online() --'cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_online", tostring(self:name())) if self.respawn_radius == -1 then sim_statistic.respawn_enabled(self, false) return end if db.actor:position():distance_to (self.position) >= self.respawn_radius then self:execute() else sim_statistic.respawn_enabled(self, false) end end
function spawn(name) local spawner = respawners[name] if spawner == nil then return end
for i=1,spawner.max_spawn do if spawner.max_count ~= -1 and #spawner.spawned_obj >= spawner.max_count then -- printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(spawner:name())) return end if spawner:create(xr_logic.pick_section_from_condlist(db.actor_proxy, spawner, spawner.conditions)) == false then return end end end
function get_respawner_by_parent(parent_id) return respawners_by_parent[parent_id] end
-- Сбор статистики function stats() local total_spawned = 0 local total_avail = 0 local total = 0 printf("***************** RESPAWN STATISTIC *********************") for k,v in pairs(respawners) do local s = xr_logic.pick_section_from_condlist(db.actor_proxy, v, v.conditions) local pops = "DISABLE" if s ~= "nil" and s ~= "0" then pops = #v.spawned_obj end local str_pops if v.max_count == pops then str_pops = "FULL "..tostring(pops) else str_pops = tostring(pops) end printf("[%s] spawns [%s] object", tostring(v:name()), str_pops) print_table(v.respawn_section) -- Увеличиваем общие счетчики total = total + v.max_count if pops ~= "DISABLE" then total_avail = total_avail + v.max_count total_spawned = total_spawned + pops end end printf("*** SUMMARY ***") printf(" total = %s", total) printf(" total_avail = %s", total_avail) printf(" total_spawned = %s", total_spawned) printf("***************") end
-- Сбор продвинутой статистики статистики по лимитам function lstats() local can_spawn = {} printf("***************** LIMITS STATISTIC *********************") for k,v in pairs(respawners) do -- Запоминаем максимальное количество весов для данного респавнера local wage = 0 for kk,vv in pairs(v.respawn_section) do wage = wage + vv.prob end
-- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить. for kk,vv in pairs(v.respawn_section) do local tt = v.sectSpawnProps[vv.section] local community_rank = tt.community.."_"..tt.rank if can_spawn[community_rank] == nil then can_spawn[community_rank] = {community = tt.community, rank = tt.rank} end end end -- Выводим все это в общей статистике local total_max, total_prob, total_current, total_limit = 0,0,0,0 for k,v in pairs(can_spawn) do local cs = sim_statistic.simNpcCount(v.community, v.rank) local gl = simMaxCount[k] if gl == nil then gl = 0 end
printf("%s current=%s limit=%s", k, cs, gl) end printf("TOTAL: current=%s limit=%s", total_current, total_limit) end
-- Сбор статистики по ненастроенным объектам function estats() printf("***************** SPAWN ERROR STATISTIC *********************") for k,v in pairs(respawners) do -- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить. for kk,vv in pairs(v.respawn_section) do local tt = v.sectSpawnProps[vv.section] if tt.community == "nil" or tt.rank == "nil" then printf("respawner [%s]", tostring(v:name())) printf("Section [%s] community[%s] rank [%s]", vv.section, tt.community, tt.rank) end end end end
function create_ammo(section, position, lvi, gvi, pid, num) local ini = system_ini()
local num_in_box = ini:r_u32(section, "box_size")
while num > num_in_box do alife():create_ammo(section, position, lvi, gvi, pid, num_in_box) num = num - num_in_box end alife():create_ammo(section, position, lvi, gvi, pid, num) end
local amk_respawner_control={} local amk_named_respawner_control={}
function init_respawn_params(obj) amk_respawner_control[obj:name()] = obj -- Вычитываем настройки спауна local ini = obj:spawn_ini() if not ini:section_exist(section_name) then return end
obj.respawn_section = r_spawns(ini, section_name, "respawn_section", obj.sectSpawnProps) if obj.respawn_section == nil then abort("RESPAWN: [%s] field 'respawn_section' doesn't exist.", obj:name()) end
obj.amk_name = r_str(ini, section_name, "amk_name", nil) if obj.amk_name then amk_named_respawner_control[obj.amk_name] = obj end
obj.min_count = r_num(ini, section_name, "min_count", 0) obj.max_count = r_num(ini, section_name, "max_count", -1) if obj.min_count > obj.max_count and obj.max_count ~= -1 then abort("RESPAWN: [%s] min_count > max_count", obj:name()) end --' FOR DEBUG ONLY, please don't forget to delete --'if obj.max_count > 0 then --' obj.min_count = obj.max_count --'end
obj.max_spawn = r_num(ini, section_name, "max_spawn", 1) obj.idle_spawn_min, obj.idle_spawn_max = r_2nums(ini, section_name, "idle_spawn") if obj.idle_spawn_min == nil then abort("RESPAWN: [%s] field 'idle_spawn' doesn't exist.", obj:name()) end if obj.idle_spawn_max == nil then obj.idle_spawn_max = obj.idle_spawn_min end
--' Вычитка пресетов if idle_spawn_preset[obj.idle_spawn_min] ~= nil then obj.idle_spawn_min = idle_spawn_preset[obj.idle_spawn_min] else obj.idle_spawn_min = tonumber(obj.idle_spawn_min) end if idle_spawn_preset[obj.idle_spawn_max] ~= nil then obj.idle_spawn_max = idle_spawn_preset[obj.idle_spawn_max] else obj.idle_spawn_max = tonumber(obj.idle_spawn_max) end
obj.str_conditions = r_str(ini, section_name, "conditions", 100) obj.conditions = xr_logic.parse_condlist(obj, section_name, "conditions", obj.str_conditions) obj.respawn_radius = r_num(ini, section_name, "respawn_radius", -1) --' Спешкейс, чтобы сохранить совместимость сейвов. if obj:name() == "mil_freedom_barier_respawn_1" then obj.respawn_radius = -1 end obj.parent = r_num(ini, section_name, "parent", nil) obj.item_spawn = r_bool(ini, section_name, "item_spawn", false)
-- производим первичную инициализацию if obj.rt_read == false then obj.respawn_time = game.CTime() --sak.dbglog("INIT [%s] %s %s", tostring(obj:name()), obj.respawn_time:dateToString(0), obj.respawn_time:timeToString(1)) end
-- Для сбора статистики сохраняем указатель на респавнер respawners[obj:name()] = obj if obj.parent ~= nil then respawners_by_parent[obj.parent] = obj end
--' Отметка респавнера мапспотом (для статистики) sim_statistic.register_respawn(obj)
end
function reinit_spawner_params(name) if amk_respawner_control[name] then init_respawn_params(amk_respawner_control[name]) end end
function get_respawner_by_name(name) if amk_named_respawner_control[name] then return alife():object(amk_named_respawner_control[name].id) end end
Добавлено (13.04.2012, 23:30) --------------------------------------------- Прошу ответить тех, кто знает наверняка или близко к этому: Если в alife.ltx в папке gamedata\config, в строчке switch_distance поставить значение =0, то персонажи игры не будут видеть ГГ ? Даже если в них стрелять? Просто готовлюсь к такому выходу, что перебить эти две группы без вреда отношений с группировками в целом и играть дальше. Если это ни на что не повлияет. Как ни противно так делать, но пока другого выхода не вижу.
ВСС Винторез: один выстрел - один труп! Добрым словом и револьвером можно добиться большего, чем просто добрым словом! Вот так и шли мы с отмычкой: то он впереди, то я сзади... Ударили по правой щеке-подставь левую...А сам поднырни под руку врага,левым боковым сбей его с ног, и по почкам,по почкам с носака!
Вот ваша же версия файла.Желтым отмечена нужная строка.
Respawner. Схема обновления популяции всего всего всего в симуляции. by Stohe (Диденко Руслан) --------------------------------------------------------------------------------------------------------------------]]
--function printf() --end
local section_name = "respawn" local i,k,v = 0,0,0
local idle_spawn_preset = { seldom = 60*60*96, medium = 60*60*48, often = 60*60*24, --seldom = 60*60*6, --medium = 60*60*3, --often = 60*60, once = -100000 }
-- Список респавнеров, для сбора статистики local respawners = {} local respawners_by_parent = {} ---------------------------------------------------------------------------------------------------------------------- -- Разные полезные функции ---------------------------------------------------------------------------------------------------------------------- function r_bool( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_bool( section, line ) else return default end end
function r_str( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_string( section, line ) else return default end end
function r_num( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_float( section, line ) else return default end end
function r_2nums( spawn_ini, section, line, def1, def2 ) if spawn_ini:line_exist( section, line ) then -- если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini local t = parse_names( spawn_ini:r_string( section, line ) ) local n = #t
if n == 0 then return def1, def2 elseif n == 1 then return t[1], def2 else return t[1], t[2] end else return def1, def2 end end
function parse_names( s ) local t = {} for name in string.gfind( s, "([%w_%-.\\]+)%p*" ) do table.insert( t, name ) end return t end
function r_spawns( spawn_ini, section, line, sectSpawnProps) if spawn_ini:line_exist( section, line ) then --' если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini local t = parse_names( spawn_ini:r_string( section, line ) ) local n = #t
local ret_table = {} local k = 1 while k <= n do local spawn = {} spawn.section = t[k] -- Проверяем что это не последняя запись if t[k+1] ~= nil then local p = tonumber(t[k+1]) -- проверяем что вторым числом задана вероятность, а не другая секция спавну if p then -- забиваем число spawn.prob = p k = k + 2 else -- забиваем дефолт 1 spawn.prob = 1 k = k + 1 end else spawn.prob = 1 k = k + 1 end table.insert(ret_table, spawn)
-- Вычитываем настройки секций респавна и кешируем их. if sectSpawnProps[spawn.section] == nil then local respawn_ini = system_ini()
local community = r_str(respawn_ini, spawn.section, "community", "nil") local rank = r_str(respawn_ini, spawn.section, "spec_rank", "nil") local check = true local custom_data = r_str(respawn_ini, spawn.section, "custom_data") if custom_data ~= nil then local custom_data_ltx = ini_file(custom_data) if custom_data_ltx:section_exist("smart_terrains") then if custom_data_ltx:line_exist("smart_terrains", "none") then if r_str(custom_data_ltx, "smart_terrains", "none") == "true" then check = false end end if custom_data_ltx:line_exist("smart_terrains", "respawn_check") then if r_str(custom_data_ltx, "smart_terrains", "respawn_check") == "false" then check = false end end end end
end return ret_table end return nil end ---------------------------------------------------------------------------------------------------------------------- -- Серверный объект спавнера ---------------------------------------------------------------------------------------------------------------------- class "se_respawn" ( cse_alife_smart_zone ) function se_respawn:__init( section ) super( section ) self.spawned_obj = {} -- Таблица для кеширования свойств секций респавна. self.sectSpawnProps = {} self.rt_read = false self.proxy_initialized = false end -- сохранение function se_respawn:STATE_Write( packet ) cse_alife_smart_zone.STATE_Write( self, packet )
local table_size = #self.spawned_obj -- printf("SPAWNER SAVE table_size[%d]", table_size) -- print_table(self.spawned_obj)
packet:w_u8(table_size) for i=1,table_size do packet:w_u16(self.spawned_obj[i]) end
utils.w_CTime(packet, self.respawn_time)
if self.respawn_time == nil then self.respawn_time = game.CTime() end --sak.dbglog("%s write respawn_time %s %s", tostring(self:name()), self.respawn_time:dateToString(0), self.respawn_time:timeToString(1)) end -- восстановление function se_respawn:STATE_Read( packet, size ) cse_alife_smart_zone.STATE_Read( self, packet, size )
if editor() then return end
local table_size = packet:r_u8() for i=1,table_size do table.insert(self.spawned_obj, packet:r_u16()) end
if not packet:r_eof() then self.respawn_time = utils.r_CTime(packet) self.rt_read = true --sak.dbglog("%s read respawn_time %s %s", tostring(self:name()), self.respawn_time:dateToString(0), self.respawn_time:timeToString(1)) end end -- инициализация объекта. -- вызывается симулятором. function se_respawn:on_register() cse_alife_smart_zone.on_register( self ) --printf("RESPAWN: [%s] se_respawn on_register", tostring(self:name())) init_respawn_params(self) end -- Создаем объект function se_respawn:create(prob) if tostring(prob)=="true" then prob=80 elseif tostring(prob)=="false" then prob=0 end if tonumber(prob) == nil then print_table(self.conditions) abort("RESPAWN[%s]spawn probability doesn't set", tostring(self:name())) prob = 0 return false end
if math.random(100) <= tonumber(prob) then local spawn_section = "" local sum = 0 -- Производим рандомную взвешенную выборку -- с учетом уже заспавленного количества человек. for k,v in pairs(self.respawn_section) do --' local tt = self.sectSpawnProps[v.section] --' local community_rank = tt.community.."_"..tt.rank --' local s_count = simMaxCount[community_rank] --' if s_count == nil then --' s_count = 0 --' end --' if tt.check == false or --' self.item_spawn == true or --' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count --' then sum = sum + v.prob --' end end sum = math.random(0, sum) for k,v in pairs(self.respawn_section) do --' local tt = self.sectSpawnProps[v.section] --' local community_rank = tt.community.."_"..tt.rank --' local s_count = simMaxCount[community_rank] --' if s_count == nil then --' s_count = 0 --' end --' if tt.check == false or --' self.item_spawn == true or --' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count --' then sum = sum - v.prob if sum <= 0 then spawn_section = v.section break end --' end end
if spawn_section == "" then -- printf("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name())) --sak.dbglog("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name())) return false end
local parent_id = nil if self.parent ~= nil then local s_obj = alife():story_object(self.parent) if s_obj == nil then abort("SPAWNING [%s], cant find parent with SID [%s]", self:name(), self.parent) return end parent_id = s_obj.id end
local obj if parent_id == nil then obj = alife():create(spawn_section, self.position, self.m_level_vertex_id, self.m_game_vertex_id) else obj = alife():create(spawn_section, self.position, self.m_level_vertex_id, self.m_game_vertex_id, parent_id) end
amk.on_REspawn(obj,self) local tt = self.sectSpawnProps[spawn_section]
--sak.dbglog("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section) -- printf("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section) return false end end end table.insert(self.spawned_obj ,obj.id) return true end end -- Попытка спаунить объекты. Анализируется сколько уже заспавнено и выбирается один из механизмов - либо -- мы доспавниваем до минимального количества, либо спавним с заданной вероятностью function se_respawn:spawn() -- printf("RESPAWN: [%s] spawn execute", tostring(self:name())) --sak.dbglog("RESPAWN: [%s] spawn execute", tostring(self:name())) if not self.spawn_once then -- Пробегаемся по списку уже заспавненных объектов и удаляем из них мертвые либо уничтоженные. for k,v in pairs(self.spawned_obj) do local obj = level.object_by_id(v) if obj == nil then obj = alife():object(v) end
if obj ~= nil then if (IAmAStalker[obj:clsid()] or IAmAMonster[obj:clsid()]) and obj:alive() ~= true then table.remove(self.spawned_obj, k) end else table.remove(self.spawned_obj, k) end end end if xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions) == "0" then -- printf("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name())) --sak.dbglog("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name())) sim_statistic.respawn_enabled(self, false) return end sim_statistic.respawn_enabled(self, true)
if self.spawn_once and not self.already_once_spawned then self.already_once_spawned = true end -- экстренный спаун минимального количества объектов if #self.spawned_obj < self.min_count then while #self.spawned_obj < self.min_count do --sak.dbglog("RESPAWN: [%s] very small object", tostring(self:name())) if self:create(100) == false then return end end return end
-- делаем несколько попыток заспаунить объект. for i=1,self.max_spawn do if self.max_count ~= -1 and #self.spawned_obj >= self.max_count then --sak.dbglog("RESPAWN: [%s] max count reached", tostring(self:name()))
-- printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(self:name())) return end if self:create(xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions)) == false then return end end end --' Удаляем уже заспавненный объект из списка заспавненных --' Используется только для ящиком со шмотками в смарттеррейнах function se_respawn:remove_spawned(id) for k,v in pairs(self.spawned_obj) do if id == v then table.remove(self.spawned_obj, k) end end end -- Обновление респавнера. В зависимости от настроек обновляется либо только в офлайне, либо и там и там. function se_respawn:execute() -- printf("RESPAWN: [%s] se_respawn execute", tostring(self:name())) if self.already_once_spawned==true then return end --' Выходим, если у нас установлен событийный спавн. if self.idle_spawn_min == -1 then return end
if self.respawn_time < game.get_game_time() then -- if not self.proxy_initialized then -- db.actor_proxy:init() -- self.proxy_initialized = true -- end local idle_time = game.CTime() local now = game.get_game_time()
-- printf("spawn_count = %s", table.getn(self.spawned_obj)) end end -- Обновление в офлайне function se_respawn:update() cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_offline", tostring(self:name())) self:execute() end -- Обновление в онлайне function se_respawn:update_online() --'cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_online", tostring(self:name())) if self.respawn_radius == -1 then sim_statistic.respawn_enabled(self, false) return end if db.actor:position():distance_to (self.position) >= self.respawn_radius then self:execute() else sim_statistic.respawn_enabled(self, false) end end
function spawn(name) local spawner = respawners[name] if spawner == nil then return end
for i=1,spawner.max_spawn do if spawner.max_count ~= -1 and #spawner.spawned_obj >= spawner.max_count then -- printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(spawner:name())) return end if spawner:create(xr_logic.pick_section_from_condlist(db.actor_proxy, spawner, spawner.conditions)) == false then return end end end
function get_respawner_by_parent(parent_id) return respawners_by_parent[parent_id] end
-- Сбор статистики function stats() local total_spawned = 0 local total_avail = 0 local total = 0 printf("***************** RESPAWN STATISTIC *********************") for k,v in pairs(respawners) do local s = xr_logic.pick_section_from_condlist(db.actor_proxy, v, v.conditions) local pops = "DISABLE" if s ~= "nil" and s ~= "0" then pops = #v.spawned_obj end local str_pops if v.max_count == pops then str_pops = "FULL "..tostring(pops) else str_pops = tostring(pops) end printf("[%s] spawns [%s] object", tostring(v:name()), str_pops) print_table(v.respawn_section) -- Увеличиваем общие счетчики total = total + v.max_count if pops ~= "DISABLE" then total_avail = total_avail + v.max_count total_spawned = total_spawned + pops end end printf("*** SUMMARY ***") printf(" total = %s", total) printf(" total_avail = %s", total_avail) printf(" total_spawned = %s", total_spawned) printf("***************") end
-- Сбор продвинутой статистики статистики по лимитам function lstats() local can_spawn = {} printf("***************** LIMITS STATISTIC *********************") for k,v in pairs(respawners) do -- Запоминаем максимальное количество весов для данного респавнера local wage = 0 for kk,vv in pairs(v.respawn_section) do wage = wage + vv.prob end
-- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить. for kk,vv in pairs(v.respawn_section) do local tt = v.sectSpawnProps[vv.section] local community_rank = tt.community.."_"..tt.rank if can_spawn[community_rank] == nil then can_spawn[community_rank] = {community = tt.community, rank = tt.rank} end end end -- Выводим все это в общей статистике local total_max, total_prob, total_current, total_limit = 0,0,0,0 for k,v in pairs(can_spawn) do local cs = sim_statistic.simNpcCount(v.community, v.rank) local gl = simMaxCount[k] if gl == nil then gl = 0 end
printf("%s current=%s limit=%s", k, cs, gl) end printf("TOTAL: current=%s limit=%s", total_current, total_limit) end
-- Сбор статистики по ненастроенным объектам function estats() printf("***************** SPAWN ERROR STATISTIC *********************") for k,v in pairs(respawners) do -- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить. for kk,vv in pairs(v.respawn_section) do local tt = v.sectSpawnProps[vv.section] if tt.community == "nil" or tt.rank == "nil" then printf("respawner [%s]", tostring(v:name())) printf("Section [%s] community[%s] rank [%s]", vv.section, tt.community, tt.rank) end end end end
function create_ammo(section, position, lvi, gvi, pid, num) local ini = system_ini()
local num_in_box = ini:r_u32(section, "box_size")
while num > num_in_box do alife():create_ammo(section, position, lvi, gvi, pid, num_in_box) num = num - num_in_box end alife():create_ammo(section, position, lvi, gvi, pid, num) end
local amk_respawner_control={} local amk_named_respawner_control={}
function init_respawn_params(obj) amk_respawner_control[obj:name()] = obj -- Вычитываем настройки спауна local ini = obj:spawn_ini() if not ini:section_exist(section_name) then return end
obj.respawn_section = r_spawns(ini, section_name, "respawn_section", obj.sectSpawnProps) if obj.respawn_section == nil then abort("RESPAWN: [%s] field 'respawn_section' doesn't exist.", obj:name()) end
obj.amk_name = r_str(ini, section_name, "amk_name", nil) if obj.amk_name then amk_named_respawner_control[obj.amk_name] = obj end
obj.min_count = r_num(ini, section_name, "min_count", 0) obj.max_count = r_num(ini, section_name, "max_count", -1) if obj.min_count > obj.max_count and obj.max_count ~= -1 then abort("RESPAWN: [%s] min_count > max_count", obj:name()) end --' FOR DEBUG ONLY, please don't forget to delete --'if obj.max_count > 0 then --' obj.min_count = obj.max_count --'end
obj.max_spawn = r_num(ini, section_name, "max_spawn", 1) obj.idle_spawn_min, obj.idle_spawn_max = r_2nums(ini, section_name, "idle_spawn") if obj.idle_spawn_min == nil then abort("RESPAWN: [%s] field 'idle_spawn' doesn't exist.", obj:name()) end if obj.idle_spawn_max == nil then obj.idle_spawn_max = obj.idle_spawn_min end
--' Вычитка пресетов if idle_spawn_preset[obj.idle_spawn_min] ~= nil then obj.idle_spawn_min = idle_spawn_preset[obj.idle_spawn_min] else obj.idle_spawn_min = tonumber(obj.idle_spawn_min) end if idle_spawn_preset[obj.idle_spawn_max] ~= nil then obj.idle_spawn_max = idle_spawn_preset[obj.idle_spawn_max] else obj.idle_spawn_max = tonumber(obj.idle_spawn_max) end
obj.str_conditions = r_str(ini, section_name, "conditions", 100) obj.conditions = xr_logic.parse_condlist(obj, section_name, "conditions", obj.str_conditions) obj.respawn_radius = r_num(ini, section_name, "respawn_radius", -1) --' Спешкейс, чтобы сохранить совместимость сейвов. if obj:name() == "mil_freedom_barier_respawn_1" then obj.respawn_radius = -1 end obj.parent = r_num(ini, section_name, "parent", nil) obj.item_spawn = r_bool(ini, section_name, "item_spawn", false)
-- производим первичную инициализацию if obj.rt_read == false then obj.respawn_time = game.CTime() --sak.dbglog("INIT [%s] %s %s", tostring(obj:name()), obj.respawn_time:dateToString(0), obj.respawn_time:timeToString(1)) end
-- Для сбора статистики сохраняем указатель на респавнер respawners[obj:name()] = obj if obj.parent ~= nil then respawners_by_parent[obj.parent] = obj end
--' Отметка респавнера мапспотом (для статистики) sim_statistic.register_respawn(obj)
end
function reinit_spawner_params(name) if amk_respawner_control[name] then init_respawn_params(amk_respawner_control[name]) end end
function get_respawner_by_name(name) if amk_named_respawner_control[name] then return alife():object(amk_named_respawner_control[name].id) end end
kapitanDemo, они будут в оффлайне, даже ты их видеть не будешь AMD Athlon II X3 435, 2900 MHz (14.5 x 200),DDR2-800 (400 МГц) 2гига,Microsoft Windows 7 Home Premium 64бит, nVIDIA GeForce 9800 GT 512Мб
Yuras70, Ден появляется после взятия ПКМ по квесту Свиблова на мех. дворе на Болотах. Кто людям помогает-тот тратит время зря. Хорошими делами прославиться нельзя...
Железо: AMD Athlon II X3 450 3.2 ГГц, 8Гб ОЗУ,GF GTS250 1Гб, Win7 64bit домашняя базовая файл подкачки 8-16 ГГб , ОС и игра на SSD
nevada47, это не ошибка, вылетает у тебя совсем не потому AMD Athlon II X3 435, 2900 MHz (14.5 x 200),DDR2-800 (400 МГц) 2гига,Microsoft Windows 7 Home Premium 64бит, nVIDIA GeForce 9800 GT 512Мб
Привет всем! У меня Народная Солянка 19.04.10 + дополнение 14.08.10 +патч от 3.09.10 + DMX 1.3.4. происходит вылет в пещере во время разговора с Шахтером при попытке взять задание на дневник.Лог вылета-
Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ...byl\ns2011 - dmx edition\gamedata\scripts\sak.script:199: attempt to index field '?' (a nil value)
Попытка загрузить игру с ранних сейвов результатов не принесла!
Пожалуйста подскажите решение!
P.S. не ругайтесь сильно если пропустил лекарство в теме!
P.P.S Похоже такой вылет происходит при каждой попытке взять новое задание(по крайней мере у Адреналина тоже вылетает).
Сообщение отредактировал Ex_Camaro - Понедельник, 16.04.2012, 20:20
Всем привет! Вылет при переходе со свалки на кордон, после взятия документов на агропроме, причем возвращался на агропром, оттуда на кордон то же не переходит, тот же вылет: Expression : fatal error Function : IRender_Visual::Load File : E:\stalker\patch_1_0004\xr_3da\FBasicVisual.cpp Line : 58 Description : <no expression> Arguments : Invalid visual
начал новую игру - сразу такой же вылет. НС 3.09, DMX1.3.4, из-за шейдеров может быть такое? Просто пробывал соляночные ставил, потом обратно из DMX1.3.4. , но дело в том , что и со свалки в бар, и в темную долину все нормально, а на кордоне Invalid visual понять бы чей?
P.S. switch_distance уменьшал до 5м
Сообщение отредактировал Booriy - Понедельник, 16.04.2012, 18:32
начал новую игру - сразу такой же вылет. НС 3.09, DMX1.3.4
А ДМХ 1.3 ставили? ------------------------------ Booriy, пробуй переустановить, что-то криво встало. ------------------------------- Booriy, да какя-то модель, но какая..? И только ли она встала криво, может ещё что-то - узнаеш позже и тогда будет не до
Сообщение отредактировал alen-fantom - Понедельник, 16.04.2012, 19:01
alen-fantom, естественно и правку по переходу и на куб теней, дошел до агропрома, взял документы, хотел вернуться с дробовиком к лису, и при переходе на кордон вылет и с агропрома и со свалки, до этого не одного не было, менял только шейдеры до этого стояли из соли, но дело в том, что на свалке, агропром, т. долина, бар переходы без проблем
Booriy, пробуй переустановить, что-то криво встало.
, логично Просто хотелось понять, что и заменить , а не переустанавливать все полностью. Не знаю прав или нет но это по моему, не текстуры? А какая-то модель?
Добавлено (16.04.2012, 19:08) --------------------------------------------- alen-fantom, Это верно, потом обидно будет, поэтому начал переустановку...
Сообщение отредактировал Booriy - Понедельник, 16.04.2012, 18:37
2saruman_ten: Логов больше нет. А из-за чего могут быть вылеты? Подумал бы на железо - буквально неделю назад не вылетало вообще, сутками. Поменял память - результатов нет. Может дрова от видяхи, попробую сменить чтоли.. Phenom x4,16Gb RAM, HD6850 1Gb, HDD SSD 250, NAS 6Tb :D
Боб0007, вот то что в конце того лога интерисует AMD Athlon II X3 435, 2900 MHz (14.5 x 200),DDR2-800 (400 МГц) 2гига,Microsoft Windows 7 Home Premium 64бит, nVIDIA GeForce 9800 GT 512Мб