Сталкер как исправить скрипты

AIM TT

StarForce — ClearSky. Вопросы и Ответы

Внимание!!!

Игра «S.T.A.L.K.E.R.: Clear Sky» была защищена с применением технологии «Периодическая Проверка Диска» сроком на 3 дня. Поэтому после первого запуска игры и успешной проверки, больше не требуется наличие оригинального диска в приводе в течение 3х дней. По истечению этого срока защита вновь потребует вставить лицензионный диск и после прохождения проверки, диск снова не потребуется в приводе… и т.д.

Наиболее часто встречающиеся ошибки:

1. Диск не проходит проверку. Сообщение гласит, что диск не лицензионный или его вообще нет в приводе. Особенно часто сообщение встречается с приводами фирмы NEC.

Происходит из-за несовместимости привода или его прошивки и системы защиты.

Советы:

Попробуйте понизить скорость привода с помощью программы Nero Drive Speed до 5-8х и повторить проверку. Иногда помогает смена прошивки на более свежую.

Сайт с прошивками —

Сылка удалена.

2. При проверке диска идет сообщение об обнаруженных эмуляторах. При этом в системе самих эмуляторов может и не быть.

Происходит по причине конфликта драйвера защиты и драйвера эмулятора (если эмулятор есть) и/или конфликта драйвера защиты и драйвера материнской платы, отвечающего за работу дисковой подсистемы компьютера.

Советы:

Удалить эмуляторы из системы. Важно отметить, что после удаления эмулятора в системе остаются драйвера эмуляторов, они находятся в активном состоянии и работают. Виртуальные диски также остаются.

Для удаления драйвера SPTD от эмулятора Deamon Tools, легче всего воспользоваться специальной утилитой SPTDinst (882 Кб):

http://www.duplexsecure.com/downloads

Выберите кнопку Uninstall, после чего компьютер следует перезагрузить.

Если у вас Алкоголь, то можно попробовать отключить в настройках опцию «Игнорировать тип носителя» (Ignore media type) и повторить проверку снова. Если у вас когда-то стоял эмулятор Алкоголь, но вы его удалили, и если данная опция при удалении эмулятора была включена, то драйвер в системе, скорее всего, остался и работает именно с включенной опцией. Можно либо удалить драйвер, либо переустановить сам эмулятор и выключить опцию.

3. При запуске проверки диска система защиты просит ввести ключ, а ключа нигде нет.

Происходит в случае, если оптический дисковод не может корректно считать дисковой ключ, занесенный в область данных диска при изготовлении дисков на заводе.

Советы:

Можно попробовать ввести ключ вручную, считав его с диска с помощью программы readcd.

Пожалуйста, скачайте маленькую утилитку — readcd.exe:

Сылка удалена.

Вставьте диск с игрой в привод, запустите утилиту.

Следуйте указаниям на экране. После окончания работы программы в папке с ней появятся файлы вида — readcd_хх.bin. В файле readcd_16.bin вы найдете дисковой ключ. Введите этот ключ по запросу программы. Либо запустите игру, удерживая клавишу Shift, и вам будет предложено ввести дисковой ключ.

В любом случае, сохраните файл-отчёт ошибки Star-Force и отправте его на support@gsc-game.com

4. При проверке диска система зависает, либо перезагружается, либо появляется синий экран.

Связано с ошибкой в драйвере эмулятора Deamon Tools версий 4.х. Как правило, проявляется при попытке эмулировать лицензионный диск.

Советы:

Необходимо выключить эмулятор и запускать игру, используя лицензионный диск. Если вы точно уверены, что эмуляторов в системе нет, то необходимо отправить в техническую поддержку файл минидампа, который создается при возникновении синего экрана. Минидамп содержит отладочную информацию, которая поможет понять, из-за чего произошла ошибка, и необходим для успешного разрешения проблемы.

Как сделать минидамп:

Удалите все файлы из папки С:WindowsMinidump.

Кликните правой клавишей на иконке «Мой компьютер», выберите «Свойства». Выберите закладку «Дополнительно», в ней раздел «Загрузка и восстановление». В этом разделе нажмите кнопку «Параметры». Уберите галку из пункта «Выполнить автоматическую перезагрузку». В секции «Запись отладочной информации» выберите «Малый дамп памяти (64кб)». Закройте все окна кнопками «ОК».

После очередного возникновения синего экрана компьютер скинет необходимую для понимания проблемы информацию в специальный файл. Вы сможете найти эти файлы тут:

С:WindowsMinidump

Вышлите все файлы в техническую поддержку support@star-force.com

5. Обновление драйверов защиты.

Для обновления драйвера защиты используйте утилиту protect.exe, которая находится в корневой папке игры. В некоторых случаях это поможет избежать определенных проблем.

Подробнее об обновлении драйверов защиты:

Сылка удалена.

Обновления драйвера защиты с помощью protect.exe требует подключение к сети Интернет. Если у вас такого подключения в данный момент нет, то можно воспользоваться подключением у друга/соседа/на работе. Для этого отправьте запрос на электронный адрес нашей технической поддержки и вам пришлют необходимые файлы и инструкцию как все установить.

Если у вас Windows Vista и утилита не отрабатывает нормально – запускайте ее с правами администратора. Соответствующая опция доступна по правой клавише.

6. Игра устанавливается нормально, но не устанавливается драйвер защиты

У вас, скорее всего, Windows Vista. Перед запуском программы отключите User Account Control. В дальнейшем эту опцию можно вновь активировать, так как драйвер ставится только 1 раз перед первым запуском игры.

Для включения/выключения User Account Control зайдите в Панель Управления, выберите User Accounts. Внутри будет опция Turn UserAccount Control on/off.

Взято с сайта www.gsc-game.ru

От себя дабавлю у меня ругался и без эмуляторов, может на картридер, а может и на второй физический DVD.

Помогала переустановка игры или тупо жмешь далее и после двух трех бсодов перестает выбрасывать. Далее выбрасывает уже сама игра -))).

Способ редактирования скрипта без выхода из игры.

Первая проблема решается при помощи двух стандартных функций самого Lua, а именно dofile и pcall.

dofile

resultChunk = dofile("C:\Study\My.script")

Открывает указанный файл и выполняет его содержимое как chunk. Возвращает результат выполнения или же генерирует ошибку.

Chunk — в переводе с английского, порция или блок. В Lua же порция — это любая последовательность операторов Lua.

Здесь важно понять, что такое «последовательность операторов«. function — это тоже порция или другими словами блок операторов. Таким образом, выполняя при помощи dofile какой-либо скрипт, в файле следует писать именно содержимое блока, который нужно выполнить.

pcall

pcall (funcName, arg1, ...)

Вызывает функцию funcName с данными параметрами (arg1, и далее, через запятую необходимое для функции funcName количество параметров) в так называемом защищенном режиме (protected mode).
Это значит, что при возникновении любой ошибки внутри функции funcName она дальше не передается; напротив, pcall перехватывает ошибку и возвращает статус. pcall возвращает сначала статус (тип boolean), который равен true если вызов завершился без ошибок, и все результаты от работы защищённой им функции. В случае возникновения ошибки, pcall возвращает false и сообщение об ошибке.
Может показаться сложным и запутанным, но на деле это не так. Попытаюсь показать Вам на примере.

Имеем простую функцию возвращающая сумму двух чисел:

function Addition (a, b)
      return a + b
end

Если вызвать функцию с параметром b отличным от числа (тип number) :

sum = Addition(13, true)

то произойдёт ошибка выполнения следующего содержания:

attempt to perform arithmetic on local 'b' (a boolean value)

Если же задействовать функцию pcall, то результат будет совершенно иным.

status, result = pcall(Addition, 13, true)

Как и говорилось, функция pcall принимает в качестве первого аргумента имя функции, а в качестве последующих — аргументы, которые принимает уже сама вызываемая функция.
Возвращает же два значения. Первое — результат выполнения, статус определяющий возникла ли ошибка (false — если возникла, true — если нет). Второе — результат выполнения функции, если ошибки не возникло, или же сообщение об ошибке, если внутри функции возникла ошибка.
В примере в переменной status будет значение false, а в переменной result — строка «attempt to perform arithmetic on local ‘b’ (a boolean value)«.
При передаче правильных параметров, которые не вызовут ошибку, в переменной status будет значение true, а в result — сумма двух чисел, переданных в качестве этих самых параметров.

В обоих случаях ошибки выполнения, а следовательно и вылета в контексте игры, не будет!

Совместив эти две функции можно получить крайне полезную конструкцию, которая позволит выявлять ошибки не приводя к вылетам игры, и легко выводить описание ошибки непосредственно в лог.
Для этого заведём для себя функцию, где pcall будет вызвать функцию dofile, которая в свою очередь будет выполнять нужный нам файл со скриптом. Выглядеть эта функция будет так:

function ProtectedFunction()
      local status, result = pcall(dofile, [[..gamedatascripts__test.script]])
      get_console():execute(status and "Successful!" or string.gsub(result, " ", "_"))
end

Всё очень просто. Вызываем pcall, в качестве параметра передаём функцию dofile и аргумент для неё — путь до нашего файла __test.scrip, который нужно предварительно создать в папке scripts.

Опытным путём было установлено, что в ТЧ корневым каталогом Lua считает папку bin, поэтому путь пишем относительно неё. В ЧН и ЗП — это корневая папка установленной игры, поэтому путь для этих частей будет таким: «[[gamedatascripts__test.script]]«

Вторая строка выводит в консоль сообщение «Successful!» если скрипт в файле _test.script выполнился без ошибок или же сообщение ошибки выполнения, если произошла ошибка. Сообщение выводится со знаком подчёркивания вместо пробела. Это необходимая мера для метода execute.

Результат выводить в консоль не имеет смысла, т.к. результат нам покажет сама игра.
Теперь если вызвать функцию ProtectedFunction, то выполнится код написанный в файле __test.script. При этом, сам код в этом файле можно менять не выходя из игры, а просто свернув её.

Поэтому, получив ошибку внутри вызываемого файла — в консоле появится сообщение с описанием данной ошибки. Далее: сворачиваете игру; правите ошибку; восстанавливаете игру; запускаете вызов функции ProtectedFunction по новой; смотрите на результаты работы исправленного скрипта.

Хочу ещё раз обратить Ваше внимание на то, что в файле __test.script должен присутствовать именно блок операторов!

Содержимое файла может быть таким:

function MyFunction ()
      db.actor.health = 1
end

При вызове ProtectedFunction не произойдёт ошибки, т.к. её там нет, но и ничего не добавится к здоровью актора, как хотелось бы. Причина в том, что данный код только описывает функцию, но вызова этой функции в файле нет. Поэтому эту функцию нужно вызвать там же, в файле:

function MyFunction ()
      db.actor.health = 1
end
MyFunction()

Последняя строка — это и есть вызов функции. Вызов функции это и есть в некотором роде оператор. При таком содержимом файла, функция ProtectedFunction выполнится без ошибок и Вы увидите результат выполнения, в виде пополнения здоровья ГГ до максимального значения.

В процессе игры, не выходя из неё, Вы можете подредактировать файл __test.script, скажем, изменив свойство health на power, тем самым последующий вызов защищённой функции пополнит уже не здоровье, а выносливость.

Важно понимать, что pcall перехватывает ошибки только той функции, которую вызывает, то беж в нашем случае dofile а это, в свою очередь, вызов нашего файла __test.script. Поэтому, если в этом файле будет вызов функции из другого файла и ошибка произойдёт уже в нём (в другом файле), то игра вылетит с логом ошибки другого файла. Тоже самое касается работы движковых функций; если Вы передаёте неверный аргумент, не правильно вызываете какую-нибудь функцию экспортированную в скрипты из движка, то игра вылетит.
В большинстве случаев, допускаются именно ошибки выполнения скрипта, поэтому данная конструкция позволяет избежать большого количества перезапуска игры, что сохранит и время, и нервы.


Что касается второй проблемы, то самым удачным вариантом её решения будет простое нажатие клавиши на клавиатуре, т.е. собственная горячая клавиша.
В качестве наилучшего исключительно скриптового метода горячих клавиш я предлагаю использовать способ предоставленный здесь: ссылка на статью, конкретно интересует действие на нажатие (первый способ).

Ключевым звеном данного способа является команда консоли bind_cosole. Команда позволяет назначить выполнение другой консольной команды на любую клавишу на клавиатуре. Её синтаксис выглядит так:
bind_cosole <Имя консольной команды> <Значение для команды> <Код клавиши>

Например:

bind_cosole save 1 knumpad1

Таким образом, при нажатии на единицу на цифровой клавиатуре, в консоле будет вызвана команда «save 1«, что приведёт к сохранению игры под именем «1».

Есть команды консоли, которые сохраняют в себе переданное ей значение, например «mm_net_player_name«. Команда изменяет/возвращает имя игрока в мультиплеере, соответственно в одиночной игре она не задействована, и именно по этому автор остановил свой выбор на ней.

В скриптах, есть возможность получения значений команд консоли, при помощи методов объекта консоли CConsole, в игре такой объект можно получить с помощью функции глобального пространства имён get_console.

Вот такой код:

local mmPlayrName = get_console():get_string("mm_net_player_name")

Запишет в переменную имя игрока в сетевой игре.

Такой тандем из из команды bind_cosole и метода get_string, позволяют при нажатии на клавишу задать для команды «mm_net_player_name» значение имени функции, которую нужно выполнить, и в нужный момент получить имя этой функции для того, чтобы её вызвать.
В этом и состоит весь принцип работы горячих клавиш данного способа.
Изначально мы проходимся по файлу в поисках функций с именем, которое совпадает с перечислением имён класса DIK_keys, только написанное строчными литерами. Присваиваем соответствующей этому имени клавише команду консоли «mm_net_player_name <имя функции>«. Таким образом при нажатии на такую клавишу, данному параметру будет присвоено имя функции. Отлавливаем значение данной команды с помощью метода get_string, если это имя функция, которая находится в текущем файле, то вызовем её, и тут же присвоим команде значение по умолчанию, чтобы функция не вызывалась в дальнейшем. При повторном нажатии на клавишу, команде снова присвоится значение с именем функции, которое отловится на ближайшем апдейте. И так по кругу.

Перед запуском игры, Вам нужно определится какую из не задействованных клавиш Вы будете использовать как «горячую».

Список клавиш в Сталкере, которые можно задействовать под это дело, можно посмотреть здесь: DIK_keys. Это перечисление констант класса DIK_keys, имена которых используются в качестве имени функций для горячих клавиш.

Я выберу клавишу Scroll Lock, чтобы хоть как-то оправдать её присутствие на клавиатуре. Код этой клавиши — dik_scroll, именно так и должна называться функция, которую будет вызывать выбранная мной клавиша.

Имена функций, которые непосредственно будет вызывать Ваши горячие клавиши, должны быть написаны строчными литерами (маленькими буквами).

Теперь, всё что остаётся сделать, это написать функцию с именем dik_scroll в файле, в котором находится функция update горячих клавиш. Выглядеть она будет так:

function dik_scroll()
      local status, result = pcall(dofile, [[..gamedatascripts__test.script]])
      get_console():execute(status and "Successful!" or string.gsub(result, " ", "_"))
end

Как видите, в тело функции я написал содержимое нашей «защищённой функции», а не вызывал отдельно её — зачем лишний раз без необходимости плодить код?


Всё, друзья мои!
Теперь, зайдя в игру и загрузив сохранение (или начав её заново), Вы можете полюбопытствовать работой нашей конструкции. Нажимаете Scroll Lock (или другую выбранную Вами клавишу) и видите запуск содержимого в файле __test.script. Если в файле не было ошибок, то в консоле вы увидите надпись «Successful!» или же сообщение об ошибке. Попытайтесь не выходя из игры, свернуть её при помощи комбинации Alt+Tab, изменить содержимое файла, а затем в восстановленной игре опять нажать горячую клавишу — как Вы сами убедитесь, результат будет основываться на изменённых данных.

Готовую мини-gamedat’у, можно скачать здесь: Яндекс.Диск

Всё, что Вам потребуется сделать — поместить два скрипта в вашу рабочую папку scripts и прописать в апдейте актора следующую строку:

bind_keys.update()

Зайти в игру и нажать на клавишу Scroll Lock.

Привет всем! Игра S.T.A.L.K.E.R., а конкретно сам движок X-Ray довольно капризный, и зачастую как в процессе модификации, так и во время игры игра «вылетает». Чтобы мы знали причину вылета, движок нам оставляет лог вылета. Лог вылета можно посмотреть несколькими способами:

  • В текстовом редакторе нажать Ctrl+V (Вставить)
  • Посмотреть лог игры включая лог вылета в файле xray_имя_пользователя.log в папке C:Documents and SettingsAll UsersДокументыSTALKER-***logs
  • Посмотреть непосредственно в окне багтрекера (только в ЧН и ЗП).

Ну приступим. Начнём с простых:


Expression    : wave&&wave->length()
Function      : CSoundRender_Source::LoadWave
File          : E:stalkerpatch_1_0004xrSoundSoundRender_Source_loader.cpp
Line          : 65
Description   : Can't open wave file:
Arguments     : d:stalkergamedatasoundsmusicsound.ogg

Здесь игра не может открыть звуковой OGG-файл под названием sound в папке d:stalkergamedatasoundsmusic


Expression    : fatal error
Function      : CRender::texture_load
File          : E:stalkerpatch_1_0004xr_3daxrRenderTexture.cpp
Line          : 295
Description   : <no expression>
Arguments     : Can't find texture 'actact_corp_monolit'

Не может найти текстуру act_corp_monolit из папки texturesact


Expression    : fatal error
Function      : CModelPool::Instance_Load
File          : E:stalkerpatch_1_0004xr_3daxrRenderModelPool.cpp
Line          : 111
Description   : <no expression>
Arguments     : Can't find model file 'physicsmesh.ogf'.

Не найдена трёхмерная OGF-модель mesh.ogf из папки meshesphysics.


Expression    : SG
Function      : CRender::model_CreateParticles
File          : E:stalkerpatch_1_0004xr_3daxrRender_R2r2.cpp
Line          : 330
Description   : Particle effect or group doesn't exist
Arguments     : hit_fxhit_water_00

Не найдена система частиц (партикл) hit_water_00 в директории hit_fx файла particles.xr (подробно опишу позже).


Expression    : !m_bAutoRemove
Function      : CParticlesObject::Init
File          : D:prog_repositorysourcestrunkxrGameParticlesObject.cpp
Line          : 50
Description   : Can't set auto-remove flag for looped particle system.
Arguments     : snow_stepsstep

Не установлен интервал (время) проигрывания группы/эффекта партиклов. В Particle Group -> End Time(s) укажите время, через которое частицы должны исчезнуть. Заодно проверьте particle effect -> Kill Old -> Age limit.


Expression    : fatal error
Function      : CResourceManager::_GetBlender
File          : E:stalkerpatch_1_0004xr_3daResourceManager.cpp
Line          : 49
Description   : <no expression>
Arguments     : Shader 'modelsantigas_glass' not found in library.

Не найден шейдер modelsantigas_glass в библиотеке шейдеров.


Expression    : fs
Function      : CResourceManager::_CreateVS
File          : E:stalkerpatch_1_0004xr_3daResourceManager_Resources.cpp
Line          : 185
Description   : shader file doesnt exist
Arguments     : d:stalkergamedatashadersr2deffer_impl_flat.vs

Тут проблема вся в том, что неправильно закомпилился шейдер, при компиляции уровня на качестве, более высоком чем Draft. Нужно скачивать исправление шейдеров от товарища Haron.
Для ЗП (ЧН) это может ещё быть из-за отсутствия thm-ок для текстур террейна уровня!


Expression : fatal error
Function : out_of_memory_handler
File : D:prog_repositorysourcestrunkxrCorexrDebugNew.cpp
Line : 336
Description : <no expression>
Arguments : Out of memory. Memory request: 55965 K 

Нехватка оперативной памяти.


[error]Expression : assertion failed
[error]Function : CBuild::Load
[error]File : .Build_Load.cpp
[error]Line : 98
[error]Description : B.dwMaterialGame<65536

Неправильно настроены шейдеры. В настройках шейдера, во вкладке R2-A поставьте текстуру, которая вдальнейшем будет накладываться
на террейн.


Expression : fatal error
Function : CInifile::r_string
File :E:stalkersourcestrunkxrCoreXr_ini.cpp
Line : 352
Description : <no expression>
Arguments : Can't find variable ammo_mag_size in [wpn_addon_grenade_launcher]

Не найдена переменная ammo_mag_size в секции [wpn_addon_grenade_launcher].


Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : D:xray-svnxr_3daxrGamescript_engine.cpp
Line          : 74
Description   : <no expression>
Arguments     : LUA error: C stack overflow

Переполнение стека. Смотрим внимательно: lua_error. Ошибка, возможно, в скриптах.


Expression : vertex || show_restrictions(m_object)
Function : CPatrolPathManager::select_point
File : E:stalkersourcestrunkxr_3daxrGamepatrol_path_manager.cpp
Line : 155
Description : any vertex in patrol path [sniper_3_walk] in inaccessible for object [stalker_0002]

Какая то вершина (вейпоинт) пути sniper_3_walk стоит в неположенном месте (например не на аи-сетке). Объект stalker_0002 (в данном случае сталкер) который якобы двигался по пути sniper_3_walk попал на эту точку, а заодно ушёл за аи-сетку. Этого движок не терпит.

То же самое произойдет если координаты(вейпоинт) пути sniper_3_walk совпадет с координатами места, где НПС запрещено находиться, будь то рестриктор или аномалия в схеме обхода аномалий.
Также этот вылет наблюдается при попытке отправить НПС за пределы места работ параметр out_rest = «имя_рестриктора» в файле загрузки работ гулага. Попробуйте любого сталкера из лагеря новичков отправить, допустим, к остановке — получите этот самый вылет.


Expression : e_entity
Function : xrServer::Process_event_reject
File : E:stalkersourcestrunkxr_3daxrGamexrServer_process_event_reject.cpp
Line : 12
Description : entity not found. id_parent=7540 id_entity=44047 frame=2075050

Возникают иногда произвольно при смерти неписей. Причина — движок, отрабатывая лут, изредка теряет серверный объект уничтожаемой вещи, в итоге происходит вылет.


Expression : fatal error
Function : CScriptEngine::lua_error
File : D:xray-svnxr_3daxrGamescript_engine.cpp
Line : 74
Description : <no expression>
Arguments : LUA error: e:stalkergamedatascripts_g.script:20: bad argument #2 to 'format' (string expected, got no value)

Ошибка распространённая. На первый взгляд кажется, что ошибка как раз в скриптах, но всё может быть иначе. В одной из пиратских версий игры этот вылет наблюдается особенно часто из-за криво модифицированного файла «XR_3DA.exe». Если же вы уверены, что у вас лицензионная версия игры, можно попробовать сделать так: открываем файл _g.script блокнотом, закомменчиваем 20 строку (ставим перед строкой —) и идём к тому месту где поймали вылет. Так мы получим более развёрнутый ответ.

Участник: Призрак: Автор прав в том что вылет очень распространен, но так его исправлять нельзя, так как nil передается в эту функцию только при каком-то форс-мажоре. Поэтому необходимо перейти в _g.script в функцию printf и перед log1(string.format(fmr,..)) дописать: get_console():execute(«load «..fmt). После этого запустить еще раз игру и посмотреть при передачи какой строки игра вылетает. Потом найти эту строку в скриптах игры и прикинуть почему аргумент (у нас это аргумент №2 (bad argument #2)) равен nil. Возможность такового вылета из — за слишком быстрой скорости актера, слишком высокому прыжку. (Редактировать: config/creatures/actor.ltx)


Expression    : assertion failed
Function      : _VertexStream::Lock
File          : E:stalkerpatch_1_0004xr_3daR_DStreams.cpp
Line          : 44
Description   : (bytes_need<=mSize) && vl_Count

Проблема возникает при убийстве НПСмутанта. Типичный вылет по нехватке ресурсов. Встречается в основном на больших локациях. Но не на всех. На болотах из ЧН такой вылет встречается, а вот с локации aver от Кости V такого вылета нет. Однако для данного вылета есть таблетка, в виде правленого экзешника. Искать на АМК-форуме.


Expression    : fatal error
Function      : IRender_Visual::Load
File          : E:stalkerpatch_1_0004xr_3daFBasicVisual.cpp
Line          : 58
Description   : <no expression>
Arguments     : Invalid visual

Неправильный визуал (модель) НПС.


Expression    : !phrase_dialog->m_PhraseVector.empty()
Function      : CPhraseDialog::SayPhrase
File          : E:stalkerpatch_1_0004xr_3daxrGamePhraseDialog.cpp
Line          : 140
Description   : No available phrase to say, dialog[esc_dialog]

В диалоге esc_dialog нет доступной для отображения фразы (скажем, все заткнуты инфопоршенами).


Expression    : motion_ID.valid()
Function      : CKinematicsAnimated::ID_Cycle
File          : D:prog_repositorysourcestrunkLayersxrRenderSkeletonAnimated.cpp
Line          : 210
Description   : ! MODEL: can't find cycle:
Arguments     : death_init

Игра не нашла в модели трёхмерную анимацию с именем death_init.


Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:stalkerpatch_1_0004xr_3daxrGamescript_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ...hadow of chernobylgamedatascriptsxr_danger.script:116: attempt to index field 'ignore_types' (a nil value)

Причина вылета в том что игра не понимает значения 0 в danger_ignore.Проще говоря в логике какого то персонажа параметр danger_ignore = 0 либо в минусовом значении. Либо его вообще нету

P.S. Также может быть причина в том, что в логике у какого-то АИ что-то неправильно указано. Для исправления рекомендую вставить строчку перед 116: get_console():execute(self.object:name()). То имя в логе, которое будет последним после вылета, указывает на персонажа с кривой логикой.


Expression    : fatal error
Function      : CInifile::r_string
File          : E:stalkerpatch_1_0004xrCoreXr_ini.cpp
Line          : 352
Description   : <no expression>
Arguments     : Can't find variable class in [test_no_klass_npc]

Не найден класс персонажа. Возможно, НПС не прописан под своим классом в gamedatanpc_profile.xml, либо в creaturesspawn_section.ltx, либо в gameplaycharacter_desc.xml


Expression    : fatal error
Function      : CInifile::r_section
File          : E:stalkerpatch_1_0004xrCoreXr_ini.cpp
Line          : 342
Description   : <no expression>
Arguments     : Can't open section 'bandage_test_kick1'

Игра не может найти секцию. Это может быть предмет, НПС и многое другое. Возможно, вы написали название с ошибками. Либо когда добавляли его в: продажу, скрипт, НПС , выпадение из НПС, а в редких случаях это может быть иммунитет чего либо(определить потом трудно). Часто такое бывает связано с названием секции.


Expression    : fatal error
Function      : CInifile::r_string
File          : E:stalkerpatch_1_0004xrCoreXr_ini.cpp
Line          : 352
Description   : <no expression>
Arguments     : Can't find variable remove_time in [vehicle_btr]

Не найдена переменная remove_time в секции [vehicle_btr]. А в данном случае ошибка в том что если вы делали предмет как физическую модель(то бишь, которую нельзя использовать, говорить и вообще он похож на декорации типа деревьев, столов и прочего хлама) то необходимо указывать remove_time в его секции.


Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:stalkerpatch_1_0004xr_3daxrGamescript_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ...dow of chernobylgamedatascriptstest_kick.script:34: attempt to call method 'section' (a nil value)

Метод обращения в игре не предусмотрен. Возможно, стоит пересмотреть подход к тому или иному скрипту.


Expression    : rpoints[0].size()
Function      : game_sv_Deathmatch::Create
File          : D:prog_repositorysourcestrunkxrGamegame_sv_deathmatch.cpp
Line          : 99
Description   : rpoints for players not found

На мультиплеерной карте не найдены точки респавна игроков. В SDK должен быть красный пацанчик. Настроить Team = 0


Expression    : fatal error
Function      : xrServer::Process_update
File          : E:stalkerpatch_1_0004xr_3daxrGamexrServer_process_update.cpp
Line          : 37
Description   : <no expression>
Arguments     : Beer from the creator of 'WP_SHOTG'

Такое иногда бывает, когда ты (ГГ) или НПС заряжает дробовик или другое оружие со значением tri_state_reload = true.
Это глюк. в игре что-то сбивается, и когда у дробовика максимальное количество заряженных патронов скажем 6, он заряжается за 6 и дальше.. дальше.. дальше.. и так пока не произойдёт вылет с вышеуказанным логом. вылет не значительный и редкий, но если он случается слишком часто, можно в конфигах всех дробовиков и ружей поменять значение tri_state_reload = true на tri_state_reload = false.


Expression    : fatal error
Function      : CInifile::r_string
File          : D:prog_repositorysourcestrunkxrCoreXr_ini.cpp
Line          : 477
Description   : <no expression>
Arguments     : Can't find variable bound_rect in [level_map]

Такой лог бывает когда подключаешь локацию из ТЧ в ЗП. Причина проста — в ЗП уровнях файл строчка bound_rect пишется в файле gamedatalevelsимя_уровняlevel.ltx, а в ТЧ строка bound_rect для каждого уровня непосредственно в файле gamedataconfiggame_maps_single.ltx …

Исправить просто, нужно изменить файл gamedatalevelsимя_уровняlevel.ltx в подключенной локации, просто перенести строку bound_rect из game_maps_single.ltx в level.ltx перед строчкой texture.


Expression : hGame
Function : CEngineAPI::Initialize
File : E:stalkerpatch_1_0004xr_3daEngineAPI.cpp
Line : 65
Description : Game DLL raised exception during loading or there is no game DLL at all

Случается когда одна из dll некорректна. Например такой вылет бывает если подсунуть в ТЧ 1.0004 xrGame от 6 патча.


Expression    : assertion failed
Function      : CInventory::Eat
File          : E:stalkersourcestrunkxr_3daxrGameInventory.cpp
Line          : 892
Description   : pIItem->m_pCurrentInventory==this

Вылет встречается только на 6 патче при попытке хаванья из трупа. Ищите, исправленную Kolmogor’om, xrGame.dll в Интернете


[error]Expression    : error handler is invoked!
[error]Function      : invalid_parameter_handler
[error]File          : E:stalkersourcestrunkxrCorexrDebugNew.cpp
[error]Line          : 804
[error]Description   : 

Данный вылет бывает когда у какого либо из объектов установлено некорректное значение (читал, сам не получал его)
Или же если данный вылет происходит при вызове класса, то проблема в том что в методе __init() класса прописано super()


Expression : !m_error_code
Function : raii_guard::~raii_guard
File : D:prog_repositorysourcestrunkxrServerEntitiesscript_storage.cpp
Line : 748
Description : d:stalker copgamedatascriptsbind_stalker.script:231: attempt to index global 'ИМЯ_ФАЙЛА' (a nil value)

Вылет происходит в двух случаях — когда скрипт пытается вызвать функцию из несуществующего файла или когда в файле допущена синтаксическая ошибка.


Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:stalkersourcestrunkxr_3daxrGamescript_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: attempt to call a nil value

Происходит при попытке вызвать класс, которого не существует


Небольшой пример из практики по определению ошибки в особых случаях(для начинающих):
Игра зависла, картинка на экране не меняется, на Ctrl + Alt+ Delete не реагирует. Только «Холодная перезагрузка» reset. Но при этом обычно в логе нет записи и обычным Ctrl + V ошибку не увидеть.
Я пользуюсь программой Punto Switcher. Есть в ней опция «дневник», она ведёт запись всех нажатий клавиш и по нажатию сочетаний клавиш содержимое памяти может записывать в дневник.
теперь когда игра зависла и картинка на экране не меняется, нажимаете Ctrl + Alt+ Delete. Внешне ничего не изменится, но ОС будет реагировать
на клавиши, нажимаете сочетание клавиш «записать в дневник». Делаете перезагрузку, открываете дневник — Ваша ошибка записана.
«дядя Саша»


Expression    : bone_id!=BI_NONE
Function      : SArtefactDetectorsSupport::SetVisible
File          : D:prog_repositorysourcestrunkxrGameArtefact.cpp
Line          : 525
Description   : link

Возникает при создании или добавлении чужих артефактов. В artefacts.ltx, в секции af_base есть параметр particles_bone=link. Это имя косточки, которая принимается за центр при проигрывании партикла. Если кость в артефакте называется по иному, например joint2, и это не указанно в секции нового арта, которая наследуется от базовой и подразумевает естественно наличие link, получаем вылет. Решается конвертированием модели арта в .object, просмотром в sdk и выяснением имени косточки с занесением в конфиг.


Expression    : error handler is invoked!
Function      : invalid_parameter_handler
File          : D:prog_repositorysourcestrunkxrCorexrDebugNew.cpp
Line          : 815
Description   : bad argument #3 to 'format' (string expected, got no value)

Вылет заканчивающийся строкой, то что выше не указываю роли не играет, здесь роль играет только «bad argument #3». Если это появилось значит у Вас ошибка в файле с расширением .ltx (обращаю внимание, не путать с файлами .script), которая находится между [….] квадратными скобками в файле. Это может быть секция предмета, секция логики, секция пути файла way_, т.е. там где присутствуют квадратные скобки.


Expression    : cross_table().header().level_guid() == level_graph().header().guid()
Function      : CAI_Space::load
File          : D:prog_repositorysourcestrunkxrGameai_space.cpp
Line          : 113
Description   : cross_table doesn't correspond to the AI-map

Скорее всего, отсутствует файл level.ai. Возможно после правки уровня в SDK и компиляции AI, вы забыли его скопировать в папку уровня. Важно помнить, что level.ai нужно обновлять для всех уровней, а не только для тех, которые подвергались правке.


Безлоговый вылет

Вылет, при котором лог отсутствует. Причины такого вылета:

1. Безлоговые вылеты бывают в основном из-за завышенных настроек видео.

Решение:
В папке с игрой открыть папку gamedata, папку config, в ней файл alife, открыть любым текстовым редактором (блокнотом, или лучше word pad’ом) и найти строку switch distance = и изменить значение на 5, сохранить изменения. Это только одна (не сильно вероятная) причина безлогового вылета. если вы знаете ещё одну причину, пожалуйста напишите здесь.

2. Вторая причина неправильно указано название пути в логике НПС или он полностью отсутствует в файле way_ all.spawn. Вылетать будет когда дойдёт время до спавна этого НПС.

3. Также, безлоговые вылеты происходят из-за ошибок в диалогах.



  • Автор статьи — Pihan13
  • Дополнительный справочник «вылетов» игры

Не стесняемся — дополняем, если знаем о чём идёт речь.

Продолжаем разговор:

sys_ini = system_ini()
global_time_ms, game_time_ms, game_time_sec, game_time_time = 0, 0, 0, 0
game_time_start, game_time_base = 0, 0	-- игровое время на начало игры, игровое время при загрузке

dist_sw_online = 150
dist_sw_offline = 180

IAmAStalker, IAmAMonster = {}, {}		-- obsolete
IAmAWeapon, IAmAWeaponFireOnly = {}, {}		-- obsolete

c_npc = false
c_actor = false
c_mob = {}
c_ai = {}
c_trader = false
c_ibox = false
c_wpn = {}
c_arms = {}

mob_online = {}		-- табличка принудительного on/off-line для монстров
force_offline = {}	-- принудительный оффлайн для неписей и тайников

function printf() end

function print_table() end

function trim( s ) return string_match( s, "^%s*(.*%S)" ) end	-- обрезаем пробелы


function Parse_StrToTbl( s, div, mode )	-- ( строка, разделитель, [true|число|nil для строк] )
	local t = {}
	local pattern
	if div then pattern = "%s*([^" .. sDiv .. "]+)%s*"
	else pattern = "[_%w]+"
	end
	if mode then
		if mode == true then for v in string_gmatch( s, pattern ) do t[v] = true end	-- таблица вида [значение] = true
		elseif type( mode ) == "number" then					-- таблица вида [idx] = число
			for v in string_gmatch( s, pattern ) do table_insert( t, tonumber( v ) or v ) end
		else abort( "Parse_StrToTbl, ivalid mode: %s", tostring( mode ) )
		end
	else for v in string_gmatch( s, pattern ) do table_insert( t, v ) end
	end
	return t
end


function parse_custom_data( str )	-- комментарии в профилях и cd не использовать ! Сохраняются в cd как есть !
	local t = {}
	if str then
		--log( "info", "parse_custom_data: [" .. string_sub( str, 1, 150 ) .. "]" )
		local ts
		for sect, data in string_gfind( str, "%s*%[([^%]]*)%]%s*([^%[%z]*)%s*" ) do
			--log( "info", "parse_custom_data, sect: [" .. sect .. "], data: [" .. string_sub( data or "nil", 1, 120 ) .. "]" )
			ts = {}
			t[sect] = ts
			for s in string_gfind( data or "", "([^n]*)n*" ) do
				if string_find( s, "=" ) then
					for k, v in string_gfind( s, "([^=]-)%s*=%s*(.*)" ) do
						--log( "info", "parse_custom_data, " .. k .. " = " .. string_sub( v or "nil", 1, 120 ) )
						if v then
							k = string_match( k, "^%s*(.*%S)" )
							if k and k ~= "" then
								ts[k] = string_match( v, "^%s*(.*%S)" )
					end	end	end
				else
					local k = string_match( s, "^%s*(.*%S)" )
					if k and k ~= "" then ts[k] = "<<no_value>>" end
	end	end	end	end
	return t
end


function gen_custom_data( t )
	local s = ""
	for k, v in pairs( t ) do
		s = s .. "[" .. k .. "]n"
		for kk, vv in pairs( v ) do
			if vv ~= "<<no_value>>" then s = s .. kk .. " = " .. vv .. "n"
			else s = s .. kk .. "n"
	end	end	end
	return s
end


function parse_names( s )
	local t, n = {}, 0
	for name in string_gfind( s, "([%w%-%._\]+)[%,%s]*" ) do n = n + 1; t[n] = name end
	return t
end


function parse_key_value( s )
	if s then
		local t = {}
		local k
		for n in string_gfind( s, "([%w%-%._\]+)[%,%s]*" ) do
			if k then t[k] = n; k = nil
      			else k = n
		end	end
		return t
	end
end


function parse_nums( s )
	local t, n = {}, 0
	for entry in string_gfind( s, "([%d%.]+)%,*" ) do n = n + 1; t[n] = tonumber( entry ) end
	return t
end

sys_ini = system_ini() — файлы в винде вообще открываются ОЧЕНЬ медленно. А сам сталкер еще и что-то с ними делает, тоже мееедленно, и печально.

Отсюда и загрузка солянки по 2 минуты. Так что открываем все один раз, и так в открытом состоянии и держим.

global_time_ms, game_time_ms, game_time_sec, game_time_time = 0, 0, 0, 0

game_time_start, game_time_base = 0, 0 — игровое время на начало игры, игровое время при загрузке

В общем, вместо времени 64 бит с многочисленными преобразованиями в таблицы и обратно я использую везде 32.

Ага, 31 мая, 32 мая, и т.д. ;) Чтобы такого не было — время всегда считается не от НИ, а от загрузки. И сохраняется дельта. А месяц топтаться на одной оркации без единого сэйва — вряд-ли кто будет.

Ну и наконец, вместо медленного вызова функций и пересчета используем быстрое обращение к переменной. А обновляются они раз в 200ms — вполне достаточно, я считаю.

dist_sw_online = 150

dist_sw_offline = 180

Опять же, чтобы не перечитывать и не пересчитывать постоянно — переменные. А из alife.ltx берем только при загрузке.

IAmAStalker, IAmAMonster = {}, {} — obsolete

IAmAWeapon, IAmAWeaponFireOnly = {}, {} — obsolete

c_npc = false

c_actor = false

c_mob = {}

c_ai = {}

c_trader = false

c_ibox = false

c_wpn = {}

c_arms = {}

— то, которое устарело — это была одна из солянковских оптимизаций. Устарело. Просто не от всюду еще дочистил. Добавлены константы и таблички с классами. Инициализируются при старте, когда отработает class_regisrator и появится alife().

mob_online = {} — табличка принудительного on/off-line для монстров

force_offline = {} — принудительный оффлайн для неписей и тайников

Как бы понятно из названия. Единые таблицы для ВСЕХ скриптов, где применяется такой фокус. Хотя вообще-то на самом деле это плохой, негодный фокус, и он не нужен, но это уже другая тема. А так — в amk было переодевание и тайники, использовавшее convert_npc={}, еще где-то — need_be_online={} в se_monster, не знаю, зачем… Тысячи их. Все снести, где реально надо — заменить на единые глобальные.

printf() и print_table() — затычки для недовычищенного и прочих разных гибридизаций ежа с ужом через 50 скриптов, гордо именуемых «адаптациями».

И, наконец, преобразования разных забавных строк в разные забавные таблицы, и обратно. Часть — была и в оригинале, часть — во вножестве экземпляров в разных скриптах, и оригинальных, и которые см. про «адаптацию».

Все собрано в одном месте и переписано.

Тут важно понимать, что в LUA НЕТ инлайна, а следовательно, все равно все это будет работать медленно и печально, и прежде чем использовать какую-нибудь функцию преобразования чего-попало во что-нибудь еще, особенно, в цикле или апдейте — подумайте, а надо ли ?

Ибо нет ничего более нелепого, и вызывающего содрогание, чем конструкция вида:

local s = «1, 2, 3»

local t = parse_nums( s )

local n1, n2, n3

for k, v in pairs( t ) do if k == 1 then n1 = v end; if k == 2 then n2 = v end; if k == 3 then n3 = v end; end


Изменено 23 Ноября 2014 пользователем Dennis_Chikin

Модостроение. Редактирование и создание скриптов

denis2000 Дата: Пн, 10.10.2011, 21:17 | Сообщение # 1

Полевой исследователь

Ученые сталкеры

Редактирование и создание скриптов

Редактирование и создание скриптов на языке LUA

Если у вас появились вопросы по применению скриптов в игре. Задавайте их в этой теме — умные головы,
модосторители и просто разбирающиеся в программировании люди вам ответят.

Много интересного материала здесь (wiki), Lua_help.script, Help из SDK 0.7

Сборник модостроения ЗП v10.10.11 (автор: XOBAH): *.CHM, *.HTML
[cut noguest=Если у вас не открывается файл CHM]Если у вас не открывается файл:
1. Запустите [Пуск]=>[Выполнить] (либо хот-кей [WIN]+[R])
2. Введите команду (без кавычек) «regsvr32 %windir%system32hhctrl.ocx»
3. Если вылезло окно об успешном завершении вы все сделали правильно и можете перезагружать компьютер (а может и не надо)
Также: файлы

МОГУТ не открываться если в пути к файлу есть: символы кириллицы, «_», «#»
Также: есть не стандартные программы-просмоторщики CHM файлов. Например: FBReader[/cut]

[cut=Где найти лог игры после вылета]Что такое LOG ошибки, и как мне его найти?
Это система отладки происходивших вылетов, которая подается игрой в форме текста, хотя не всегда.
Для того чтоб найти LOG необходимо зайти вот сюда:

В Win хр лог находится:

C:Documents and SettingsAll UsersДокументыS.T.A.L.K.E.R. — Зов Припятиlogs

Затем открываете первый файл в формате TXT, и в нем отбираете с низу 25 строчек. После кидаете эти 25 строчек в сообщение на форум.

В Win7 лог находится C:UsersPublicDocumentsS.T.A.L.K.E.R. — Зов Припятиlogs

Путь к папке с логом можно найти открыв файл fsgame.ltx который находится в корневой директории ЗП, за это отвечает строка:

$app_data_root$ = true | false| $fs_root$| users
(тут мы указываем что папка пользователя, будет хранится рядом с Fsgame.ltx)

$logs$ = true| false| $app_data_root$| logs
(а тут мы указываем что в папке пользователя, в подпапке Logs будут храниться наши логи)

[/cut][cut=Получение более подробной информации о вылете (ХОВАН)]
Открываем файл _g.script и ищем такую функцию: function abort(fmt, …)
Там есть заккомментированная строчка «—error_log(reason)«, ее и надо расскомментировать, должно получиться вот так:

Code

function abort(fmt, …)
                             local reason = string.format(fmt, …)
                             error_log(reason)
end

Вот для примера два одинаковых вылета, первый с функцией по умолчанию, второй — с поправленной функцией

Первый:

Code

Expression    : !m_error_code
Function      : raii_guard::~raii_guard
File          : D:prog_repositorysourcestrunkxrServerEntitiesscript_storage.cpp
Line          : 748
Description   : ….a.l.k.e.r. — Зов Припятиgamedatascripts_g.script:478: bad argument #2 to ‘format’ (string expected, got nil)

Второй:

Code

Expression    : 0
Function      : ErrorLog
File          : D:prog_repositorysourcestrunkxrServerEntitiesscript_engine_script.cpp
Line          : 49
Description   : ‘Attempt to read a non-existant string field ‘path_walk’ in section ‘walker@mechanic’

[/cut]


Перед тем, как задать вопрос в этой теме, прочтите все предыдущие страницы,
статьи в wiki по ссылке из шапки и соседнюю тему «Курс молодого бойца»,
возможно Ваш вопрос уже рассматривался.

Если произошел вылет — выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки.
Помните чем подробнее вопрос, тем точнее ответ.


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
denis2000 Дата: Вт, 22.01.2013, 22:26 | Сообщение # 136

Полевой исследователь

Ученые сталкеры

yakuti, Из скрипта можно выполнить любую консольную команду кодом:

Код

get_console():execute(«ТЕКСТ КОММАНДЫ»))


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
yakuti Дата: Ср, 23.01.2013, 09:06 | Сообщение # 137

Отмычка

Пользователи

А какой текст команды, подскажите плиз

 
denis2000 Дата: Ср, 23.01.2013, 22:49 | Сообщение # 138

Полевой исследователь

Ученые сталкеры

yakuti, demo_record x — начинается запись всего происходящего где x — это любая цифра или слово на английской раскладке!


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
Geonezis Дата: Пт, 25.01.2013, 22:23 | Сообщение # 139

Разработчик «Смерти вопреки»

Свобода

Здравствуйте. Наверное глупый вопрос.
Где можно посмотреть список всех возможных параметров актора подобного типа:

Код

db.actor.health
db.actor.power
db.actor.radiation
db.actor.bleeding

Это те, которые вспомнил.


Смерти Вопреки
Spectrum Project
AP_Prodaction

 
denis2000 Дата: Пт, 25.01.2013, 23:39 | Сообщение # 140

Полевой исследователь

Ученые сталкеры

Geonezis, В файле lua_help.script, объект класса game_object обладает свойствами (property):

Код

property bleeding;
property health;
property morale;
property power;
property psy_health;
property radiation;


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
Азазель Дата: Вс, 27.01.2013, 17:59 | Сообщение # 141

Новичок

Пользователи

Доброго времени суток. Сейчас занимаюсь фиком для пака Fraser. И попутно вспомнил что в SGM версси что будет. Сделана g36 с двойным прицеливанием. Реально ли сделать так чтобы скажем на ПКМ прицеливание шло по колиматору. А при нажатии на СКМ идет по целику ?

Движок в курсе ваших желаний? denis2000

 
ted80 Дата: Чт, 31.01.2013, 23:08 | Сообщение # 142

Гражданский

Пользователи

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

[cut noguest=ПРИМЕР] if victim and IsStalker(victim) and IsStalker(who) then
local dead_news = «Сообщение \nПогиб сталкер !!! \n%c[255,255,160,160]Имя: %c[default]»..victim:character_name()..»\n%c[255,160,255,160]Группировка: %c[default]»»..game.translate_string(victim:character_community())..»»\n%c[255,160,160,160]Локация: %c[default]»..game.translate_string(level.name())..»\n%c[255,225,100,100]Убийца: %c[default]«..who:character_name()..» «»..game.translate_string(who:character_community())..»«»
db.actor:give_game_news(dead_news, «ui\ui_iconsTotal», Frect():set(498,188,83,47), 2000, 5000)
end[/cut]
[cut noguest=СКРИН][/cut]

Но вот с сообщениями о смерти от монстров и аномалий, проблема — как, при отсылке сообщений, получить названия монстров и аномалий, причастных к смерти НПС

[cut noguest] if victim and IsStalker(victim) and IsMonster(who) then
local dead_news = «Сообщение \nПогиб сталкер !!! \n%c[255,255,160,160]Имя: %c[default]»..victim:character_name()..»\n%c[255,160,255,160]Группировка: %c[default]»»..game.translate_string(victim:character_community())..»»\n%c[255,160,160,160]Локация: %c[default]»..game.translate_string(level.name())..»\n%c[255,225,160,160]Причина смерти:%c[default]»..»»
db.actor:give_game_news(dead_news, «ui\ui_iconsTotal», Frect():set(498,188,83,47), 3, 4000)
end

if victim and (IsStalker(victim) and (who == nil or (not IsStalker(who) and not IsMonster(who))) ) then
local dead_news = «Сообщение \nПогиб сталкер !!! \n%c[255,255,160,160]Имя: %c[default]»..victim:character_name()..»\n%c[255,160,255,160]Группировка: %c[default]»»..game.translate_string(victim:character_community())..»»\n%c[255,160,160,160]Локация: %c[default]»..game.translate_string(level.name())..»\n%c[255,225,160,160]Причина смерти: Аномалия»..»»
db.actor:give_game_news(dead_news, «ui\ui_iconsTotal», Frect():set(498,188,83,47), 1, 4000)
end[/cut]

Стабильный вылет: attempt to call method ‘section_name’ (a nil value)

Таки заработало : who:section() таким макаром
[cut noguest=скрин][/cut]

теперь выглядит так: «..game.translate_string(who:section())..»

[cut noguest=Скрин][/cut]

Спасибо что подсказали где искать — теперь буду ковырять аномалии biggrin


Сообщение отредактировал ted80Пт, 01.02.2013, 17:42

 
denis2000 Дата: Пт, 01.02.2013, 19:54 | Сообщение # 143

Полевой исследователь

Ученые сталкеры

ted80, Пробуй получать имя секции объекта who:section_name() и в зависимости от полученной строки составляй текст.

Цитата (ted80)

who:section() таким макаром

Ну или так, или можно еще по классам объектов clsid


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
Пpизpак Дата: Пн, 25.02.2013, 19:10 | Сообщение # 144

Новичок

Пользователи

Здравствуйте. Может кто-нибудь объяснить что такое нет пакет?
Сегодня лазил по файлам АМК-мода и нашел там вот такой код:

[cut noguest]— Читает STATE и UPDATE нет-пакеты сталкера и разбирает их
— @param sobj Серверный объект сталкера
— @return Таблица параметров сталкера

Код

function read_stalker_params(sobj)
   g_stpk:w_begin(0)
   g_uppk:w_begin(0)
   sobj:STATE_Write(g_stpk)
   sobj:UPDATE_Write(g_uppk)
   g_stpk:r_seek(2)
   g_uppk:r_seek(2)
   local tbl=parse_se_stalker({}, g_stpk, g_uppk)
   return tbl
end

[/cut]

В ACDC видел что то подобное. Они(нет пакеты) как-то связаны со спавном?


Комп: Intel Core i5 2400 3.1GHz, 8gb RAM, GeForce GTX 570 1gb, Win 7 64bit
Stalker 1.0004 + НС от 03.09.10 + DMX 1.3.5 + фикс 1.3.5 + свои правки
Stalker 1.6.02 + SGM 1.7 + свои правки

Сообщение отредактировал ПpизpакПн, 25.02.2013, 19:11

 
denis2000 Дата: Пн, 25.02.2013, 21:40 | Сообщение # 145

Полевой исследователь

Ученые сталкеры

Пpизpак, net_packet — это один из вспомогательных классов. Представляет собой буфер размером ровно 8 кбайт (т.е. 8192 байта). Из буфера можно последовательно читать и записывать данные, используя методы класса. Имеется текущая позиция чтения и записи. Теперь подробности.
[cut=Информация из lua_help.script]class net_packet {
net_packet ();

number w_tell();
number r_tell();
void w_begin(number);
function r_begin(number&);
function r_advance(number);
function r_seek(number);
number r_elapsed();
bool r_eof();

number r_u8();
void w_u8(number);
number r_s8();

number r_u16();
void w_u16(number);
number r_s16();
void w_s16(number);
number r_u24();
void w_u24(number);

number r_u32();
void w_u32(number);
number r_s32();
void w_s32(number);

number r_u64();
void w_u64(unsigned __int64);
number r_s64();
void w_s64(__int64);

number r_float();
function w_float(number);
string r_stringZ();
void w_stringZ(string);
bool r_bool();
void w_bool(bool);

vector r_vec3();
void w_vec3(const vector&);
matrix r_matrix();
void w_matrix(matrix&);

vector r_sdir();
void w_sdir(const vector&);
vector r_dir();
void w_dir(const vector&);

number r_angle8();
void w_angle8(number);
number r_angle16();
void w_angle16(number);

function r_float_q8(number&, number, number);
function w_float_q8(number, number, number);
function r_float_q16(number&, number, number);
function w_float_q16(number, number, number);

function w_chunk_open8(number&);
function w_chunk_open16(number&);
function w_chunk_close16(number);
function w_chunk_close8(number);

ClientID r_clientID();
void w_clientID(ClientID&);
};[/cut]
[cut=Более подробно о методах класса]net_packet() — конструктор, вызывается в виде глобальной функции так:
local packet = net_packet()
созданный пакет по умолчанию имеет позиции чтения и записи установленные в 0
Не всегда надо создавать свой пакет. Часто приходится иметь дело с уже готовым пакетом (см. следующую статью об использовании нетпакетов)

w_tell() — возвращает текущую позицию записи
r_tell() — возвращает текущую позицию чтения
r_advance(shift) — смещает позицию чтения на shift байт. Смещение может быть отрицательным.
r_seek(pos) — устанавливает позицию чтения в pos
r_elapsed() — возвращает w_tell() — r_tell()
r_eof() — возвращает true, если r_tell() < w_tell(), иначе false

w_begin(number) — пишет двухбайтовое число в начало пакета и устанавливает позицию записи равной 2. Единственным другим способом начать запись с начала пакета — это создать новый пакет, у которого позиция записи установлена в 0.
r_begin(number&) — Непонятный метод. По аналогии с w_begin должен читать с начала пакета два байта и устанавливать позицию чтения в 2. Однако у меня приводит к вылету. Ну, в любом случае можно обойтись и без него.

Важный момент! Нет никакого способа узнать, что в процессе чтения или записи позиция чтения или записи вышла за пределы пакета. При чтении подразумевается, что прочитать можно столько, сколько записано. Для этого и есть функции r_elapsed() и r_eof(). А вот при записи никакой границы сверху нет, поэтому можно запросто записать больше, чем 8 кбайт. Ясно, что при этом произойдёт переполнение буфера с почти обязательным последующим вылетом игры. Так что надо самостоятельно следить за размером позиции записи и проверять, чтобы при последующей записи она не вышла бы за размеры пакета. Для этого надо знать, сколько мы запишем, ещё до того, как запишем. В особенности это важно для строк, которые имеют переменную длину. Поступаем примерно так:
Код
if string.len(s) + 1 + packet:w_tell() > 8192 then
— здесь делаем что-то, например крашим игру и выводим сообщение, что не надо жадничать =)
end
packet:w_stringZ(s)Обратите внимание на «+ 1» в вычислении новой позиции записи. Строки имеют дополнительный невидимый нулевой символ в конце, и их физическая длина на один больше, чем длина в символах, которую возвращает функция string.len().

Остальные методы предназначены собственно для чтения и записи. Описывать их все в подробностях нет смысла, только общий принцип. Читаем так:
local value = packet:r_XXX()
здесь XXX — это тип значения, которое читается. Значение читается из буфера начиная с текущей позиции чтения, а позиция чтения увеличивается на размер читаемого значения. В переменную value будет помещено значение того типа, которое прочитано.
аналогично пишем в буфер:
packet:w_XXX(value)
Значение пишется начиная с текущей позиции записи, а позиция записи увеличивается на размер типа XXX.
для целых типов:
u — знаковое значение
s — беззнаковое значение
8, 16, 24, 32, 64 — один, два, три, четыре, восемь байт соответственно
Обратите внимаение, что для типа s8 (знаковый байт) нет метода записи. Подозреваю, что вместо него можно использовать соответствующий метод для беззнакового типа.
float — число с плавающей запятой одинарной точности, 4 байта
stringZ — строка (размер равен длине + 1 байт)
bool — логическое значение (1 байт)
vec3 — объект типа vector — вектор из трёх float (12 байт)
matrix — объект типа matrix. Состоит из 4-х векторов (48 байт)
sdir — ? непонятно, на запись берёт вектор и пишет 6 байт
dir — ? аналогично, но пишет 2 байта
angle8 — ? берёт float и пишет 1 байт
angle16 — ? аналогично, но пишет 2 байта
четыре последних метода при чтении у меня вызывают вылет. зачем нужны, неизвестно.
ClientID — объект класа ClientID. Судя по всему, это надо для сетевой игры.
float_q8, float_q16 — пока непонятно
Назначение методов с w_chunk_ вообще непонятно, тем более, что для них отсутствуют соответствующие методы на чтение.[/cut]
[cut=Использование объектов класса net_packet]Собственно, законное использование нетпакетов — это буфер, в котором объект сохраняет своё состояние. Скорее всего это используется в первую очередь при передаче данных по сети. Потому и net_packet, т.е. буквально «сетевой пакет». Сначала объект записывает себя в пакет, затем он отправляется по сети. Похоже, однако, что используется не только при передаче по сети, но и для сохранения объектов вообще.
Теперь конкретнее.
1. Сохранение состояния серверного класса
На серверной стороне есть классы, унаследованные от cse_abstract. У них есть методы STATE_Read и STATE_Write.
метод STATE_Read вызывается при загрузке состояния объекта из сохранёнки, в нём данные читаются из переданного методу пакета. STATE_Write вызывается при сохранении объекта, в нём данные объекта сохраняются в пакет.
Если создать свой класс и перегрузить эти методы, то увидим такую картину:
Код
class «se_my_server_class» (<имя_базового_класса>)

function se_my_server_class:STATE_Write(packet)
<имя_базового_класса>.STATE_Write(self, packet) — базовый класс сохраняет свои данные
— здесь можно сохранить какие-то данные, в дополнение к данным базового класса
packet:w_stringZ(«моя строка»)
end

function se_my_server_class:STATE_Read(packet, size)
<имя_базового_класса>.STATE_Read(self, packet) — здесь базовый класс читает своё состояние из пакета
— здесь можно прочитать состояние своего класса, которое было сохранено ранее
local s = packet:r_stringZ() — получим строку «моя строка»
end
2. Сохранение состояния клиентского класса
На клиентской стороне также имеется нечто подобное. Это реализуется методами биндера save и load. При создании биндера (см. мою статью насчёт класса object_binder) можно в этих методах что-то сохранить. Однако, нетпакет используется для сохранения в методе save. в этом он подобен методу STATE_Write серверного класса. А вот при загрузке почему-то вместо нетпакета передаётся поток на чтение (класс reader). Таким образом трюкачество, описанное в следующем пункте для клиентских объектов не выйдет.

3. Перепаковка серверных объектов с целью изменения их параметров
Предыдущие два варианта использования нетпакетов — это так сказать «законное» их использование. Но это не всё. Ничто не мешает вызывать методы STATE_Read и STATE_Write в произвольный момент времени, имитируя процесс сохранения и загрузки объекта. При этом можно сделать следующее:
Код
local packet = net_packet() — создаём пустой пакет
sobj:STATE_Write(packet) — загрузили в наш пакет состояние серверного объекта
— используя методы класса net_packet меняем нужные нам значения.
sobj:STATE_Read(packet, packet:w_tell()) — записали в объект изменённое состояние обратно, имитируя процесс его загрузки
Несколько замечаний:
— Все эти манипуляции надо проводить над объектами в оффлайне, поскольку онлайновый объект регулярно обновляет серверную часть и полностью его переписывает, так что любые изменения такого рода будут потеряны.
— Надо знать структуру нетпакета для того объекта, который Вы собираетесь изменить. При таких хирургических операциях запросто можно всё испортить.[/cut]
По информации front


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
Пpизpак Дата: Ср, 27.02.2013, 10:29 | Сообщение # 146

Новичок

Пользователи

denis2000, Спасибо. А STATE и UPDATE чем различаются? STATE для серверного, UPDATE для клиентского?

Добавлено (27.02.2013, 10:29)
———————————————
denis2000,

Цитата (denis2000)

u — знаковое значение
s — беззнаковое значение

Цитата (denis2000)

что для типа s8 (знаковый байт)

Как это понимать? Насколько я знаю, здесь должно быть вот так:
u(unsigned) — беззнаковое значение
s(signed) — знаковое значение
возможно Вы/автор ошиб(лись)ся при написании статьи.

P.S. Для информации: в С++ у типа int есть модификатор unsigned, который принимает только неотрицательные(беззнаковые) значения.


Комп: Intel Core i5 2400 3.1GHz, 8gb RAM, GeForce GTX 570 1gb, Win 7 64bit
Stalker 1.0004 + НС от 03.09.10 + DMX 1.3.5 + фикс 1.3.5 + свои правки
Stalker 1.6.02 + SGM 1.7 + свои правки

Сообщение отредактировал ПpизpакСр, 27.02.2013, 10:30

 
denis2000 Дата: Ср, 27.02.2013, 13:54 | Сообщение # 147

Полевой исследователь

Ученые сталкеры

Цитата (Пpизpак)

Как это понимать?

Как написано в «Справочнике по функциям и классам» на сталкерине так и понимать. Все вопросы не ко мне, а в тему на АМК форуме.


«Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика…»
(Чугунный всадник)

 
KADAR Дата: Вт, 05.03.2013, 17:35 | Сообщение # 148

Бывалый

Пользователи

Ребята, всем привет помощь нужна. решил адаптировать нано-броню из Monnoroch addons 1.5.2 для DMX мода 1.3.5. Делал-делал, за помощью обратился к одному человеку, ну и до делался до того что все вроде бы в норме, кроме одного в режиме брони костюм должен восстанавливать состояние костюма, но упорно этого не делает.
Все скрипты перенес что связаны с костюмом из аддона Monnoroch addons 1.5.2 и еще добавлял скрипт bind_stalker из уже вырезанного варианта этой брони для ТЧ, при этом костюм работает, но не работают функции DMX мода. Следовательно я попытался (с помощью) адаптировать скрипт bind_stalker который содержится в DMX моде, функции DMX заработали, а режим брони перестал восстанавливать состояние костюма, что делать?
Вот скрипт bind_stalker из уже вырезанного варианта этой брони для ТЧ который урезал возможности DMX. http://rghost.ru/44286613
А вот тот который адаптировался и после которого режим брони перестал восстанавливать состояние костюма
http://rghost.ru/44286659

 
banananua Дата: Ср, 06.03.2013, 09:39 | Сообщение # 149

Удаленные

Всем привет , подскажите пожалуста почему при установке немецкой озвучки отряд альфа не разговаривает на немецком икак это можно реализовать ?

 
KADAR Дата: Ср, 06.03.2013, 15:56 | Сообщение # 150

Бывалый

Пользователи

banananua, нуу должны разговаривать НАЕМНИКИ если не ошибаюсь. Ты не совсем туда пишешь

 
  • Страница 10 из 61
  • «
  • 1
  • 2
  • 8
  • 9
  • 10
  • 11
  • 12
  • 60
  • 61
  • »

Понравилась статья? Поделить с друзьями:
  • Как найти пробку в отоплении дома
  • Как найти свое положение на карте
  • Как найти usb флешку на андроид
  • Как найти выключенный телефон по коду
  • Как найти стучащий компенсатор