<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://stalkerin.gameru.net/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://stalkerin.gameru.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rekongstor</id>
		<title>S.T.A.L.K.E.R. Inside Wiki - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://stalkerin.gameru.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rekongstor"/>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Rekongstor"/>
		<updated>2026-06-13T21:51:14Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.22.6</generator>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=3dsmax._%D0%9E%D0%B4%D0%B8%D0%BD_%D0%B8%D0%B7_%D1%81%D0%BF%D0%BE%D1%81%D0%BE%D0%B1%D0%BE%D0%B2_%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D1%80%D0%BE%D0%B3%D0%B8_%D0%BD%D0%B0_%D1%82%D0%B5%D1%80%D1%80%D0%B5%D0%B9%D0%BD%D0%B5</id>
		<title>3dsmax. Один из способов создания дороги на террейне</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=3dsmax._%D0%9E%D0%B4%D0%B8%D0%BD_%D0%B8%D0%B7_%D1%81%D0%BF%D0%BE%D1%81%D0%BE%D0%B1%D0%BE%D0%B2_%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B4%D0%BE%D1%80%D0%BE%D0%B3%D0%B8_%D0%BD%D0%B0_%D1%82%D0%B5%D1%80%D1%80%D0%B5%D0%B9%D0%BD%D0%B5"/>
				<updated>2012-05-28T19:12:53Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Создание дороги на терейне при помощи сплайнов и объёмной(2D) привязки==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Прежде хочется сказать, что данный урок рассчитан на пользователей имеющих минимальные знания пакета 3ds max и умеющих создавать стандартные примитивы и которые уже пытаются что то сделать сами и имеющих понятие о элементах интерфейса(основные элементы интерфейса я рассматривал в предыдущем уроке)&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;И так приступим. Допустим мы имеем такой, ну или почти такой терейн (естественно это не шедевр но для демонстрации принципов сойдёт) :&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road1.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Террейн имеет достаточно много полигонов и не является плоским что значительно усложняет процесс создания дороги на нем. &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Ну что ж приступим, для начала мы создадим сплайн который будет являться как бы линейкой для последующего вырезания cut -ом дороги. Для этого нужно перейти в окно Top (Т на клавиатуре) и открыв вкладку create выбрать под вкладку Shapes и выберите line с настройками как на рисунке:&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road2.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;После создания сплайна вы увидите примерно следующее:&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road3.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Затем выделив сплайн перейдём на вкладку Modify и нажав на плюсик около слова line перейдём на уровень Spline после чего в свойствах сплайна около слова Outline в поле числового ввода укажем ширину нашей дороги(у меня 2,5 метра) :&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road4.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;После нажатия Enter увидим&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road5.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;После выделим сам террейн и включим привязку нажав и удерживая на иконку с изображением магнита и цифры&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road6.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;после снова щелкнем на иконке но уже правой клавишей мыши и выберем как на рисунке&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road7.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Выделим террейн перейдём в режим редактирования вертекстов и при нажатой кнопке 2D привязки выберем инструмент cut и щёлкнув на край террейна начнём разрезать(привязка к сплайну служит для того чтобы дорога получилась идеально точной ширины)&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road8.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Такой трюк делаем для всей дороги(если вам вдруг понадобится дорога с высокой плотностью полигонов то outline можно применить несколько раз, те как бы усложнить линейку — сплайн). Вот что получилось в итоге у меня&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road9.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Но это не конец теперь ещё нужно отредактировать сетку(вспомним remove), те привести её к нормальному виду(если этого не сделать то вы рискуете напороться на инвалид фэйс при попытке добавления вашего творения в игру :))&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Вот как стало выглядеть у меня&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Изображение:max_road10.jpg|300px]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Ну вот собственно и всё, хотя лично я придерживаюсь мнения что сначала нужно хорошо продумать геометрию а затем начинать моделировать, дорогу я создаю путём перемещения вертекстов и использованием cut-а. &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;PS Существуют и другие способы моделирования, но о них расскажу позже, как будет свободное время.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Автор: Жуков Антон(Dzot), AMK-II(c)'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* В 3dsmax 9 можно сделать намного проще - Create - Compound Objects - ShapeMerge. Выбираем Copy, Pick Shape и кликаем по лайну. Всё, террейн разрезан. Только придётся поправить текстуру, но это труда, думаю, не составит.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Wireframe]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=Maya._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_HUD_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8_%D0%BE%D1%80%D1%83%D0%B6%D0%B8%D1%8F_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D1%81%D0%BA%D0%B8%D1%85_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2.</id>
		<title>Maya. Создание HUD модели оружия с использованием авторских скриптов.</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=Maya._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_HUD_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8_%D0%BE%D1%80%D1%83%D0%B6%D0%B8%D1%8F_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D1%81%D0%BA%D0%B8%D1%85_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2."/>
				<updated>2012-02-19T09:41:08Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Начало==&lt;br /&gt;
===Введение===&lt;br /&gt;
Итак, я снова с вами и теперь я хочу рассказать об авторских скриптах скриптах и их пользе. И всё же, чем эта статья вам поможет:&lt;br /&gt;
* Откроет вам глаза на использование скриптов.&lt;br /&gt;
* Покажет вам скрипты, которые очень необходимы.&lt;br /&gt;
* Научит или напомнит о пользовании этими скриптами.&lt;br /&gt;
И самое главное, расскажет, как создать саму модель не только худа оружия (хотя в статье будет подробно расписано создание именно этой модели), но и создания или редактирования других моделей по аналогии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Итак, почему же я решил написать эту статью?&lt;br /&gt;
* Я не знал о том, что я нуб и не знаю, как всё это сделать всё это с помощью обычных средств.&lt;br /&gt;
* Я нуб, но есть такие же нубы, которые также мало знают о всём, что было перечислено в списке, именуемым &amp;quot;чем поможет эта статья&amp;quot;.&lt;br /&gt;
* Я не нуб и действительно нужно объяснить многим людям, как всё это сделать.&lt;br /&gt;
&lt;br /&gt;
В любом случае, понимайте так, как захотите.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Рекомендую прочитать другую мою [[Maya._Подробное_описание_создания_объектов|'''статью''']] по работе с объектами и костями.&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Теперь приступим к инструментарию!&lt;br /&gt;
&lt;br /&gt;
===Инструменты===&lt;br /&gt;
* Разумеется, сама [http://thepiratebay.org/torrent/3602763/AUTODESK.MAYA.UNLIMITED.V8.5.HYBRID.DVD-ISO Maya]&lt;br /&gt;
* [http://www.stalkerin.gameru.net/downloads/SDK/ai_compiler/xray_re-tools-10sep2008.rar Плагины] для работы с ней&lt;br /&gt;
* Специальные [http://intreface.narod2.ru/scripts.rar скрипты]&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Сразу скажу, что эти скрипты я нашёл в Google почти случайным образом. Вот [http://dlight.ru/forums/showthread.php?t=848 ссылка на страницу], где эти скрипты и находятся&amp;lt;/blockquote&amp;gt; (скрипты были обновлены! скачивайте по ссылке, указанной в инструментах (старую версию), т.к. из новой вырезали нужную функцию)&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
==Основное содержание статьи==&lt;br /&gt;
===Работа со скриптами===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Настоятельно рекомендую прочитать документацию к скриптам ''(Инструкция.doc)'' т.к. там находится куча полезной информации о скачанных скриптах&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Для начала установим эти скрипты. Это как раз и описано в документации, но я ещё раз это напишу:&lt;br /&gt;
* В вашем файловом браузере зайдите в папку Мои документы/maya/scripts.&lt;br /&gt;
* Если в папке пусто, нет файлов - залейте в эту папку все скрипты из архива и перезагрузите Maya, ВСЁ!&lt;br /&gt;
Сами скрипты довольно просто найти в главной панели Maya: ''Запустите Maya. В строке меню “File, Edit…” в конце будет меню Scripts.''&lt;br /&gt;
&lt;br /&gt;
Итак, в скриптах много чего интересного для создания объектов. Начну разбирать некоторые скрипты, о которых просто стоит сделать отдельное описание:&lt;br /&gt;
*'''Соединение мешей или ''Combine + ...'''''&lt;br /&gt;
Не знаю, как у вас, но лично у меня (может, проблема в плагинах?) просто объединить меши нельзя. Для этого можно использовать Mesh\Combine, но сразу после экспорта в любой формат *.object, у меня случается вылет с предложением отправить отсчёт об ошибке. Но не соединят же Autodesk нам геометрию! Вот и тема остаётся нетронутой. Вот я сразу, после того как установил плагин, попробовал использовать этот скрипт (он находит по адресу ''Scripts\Objects\Combine + weld + soft border edges''). После него всё заработало! Выделяем объекты и запускаем скрипт. После этого Maya подумает (зависит от размера объекта) и сделает сливание объектов. Экспорт проходит на ура.&lt;br /&gt;
&lt;br /&gt;
*'''Сохранение/загрузка костей (аналог сохранения у Physique в Max) или ''Save/load weights to file-cache''''''&lt;br /&gt;
К сожалению, этот скрипт не понадобится в создании худа, но, скорее всего, пригодится в других ситуациях, потому что в отличии от привычного некоторым людям сохранения/загрузки Physique в максе, он почему-то исключает любую добавленную геометрию. Но тем не менее все кости после загрузки взаимодействуют с мешом отлично. Вообще, я на него сразу обратил внимание, но только потратил время, достигая нужной цели. Эти функции находится в ''Scripts\Skelet/Skin'' под соответствующими названиями.&lt;br /&gt;
----&lt;br /&gt;
Возможно, существует для присоединения костей или их изменения...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Изменение геометрии или ''Edit skinned geometry'''''&lt;br /&gt;
Этот, скорее, один из самых важнейших в этом уроке скриптов, потому что он обеспечивает редактирование геометрии без необходимости детача скина (то есть удаления привязки костей - Detach Skin). Вот что пишет автор об этом скрипте: ''Выделите скиненый объект, запустите скрипт, теперь вы можете редактировать его геометрию как угодно без боязни потерять тщательно разложенные ранее веса, можно резать геометрию, свелдживать вершины, удалять полигоны, создавать новые, менять развертку, удалять историю, все что угодно.'' Это значит, что можно спокойно присоединять к мешу объекты, которые нам нужны (например, оружие или плюшевый мишка для создания худа :D). Сам скрипт лежит по адресу ''Scripts\Skelet/Skin\Edit skinned geometry''. Чтобы прекратить режим изменения геометрии - заново активируйте этот же скрипт.&lt;br /&gt;
&lt;br /&gt;
*'''Редактирование привязки или ''Skin weights editor'''''&lt;br /&gt;
Это второй скрипт, который немаловажен для последующего урока. Автор даже сделал отдельную сноску в документации для этого скрипта, но я ему уделю не так много. Просто скажу, что с помощью этого скрипта можно удалять привязку отдельной или наоборот - создавать её. Она работает довольно просто - выделяем сначала объект, потом активируем скрипт, потом выделяем некоторые вертексы и кость, которая вам нужна. Затем нажимаем Assign и дело в шляпе. Выделенные вертексы поменяют отношение к выделенной кости. Т.е. были привязаны - станут отвязанными и наоборот. Но только есть один момент - если я хочу вернуть действие назад (например, обратно отвязать объект), то окошко выдаёт текст того, что вертексы проассигнены. Об этом попробую написать потом. Этот скрипт лежит в ''Scripts\Skelet/Skin\Skin weights editor''&lt;br /&gt;
&lt;br /&gt;
===Создание худ модели===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Предупреждаю сразу - эта часть не предусматривает создание сложных объектов с костями, прикреплёнными к wpn_body и ниже (вроде wpn_scope).О таких случаях я напишу позже.&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Итак, вот то, ради чего многие сюда пришли. Как помню, в [[Milkshape._Перенос_моделей_оружия_из_ЧН%2C_ЗП_в_ТЧ|статье, посвящённой похожему делу, но в ''MilkShape'']] есть такой текст: &lt;br /&gt;
* &amp;quot;''Видим, что, вроде бы, перенести оружие из ЧН\ЗП в ТЧ достаточно просто – надо только объединить скелеты рук и оружия, и дело в шляпе. На практике это действительно несложно – при условии, что работаем мы в Maya. Но модмейкеры, как известно, в большинстве своем народ бедный, и Maya им не по карману :). Что же, придется действовать «народными средствами», т.е. при помощи Milkshape 3d, благо, необходимые плагины для него имеются.''&amp;quot;&lt;br /&gt;
* &amp;quot;''Ищем в меню пункт, позволяющий присоединить один джоинт к другому, и… нервно бьем кулаком по столу, так как такого пункта там, как ни странно, нет.''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Почему-то я тут увидел намёк на то, что в майе такая кнопка быть должна... Тем не менее такой кнопки нет (впоследствии узнаётся то, что она легко появляется после установки скриптов и, при правильном использовании, даёт нужный результат. &amp;lt;font color = &amp;quot;gray&amp;quot;&amp;gt; Вообще-то можно просто в Outliner'е перетащить потомка на родителя. --[[Участник:RedPython|RedPython]] 05:05, 26 марта 2011 (UTC) &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как же пользоваться этими скриптами, я сейчас и расскажу. &lt;br /&gt;
&lt;br /&gt;
Запускаем Maya. В ней настраиваем нужные параметры (если хотим): ед. измерения и отображение камеры.&lt;br /&gt;
Потом импортируем нужные руки. Я работал с руками из ЧН, но можно взять и руки ТЧ (только там пока нет кости wpn_body и её придётся создать и присоединить к основному скелету).&lt;br /&gt;
* Если вы импортируете руки из ЧН (или ЗП), то вам придётся задать им путь к текстуре этих рук, которая была прежде скопирована из ЧН/ЗП и навана, к примеру, '''act_arm_perchatka_cs'''&lt;br /&gt;
[[Изображение:Руки-Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
Теперь производим импорт любого объекта (как статики, как и динамики. лучше - статики из СДК, но будет также рассмотрен случай с динамикой).&lt;br /&gt;
Если вы импортировали динамический объект, то нажимаем на сам объект и в режиме редактирования анимации нажимаем на Skin\Detach Skin. Потом убираемся - удаляем кости, которые остались после '''этого''' объекта. У нас получился статичный объект. &lt;br /&gt;
&lt;br /&gt;
Теперь надо подвинуть объект на нужное место (лучше, чтобы его можно было легко выделять без рук и анимировать). Удаляем изменяем нужные вертексы объекта и получается что-то вроде:&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Руки и объект - Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь, имея динамические руки и статичный объект, можно двигаться дальше. Нажимаем на руки и активируем скрипт ''Scripts\Skelet/Skin\'''Edit skinned geometry'''''&lt;br /&gt;
&lt;br /&gt;
Теперь выделяем руки и объект и активируем ''Scripts\Objects\'''Combine + weld + soft border edges'''''&lt;br /&gt;
&lt;br /&gt;
Пауза...&lt;br /&gt;
&lt;br /&gt;
Нажимаем ещё раз ''Scripts\Skelet/Skin\'''Edit skinned geometry'''''&lt;br /&gt;
&lt;br /&gt;
Всё. Модель объекта присоединена к худу, но если подвигать некоторыми костями, то будет видно, как объект двигается вместе с костями и причём очень криво. Примерно так:&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Кривое движение - Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
Нам это не нужно. Если двигали кости, то возвращаемся назад или нажимаем с выбором главной кости Skin\Go to bind pose&lt;br /&gt;
&lt;br /&gt;
Теперь настало время привязки объекта к костям. Для этого выделяем худ и активируем ''Scripts\Skelet/Skin\'''Skin weights editor'''''&lt;br /&gt;
&lt;br /&gt;
У меня появляется окошко, но немного неправильной формы. Чтобы посмотреть содержимое, я просто расширяю его. Видим содержимое: Select some joints and skinned verticies... Я бы сначала выделил ''skinned verticies'' т.е. вертексы объекта. Выделяем объект (у меня это сейф) без рук.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Если вы не послушали совета, что объект надо передвигать туда, где легко не задеть рук, то выделяем несколько вертексов и нажимаем Shift + Ю (на англ. раскладке)&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Я выделил свой объект и получилось что-то вроде этого:&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Аттач объекта - Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
Если у вас получилось что-то аналогичное, то всё, должно быть, правильно.&lt;br /&gt;
&lt;br /&gt;
Теперь окошко просит выделить кости. Для начала выделим главную кость - ту, что скрепляет все кости. У меня она называется bip01 (напомню, что руки ЧН). Когда вы выделите эту кость, то все остальные кости выделятся вместе с ней. Теперь нажимаем на кнопку внутри окошка: '''Assign'''.&lt;br /&gt;
Это исключит объект из всего скелета и, сколько не двигай костями (кроме основной, т.к. она определяет позицию самого объекта), ничего мы не добьёмся. Теперь намечается новый случай - многокостие. Я его так назвал, потому что в некоторых случаях бывает, что объекту нужны кости вроде wpn_scope и т.п. Пока я их не трогаю и создание больших пушек я опишу в отдельной части и потом.&lt;br /&gt;
&lt;br /&gt;
Если у вас один объект без наворотов, то можно продолжать. Выделяем заново все вертексы объекта и кликаем по косточке wpn_body. Нажимаем Assign. В этом случае скрипт наоборот - сделает вертексы привязвнными к кости.&lt;br /&gt;
&lt;br /&gt;
Закрываем окно скрипта. Всё с объектом... Экспортируем объект в X-Ray Skeletal Object (выделив меш худа)&lt;br /&gt;
&lt;br /&gt;
Худ Готов. Теперь осталось его только анимировать. Анимки экспортируем также, как и объект, но только X-Ray Skeletal Motion.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;На заметку: главное в анимации - правильный поворот худа. Он итак по идее правильный. Просто если вы ошиблись в положении худа, то не стоит переделывать положение худа через анимку. Пользуйтесь параметром position в конфиге худа оружия.&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Настройки в актор эдиторе можно посмотреть в [[3dsmax._Создание_HUD-модели_оружия#5._.D0.9D.D0.B0.D1.81.D1.82.D1.80.D0.BE.D0.B9.D0.BA.D0.B0_.D0.BF.D0.B0.D1.80.D0.B0.D0.BC.D0.B5.D1.82.D1.80.D0.BE.D0.B2_.D0.B2_Actor_Editor|аналогичной статье по 3ds максу]]&lt;br /&gt;
&lt;br /&gt;
Удачи!&lt;br /&gt;
&lt;br /&gt;
[[Изображение:В_игре.jpg|640px]]&lt;br /&gt;
&lt;br /&gt;
 На заметку: попробуйте себя проверить, добавив какой-нибудь простенький объект.&lt;br /&gt;
&lt;br /&gt;
==Немного о руках ТЧ==&lt;br /&gt;
Если вы хотите историю создания рук, то вы не по адресу, потому что этот раздел посвящён тому, чем может отличаться работа с руками из ТЧ. Итак, распишу по пунктам.&lt;br /&gt;
* Импортируем [http://intreface.narod2.ru/wpn_hands_soc.mb модель рук формата] .object&lt;br /&gt;
* Импортируем оружие, не забываем отсоединить скин и удалить кости, если оружие было динамическим.&lt;br /&gt;
* Включаем '''Edit skinned geometry'''&lt;br /&gt;
* Подсоединяем оружие (или погремушку) через '''Combine + weld + soft border edges'''&lt;br /&gt;
* Вырубаем '''Edit skinned geometry'''&lt;br /&gt;
* Открываем '''Skin weights editor'''&lt;br /&gt;
* Выделяем (только) вертексы оружия (или погремушки)&lt;br /&gt;
** Если не видим вертексов оружия, то удерживаем правой кнопкой на худе и выбираем '''Vertex'''&lt;br /&gt;
* C зажатым Shift, выделяем кость '''root'''&lt;br /&gt;
* Нажимем '''Assign'''&lt;br /&gt;
* Опять выделяем вертексы оружия&lt;br /&gt;
* C зажатым Shift, выделяем кость '''wpn_body'''&lt;br /&gt;
* Нажимем '''Assign''' и закрываем окно&lt;br /&gt;
** Можно немного полюбоваться, подвигать кости. Не забудьте вернуть всё в порядок через '''Go to bind pose'''&lt;br /&gt;
&lt;br /&gt;
==Авторы==&lt;br /&gt;
*[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
==Ссылки на руки==&lt;br /&gt;
*[http://rekongstor.narod2.ru/wpn_hand_cs.object wpn_hand_cs.object] - ЧН&lt;br /&gt;
*[http://rekongstor.narod2.ru/wpn_hands_soc.object wpn_hands_soc.object] - ТЧ&lt;br /&gt;
*[http://intreface.narod2.ru/wpn_hands_soc.object] - ТЧ '''(обновление)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Wireframe]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D1%87%D0%B8%D0%BD%D1%8B_%D0%B2%D1%8B%D0%BB%D0%B5%D1%82%D0%BE%D0%B2_%D0%B8%D0%B3%D1%80%D1%8B_(%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC_%D0%BB%D0%BE%D0%B3%D0%B8)</id>
		<title>Причины вылетов игры (разбираем логи)</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D1%87%D0%B8%D0%BD%D1%8B_%D0%B2%D1%8B%D0%BB%D0%B5%D1%82%D0%BE%D0%B2_%D0%B8%D0%B3%D1%80%D1%8B_(%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC_%D0%BB%D0%BE%D0%B3%D0%B8)"/>
				<updated>2011-08-30T09:19:48Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Привет всем! Игра сталкер, а конкретно сам движок X-ray довольно капризный, и зачастую как в процессе модификации, так и во время игры игра «вылетает». Чтобы мы знали причину вылета, движок нам оставляет лог вылета. Лог вылета можно посмотреть несколькими способами:&lt;br /&gt;
* В текстовом редакторе нажать Ctrl+V (Вставить)&lt;br /&gt;
* Посмотреть лог игры включая лог вылета в файле xray_имя_пользователя.log в папке C:\Documents and Settings\All Users\Документы\STALKER-***\logs&lt;br /&gt;
* Посмотреть непосредственно в окне багтрекера (только в ЧН и ЗП).&lt;br /&gt;
Ну приступим. Начнём с простых:&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : wave&amp;amp;&amp;amp;wave-&amp;gt;length()&lt;br /&gt;
Function      : CSoundRender_Source::LoadWave&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrSound\SoundRender_Source_loader.cpp&lt;br /&gt;
Line          : 65&lt;br /&gt;
Description   : Can't open wave file:&lt;br /&gt;
Arguments     : d:\stalker\gamedata\sounds\music\sound.ogg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь игра не может открыть звуковой OGG-файл под названием sound в папке d:\stalker\gamedata\sounds\music\&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CRender::texture_load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender\Texture.cpp&lt;br /&gt;
Line          : 295&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find texture 'act\act_corp_monolit'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не может найти текстуру act_corp_monolit из папки textures\act&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CModelPool::Instance_Load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender\ModelPool.cpp&lt;br /&gt;
Line          : 111&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find model file 'physics\mesh.ogf'.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена трёхмерная OGF-модель mesh.ogf из папки meshes\physics.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : SG&lt;br /&gt;
Function      : CRender::model_CreateParticles&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender_R2\r2.cpp&lt;br /&gt;
Line          : 330&lt;br /&gt;
Description   : Particle effect or group doesn't exist&lt;br /&gt;
Arguments     : hit_fx\hit_water_00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена система частиц (партикл) hit_water_00 в директории hit_fx файла particles.xr (подробно опишу позже).&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CResourceManager::_GetBlender&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\ResourceManager.cpp&lt;br /&gt;
Line          : 49&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Shader 'models\antigas_glass' not found in library.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден шейдер models\antigas_glass в библиотеке шейдеров.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fs&lt;br /&gt;
Function      : CResourceManager::_CreateVS&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\ResourceManager_Resources.cpp&lt;br /&gt;
Line          : 185&lt;br /&gt;
Description   : shader file doesnt exist&lt;br /&gt;
Arguments     : d:\stalker\gamedata\shaders\r2\deffer_impl_flat.vs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден файл шейдера deffer_impl_flat.vs.&lt;br /&gt;
&amp;lt;tt&amp;gt;--Added by Герр. Роммель&lt;br /&gt;
Да нет. Тут проблема вся в том, что неправильно закомпилился шейдер, при компиляции уровня на качестве, более высоком чем Draft. Нужно скачивать исправление шейдеров от товарища Haron.&lt;br /&gt;
Для ЗП (ЧН) это может ещё быть из-за отсутствия thm&amp;quot;ок для текстур терраина уровня!&amp;lt;/tt&amp;gt;&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : out_of_memory_handler&lt;br /&gt;
File : D:\prog_repository\sources\trunk\xrCore\xrDebugNew.cpp&lt;br /&gt;
Line : 336&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : Out of memory. Memory request: 55965 K &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Нехватка оперативной памяти.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : CInifile::r_string&lt;br /&gt;
File :E:\stalker\sources\trunk\xrCore\Xr_ini.cpp&lt;br /&gt;
Line : 352&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : Can't find variable ammo_mag_size in [wpn_addon_grenade_launcher]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена переменная ammo_mag_size в секции [wpn_addon_grenade_launcher].&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : D:\xray-svn\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 74&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: C stack overflow&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Переполнение стека. Смотрим внимательно: lua_error. Ошибка возможно в скриптах.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : vertex || show_restrictions(m_object)&lt;br /&gt;
Function : CPatrolPathManager::select_point&lt;br /&gt;
File : E:\stalker\sources\trunk\xr_3da\xrGame\patrol_path_manager.cpp&lt;br /&gt;
Line : 155&lt;br /&gt;
Description : any vertex in patrol path [sniper_3_walk] in inaccessible for object [stalker_0002]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Какая то вершина (вейпоинт) пути sniper_3_walk стоит в неположенном месте (например не на аи-сетке). Объект stalker_0002 (в данном случае сталкер) который якобы двигался по пути sniper_3_walk попал на эту точку, а заодно ушёл за аи-сетку. Этого движок не терпит.&lt;br /&gt;
&lt;br /&gt;
Тоже самое произойдет если координаты(вейпоинт) пути sniper_3_walk совпадет с координатами места где нпс запрешенно находится буть то рестриктор или аномалия в схеме обхода аномалий.&lt;br /&gt;
Также этот вылет набюдается при попытке отправить нпс за пределы места работ параметр out_rest = &amp;quot;имя_рестриктора&amp;quot;,&lt;br /&gt;
в файле загрузки работ гулага&lt;br /&gt;
&lt;br /&gt;
попробуйте любого сталкера из лагеря новичков отправить допустим к остановке&lt;br /&gt;
получите этот самый вылет&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : e_entity&lt;br /&gt;
Function : xrServer::Process_event_reject&lt;br /&gt;
File : E:\stalker\sources\trunk\xr_3da\xrGame\xrServer_process_event_reject.cpp&lt;br /&gt;
Line : 12&lt;br /&gt;
Description : entity not found. id_parent=7540 id_entity=44047 frame=2075050&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Возникают иногда произвольно при смерти неписей. Причина — движок отрабатывая лут изредка теряет серверный объект уничтожаемой вещи, в итоге происходит вылет.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : CScriptEngine::lua_error&lt;br /&gt;
File : D:\xray-svn\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line : 74&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : LUA error: e:\stalker\gamedata\scripts\_g.script:20: bad argument #2 to 'format' (string expected, got no value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ошибка распространённая. На первый взгляд кажется, что ошибка как раз в скриптах, но всё может быть иначе. Делаем так: открываем файл _g.script блокнотом, закоменчиваем 20 строку (ставим перед строкой --) и идём к тому месту где поймали вылет. Так мы получим более развёрнутый ответ.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : assertion failed&lt;br /&gt;
Function      : _VertexStream::Lock&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\R_DStreams.cpp&lt;br /&gt;
Line          : 44&lt;br /&gt;
Description   : (bytes_need&amp;lt;=mSize) &amp;amp;&amp;amp; vl_Count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Проблема возникает при убийстве НПС\мутанта. Типичный вылет по нехватке ресурсов. Встречается в основном на больший локациях.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : IRender_Visual::Load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\FBasicVisual.cpp&lt;br /&gt;
Line          : 58&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Invalid visual&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Неправильный визуал (модель) НПС.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : !phrase_dialog-&amp;gt;m_PhraseVector.empty()&lt;br /&gt;
Function      : CPhraseDialog::SayPhrase&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\PhraseDialog.cpp&lt;br /&gt;
Line          : 140&lt;br /&gt;
Description   : No available phrase to say, dialog[esc_dialog]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
В диалоге esc_dialog нет доступной для отображения фразы (скажем все заткнуты инфопоршенами).&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : motion_ID.valid()&lt;br /&gt;
Function      : CKinematicsAnimated::ID_Cycle&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\Layers\xrRender\SkeletonAnimated.cpp&lt;br /&gt;
Line          : 210&lt;br /&gt;
Description   : ! MODEL: can't find cycle:&lt;br /&gt;
Arguments     : death_init&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Игра не нашла в модели трёхмерную анимацию с именем death_init.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
--------------&lt;br /&gt;
* Автор статьи — '''Pihan13'''&lt;br /&gt;
* Дополнил статью — '''Fireman3000'''&lt;br /&gt;
* Частично использовалась информация с сайта http://forum.stalker-simbion.ru/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt; '''Не стесняемся — дополняем, если знаем о чём идёт речь.''' &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнение к статье(От Fireman3000):&lt;br /&gt;
Извините если где нибудь я неправильно пишу. Уж не родился я Колмогором :(&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 73&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: ...hadow of chernobyl\gamedata\scripts\xr_danger.script:116: attempt to index field 'ignore_types' (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Причина вылета в том что игра не понимает значения 0 в danger_ignore.Проще говоря в логике какого то персонажа параметр danger_ignore = 0 либо в минусовом значении. Либо его вообще нету&lt;br /&gt;
&lt;br /&gt;
P.S. Также может быть причина в том, что в логике у какого-то АИ что-то неправильно указано. Для исправления рекомендую вставить строчку перед 116: get_console():execute(self.object:name()). То имя в логе, которое будет последним после вылета, указывает на персонажа с кривой логикой. --[[Участник:Rekongstor|Rekongstor]] 14:01, 2 июня 2011 (UTC)&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 352&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable class in [test_no_klass_npc]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден класс персонажа. Возможно, нпс не прописан под своим классом в gamedata\npc_profile.xml, либо в creatures\spawn_section.ltx, либо в gameplay\character_desc.xml&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_section&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 342&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't open section 'bandage_test_kick1'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Игра не может найти секцию. Это может быть предмет, нпс и многое другое. Возможно, вы написали название с ошибками. Либо когда добавляли его в: продажу, скрипт, нпс, выпадение из нпс а в редких случиях это может быть иммунитет чего либо(определить пото трудно). Часто такое бывает связано с названием&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 352&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable remove_time in [vehicle_btr]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена переменная remove_time в секции [vehicle_btr]. А в данном случае ошибка в том что если вы делали предмет как физическую модель(тобишь которую нельзя использовать, говорить и вообще он похож на декорации типа деревьев, столов и прочего хлама) то необходимо указывать remove_time в его секции&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 73&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: ...dow of chernobyl\gamedata\scripts\test_kick.script:34: attempt to call method 'section' (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Метод обращения в игре не предусмотрен. Возможно, стоит пересмотреть подход к тому или иному скрипту&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : rpoints[0].size()&lt;br /&gt;
Function      : game_sv_Deathmatch::Create&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\xrGame\game_sv_deathmatch.cpp&lt;br /&gt;
Line          : 99&lt;br /&gt;
Description   : rpoints for players not found&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
На мультиплеерной карте не найдены точки респавна игроков. В SDK должен быть красный пацанчик. Настроить Team = 0&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Expression    : fatal error&lt;br /&gt;
Function      : xrServer::Process_update&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\xrServer_process_update.cpp&lt;br /&gt;
Line          : 37&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Beer from the creator of 'WP_SHOTG'&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Такое иногда бывает, когда ты (ГГ) или НПС заряжает дробовик или другое оружие со значением tri_state_reload = true.&lt;br /&gt;
Это глюк. в игре что-то сбивается, и когда у дробовика максимальное количество заряженых патронов скажем 6, он заряжается за 6 и дальше.. дальше.. дальше.. и так пока не произойдёт вылет с вышеуказанным логом. вылет не значительный и редкий, но если он случается слишком часто, можно в конфигах всех дробовиков и ружей поменять значение tri_state_reload = true на tri_state_reload = false.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 477&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable bound_rect in [level_map]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Такой лог бывает когда подключаеш локу с ТЧ в ЗП. Причина проста в ЗП уровнях файл строчка bound_rect пишется в файле gamedata\levels\имя_уровня\level.ltx , а в ТЧ строка bound_rect для каждого уровня непосредствено в файле gamedata\config\game_maps_single.ltx ... &lt;br /&gt;
&amp;lt;br /&amp;gt; Исправить просто, нужно изменить файл gamedata\levels\имя_уровня\level.ltx в подключеной локации, просто перенести строку bound_rect из game_maps_single.ltx в level.ltx перед строчкой texture .   &lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Небольшой пример из практики по определению ошибки в особых случаях(для начинающих):&lt;br /&gt;
Игра зависла, картинка на экране не меняется, на Ctrl + Alt+ Delete не реагирует. Только &amp;quot;Холодная перезагрузка&amp;quot; reset. Но при этом обычно в логе нет записи и обычным Ctrl + V ошибку не увидеть.&lt;br /&gt;
Я пользуюсь программой Punto Switcher. Есть в ней опция &amp;quot;дневник&amp;quot;, она ведёт запись всех нажатий клавиш и по нажатию сочетаний клавиш содержимое памяти может записывать в дневник.&lt;br /&gt;
теперь когда игра зависла и картинка на экране не меняется, нажимаете Ctrl + Alt+ Delete. Внешне ничего не изменится, но ОС будет реагировать&lt;br /&gt;
на клавиши, нажимаете сочетание клавишь &amp;quot;записать в дневник&amp;quot;. Делаете перезагрузку, открываете дневник - Ваша ошибка записана.&lt;br /&gt;
&amp;quot;дядя Саша&amp;quot;&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
[[Категория:FAQ]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%9E%D0%B1%D1%85%D0%BE%D0%B4_%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_mp_ranks.ltx_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%80%D0%B8%D1%82%D0%B0)</id>
		<title>Обсуждение:Обход ограничений mp ranks.ltx (метод рекрита)</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%9E%D0%B1%D1%85%D0%BE%D0%B4_%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_mp_ranks.ltx_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%80%D0%B8%D1%82%D0%B0)"/>
				<updated>2011-06-28T21:47:08Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: Новая страница: «а как насчёт сохранения\загрузки? данные сохранятся?»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;а как насчёт сохранения\загрузки? данные сохранятся?&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D1%87%D0%B8%D0%BD%D1%8B_%D0%B2%D1%8B%D0%BB%D0%B5%D1%82%D0%BE%D0%B2_%D0%B8%D0%B3%D1%80%D1%8B_(%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC_%D0%BB%D0%BE%D0%B3%D0%B8)</id>
		<title>Причины вылетов игры (разбираем логи)</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D1%87%D0%B8%D0%BD%D1%8B_%D0%B2%D1%8B%D0%BB%D0%B5%D1%82%D0%BE%D0%B2_%D0%B8%D0%B3%D1%80%D1%8B_(%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC_%D0%BB%D0%BE%D0%B3%D0%B8)"/>
				<updated>2011-06-02T14:02:15Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Привет всем! Игра сталкер, а конкретно сам движок X-ray довольно капризный, и зачастую как в процессе модификации, так и во время игры игра «вылетает». Чтобы мы знали причину вылета, движок нам оставляет лог вылета. Лог вылета можно посмотреть несколькими способами:&lt;br /&gt;
* В текстовом редакторе нажать Ctrl+V (Вставить)&lt;br /&gt;
* Посмотреть лог игры включая лог вылета в файле xray_имя_пользователя.log в папке C:\Documents and Settings\All Users\Документы\STALKER-***\logs&lt;br /&gt;
* Посмотреть непосредственно в окне багтрекера (только в ЧН и ЗП).&lt;br /&gt;
Ну приступим. Начнём с простых:&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : wave&amp;amp;&amp;amp;wave-&amp;gt;length()&lt;br /&gt;
Function      : CSoundRender_Source::LoadWave&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrSound\SoundRender_Source_loader.cpp&lt;br /&gt;
Line          : 65&lt;br /&gt;
Description   : Can't open wave file:&lt;br /&gt;
Arguments     : d:\stalker\gamedata\sounds\music\sound.ogg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь игра не может открыть звуковой OGG-файл под названием sound в папке d:\stalker\gamedata\sounds\music\&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CRender::texture_load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender\Texture.cpp&lt;br /&gt;
Line          : 295&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find texture 'act\act_corp_monolit'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не может найти текстуру act_corp_monolit из папки textures\act&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CModelPool::Instance_Load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender\ModelPool.cpp&lt;br /&gt;
Line          : 111&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find model file 'physics\mesh.ogf'.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена трёхмерная OGF-модель mesh.ogf из папки meshes\physics.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : SG&lt;br /&gt;
Function      : CRender::model_CreateParticles&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender_R2\r2.cpp&lt;br /&gt;
Line          : 330&lt;br /&gt;
Description   : Particle effect or group doesn't exist&lt;br /&gt;
Arguments     : hit_fx\hit_water_00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена система частиц (партикл) hit_water_00 в директории hit_fx файла particles.xr (подробно опишу позже).&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CResourceManager::_GetBlender&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\ResourceManager.cpp&lt;br /&gt;
Line          : 49&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Shader 'models\antigas_glass' not found in library.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден шейдер models\antigas_glass в библиотеке шейдеров.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fs&lt;br /&gt;
Function      : CResourceManager::_CreateVS&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\ResourceManager_Resources.cpp&lt;br /&gt;
Line          : 185&lt;br /&gt;
Description   : shader file doesnt exist&lt;br /&gt;
Arguments     : d:\stalker\gamedata\shaders\r2\deffer_impl_flat.vs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден файл шейдера deffer_impl_flat.vs.&lt;br /&gt;
&amp;lt;tt&amp;gt;--Added by Герр. Роммель&lt;br /&gt;
Да нет. Тут проблема вся в том, что неправильно закомпилился шейдер, при компиляции уровня на качестве, более высоком чем Draft. Нужно скачивать исправление шейдеров от товарища Haron.&lt;br /&gt;
Для ЗП (ЧН) это может ещё быть из-за отсутствия thm&amp;quot;ок для текстур терраина уровня!&amp;lt;/tt&amp;gt;&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : out_of_memory_handler&lt;br /&gt;
File : D:\prog_repository\sources\trunk\xrCore\xrDebugNew.cpp&lt;br /&gt;
Line : 336&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : Out of memory. Memory request: 55965 K &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Нехватка оперативной памяти.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : CInifile::r_string&lt;br /&gt;
File :E:\stalker\sources\trunk\xrCore\Xr_ini.cpp&lt;br /&gt;
Line : 352&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : Can't find variable ammo_mag_size in [wpn_addon_grenade_launcher]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена переменная ammo_mag_size в секции [wpn_addon_grenade_launcher].&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : D:\xray-svn\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 74&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: C stack overflow&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Переполнение стека. Смотрим внимательно: lua_error. Ошибка возможно в скриптах.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : vertex || show_restrictions(m_object)&lt;br /&gt;
Function : CPatrolPathManager::select_point&lt;br /&gt;
File : E:\stalker\sources\trunk\xr_3da\xrGame\patrol_path_manager.cpp&lt;br /&gt;
Line : 155&lt;br /&gt;
Description : any vertex in patrol path [sniper_3_walk] in inaccessible for object [stalker_0002]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Какая то вершина (вейпоинт) пути sniper_3_walk стоит в неположенном месте (например не на аи-сетке). Объект stalker_0002 (в данном случае сталкер) который якобы двигался по пути sniper_3_walk попал на эту точку, а заодно ушёл за аи-сетку. Этого движок не терпит.&lt;br /&gt;
&lt;br /&gt;
Тоже самое произойдет если координаты(вейпоинт) пути sniper_3_walk совпадет с координатами места где нпс запрешенно находится буть то рестриктор или аномалия в схеме обхода аномалий.&lt;br /&gt;
Также этот вылет набюдается при попытке отправить нпс за пределы места работ параметр out_rest = &amp;quot;имя_рестриктора&amp;quot;,&lt;br /&gt;
в файле загрузки работ гулага&lt;br /&gt;
&lt;br /&gt;
попробуйте любого сталкера из лагеря новичков отправить допустим к остановке&lt;br /&gt;
получите этот самый вылет&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : e_entity&lt;br /&gt;
Function : xrServer::Process_event_reject&lt;br /&gt;
File : E:\stalker\sources\trunk\xr_3da\xrGame\xrServer_process_event_reject.cpp&lt;br /&gt;
Line : 12&lt;br /&gt;
Description : entity not found. id_parent=7540 id_entity=44047 frame=2075050&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Возникают иногда произвольно при смерти неписей. Причина — движок отрабатывая лут изредка теряет серверный объект уничтожаемой вещи, в итоге происходит вылет.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : CScriptEngine::lua_error&lt;br /&gt;
File : D:\xray-svn\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line : 74&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : LUA error: e:\stalker\gamedata\scripts\_g.script:20: bad argument #2 to 'format' (string expected, got no value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ошибка распространённая. На первый взгляд кажется, что ошибка как раз в скриптах, но всё может быть иначе. Делаем так: открываем файл _g.script блокнотом, закоменчиваем 20 строку (ставим перед строкой --) и идём к тому месту где поймали вылет. Так мы получим более развёрнутый ответ.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : assertion failed&lt;br /&gt;
Function      : _VertexStream::Lock&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\R_DStreams.cpp&lt;br /&gt;
Line          : 44&lt;br /&gt;
Description   : (bytes_need&amp;lt;=mSize) &amp;amp;&amp;amp; vl_Count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Проблема возникает при убийстве НПС\мутанта. Типичный вылет по нехватке ресурсов. Встречается в основном на больший локациях.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : IRender_Visual::Load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\FBasicVisual.cpp&lt;br /&gt;
Line          : 58&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Invalid visual&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Неправильный визуал (модель) НПС.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : !phrase_dialog-&amp;gt;m_PhraseVector.empty()&lt;br /&gt;
Function      : CPhraseDialog::SayPhrase&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\PhraseDialog.cpp&lt;br /&gt;
Line          : 140&lt;br /&gt;
Description   : No available phrase to say, dialog[esc_dialog]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
В диалоге esc_dialog нет доступной для отображения фразы (скажем все заткнуты инфопоршенами).&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : motion_ID.valid()&lt;br /&gt;
Function      : CKinematicsAnimated::ID_Cycle&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\Layers\xrRender\SkeletonAnimated.cpp&lt;br /&gt;
Line          : 210&lt;br /&gt;
Description   : ! MODEL: can't find cycle:&lt;br /&gt;
Arguments     : death_init&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Игра не нашла в модели трёхмерную анимацию с именем death_init.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
--------------&lt;br /&gt;
* Автор статьи — '''Pihan13'''&lt;br /&gt;
* Дополнил статью — '''Fireman3000'''&lt;br /&gt;
* Частично использовалась информация с сайта http://forum.stalker-simbion.ru/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt; '''Не стесняемся — дополняем, если знаем о чём идёт речь.''' &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнение к статье(От Fireman3000):&lt;br /&gt;
Извините если где нибудь я неправильно пишу. Уж не родился я Колмогором :(&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 73&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: ...hadow of chernobyl\gamedata\scripts\xr_danger.script:116: attempt to index field 'ignore_types' (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Причина вылета в том что игра не понимает значения 0 в danger_ignore.Проще говоря в логике какого то персонажа параметр danger_ignore = 0 либо в минусовом значении. Либо его вообще нету&lt;br /&gt;
&lt;br /&gt;
P.S. Также может быть причина в том, что в логике у какого-то АИ что-то неправильно указано. Для исправления рекомендую вставить строчку перед 116: get_console():execute(self.object:name()). То имя в логе, которое будет последним после вылета, указывает на персонажа с кривой логикой. --[[Участник:Rekongstor|Rekongstor]] 14:01, 2 июня 2011 (UTC)&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 352&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable class in [test_no_klass_npc]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден класс персонажа. Возможно, нпс не прописан под своим классом в gamedata\npc_profile.xml, либо в creatures\spawn_section.ltx, либо в gameplay\character_desc.xml&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_section&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 342&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't open section 'bandage_test_kick1'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Игра не может найти секцию. Это может быть предмет, нпс и многое другое. Возможно, вы написали название с ошибками. Либо когда добавляли его в: продажу, скрипт, нпс, выпадение из нпс а в редких случиях это может быть иммунитет чего либо(определить пото трудно). Часто такое бывает связано с названием&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 352&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable remove_time in [vehicle_btr]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена переменная remove_time в секции [vehicle_btr]. А в данном случае ошибка в том что если вы делали предмет как физическую модель(тобишь которую нельзя использовать, говорить и вообще он похож на декорации типа деревьев, столов и прочего хлама) то необходимо указывать remove_time в его секции&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 73&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: ...dow of chernobyl\gamedata\scripts\test_kick.script:34: attempt to call method 'section' (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Метод обращения в игре не предусмотрен. Возможно, стоит пересмотреть подход к тому или иному скрипту&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : rpoints[0].size()&lt;br /&gt;
Function      : game_sv_Deathmatch::Create&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\xrGame\game_sv_deathmatch.cpp&lt;br /&gt;
Line          : 99&lt;br /&gt;
Description   : rpoints for players not found&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
На мультиплеерной карте не найдены точки респавна игроков.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Expression    : fatal error&lt;br /&gt;
Function      : xrServer::Process_update&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\xrServer_process_update.cpp&lt;br /&gt;
Line          : 37&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Beer from the creator of 'WP_SHOTG'&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Такое иногда бывает, когда ты (ГГ) или НПС заряжает дробовик или другое оружие со значением tri_state_reload = true.&lt;br /&gt;
Это глюк. в игре что-то сбивается, и когда у дробовика максимальное количество заряженых патронов скажем 6, он заряжается за 6 и дальше.. дальше.. дальше.. и так пока не произойдёт вылет с вышеуказанным логом. вылет не значительный и редкий, но если он случается слишком часто, можно в конфигах всех дробовиков и ружей поменять значение tri_state_reload = true на tri_state_reload = false.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Expression    : fatal error&lt;br /&gt;
Function      : _out_of_memory&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\xrDebugNew.cpp&lt;br /&gt;
Line          : 359&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Out of memory. Memory request: 114688 K&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это банальная нехватка памяти. может быть вы включили какую-нибудь программу, которая жрёт много ресурсов (например fraps).&lt;br /&gt;
Закройте все активные приложения, и переиграйте.&lt;br /&gt;
--------------------------------------------------------------------------------------&lt;br /&gt;
Небольшой пример из практики по определению ошибки в особых случаях(для начинающих):&lt;br /&gt;
Игра зависла, картинка на экране не меняется, на Ctrl + Alt+ Delete не реагирует. Только &amp;quot;Холодная перезагрузка&amp;quot; reset. Но при этом обычно в логе нет записи и обычным Ctrl + V ошибку не увидеть.&lt;br /&gt;
Я пользуюсь программой Punto Switcher. Есть в ней опция &amp;quot;дневник&amp;quot;, она ведёт запись всех нажатий клавиш и по нажатию сочетаний клавиш содержимое памяти может записывать в дневник.&lt;br /&gt;
теперь когда игра зависла и картинка на экране не меняется, нажимаете Ctrl + Alt+ Delete. Внешне ничего не изменится, но ОС будет реагировать&lt;br /&gt;
на клавиши, нажимаете сочетание клавишь &amp;quot;записать в дневник&amp;quot;. Делаете перезагрузку, открываете дневник - Ваша ошибка записана.&lt;br /&gt;
&amp;quot;дядя Саша&amp;quot;&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
[[Категория:FAQ]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D1%87%D0%B8%D0%BD%D1%8B_%D0%B2%D1%8B%D0%BB%D0%B5%D1%82%D0%BE%D0%B2_%D0%B8%D0%B3%D1%80%D1%8B_(%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC_%D0%BB%D0%BE%D0%B3%D0%B8)</id>
		<title>Причины вылетов игры (разбираем логи)</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9F%D1%80%D0%B8%D1%87%D0%B8%D0%BD%D1%8B_%D0%B2%D1%8B%D0%BB%D0%B5%D1%82%D0%BE%D0%B2_%D0%B8%D0%B3%D1%80%D1%8B_(%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC_%D0%BB%D0%BE%D0%B3%D0%B8)"/>
				<updated>2011-06-02T14:01:08Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Привет всем! Игра сталкер, а конкретно сам движок X-ray довольно капризный, и зачастую как в процессе модификации, так и во время игры игра «вылетает». Чтобы мы знали причину вылета, движок нам оставляет лог вылета. Лог вылета можно посмотреть несколькими способами:&lt;br /&gt;
* В текстовом редакторе нажать Ctrl+V (Вставить)&lt;br /&gt;
* Посмотреть лог игры включая лог вылета в файле xray_имя_пользователя.log в папке C:\Documents and Settings\All Users\Документы\STALKER-***\logs&lt;br /&gt;
* Посмотреть непосредственно в окне багтрекера (только в ЧН и ЗП).&lt;br /&gt;
Ну приступим. Начнём с простых:&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : wave&amp;amp;&amp;amp;wave-&amp;gt;length()&lt;br /&gt;
Function      : CSoundRender_Source::LoadWave&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrSound\SoundRender_Source_loader.cpp&lt;br /&gt;
Line          : 65&lt;br /&gt;
Description   : Can't open wave file:&lt;br /&gt;
Arguments     : d:\stalker\gamedata\sounds\music\sound.ogg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь игра не может открыть звуковой OGG-файл под названием sound в папке d:\stalker\gamedata\sounds\music\&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CRender::texture_load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender\Texture.cpp&lt;br /&gt;
Line          : 295&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find texture 'act\act_corp_monolit'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не может найти текстуру act_corp_monolit из папки textures\act&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CModelPool::Instance_Load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender\ModelPool.cpp&lt;br /&gt;
Line          : 111&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find model file 'physics\mesh.ogf'.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена трёхмерная OGF-модель mesh.ogf из папки meshes\physics.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : SG&lt;br /&gt;
Function      : CRender::model_CreateParticles&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrRender_R2\r2.cpp&lt;br /&gt;
Line          : 330&lt;br /&gt;
Description   : Particle effect or group doesn't exist&lt;br /&gt;
Arguments     : hit_fx\hit_water_00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена система частиц (партикл) hit_water_00 в директории hit_fx файла particles.xr (подробно опишу позже).&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CResourceManager::_GetBlender&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\ResourceManager.cpp&lt;br /&gt;
Line          : 49&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Shader 'models\antigas_glass' not found in library.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден шейдер models\antigas_glass в библиотеке шейдеров.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fs&lt;br /&gt;
Function      : CResourceManager::_CreateVS&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\ResourceManager_Resources.cpp&lt;br /&gt;
Line          : 185&lt;br /&gt;
Description   : shader file doesnt exist&lt;br /&gt;
Arguments     : d:\stalker\gamedata\shaders\r2\deffer_impl_flat.vs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден файл шейдера deffer_impl_flat.vs.&lt;br /&gt;
&amp;lt;tt&amp;gt;--Added by Герр. Роммель&lt;br /&gt;
Да нет. Тут проблема вся в том, что неправильно закомпилился шейдер, при компиляции уровня на качестве, более высоком чем Draft. Нужно скачивать исправление шейдеров от товарища Haron.&lt;br /&gt;
Для ЗП (ЧН) это может ещё быть из-за отсутствия thm&amp;quot;ок для текстур терраина уровня!&amp;lt;/tt&amp;gt;&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : out_of_memory_handler&lt;br /&gt;
File : D:\prog_repository\sources\trunk\xrCore\xrDebugNew.cpp&lt;br /&gt;
Line : 336&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : Out of memory. Memory request: 55965 K &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Нехватка оперативной памяти.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : CInifile::r_string&lt;br /&gt;
File :E:\stalker\sources\trunk\xrCore\Xr_ini.cpp&lt;br /&gt;
Line : 352&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : Can't find variable ammo_mag_size in [wpn_addon_grenade_launcher]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена переменная ammo_mag_size в секции [wpn_addon_grenade_launcher].&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : D:\xray-svn\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 74&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: C stack overflow&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Переполнение стека. Смотрим внимательно: lua_error. Ошибка возможно в скриптах.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : vertex || show_restrictions(m_object)&lt;br /&gt;
Function : CPatrolPathManager::select_point&lt;br /&gt;
File : E:\stalker\sources\trunk\xr_3da\xrGame\patrol_path_manager.cpp&lt;br /&gt;
Line : 155&lt;br /&gt;
Description : any vertex in patrol path [sniper_3_walk] in inaccessible for object [stalker_0002]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Какая то вершина (вейпоинт) пути sniper_3_walk стоит в неположенном месте (например не на аи-сетке). Объект stalker_0002 (в данном случае сталкер) который якобы двигался по пути sniper_3_walk попал на эту точку, а заодно ушёл за аи-сетку. Этого движок не терпит.&lt;br /&gt;
&lt;br /&gt;
Тоже самое произойдет если координаты(вейпоинт) пути sniper_3_walk совпадет с координатами места где нпс запрешенно находится буть то рестриктор или аномалия в схеме обхода аномалий.&lt;br /&gt;
Также этот вылет набюдается при попытке отправить нпс за пределы места работ параметр out_rest = &amp;quot;имя_рестриктора&amp;quot;,&lt;br /&gt;
в файле загрузки работ гулага&lt;br /&gt;
&lt;br /&gt;
попробуйте любого сталкера из лагеря новичков отправить допустим к остановке&lt;br /&gt;
получите этот самый вылет&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : e_entity&lt;br /&gt;
Function : xrServer::Process_event_reject&lt;br /&gt;
File : E:\stalker\sources\trunk\xr_3da\xrGame\xrServer_process_event_reject.cpp&lt;br /&gt;
Line : 12&lt;br /&gt;
Description : entity not found. id_parent=7540 id_entity=44047 frame=2075050&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Возникают иногда произвольно при смерти неписей. Причина — движок отрабатывая лут изредка теряет серверный объект уничтожаемой вещи, в итоге происходит вылет.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression : fatal error&lt;br /&gt;
Function : CScriptEngine::lua_error&lt;br /&gt;
File : D:\xray-svn\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line : 74&lt;br /&gt;
Description : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments : LUA error: e:\stalker\gamedata\scripts\_g.script:20: bad argument #2 to 'format' (string expected, got no value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Ошибка распространённая. На первый взгляд кажется, что ошибка как раз в скриптах, но всё может быть иначе. Делаем так: открываем файл _g.script блокнотом, закоменчиваем 20 строку (ставим перед строкой --) и идём к тому месту где поймали вылет. Так мы получим более развёрнутый ответ.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : assertion failed&lt;br /&gt;
Function      : _VertexStream::Lock&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\R_DStreams.cpp&lt;br /&gt;
Line          : 44&lt;br /&gt;
Description   : (bytes_need&amp;lt;=mSize) &amp;amp;&amp;amp; vl_Count&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Проблема возникает при убийстве НПС\мутанта. Типичный вылет по нехватке ресурсов. Встречается в основном на больший локациях.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : IRender_Visual::Load&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\FBasicVisual.cpp&lt;br /&gt;
Line          : 58&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Invalid visual&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Неправильный визуал (модель) НПС.&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : !phrase_dialog-&amp;gt;m_PhraseVector.empty()&lt;br /&gt;
Function      : CPhraseDialog::SayPhrase&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\PhraseDialog.cpp&lt;br /&gt;
Line          : 140&lt;br /&gt;
Description   : No available phrase to say, dialog[esc_dialog]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
В диалоге esc_dialog нет доступной для отображения фразы (скажем все заткнуты инфопоршенами).&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : motion_ID.valid()&lt;br /&gt;
Function      : CKinematicsAnimated::ID_Cycle&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\Layers\xrRender\SkeletonAnimated.cpp&lt;br /&gt;
Line          : 210&lt;br /&gt;
Description   : ! MODEL: can't find cycle:&lt;br /&gt;
Arguments     : death_init&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Игра не нашла в модели трёхмерную анимацию с именем death_init.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
--------------&lt;br /&gt;
* Автор статьи — '''Pihan13'''&lt;br /&gt;
* Дополнил статью — '''Fireman3000'''&lt;br /&gt;
* Частично использовалась информация с сайта http://forum.stalker-simbion.ru/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt; '''Не стесняемся — дополняем, если знаем о чём идёт речь.''' &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнение к статье(От Fireman3000):&lt;br /&gt;
Извините если где нибудь я неправильно пишу. Уж не родился я Колмогором :(&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 73&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: ...hadow of chernobyl\gamedata\scripts\xr_danger.script:116: attempt to index field 'ignore_types' (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Причина вылета в том что игра не понимает значения 0 в danger_ignore.Проще говоря в логике какого то персонажа параметр danger_ignore = 0 либо в минусовом значении. Либо его вообще нету&lt;br /&gt;
&lt;br /&gt;
P.S. Также может быть причина в том, что в логике у какого-то АИ что-то неправильно указано. Для исправления рекомендую вставить строчку перед 115: get_console():execute(self.object:name()). То имя в логе, которое будет последним после вылета, указывает на персонажа с кривой логикой. --[[Участник:Rekongstor|Rekongstor]] 14:01, 2 июня 2011 (UTC)&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 352&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable class in [test_no_klass_npc]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найден класс персонажа. Возможно, нпс не прописан под своим классом в gamedata\npc_profile.xml, либо в creatures\spawn_section.ltx, либо в gameplay\character_desc.xml&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_section&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 342&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't open section 'bandage_test_kick1'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Игра не может найти секцию. Это может быть предмет, нпс и многое другое. Возможно, вы написали название с ошибками. Либо когда добавляли его в: продажу, скрипт, нпс, выпадение из нпс а в редких случиях это может быть иммунитет чего либо(определить пото трудно). Часто такое бывает связано с названием&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CInifile::r_string&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\Xr_ini.cpp&lt;br /&gt;
Line          : 352&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Can't find variable remove_time in [vehicle_btr]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Не найдена переменная remove_time в секции [vehicle_btr]. А в данном случае ошибка в том что если вы делали предмет как физическую модель(тобишь которую нельзя использовать, говорить и вообще он похож на декорации типа деревьев, столов и прочего хлама) то необходимо указывать remove_time в его секции&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : fatal error&lt;br /&gt;
Function      : CScriptEngine::lua_error&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp&lt;br /&gt;
Line          : 73&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : LUA error: ...dow of chernobyl\gamedata\scripts\test_kick.script:34: attempt to call method 'section' (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Метод обращения в игре не предусмотрен. Возможно, стоит пересмотреть подход к тому или иному скрипту&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Expression    : rpoints[0].size()&lt;br /&gt;
Function      : game_sv_Deathmatch::Create&lt;br /&gt;
File          : D:\prog_repository\sources\trunk\xrGame\game_sv_deathmatch.cpp&lt;br /&gt;
Line          : 99&lt;br /&gt;
Description   : rpoints for players not found&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
На мультиплеерной карте не найдены точки респавна игроков.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Expression    : fatal error&lt;br /&gt;
Function      : xrServer::Process_update&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\xrServer_process_update.cpp&lt;br /&gt;
Line          : 37&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Beer from the creator of 'WP_SHOTG'&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Такое иногда бывает, когда ты (ГГ) или НПС заряжает дробовик или другое оружие со значением tri_state_reload = true.&lt;br /&gt;
Это глюк. в игре что-то сбивается, и когда у дробовика максимальное количество заряженых патронов скажем 6, он заряжается за 6 и дальше.. дальше.. дальше.. и так пока не произойдёт вылет с вышеуказанным логом. вылет не значительный и редкий, но если он случается слишком часто, можно в конфигах всех дробовиков и ружей поменять значение tri_state_reload = true на tri_state_reload = false.&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Expression    : fatal error&lt;br /&gt;
Function      : _out_of_memory&lt;br /&gt;
File          : E:\stalker\patch_1_0004\xrCore\xrDebugNew.cpp&lt;br /&gt;
Line          : 359&lt;br /&gt;
Description   : &amp;lt;no expression&amp;gt;&lt;br /&gt;
Arguments     : Out of memory. Memory request: 114688 K&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это банальная нехватка памяти. может быть вы включили какую-нибудь программу, которая жрёт много ресурсов (например fraps).&lt;br /&gt;
Закройте все активные приложения, и переиграйте.&lt;br /&gt;
--------------------------------------------------------------------------------------&lt;br /&gt;
Небольшой пример из практики по определению ошибки в особых случаях(для начинающих):&lt;br /&gt;
Игра зависла, картинка на экране не меняется, на Ctrl + Alt+ Delete не реагирует. Только &amp;quot;Холодная перезагрузка&amp;quot; reset. Но при этом обычно в логе нет записи и обычным Ctrl + V ошибку не увидеть.&lt;br /&gt;
Я пользуюсь программой Punto Switcher. Есть в ней опция &amp;quot;дневник&amp;quot;, она ведёт запись всех нажатий клавиш и по нажатию сочетаний клавиш содержимое памяти может записывать в дневник.&lt;br /&gt;
теперь когда игра зависла и картинка на экране не меняется, нажимаете Ctrl + Alt+ Delete. Внешне ничего не изменится, но ОС будет реагировать&lt;br /&gt;
на клавиши, нажимаете сочетание клавишь &amp;quot;записать в дневник&amp;quot;. Делаете перезагрузку, открываете дневник - Ваша ошибка записана.&lt;br /&gt;
&amp;quot;дядя Саша&amp;quot;&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
[[Категория:FAQ]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=Space_restrictor</id>
		<title>Space restrictor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=Space_restrictor"/>
				<updated>2011-06-01T09:57:44Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Начало==&lt;br /&gt;
----------------------------------------------------------&lt;br /&gt;
Значит, распаковываем алл.спавн с помощью ACDC...Распаковали.&lt;br /&gt;
Откроем, например, alife_l02_garbage.ltx.&lt;br /&gt;
В самом конце допишем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[2145]&lt;br /&gt;
; cse_abstract properties&lt;br /&gt;
section_name = space_restrictor&lt;br /&gt;
name = sgm_kvest&lt;br /&gt;
position = 41.297409057617,0.44233170151711,-299.86953735352&lt;br /&gt;
direction = 0,0,0&lt;br /&gt;
&lt;br /&gt;
; cse_alife_object properties&lt;br /&gt;
game_vertex_id = 253&lt;br /&gt;
distance = 0&lt;br /&gt;
level_vertex_id = 214760&lt;br /&gt;
object_flags = 0xffffff3e&lt;br /&gt;
custom_data = &amp;lt;&amp;lt;END&lt;br /&gt;
[logic]&lt;br /&gt;
active = sr_idle&lt;br /&gt;
[sr_idle]&lt;br /&gt;
on_actor_inside = %+story_sgm_kvest2_3%&lt;br /&gt;
END&lt;br /&gt;
&lt;br /&gt;
; cse_shape properties&lt;br /&gt;
shapes = shape0&lt;br /&gt;
shape0:type = box&lt;br /&gt;
shape0:axis_x = 6.5,0,0&lt;br /&gt;
shape0:axis_y = 0,6.5,0&lt;br /&gt;
shape0:axis_z = 0,0,6.5&lt;br /&gt;
shape0:offset = 0,0,0&lt;br /&gt;
; cse_alife_space_restrictor properties&lt;br /&gt;
restrictor_type = 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Где&amp;lt;br&amp;gt;&lt;br /&gt;
[2145] - порядковый номер&amp;lt;br&amp;gt;&lt;br /&gt;
section_name = space_restrictor - имя секции (нам надо space_restrictor)&amp;lt;br&amp;gt;&lt;br /&gt;
name = svalka_prikol - личное имя (задаём любое)&amp;lt;br&amp;gt;&lt;br /&gt;
position = - позиции (место, где будем спавнить его)&amp;lt;br&amp;gt;&lt;br /&gt;
direction = - поворот рестриктра (не трогаем...)&amp;lt;br&amp;gt;&lt;br /&gt;
game_vertex_id = - геймвертекс &amp;lt;br&amp;gt;&lt;br /&gt;
level_vertex_id = - левелвертекс &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Примечание: координаты спавна, game_vertex_id и level_vertex_id можно получить с помощью следующей функции:''&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function main_menu:OnButton_credits_clicked()&lt;br /&gt;
local text&lt;br /&gt;
local vid&lt;br /&gt;
local gvid&lt;br /&gt;
local a = vector()&lt;br /&gt;
local text&lt;br /&gt;
a = db.actor:position()&lt;br /&gt;
vid = db.actor:level_vertex_id()&lt;br /&gt;
gvid = db.actor:game_vertex_id() &lt;br /&gt;
text = &amp;quot;Позиция:\\nX= &amp;quot;..a.x..&amp;quot;\\nY= &amp;quot;..a.y..&amp;quot;\\nZ= &amp;quot;..a.z..&amp;quot;\\nlevel_vertex= &amp;quot;..vid..&amp;quot;\\ngame_vertex_id= &amp;quot;..gvid&lt;br /&gt;
news_manager.send_tip(db.actor, text, nil, nil, 30000)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
просто допишите её в ui_main_menu.script, в самом конце.&lt;br /&gt;
&lt;br /&gt;
==Логика==&lt;br /&gt;
&lt;br /&gt;
===Выдача infoportions===&lt;br /&gt;
Теперь логика для рестриктора:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[logic]&lt;br /&gt;
active = sr_idle&lt;br /&gt;
&lt;br /&gt;
[sr_idle]&lt;br /&gt;
on_actor_inside = %+имя инфопоршня%&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С такой логикой рестриктор будет выдавать ГГ инфопоршень.&lt;br /&gt;
&lt;br /&gt;
===Эффекты выброса===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[logic]&lt;br /&gt;
active = sr_idle&lt;br /&gt;
&lt;br /&gt;
[sr_idle]&lt;br /&gt;
on_timer = 100000| %=start_small_reject% sr_idle2&lt;br /&gt;
&lt;br /&gt;
[sr_idle2]&lt;br /&gt;
on_timer = 100000| %=start_small_reject% sr_idle&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Такая логика будет запускать каждые 100 сек. эффекты выброса.&lt;br /&gt;
&lt;br /&gt;
===Проверка на наличие и выдача infoportion===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[logic]&lt;br /&gt;
active = sr_idle&lt;br /&gt;
&lt;br /&gt;
[sr_idle]&lt;br /&gt;
on_actor_inside = {=имя_инфопоршня_3 +имя_инфопоршня_2} nil %+имя_инфопоршня_1%&lt;br /&gt;
END&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{=имя_инфопоршня_3 +имя_инфопоршня_2} - это проверка(условие) что у ГГ есть нужный инфопоршень.Если есть,то рестриктор выдаст нужный инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Shapes==&lt;br /&gt;
Двигаем дальше.&amp;lt;br&amp;gt;&lt;br /&gt;
shapes = тут вписываем названия шейпов&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
shapes = shape0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
shape0:type = - это тип шейпа. Ставить или box,или sphere.&amp;lt;br&amp;gt;&lt;br /&gt;
box - коробка&amp;lt;br&amp;gt;&lt;br /&gt;
sphere - сфера&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
shape0:axis_x = ваша цифра,0,0&amp;lt;br&amp;gt;&lt;br /&gt;
shape0:axis_y = 0,ваша цифра,0&amp;lt;br&amp;gt;&lt;br /&gt;
shape0:axis_z = 0,0,ваша цифра&amp;lt;br&amp;gt;&lt;br /&gt;
- это размеры шейпа.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
restrictor_type - тип рестриктра.&amp;lt;br /&amp;gt;&lt;br /&gt;
Я везде ставлю restrictor_type = 3, поэтому сказать не могу на что влияет значение.&amp;lt;br /&amp;gt;&lt;br /&gt;
Ну вот и всё.Думаю всё чётко и ясно.Будут вопросы обращайтесь.&amp;lt;br /&amp;gt;&lt;br /&gt;
ПС: спасибо р-09 за объяснение некоторых моментов с логикой.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Статью написал:&lt;br /&gt;
'''джЭдай, SGMTeam.'''&amp;lt;br&amp;gt;&lt;br /&gt;
Статью преобразовывал в вики (неправильный перенос строк, ошибки с отсутствием некоторых знаков, запись в категорию) - '''Rekongstor'''&lt;br /&gt;
&lt;br /&gt;
[[Категория:Конфигурационные файлы]] [[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:SoC._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%B5%D0%BC_%D1%85%D1%83%D0%B4_%D0%BC%D0%B0%D1%81%D0%BA%D0%B8</id>
		<title>Обсуждение:SoC. Создаем худ маски</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:SoC._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%B5%D0%BC_%D1%85%D1%83%D0%B4_%D0%BC%D0%B0%D1%81%D0%BA%D0%B8"/>
				<updated>2011-05-30T16:48:02Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;а не спижжен ли у xstream &amp;amp; red75 этот скрипт?&lt;br /&gt;
&lt;br /&gt;
Weanchester: &amp;quot;Ответишь?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Rekongstor : да тут, вижу, назревает холивар по поводу неправильного скрипта :)&lt;br /&gt;
xstream &amp;amp; red75, если вы делали этот скрипт, то займитесь логикой: если у меня в инвентаре костюм сталкера, а надет костюм новичка, то будет выдан худ. надо делать такую проверку&lt;br /&gt;
local slot = db.actor:item_in_slot(6)&lt;br /&gt;
if slot then&lt;br /&gt;
	if slot:section() == &amp;quot;stalker_outfit&amp;quot; or slot:section() == &amp;quot;killer_outfit&amp;quot; then -- можно указать другие костюмы&lt;br /&gt;
	-- далее установка худа или его удаление, если условие вернёт false&lt;br /&gt;
	else&lt;br /&gt;
	-- убираем худ&lt;br /&gt;
	end&lt;br /&gt;
else &lt;br /&gt;
-- убираем худ&lt;br /&gt;
end&lt;br /&gt;
правильней, конечно, всё в один if запихнуть, но я не рискую и считаю, что так правильно.&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:SoC._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%B5%D0%BC_%D1%85%D1%83%D0%B4_%D0%BC%D0%B0%D1%81%D0%BA%D0%B8</id>
		<title>Обсуждение:SoC. Создаем худ маски</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:SoC._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%B5%D0%BC_%D1%85%D1%83%D0%B4_%D0%BC%D0%B0%D1%81%D0%BA%D0%B8"/>
				<updated>2011-05-30T16:47:30Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;а не спижжен ли у xstream &amp;amp; red75 этот скрипт?&lt;br /&gt;
&lt;br /&gt;
Weanchester: &amp;quot;Ответишь?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
да тут, вижу, назревает холивар по поводу неправильного скрипта :)&lt;br /&gt;
xstream &amp;amp; red75, если вы делали этот скрипт, то займитесь логикой: если у меня в инвентаре костюм сталкера, а надет костюм новичка, то будет выдан худ. надо делать такую проверку&lt;br /&gt;
local slot = db.actor:item_in_slot(6)&lt;br /&gt;
if slot then&lt;br /&gt;
	if slot:section() == &amp;quot;stalker_outfit&amp;quot; or slot:section() == &amp;quot;killer_outfit&amp;quot; then -- можно указать другие костюмы&lt;br /&gt;
	-- далее установка худа или его удаление, если условие вернёт false&lt;br /&gt;
	else&lt;br /&gt;
	-- убираем худ&lt;br /&gt;
	end&lt;br /&gt;
else &lt;br /&gt;
-- убираем худ&lt;br /&gt;
end&lt;br /&gt;
правильней, конечно, всё в один if запихнуть, но я не рискую и считаю, что так правильно.&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-03-07T13:52:30Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
-----&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
:'''Rekongstor, используй кнопку предпросмотра:'''&lt;br /&gt;
&lt;br /&gt;
http://img.gameru.net/img/65fbc.png&lt;br /&gt;
&lt;br /&gt;
[[Участник:RedPython|RedPython]] 12:24, 9 января 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
Та я использую :) Просто так иногда приходится комп вырубать или добавить что-то... Так что вот не получается. Но я постараюсь :)&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=Maya._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_HUD_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8_%D0%BE%D1%80%D1%83%D0%B6%D0%B8%D1%8F_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D1%81%D0%BA%D0%B8%D1%85_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2.</id>
		<title>Maya. Создание HUD модели оружия с использованием авторских скриптов.</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=Maya._%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_HUD_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8_%D0%BE%D1%80%D1%83%D0%B6%D0%B8%D1%8F_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D1%81%D0%BA%D0%B8%D1%85_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2."/>
				<updated>2011-01-21T10:39:07Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: Обновил для рук ТЧ&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Начало==&lt;br /&gt;
===Введение===&lt;br /&gt;
Итак, я снова с вами и теперь я хочу рассказать об авторских скриптах скриптах и их пользе. И всё же, чем эта статья вам поможет:&lt;br /&gt;
* Откроет вам глаза на использование скриптов.&lt;br /&gt;
* Покажет вам скрипты, которые очень необходимы.&lt;br /&gt;
* Научит или напомнит о пользовании этими скриптами.&lt;br /&gt;
И самое главное, расскажет, как создать саму модель не только худа оружия (хотя в статье будет подробно расписано создание именно этой модели), но и создания или редактирования других моделей по аналогии.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Итак, почему же я решил написать эту статью?&lt;br /&gt;
* Я не знал о том, что я нуб и не знаю, как всё это сделать всё это с помощью обычных средств.&lt;br /&gt;
* Я нуб, но есть такие же нубы, которые также мало знают о всём, что было перечислено в списке, именуемым &amp;quot;чем поможет эта статья&amp;quot;.&lt;br /&gt;
* Я не нуб и действительно нужно объяснить многим людям, как всё это сделать.&lt;br /&gt;
&lt;br /&gt;
В любом случае, понимайте так, как захотите.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Рекомендую прочитать другую мою [[Maya._Подробное_описание_создания_объектов|'''статью''']] по работе с объектами и костями.&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Теперь приступим к инструментарию!&lt;br /&gt;
&lt;br /&gt;
===Инструменты===&lt;br /&gt;
* Разумеется, сама [http://thepiratebay.org/torrent/3602763/AUTODESK.MAYA.UNLIMITED.V8.5.HYBRID.DVD-ISO Maya]&lt;br /&gt;
* [http://www.stalkerin.gameru.net/downloads/SDK/ai_compiler/xray_re-tools-10sep2008.rar Плагины] для работы с ней&lt;br /&gt;
* Специальные [http://www.propergraphics.com/www/denis/scripts.rar скрипты]&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Сразу скажу, что эти скрипты я нашёл в Google почти случайным образом. Вот [http://dlight.ru/forums/showthread.php?t=848 ссылка на страницу], где эти скрипты и находятся&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
==Основное содержание статьи==&lt;br /&gt;
===Работа со скриптами===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Настоятельно рекомендую прочитать документацию к скриптам ''(Инструкция.doc)'' т.к. там находится куча полезной информации о скачанных скриптах&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Для начала установим эти скрипты. Это как раз и описано в документации, но я ещё раз это напишу:&lt;br /&gt;
* В вашем файловом браузере зайдите в папку Мои документы/maya/scripts.&lt;br /&gt;
* Если в папке пусто, нет файлов - залейте в эту папку все скрипты из архива и перезагрузите Maya, ВСЁ!&lt;br /&gt;
Сами скрипты довольно просто найти в главной панели Maya: ''Запустите Maya. В строке меню “File, Edit…” в конце будет меню Scripts.''&lt;br /&gt;
&lt;br /&gt;
Итак, в скриптах много чего интересного для создания объектов. Начну разбирать некоторые скрипты, о которых просто стоит сделать отдельное описание:&lt;br /&gt;
*'''Соединение мешей или ''Combine + ...'''''&lt;br /&gt;
Не знаю, как у вас, но лично у меня (может, проблема в плагинах?) просто объединить меши нельзя. Для этого можно использовать Mesh\Combine, но сразу после экспорта в любой формат *.object, у меня случается вылет с предложением отправить отсчёт об ошибке. Но не соединят же Autodesk нам геометрию! Вот и тема остаётся нетронутой. Вот я сразу, после того как установил плагин, попробовал использовать этот скрипт (он находит по адресу ''Scripts\Objects\Combine + weld + soft border edges''). После него всё заработало! Выделяем объекты и запускаем скрипт. После этого Maya подумает (зависит от размера объекта) и сделает сливание объектов. Экспорт проходит на ура.&lt;br /&gt;
&lt;br /&gt;
*'''Сохранение/загрузка костей (аналог сохранения у Physique в Max) или ''Save/load weights to file-cache''''''&lt;br /&gt;
К сожалению, этот скрипт не понадобится в создании худа, но, скорее всего, пригодится в других ситуациях, потому что в отличии от привычного некоторым людям сохранения/загрузки Physique в максе, он почему-то исключает любую добавленную геометрию. Но тем не менее все кости после загрузки взаимодействуют с мешом отлично. Вообще, я на него сразу обратил внимание, но только потратил время, достигая нужной цели. Эти функции находится в ''Scripts\Skelet/Skin'' под соответствующими названиями.&lt;br /&gt;
----&lt;br /&gt;
Возможно, существует для присоединения костей или их изменения...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Изменение геометрии или ''Edit skinned geometry'''''&lt;br /&gt;
Этот, скорее, один из самых важнейших в этом уроке скриптов, потому что он обеспечивает редактирование геометрии без необходимости детача скина (то есть удаления привязки костей - Detach Skin). Вот что пишет автор об этом скрипте: ''Выделите скиненый объект, запустите скрипт, теперь вы можете редактировать его геометрию как угодно без боязни потерять тщательно разложенные ранее веса, можно резать геометрию, свелдживать вершины, удалять полигоны, создавать новые, менять развертку, удалять историю, все что угодно.'' Это значит, что можно спокойно присоединять к мешу объекты, которые нам нужны (например, оружие или плюшевый мишка для создания худа :D). Сам скрипт лежит по адресу ''Scripts\Skelet/Skin\Edit skinned geometry''. Чтобы прекратить режим изменения геометрии - заново активируйте этот же скрипт.&lt;br /&gt;
&lt;br /&gt;
*'''Редактирование привязки или ''Skin weights editor'''''&lt;br /&gt;
Это второй скрипт, который немаловажен для последующего урока. Автор даже сделал отдельную сноску в документации для этого скрипта, но я ему уделю не так много. Просто скажу, что с помощью этого скрипта можно удалять привязку отдельной или наоборот - создавать её. Она работает довольно просто - выделяем сначала объект, потом активируем скрипт, потом выделяем некоторые вертексы и кость, которая вам нужна. Затем нажимаем Assign и дело в шляпе. Выделенные вертексы поменяют отношение к выделенной кости. Т.е. были привязаны - станут отвязанными и наоборот. Но только есть один момент - если я хочу вернуть действие назад (например, обратно отвязать объект), то окошко выдаёт текст того, что вертексы проассигнены. Об этом попробую написать потом. Этот скрипт лежит в ''Scripts\Skelet/Skin\Skin weights editor''&lt;br /&gt;
&lt;br /&gt;
===Создание худ модели===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Предупреждаю сразу - эта часть не предусматривает создание сложных объектов с костями, прикреплёнными к wpn_body и ниже (вроде wpn_scope).О таких случаях я напишу позже.&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Итак, вот то, ради чего многие сюда пришли. Как помню, в [[Milkshape._Перенос_моделей_оружия_из_ЧН%2C_ЗП_в_ТЧ|статье, посвящённой похожему делу, но в ''MilkShape'']] есть такой текст: &lt;br /&gt;
* &amp;quot;''Видим, что, вроде бы, перенести оружие из ЧН\ЗП в ТЧ достаточно просто – надо только объединить скелеты рук и оружия, и дело в шляпе. На практике это действительно несложно – при условии, что работаем мы в Maya. Но модмейкеры, как известно, в большинстве своем народ бедный, и Maya им не по карману :). Что же, придется действовать «народными средствами», т.е. при помощи Milkshape 3d, благо, необходимые плагины для него имеются.''&amp;quot;&lt;br /&gt;
* &amp;quot;''Ищем в меню пункт, позволяющий присоединить один джоинт к другому, и… нервно бьем кулаком по столу, так как такого пункта там, как ни странно, нет.''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Почему-то я тут увидел намёк на то, что в майе такая кнопка быть должна... Тем не менее такой кнопки нет (впоследствии узнаётся то, что она легко появляется после установки скриптов и, при правильном использовании, даёт нужный результат.&lt;br /&gt;
&lt;br /&gt;
Как же пользоваться этими скриптами, я сейчас и расскажу. &lt;br /&gt;
&lt;br /&gt;
Запускаем Maya. В ней настраиваем нужные параметры (если хотим): ед. измерения и отображение камеры.&lt;br /&gt;
Потом импортируем нужные руки. Я работал с руками из ЧН, но можно взять и руки ТЧ (только там пока нет кости wpn_body и её придётся создать и присоединить к основному скелету).&lt;br /&gt;
* Если вы импортируете руки из ЧН (или ЗП), то вам придётся задать им путь к текстуре этих рук, которая была прежде скопирована из ЧН/ЗП и навана, к примеру, '''act_arm_perchatka_cs'''&lt;br /&gt;
[[Изображение:Руки-Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
Теперь производим импорт любого объекта (как статики, как и динамики. лучше - статики из СДК, но будет также рассмотрен случай с динамикой).&lt;br /&gt;
Если вы импортировали динамический объект, то нажимаем на сам объект и в режиме редактирования анимации нажимаем на Skin\Detach Skin. Потом убираемся - удаляем кости, которые остались после '''этого''' объекта. У нас получился статичный объект. &lt;br /&gt;
&lt;br /&gt;
Теперь надо подвинуть объект на нужное место (лучше, чтобы его можно было легко выделять без рук и анимировать). Удаляем изменяем нужные вертексы объекта и получается что-то вроде:&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Руки и объект - Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь, имея динамические руки и статичный объект, можно двигаться дальше. Нажимаем на руки и активируем скрипт ''Scripts\Skelet/Skin\'''Edit skinned geometry'''''&lt;br /&gt;
&lt;br /&gt;
Теперь выделяем руки и объект и активируем ''Scripts\Objects\'''Combine + weld + soft border edges'''''&lt;br /&gt;
&lt;br /&gt;
Пауза...&lt;br /&gt;
&lt;br /&gt;
Нажимаем ещё раз ''Scripts\Skelet/Skin\'''Edit skinned geometry'''''&lt;br /&gt;
&lt;br /&gt;
Всё. Модель объекта присоединена к худу, но если подвигать некоторыми костями, то будет видно, как объект двигается вместе с костями и причём очень криво. Примерно так:&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Кривое движение - Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
Нам это не нужно. Если двигали кости, то возвращаемся назад или нажимаем с выбором главной кости Skin\Go to bind pose&lt;br /&gt;
&lt;br /&gt;
Теперь настало время привязки объекта к костям. Для этого выделяем худ и активируем ''Scripts\Skelet/Skin\'''Skin weights editor'''''&lt;br /&gt;
&lt;br /&gt;
У меня появляется окошко, но немного неправильной формы. Чтобы посмотреть содержимое, я просто расширяю его. Видим содержимое: Select some joints and skinned verticies... Я бы сначала выделил ''skinned verticies'' т.е. вертексы объекта. Выделяем объект (у меня это сейф) без рук.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;Если вы не послушали совета, что объект надо передвигать туда, где легко не задеть рук, то выделяем несколько вертексов и нажимаем Shift + Ю (на англ. раскладке)&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Я выделил свой объект и получилось что-то вроде этого:&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Аттач объекта - Rek0.png]]&lt;br /&gt;
&lt;br /&gt;
Если у вас получилось что-то аналогичное, то всё, должно быть, правильно.&lt;br /&gt;
&lt;br /&gt;
Теперь окошко просит выделить кости. Для начала выделим главную кость - ту, что скрепляет все кости. У меня она называется bip01 (напомню, что руки ЧН). Когда вы выделите эту кость, то все остальные кости выделятся вместе с ней. Теперь нажимаем на кнопку внутри окошка: '''Assign'''.&lt;br /&gt;
Это исключит объект из всего скелета и, сколько не двигай костями (кроме основной, т.к. она определяет позицию самого объекта), ничего мы не добьёмся. Теперь намечается новый случай - многокостие. Я его так назвал, потому что в некоторых случаях бывает, что объекту нужны кости вроде wpn_scope и т.п. Пока я их не трогаю и создание больших пушек я опишу в отдельной части и потом.&lt;br /&gt;
&lt;br /&gt;
Если у вас один объект без наворотов, то можно продолжать. Выделяем заново все вертексы объекта и кликаем по косточке wpn_body. Нажимаем Assign. В этом случае скрипт наоборот - сделает вертексы привязвнными к кости.&lt;br /&gt;
&lt;br /&gt;
Закрываем окно скрипта. Всё с объектом... Экспортируем объект в X-Ray Skeletal Object (выделив меш худа)&lt;br /&gt;
&lt;br /&gt;
Худ Готов. Теперь осталось его только анимировать. Анимки экспортируем также, как и объект, но только X-Ray Skeletal Motion.&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;big&amp;gt;&amp;lt;blockquote&amp;gt;На заметку: главное в анимации - правильный поворот худа. Он итак по идее правильный. Просто если вы ошиблись в положении худа, то не стоит переделывать положение худа через анимку. Пользуйтесь параметром position в конфиге худа оружия.&amp;lt;/blockquote&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
Настройки в актор эдиторе можно посмотреть в [[3dsmax._Создание_HUD-модели_оружия#5._.D0.9D.D0.B0.D1.81.D1.82.D1.80.D0.BE.D0.B9.D0.BA.D0.B0_.D0.BF.D0.B0.D1.80.D0.B0.D0.BC.D0.B5.D1.82.D1.80.D0.BE.D0.B2_.D0.B2_Actor_Editor|аналогичной статье по 3ds максу]]&lt;br /&gt;
&lt;br /&gt;
Удачи!&lt;br /&gt;
&lt;br /&gt;
[[Изображение:В_игре.jpg|640px]]&lt;br /&gt;
&lt;br /&gt;
 На заметку: попробуйте себя проверить, добавив какой-нибудь простенький объект.&lt;br /&gt;
&lt;br /&gt;
==Немного о руках ТЧ==&lt;br /&gt;
Если вы хотите историю создания рук, то вы не по адресу, потому что этот раздел посвящён тому, чем может отличаться работа с руками из ТЧ. Итак, распишу по пунктам.&lt;br /&gt;
* Импортируем [http://intreface.narod2.ru/wpn_hands_soc.mb модель рук формата] .object&lt;br /&gt;
* Импортируем оружие, не забываем отсоединить скин и удалить кости, если оружие было динамическим.&lt;br /&gt;
* Включаем '''Edit skinned geometry'''&lt;br /&gt;
* Подсоединяем оружие (или погремушку) через '''Combine + weld + soft border edges'''&lt;br /&gt;
* Вырубаем '''Edit skinned geometry'''&lt;br /&gt;
* Открываем '''Skin weights editor'''&lt;br /&gt;
* Выделяем (только) вертексы оружия (или погремушки)&lt;br /&gt;
** Если не видим вертексов оружия, то удерживаем правой кнопкой на худе и выбираем '''Vertex'''&lt;br /&gt;
* C зажатым Shift, выделяем кость '''root'''&lt;br /&gt;
* Нажимем '''Assign'''&lt;br /&gt;
* Опять выделяем вертексы оружия&lt;br /&gt;
* C зажатым Shift, выделяем кость '''wpn_body'''&lt;br /&gt;
* Нажимем '''Assign''' и закрываем окно&lt;br /&gt;
** Можно немного полюбоваться, подвигать кости. Не забудьте вернуть всё в порядок через '''Go to bind pose'''&lt;br /&gt;
&lt;br /&gt;
==Авторы==&lt;br /&gt;
*[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
==Ссылки на руки==&lt;br /&gt;
*[http://rekongstor.narod2.ru/wpn_hand_cs.object wpn_hand_cs.object] - ЧН&lt;br /&gt;
*[http://rekongstor.narod2.ru/wpn_hands_soc.object wpn_hands_soc.object] - ТЧ&lt;br /&gt;
*[http://intreface.narod2.ru/wpn_hands_soc.object] - ТЧ '''(обновление)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Wireframe]] [[Категория:Незаконченные_статьи]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=SoC._%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D0%BC_%D0%BF%D1%80%D0%BE%D0%B2%D0%BE%D0%B4%D0%BD%D0%B8%D0%BA%D0%B0</id>
		<title>SoC. Добавляем проводника</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=SoC._%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D0%BC_%D0%BF%D1%80%D0%BE%D0%B2%D0%BE%D0%B4%D0%BD%D0%B8%D0%BA%D0%B0"/>
				<updated>2011-01-21T07:43:30Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В ТЧ есть единственный момент ,когда в результате диалога с НПС ,ГГ перемещается. Это диалог с О - сознанием. После отказа от вступления, ГГ перемещается на АЭС 2. Если использовать эту функцию ,можно создать в ТЧ проводника.&lt;br /&gt;
Примечание: Проводник не будет перемещаться вместе с вами ,как в ЗП. Вы будете перемещаться в одиночку ,как в ЧН.&lt;br /&gt;
Для этого:&lt;br /&gt;
1)Для этого в '''gamedata\scripts''' находим файл '''dialogs_aes.script'''. В нём имеется следующая функция&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function osoznanie_decline(npc, actor)&lt;br /&gt;
db.actor:disable_info_portion(&amp;quot;oso_init_dialog&amp;quot;)&lt;br /&gt;
npc:stop_talk()&lt;br /&gt;
actor:stop_talk()&lt;br /&gt;
xr_effects.enable_ui(db.actor, nil) &lt;br /&gt;
local point = patrol(&amp;quot;mon_jump_aes2_walk&amp;quot;)&lt;br /&gt;
local look = patrol(&amp;quot;mon_jump_aes2_look&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
db.actor:set_actor_position(point:point(0))&lt;br /&gt;
local dir = look:point(0):sub(point:point(0))&lt;br /&gt;
db.actor:set_actor_direction(-dir:getH())&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
2)Копируем эту функцию ,допустим ,в '''escape_dialog''' из директории '''gamedata\scripts'''&lt;br /&gt;
3)Обратите внимание на вот этот фрагмент из функции: '''db.actor:disable_info_portion(&amp;quot;oso_init_dialog&amp;quot;)'''. Здесь функция ссылается на инфопоршень ,но на Кордоне данный инфопоршень не прописан. Тогда&lt;br /&gt;
4)Переименовываем данный инфопоршень так ,как вам удобно ,например '''db.actor:disable_info_portion(&amp;quot;esc_init_dialog&amp;quot;)'''. Примечание: Название инфопоршня это '''&amp;quot;esc_init_dialog&amp;quot;''' , (то ,что за скобками ,переименовывать не надо). Затем добавляем инфопоршень в файл '''info_101escape.xml''' из директории '''gamedata\config\gameplay'''. В этом файле добавляем следующее: '''&amp;lt;info_portion id=&amp;quot;esc_init_dialog&amp;quot;&amp;gt;&amp;lt;/info_portion&amp;gt;'''&lt;br /&gt;
5)Итак ,функция есть ,инфопоршень тоже есть. Теперь нужны координаты. Обратите внимание на следующий фрагмент функции:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
local point = patrol(&amp;quot;mon_jump_aes2_walk&amp;quot;)&lt;br /&gt;
local look = patrol(&amp;quot;mon_jump_aes2_look&amp;quot;)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
Здесь функция ссылается на определённые координаты на АЭС2. Но нам нужны координаты на Кордоне. Для этого открываем '''way_101_escape.ltx''' и там дописываем пути. Например вот так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
[mon_jump_esc8_look]&lt;br /&gt;
points = p0&lt;br /&gt;
p0:name = wp00&lt;br /&gt;
p0:position = -239.110947,-19.788391,-134.999161&lt;br /&gt;
p0:game_vertex_id = 8&lt;br /&gt;
p0:level_vertex_id = 16191&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[mon_jump_esc8_walk]&lt;br /&gt;
points = p0&lt;br /&gt;
p0:name = wp00&lt;br /&gt;
p0:position = -238.017761,-19.888292,-140.161987&lt;br /&gt;
p0:game_vertex_id = 47&lt;br /&gt;
p0:level_vertex_id = 17468&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
Всё пути есть. Только теперь в функции ,переименуйте фрагмент:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
local point = patrol(&amp;quot;mon_jump_aes2_walk&amp;quot;)&lt;br /&gt;
local look = patrol(&amp;quot;mon_jump_aes2_look&amp;quot;)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На фрагмент:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
local point = patrol(&amp;quot;mon_jump_esc8_walk&amp;quot;)&lt;br /&gt;
local look = patrol(&amp;quot;mon_jump_esc8_look&amp;quot;)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь осталось только привязать всё это к диалогу. Я взял диалог с Кузнецовым.&lt;br /&gt;
Открываем файл dialogs_escape.xml и находим следующие строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
&amp;lt;dialog id=&amp;quot;esc_bridge_soldiers_start&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;precondition&amp;gt;dialogs.is_not_wounded&amp;lt;/precondition&amp;gt;&lt;br /&gt;
&amp;lt;phrase_list&amp;gt;&lt;br /&gt;
&amp;lt;phrase id=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;text&amp;gt;esc_bridge_soldiers_start_12&amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;next&amp;gt;13&amp;lt;/next&amp;gt;&lt;br /&gt;
&amp;lt;/phrase&amp;gt;&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это фраза &amp;quot;Мне надо дальше&amp;quot;. Сюда вставляем активизацию нашей функции. Получется следующее:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
&amp;lt;dialog id=&amp;quot;esc_bridge_soldiers_start&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;precondition&amp;gt;dialogs.is_not_wounded&amp;lt;/precondition&amp;gt;&lt;br /&gt;
&amp;lt;phrase_list&amp;gt;&lt;br /&gt;
&amp;lt;phrase id=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;text&amp;gt;esc_bridge_soldiers_start_12&amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;action&amp;gt;escape_dialog.osoznanie_decline&amp;lt;/action&amp;gt; Здесь следующая структура: &amp;lt;action&amp;gt;Название_скрипта. Название_функции&amp;lt;/action&amp;gt;&lt;br /&gt;
&amp;lt;next&amp;gt;13&amp;lt;/next&amp;gt;&lt;br /&gt;
&amp;lt;/phrase&amp;gt;&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот ,собственно и всё. Теперь после фразы &amp;quot;Мне надо дальше&amp;quot; вы переместитесь к бункеру Сидоровича.&lt;br /&gt;
Автор: '''mma'''&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:Maya._%D0%9F%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%BE%D0%B5_%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5_%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BE%D0%B2</id>
		<title>Обсуждение:Maya. Подробное описание создания объектов</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:Maya._%D0%9F%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%BE%D0%B5_%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5_%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F_%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BE%D0%B2"/>
				<updated>2011-01-13T19:52:19Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Здесь задавайте вопросы по статье.&lt;br /&gt;
Уменя вопрос немонго не по теме- как в майе соединить 2 объекта (attach в maxЕ)&lt;br /&gt;
&lt;br /&gt;
У меня самого не получалось это соединить. Но я знаю, что в Милке это можно сделать.&lt;br /&gt;
&lt;br /&gt;
моя недавняя статья по привязыванию объекта (сейф на примере) к худу (к одной из костей)&lt;br /&gt;
[[Maya._Создание_HUD_модели_оружия_с_использованием_авторских_скриптов.]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Обсуждение:Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-13T18:49:56Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;А тут обсуждаем статью.&lt;br /&gt;
&lt;br /&gt;
Любопытно было бы  узнать, а чем автора InfoScripts не устраивает запись в pstor? Если, конечно, он он вообще знает об этом.&lt;br /&gt;
Запись &lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if xr_logic.pstor_retrieve(db.actor, &amp;quot;first_spawn&amp;quot;, 0)==0 then&lt;br /&gt;
тут что делаем&lt;br /&gt;
xr_logic.pstor_store(db.actor, &amp;quot;first_spawn&amp;quot;, 1)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
прекрасно заменяет инфопоршни. И pstor вообще достаточно удобное место для хранения своих данных.&lt;br /&gt;
&lt;br /&gt;
'''Erlik'''&lt;br /&gt;
&lt;br /&gt;
в общем-то да. про pstor знаю. упростить можно. тем не менее сами инфоскрипты можно бы было попробовать использовать не только в качестве &amp;quot;заглушек&amp;quot;, но и для диалогов, а то и для квестов попробовать.&lt;br /&gt;
&lt;br /&gt;
--[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
а ещё сложно будет умещать текст в 16000. кстати, я так и не понял, чего именно??? байт или всё-таки бит?&lt;br /&gt;
&lt;br /&gt;
--[[Участник:Rekongstor|Rekongstor]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Обсуждение:Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-13T18:49:43Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;А тут обсуждаем статью.&lt;br /&gt;
&lt;br /&gt;
Любопытно было бы  узнать, а чем автора InfoScripts не устраивает запись в pstor? Если, конечно, он он вообще знает об этом.&lt;br /&gt;
Запись &lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if xr_logic.pstor_retrieve(db.actor, &amp;quot;first_spawn&amp;quot;, 0)==0 then&lt;br /&gt;
тут что делаем&lt;br /&gt;
xr_logic.pstor_store(db.actor, &amp;quot;first_spawn&amp;quot;, 1)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
прекрасно заменяет инфопоршни. И pstor вообще достаточно удобное место для хранения своих данных.&lt;br /&gt;
&lt;br /&gt;
'''Erlik'''&lt;br /&gt;
&lt;br /&gt;
в общем-то да. про pstor знаю. упростить можно. тем не менее сами инфоскрипты можно бы было попробовать использовать не только в качестве &amp;quot;заглушек&amp;quot;, но и для диалогов, а то и для квестов попробовать.&lt;br /&gt;
&lt;br /&gt;
--[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
а ещё сложно будет умещать текст в 16000. кстати, я так и не понял, чего именно??? байт или всё-таки бит?&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Обсуждение:Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-13T18:48:24Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;А тут обсуждаем статью.&lt;br /&gt;
&lt;br /&gt;
Любопытно было бы  узнать, а чем автора InfoScripts не устраивает запись в pstor? Если, конечно, он он вообще знает об этом.&lt;br /&gt;
Запись &lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if xr_logic.pstor_retrieve(db.actor, &amp;quot;first_spawn&amp;quot;, 0)==0 then&lt;br /&gt;
тут что делаем&lt;br /&gt;
xr_logic.pstor_store(db.actor, &amp;quot;first_spawn&amp;quot;, 1)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
прекрасно заменяет инфопоршни. И pstor вообще достаточно удобное место для хранения своих данных.&lt;br /&gt;
&lt;br /&gt;
'''Erlik'''&lt;br /&gt;
&lt;br /&gt;
в общем-то да. про pstor знаю. упростить можно. тем не менее сами инфоскрипты можно бы было попробовать использовать не только в качестве &amp;quot;заглушек&amp;quot;, но и для диалогов, а то и для квестов попробовать.&lt;br /&gt;
&lt;br /&gt;
--[[Участник:Rekongstor|Rekongstor]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Обсуждение:Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-13T18:48:14Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;А тут обсуждаем статью.&lt;br /&gt;
&lt;br /&gt;
Любопытно было бы  узнать, а чем автора InfoScripts не устраивает запись в pstor? Если, конечно, он он вообще знает об этом.&lt;br /&gt;
Запись &lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if xr_logic.pstor_retrieve(db.actor, &amp;quot;first_spawn&amp;quot;, 0)==0 then&lt;br /&gt;
тут что делаем&lt;br /&gt;
xr_logic.pstor_store(db.actor, &amp;quot;first_spawn&amp;quot;, 1)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
прекрасно заменяет инфопоршни. И pstor вообще достаточно удобное место для хранения своих данных.&lt;br /&gt;
&lt;br /&gt;
'''Erlik'''&lt;br /&gt;
&lt;br /&gt;
в общем-то да. про pstor знаю. упростить можно. тем не менее сами инфоскрипты можно бы было попробовать использовать не только в качестве &amp;quot;заглушек&amp;quot;, но и для диалогов, а то и для квестов попробовать.&lt;br /&gt;
&lt;br /&gt;
--[[Участник:Rekongstor|Rekongstor]] 18:48, 13 января 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=CoP._%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D1%80%D0%B0%D0%B7%D0%BD%D0%BE%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%B8%D1%8F_%D0%B0%D1%80%D1%82%D0%B5%D1%84%D0%B0%D0%BA%D1%82%D0%BE%D0%B2</id>
		<title>CoP. Эффект разнообразия артефактов</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=CoP._%D0%AD%D1%84%D1%84%D0%B5%D0%BA%D1%82_%D1%80%D0%B0%D0%B7%D0%BD%D0%BE%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%B8%D1%8F_%D0%B0%D1%80%D1%82%D0%B5%D1%84%D0%B0%D0%BA%D1%82%D0%BE%D0%B2"/>
				<updated>2011-01-13T11:30:58Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Давным давно читал на форуме GSC такое предложение: '''Сделайте так чтобы артефакты были более уникальны. Тоесть каждая Медуза имела отличия от такой же Медузы.'''&lt;br /&gt;
&lt;br /&gt;
Честно говоря идея хорошая, я тоже считаю неправильным то что каждая найденая мной Медуза весит пол килограмма выводит 2 условные единицы радиации и стоит 4000 рублей (тут конечно есть разброс цен у торгашей) дети ведь не рождаются с весом ровно 3200 со светлыми волосами и голубыми глазами. Менять можно впринципе любые параметры, но на практике столкнулся с тем что приходится поднимать общую радиоизлучаемость артефактов до минимума равного 5-6 и максисума равного 12-13.&lt;br /&gt;
&lt;br /&gt;
'''НАЧНЕМ'''&lt;br /&gt;
&lt;br /&gt;
Вот исправленный конфиг медузы:&lt;br /&gt;
&lt;br /&gt;
 [af_medusa]:af_base&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\gravitational_1_medusa&amp;quot;&lt;br /&gt;
 class				= ARTEFACT  	; будет подпрыгивать&lt;br /&gt;
 visual				= dynamics\artefacts\af_medusa.ogf&lt;br /&gt;
 description			= st_af_medusa_descr&lt;br /&gt;
 inv_name			= st_af_medusa_name&lt;br /&gt;
 inv_name_short		= st_af_medusa_name&lt;br /&gt;
 inv_weight			= 0.5&lt;br /&gt;
 &lt;br /&gt;
 inv_grid_x			= 9&lt;br /&gt;
 inv_grid_y			= 4&lt;br /&gt;
 &lt;br /&gt;
 cost				= 4000&lt;br /&gt;
 &lt;br /&gt;
 jump_height			= .5    	; высота прыжка&lt;br /&gt;
 &lt;br /&gt;
 particles				= artefact\af_gravi_idle&lt;br /&gt;
 det_show_particles		= artefact\af_gravi_show&lt;br /&gt;
 det_hide_particles		= artefact\af_gravi_hide&lt;br /&gt;
 &lt;br /&gt;
 af_rank				= 1&lt;br /&gt;
 &lt;br /&gt;
 lights_enabled = true&lt;br /&gt;
 &lt;br /&gt;
 trail_light_color 		= 0.4,0.4,0&lt;br /&gt;
 trail_light_range 		= 2.0&lt;br /&gt;
 &lt;br /&gt;
 ;скорости увеличения (уменьшения)&lt;br /&gt;
 health_restore_speed		= 0&lt;br /&gt;
 radiation_restore_speed		= -0.003&lt;br /&gt;
 satiety_restore_speed		= 0&lt;br /&gt;
 power_restore_speed			= 0&lt;br /&gt;
 bleeding_restore_speed		= 0&lt;br /&gt;
 hit_absorbation_sect		= af_medusa_absorbation&lt;br /&gt;
 &lt;br /&gt;
 additional_inventory_weight		= 0&lt;br /&gt;
 additional_inventory_weight2	= 0&lt;br /&gt;
 &lt;br /&gt;
 artefact_activation_seq		= af_activation_bold&lt;br /&gt;
 &lt;br /&gt;
 [af_medusa_absorbation]&lt;br /&gt;
 burn_immunity 			= 0				;коэффициенты иммунитета&lt;br /&gt;
 strike_immunity 		= 0&lt;br /&gt;
 shock_immunity 			= 0&lt;br /&gt;
 wound_immunity 			= 0&lt;br /&gt;
 radiation_immunity 		= 0&lt;br /&gt;
 telepatic_immunity 		= 0&lt;br /&gt;
 chemical_burn_immunity 	= 0&lt;br /&gt;
 explosion_immunity 		= 0&lt;br /&gt;
 fire_wound_immunity  	= 0&lt;br /&gt;
&lt;br /&gt;
Сразу же после него вписываем что то вроде:&lt;br /&gt;
&lt;br /&gt;
 [af_medusa_mini]:af_medusa&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\my_addon_af_medusa_mini&amp;quot;&lt;br /&gt;
 inv_weight			= 0.3&lt;br /&gt;
 &lt;br /&gt;
 cost				= 3500&lt;br /&gt;
 &lt;br /&gt;
 radiation_restore_speed		= -0.002&lt;br /&gt;
 &lt;br /&gt;
 ;------------------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
 [af_medusa_maxi]:af_medusa&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\my_addon_af_medusa_maxi&amp;quot;&lt;br /&gt;
 inv_weight			= 0.7&lt;br /&gt;
 &lt;br /&gt;
 cost				= 4500&lt;br /&gt;
 &lt;br /&gt;
 radiation_restore_speed		= -0.004&lt;br /&gt;
 &lt;br /&gt;
 ;------------------------------------------------------------------------------------------&lt;br /&gt;
 &lt;br /&gt;
 [af_medusa_super]:af_medusa&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\my_addon_af_medusa_super&amp;quot;&lt;br /&gt;
 inv_weight			= 0.3&lt;br /&gt;
 &lt;br /&gt;
 cost				= 5500&lt;br /&gt;
 &lt;br /&gt;
 radiation_restore_speed		= -0.004&lt;br /&gt;
&lt;br /&gt;
Я в данном случае создал еще три артефакта которые в игре будут полностью похожи на медузу (Название, описание, свойства) С разницей лишь в том что все четыре Медузы будут по разному стоить, имеют разный вес, и по разному выводят радиацию. Далее нам необходимо добавить их в игру.&lt;br /&gt;
&lt;br /&gt;
'''1) gamedata\configs\misc\devices.ltx'''&lt;br /&gt;
&lt;br /&gt;
Дописываем по аналогии секции:&lt;br /&gt;
&lt;br /&gt;
 af_class_40		= af_medusa_mini&lt;br /&gt;
 af_sound_40_		= detectors\art_beep1&lt;br /&gt;
 af_freq_40			= 0.05, 2&lt;br /&gt;
 af_class_41		= af_medusa_maxi&lt;br /&gt;
 af_sound_41_		= detectors\art_beep1&lt;br /&gt;
 af_freq_41			= 0.05, 2&lt;br /&gt;
 af_class_42		= af_medusa_super&lt;br /&gt;
 af_sound_42_		= detectors\art_beep1&lt;br /&gt;
 af_freq_42			= 0.05, 2&lt;br /&gt;
&lt;br /&gt;
К нужному детектору. Не забывая при этом сместить номера последующих секций в следующих детекторах если приписываете на Отклик, Медведь или Велес (detector_simple, detector_advanced, detector_elite)&lt;br /&gt;
&lt;br /&gt;
'''2) gamedata\configs\ui\ui_detector_artefact.xml'''&lt;br /&gt;
&lt;br /&gt;
Дописываем по аналогии:&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;palette id=&amp;quot;af_medusa_mini&amp;quot; width=&amp;quot;0.0015&amp;quot; height=&amp;quot;0.0015&amp;quot; stretch=&amp;quot;1&amp;quot; alignment=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;texture shader=&amp;quot;hud\p3d&amp;quot;&amp;gt;ui_temp_ad3_artefact&amp;lt;/texture&amp;gt;&lt;br /&gt;
    &amp;lt;/palette&amp;gt;&lt;br /&gt;
    &amp;lt;palette id=&amp;quot;af_medusa_maxi&amp;quot; width=&amp;quot;0.0015&amp;quot; height=&amp;quot;0.0015&amp;quot; stretch=&amp;quot;1&amp;quot; alignment=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;texture shader=&amp;quot;hud\p3d&amp;quot;&amp;gt;ui_temp_ad3_artefact&amp;lt;/texture&amp;gt;&lt;br /&gt;
    &amp;lt;/palette&amp;gt;&lt;br /&gt;
    &amp;lt;palette id=&amp;quot;af_medusa_super&amp;quot; width=&amp;quot;0.0015&amp;quot; height=&amp;quot;0.0015&amp;quot; stretch=&amp;quot;1&amp;quot; alignment=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;texture shader=&amp;quot;hud\p3d&amp;quot;&amp;gt;ui_temp_ad3_artefact&amp;lt;/texture&amp;gt;&lt;br /&gt;
    &amp;lt;/palette&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''И'''&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;palette id=&amp;quot;af_medusa_mini&amp;quot; width=&amp;quot;0.0011&amp;quot; height=&amp;quot;0.0011&amp;quot; stretch=&amp;quot;1&amp;quot; alignment=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;texture shader=&amp;quot;hud\p3d&amp;quot;&amp;gt;ui_inGame2_Detector_icon_artefact&amp;lt;/texture&amp;gt;&lt;br /&gt;
    &amp;lt;/palette&amp;gt;&lt;br /&gt;
    &amp;lt;palette id=&amp;quot;af_medusa_maxi&amp;quot; width=&amp;quot;0.0011&amp;quot; height=&amp;quot;0.0011&amp;quot; stretch=&amp;quot;1&amp;quot; alignment=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;texture shader=&amp;quot;hud\p3d&amp;quot;&amp;gt;ui_inGame2_Detector_icon_artefact&amp;lt;/texture&amp;gt;&lt;br /&gt;
    &amp;lt;/palette&amp;gt;&lt;br /&gt;
    &amp;lt;palette id=&amp;quot;af_medusa_super&amp;quot; width=&amp;quot;0.0011&amp;quot; height=&amp;quot;0.0011&amp;quot; stretch=&amp;quot;1&amp;quot; alignment=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;texture shader=&amp;quot;hud\p3d&amp;quot;&amp;gt;ui_inGame2_Detector_icon_artefact&amp;lt;/texture&amp;gt;&lt;br /&gt;
    &amp;lt;/palette&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3) gamedata\configs\scripts\локация\anomaly\аномалия.ltx'''&lt;br /&gt;
&lt;br /&gt;
Делаем из:&lt;br /&gt;
&lt;br /&gt;
 [anomal_zone]&lt;br /&gt;
 layers_count = 1&lt;br /&gt;
 respawn_tries = 2&lt;br /&gt;
 max_artefacts = 3&lt;br /&gt;
 ;applying_force_xz = 200&lt;br /&gt;
 ;applying_force_y = 200 &lt;br /&gt;
 artefacts = af_medusa&lt;br /&gt;
 start_artefact = af_medusa&lt;br /&gt;
 coeff = 3&lt;br /&gt;
 artefact_ways = zaton_zanaveska_af_way&lt;br /&gt;
&lt;br /&gt;
Вот это&lt;br /&gt;
&lt;br /&gt;
 [anomal_zone]&lt;br /&gt;
 layers_count = 1&lt;br /&gt;
 respawn_tries = 2&lt;br /&gt;
 max_artefacts = 3&lt;br /&gt;
 ;applying_force_xz = 200&lt;br /&gt;
 ;applying_force_y = 200 &lt;br /&gt;
 artefacts = af_medusa, af_medusa_mini, af_medusa_maxi, af_medusa_super&lt;br /&gt;
 start_artefact = af_medusa_mini&lt;br /&gt;
 coeff = 3, 3, 2, 1&lt;br /&gt;
 artefact_ways = zaton_zanaveska_af_way&lt;br /&gt;
&lt;br /&gt;
Вот собственно и всё (осталось только добавить в торговлю)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Да как же всё =)'''&lt;br /&gt;
&lt;br /&gt;
Очень вероятно кто то захочет провернуть такое со всеми артефактами (у меня ушло около 7-8 часов (долго искал БАГ).&lt;br /&gt;
&lt;br /&gt;
Так вот в случае с Медузой мы не использовали секцию иммунитетов которые даёт артефакт: hit_absorbation_sect&lt;br /&gt;
&lt;br /&gt;
К примеру:&lt;br /&gt;
&lt;br /&gt;
 hit_absorbation_sect		= af_cristall_flower_mini_absorbation&lt;br /&gt;
&lt;br /&gt;
Вот тут есть правило что если мы используем иммунитеты то они должны вписываться вот так:&lt;br /&gt;
&lt;br /&gt;
 [af_cristall_flower_mini]:af_cristall_flower&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\my_addon_af_cristall_flower_mini&amp;quot;&lt;br /&gt;
 inv_weight			= 0.4&lt;br /&gt;
 &lt;br /&gt;
 cost				= 2500&lt;br /&gt;
 &lt;br /&gt;
 radiation_restore_speed		= 0.006&lt;br /&gt;
 hit_absorbation_sect		= af_cristall_flower_mini_absorbation&lt;br /&gt;
 &lt;br /&gt;
 [af_cristall_flower_mini_absorbation]&lt;br /&gt;
 burn_immunity 			= 0&lt;br /&gt;
 strike_immunity 		= 0&lt;br /&gt;
 shock_immunity 		= 0&lt;br /&gt;
 wound_immunity 		= 0&lt;br /&gt;
 radiation_immunity 		= 0&lt;br /&gt;
 telepatic_immunity 		= 0.01&lt;br /&gt;
 chemical_burn_immunity 	= 0&lt;br /&gt;
 explosion_immunity 		= 0&lt;br /&gt;
 fire_wound_immunity  		= 0&lt;br /&gt;
&lt;br /&gt;
А не вот так:&lt;br /&gt;
&lt;br /&gt;
 [af_cristall_flower_mini]:af_cristall_flower&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\my_addon_af_cristall_flower_mini&amp;quot;&lt;br /&gt;
 inv_weight			= 0.4&lt;br /&gt;
 &lt;br /&gt;
 cost				= 2500&lt;br /&gt;
 &lt;br /&gt;
 radiation_restore_speed		= 0.006&lt;br /&gt;
 hit_absorbation_sect		= af_cristall_flower_mini_absorbation&lt;br /&gt;
 &lt;br /&gt;
 [af_cristall_flower_mini_absorbation]&lt;br /&gt;
 telepatic_immunity 		= 0.01&lt;br /&gt;
&lt;br /&gt;
Во втором случае при спавне артефакта игра вылетит с ошибкой типа не найден '''burn_immunity''' в '''af_cristall_flower_mini_absorbation''' тоесть af_cristall_flower_mini_absorbation должен содержать все иммунитеты даже если их значение ноль.&lt;br /&gt;
&lt;br /&gt;
Хотя впринципе можно создать в файле секцию:&lt;br /&gt;
&lt;br /&gt;
 [af_bla_bla_bla_absorbation]&lt;br /&gt;
 burn_immunity 			= 0&lt;br /&gt;
 strike_immunity 		= 0&lt;br /&gt;
 shock_immunity 		= 0&lt;br /&gt;
 wound_immunity 		= 0&lt;br /&gt;
 radiation_immunity 		= 0&lt;br /&gt;
 telepatic_immunity 		= 0&lt;br /&gt;
 chemical_burn_immunity 	= 0&lt;br /&gt;
 explosion_immunity 		= 0&lt;br /&gt;
 fire_wound_immunity  		= 0&lt;br /&gt;
&lt;br /&gt;
А все следующие иммунитеты писать вот так:&lt;br /&gt;
&lt;br /&gt;
 [af_cristall_flower_mini]:af_cristall_flower&lt;br /&gt;
 $spawn				= &amp;quot;artefacts\my_addon_af_cristall_flower_mini&amp;quot;&lt;br /&gt;
 inv_weight			= 0.4&lt;br /&gt;
 &lt;br /&gt;
 cost				= 2500&lt;br /&gt;
 &lt;br /&gt;
 radiation_restore_speed		= 0.006&lt;br /&gt;
 hit_absorbation_sect		= af_cristall_flower_mini_absorbation&lt;br /&gt;
 &lt;br /&gt;
 [af_cristall_flower_mini_absorbation]:af_bla_bla_bla_absorbation&lt;br /&gt;
 telepatic_immunity 		= 0.01&lt;br /&gt;
&lt;br /&gt;
Не пробовал но должно работать =)&lt;br /&gt;
&lt;br /&gt;
В итоге если создать для каждого артефакта 3 можно и больше дублей и добавить их все в аномалии и торговлю то сложится впечатление что каждый конкретный артефакт может быть разным.&lt;br /&gt;
&lt;br /&gt;
--[[Участник:Rekongstor|Rekongstor]] 11:30, 13 января 2011 (UTC)&lt;br /&gt;
Я смотрю на &lt;br /&gt;
это и предлагаю сделать кое-что. Ведь есть возможность записи в консоль параметров и в итоге можно сделать для каждого артефакта свой разброс параметров. &lt;br /&gt;
&lt;br /&gt;
Автор: [[Участник:WincentDark69|WincentDark69]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Конфигурационные_файлы]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Обсуждение:Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-13T11:23:40Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;А тут обсуждаем статью.&lt;br /&gt;
&lt;br /&gt;
Любопытно было бы  узнать, а чем автора InfoScripts не устраивает запись в pstor? Если, конечно, он он вообще знает об этом.&lt;br /&gt;
Запись &lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if xr_logic.pstor_retrieve(db.actor, &amp;quot;first_spawn&amp;quot;, 0)==0 then&lt;br /&gt;
тут что делаем&lt;br /&gt;
xr_logic.pstor_store(db.actor, &amp;quot;first_spawn&amp;quot;, 1)&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
прекрасно заменяет инфопоршни. И pstor вообще достаточно удобное место для хранения своих данных.&lt;br /&gt;
&lt;br /&gt;
'''Erlik'''&lt;br /&gt;
&lt;br /&gt;
в общем-то да. про pstor знаю. упростить можно. тем не менее сами инфоскрипты можно бы было попробовать использовать не только в качестве &amp;quot;заглушек&amp;quot;, но и для диалогов, а то и для квестов попробовать.&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-10T12:19:51Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
* Ещё сейчас начну проверку по АМК скриптам. Там вроде что-то тоже упоминалось про сохранение и загрузку переменных.&lt;br /&gt;
-----&lt;br /&gt;
* Проверил АМК скрипты. Там присутствует загрузка переменных, но, в основном, роль у них одна - сохранение какой-нибудь стадии для скриптовых событий (выброса) или простое присваивание скриптам значения, которое должно сохраниться. У инфоскриптов, я бы сказал, аналогичное действие, но другая функция. Они существуют заместо стандартных инфопоршней и должны контролировать и облегчать создание диалогов и заданий, контролировать выдачу статей энциклопедии или простого каких-то действий, схожих с перечисленными.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]] ~19:30-22:54, 9 января 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-10T12:19:19Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
* Ещё сейчас начну проверку по АМК скриптам. Там вроде что-то тоже упоминалось про сохранение и загрузку переменных.&lt;br /&gt;
-----&lt;br /&gt;
* Проверил АМК скрипты. Там присутствует загрузка переменных, но, в основном, роль у них одна - сохранение какой-нибудь стадии для скриптовых событий (выброса) или простое присваивание скриптам значения, которое должно сохраниться. У инфоскриптов, я бы сказал, аналогичное действие, но другая функция. Они существуют заместо стандартных инфопоршней и должны контролировать и облегчать создание диалогов и заданий, контролировать выдачу статей энциклопедии или простого каких-то действий, схожих с перечисленными.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]] ~20:13-22:54, 9 января 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-10T12:18:08Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
* Ещё сейчас начну проверку по АМК скриптам. Там вроде что-то тоже упоминалось про сохранение и загрузку переменных.&lt;br /&gt;
-----&lt;br /&gt;
* Проверил АМК скрипты. Там присутствует загрузка переменных, но, в основном, роль у них одна - сохранение какой-нибудь стадии для скриптовых событий (выброса) или простое присваивание скриптам значения, которое должно сохраниться. У инфоскриптов, я бы сказал, аналогичное действие, но другая функция. Они существуют заместо стандартных инфопоршней и должны контролировать и облегчать создание диалогов и заданий, контролировать выдачу статей энциклопедии или простого каких-то действий, схожих с перечисленными.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]] --[[Участник:Rekongstor|Rekongstor]] 12:18, 10 января 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-10T12:14:16Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: /* Дополнения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
* Ещё сейчас начну проверку по АМК скриптам. Там вроде что-то тоже упоминалось про сохранение и загрузку переменных.&lt;br /&gt;
-----&lt;br /&gt;
* Проверил АМК скрипты. Там присутствует загрузка переменных, но, в основном, роль у них одна - сохранение какой-нибудь стадии для скриптовых событий (выброса) или простое присваивание скриптам значения, которое должно сохраниться. У инфоскриптов, я бы сказал, аналогичное действие, но другая функция. Они существуют заместо стандартных инфопоршней и должны контролировать и облегчать создание диалогов и заданий, контролировать выдачу статей энциклопедии или простого каких-то действий, схожих с перечисленными.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-10T12:13:58Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: /* Дополнения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
* Ещё сейчас начну проверку по АМК скриптам. Там вроде что-то тоже упоминалось про сохранение и загрузку переменных.&lt;br /&gt;
* Проверил АМК скрипты. Там присутствует загрузка переменных, но, в основном, роль у них одна - сохранение какой-нибудь стадии для скриптовых событий (выброса) или простое присваивание скриптам значения, которое должно сохраниться. У инфоскриптов, я бы сказал, аналогичное действие, но другая функция. Они существуют заместо стандартных инфопоршней и должны контролировать и облегчать создание диалогов и заданий, контролировать выдачу статей энциклопедии или простого каких-то действий, схожих с перечисленными.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-10T10:37:01Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: /* Дополнения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
* Ещё сейчас начну проверку по АМК скриптам. Там вроде что-то тоже упоминалось про сохранение и загрузку переменных.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-09T20:12:45Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию (на проверке ключи и другие, если найду и эти не помогут set_article_key и set_article_id)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
* Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
* То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
* Сейчас появилась возможность, что выдать статью возможно - произвёл поиск по всем скриптам по article. Нашёл set_article_key и set_article_id. Буду пробовать.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-09T20:07:47Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: /* Различия и сходства Infoportion и Infoscript */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость - за основу dialog_manager.script) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость за основу task_manager.script)&lt;br /&gt;
** Не может выдать статью в энциклопедию&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-09T20:03:19Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Дополнения==&lt;br /&gt;
Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
То же самое и для заданий! Скорее всего, можно будет использовать некоторые возможности task_maneger.script, чтобы занести задание в КПК.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-09T20:01:21Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
==Дополнения==&lt;br /&gt;
Возможно, получится создать аналог диалогу с помощью dialog_manager.script&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Обсуждение:Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-09T20:00:11Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;А тут обсуждаем статью.&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions</id>
		<title>Разбор Bind или новая замена Infoportions</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D0%B1%D0%BE%D1%80_Bind_%D0%B8%D0%BB%D0%B8_%D0%BD%D0%BE%D0%B2%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_Infoportions"/>
				<updated>2011-01-09T19:54:28Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание статьи==&lt;br /&gt;
В этой статье я расскажу о бинде объекта, о последовательности этапов класса бинда, о сохранении и загрузке переменных и на основе всех этих фактов, сделаю переменную, которая будет в некотором смысле напоминать инфопоршень.&lt;br /&gt;
&lt;br /&gt;
==Что такое Bind и как его используют?==&lt;br /&gt;
Итак, разберу сначала такую штуку, как bind. Для меня Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн. Не работает во время паузы. Итак, как же используется бинд? Начну с самых верхов. У нас есть какая-нибудь секция. По умолчанию там присутствует такая строка:&lt;br /&gt;
 '''script_binding'''&lt;br /&gt;
И она ничему не равна. Как бы сказали скрипты: nil. Но есть такие секции, которым присвоены определённые значения script_binding. Например:&lt;br /&gt;
&lt;br /&gt;
 '''[actor]''':common_ph_friction_params_on_npc_death&lt;br /&gt;
 GroupControlSection		= spawn_group&lt;br /&gt;
 $spawn 					= &amp;quot;actor&amp;quot;&lt;br /&gt;
 $ed_icon				= ed\ed_actor&lt;br /&gt;
 $player 				= on&lt;br /&gt;
 $prefetch 				= 16&lt;br /&gt;
 cform                   = skeleton&lt;br /&gt;
 class                   = O_ACTOR&lt;br /&gt;
 money					= 40;&lt;br /&gt;
 rank					= 3;&lt;br /&gt;
 &amp;lt;big&amp;gt;'''script_binding			= bind_stalker.actor_init'''&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Мы видим, что актор (собственно, сам Меченый или, если выражаться правильней, Главный Герой, ГГ) имеет скриптовый бинд. Теперь люди, знакомые со скриптом bind_stalker, могли заметить там функцию:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Разберём её. Прямо с первой строки.&lt;br /&gt;
* '''actor_init''' - название функции&lt;br /&gt;
* '''npc''' - тот объект, у которого в секции имеется script_binding, будет каждый раз при переходе в онлайн, биндиться тем самым скриптом, указаным в script_binding. Т.к. всё вертится вокруг актора, то получается так, что актор всегда в онлайне, не считая его удаления (при выходе/перезагрузке или при переходе на др. локацию)&lt;br /&gt;
Вторая строка:&lt;br /&gt;
* '''bind_object''' - т.к. npc уже обсуждали, то скажу так: объект, получаемый скриптом через скриптовый бинд (на выходе '''npc''') является объектом, к которому обращение идёт через двоеточие ('''game_object*'''). Например, можно написать npc:position(). Для примера можно вставить такой код:&lt;br /&gt;
&amp;lt;lua&amp;gt;function actor_init    (npc)&lt;br /&gt;
	get_console():execute(npc:game_vertex_id())&lt;br /&gt;
	npc:bind_object(actor_binder(npc))&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
Я его не проверял, но, по идее, он должен вывести в консоль текущий гейм-вертекс актора. Будет это выглядеть как-то так:&lt;br /&gt;
 '''! Unknown command:  666'''&lt;br /&gt;
Это так будет, если гейм-вертекс актора будет аццкий - '''666'''.&lt;br /&gt;
&lt;br /&gt;
Итак... С обращением разобрались. Теперь разберём само обращение '''bind_object'''. Это обращение зашито в dll (скорее всего, в xrGame) и про него можно посмотреть в скрипте lua_help.script:&lt;br /&gt;
&amp;lt;c&amp;gt;function bind_object(object_binder*);&amp;lt;/c&amp;gt;&lt;br /&gt;
Сразу перейдём к следующим после bind_object словам, не забывая про '''object_binder*''' из lua_help.script&lt;br /&gt;
* '''actor_binder(npc)''' - это то, с помощью чего мы обращаемся. Если поднапряжёмся и вспомним, что было друмя строками выше, то поймём, что '''actor_binder(npc)''' - это и есть '''object_binder*'''. Но это не полное объяснение. Ещё надо добавить, что actor_binder - это класс в том же скрипте - bind_stalker, который носит назввание '''''actor_binder'''''. Как же он выглядит, это класс бинда:&lt;br /&gt;
&amp;lt;lua&amp;gt;class &amp;quot;actor_binder&amp;quot; (object_binder)&amp;lt;/lua&amp;gt;&lt;br /&gt;
А npc в скобках - это object_binder, который указан в скобках класса. &lt;br /&gt;
 &amp;quot;actor_binder&amp;quot; ('''object_binder''')&lt;br /&gt;
&lt;br /&gt;
Итак, мы разобрали построчно функцию '''actor_init''', но ещё не знаем, чем же различаются класс actor_binder и функция actor_init, начинающая этот бинд. Так вот в чём различия:&lt;br /&gt;
* actor_binder - это класс, который постоянно повторяется (биндится)&lt;br /&gt;
* actor_init - это вызываемая из секции конфига функция, которая начинает бинд, но она выполняется только один раз - при переходе объекта в онлайн и ждёт перехода объекта в режим офлайн или удаления этого объекта из игры. После того, как объект пропадает, функция отключается и при его следующем появлении в онлайне, выполняется снова.&lt;br /&gt;
&lt;br /&gt;
Но и бинд не длится вечно. Как я уже говорил, ''Bind - это повторение одного и того же действия в режиме alife (во время игры), производимого для определённого объекта, пока он не перейдёт в офлайн.'' Сам переход в офлайн происходит через net_destroy. Это я называю функцией класса. Теперь рассмотрим работу функций класса.&lt;br /&gt;
&lt;br /&gt;
 Я пока только начал подробное изучение биндеров и могу ошибиться в порядке выполнения функций класса типа bind. &lt;br /&gt;
 Тем не менее, у меня уже есть свой порядок выполнения функций класса bind.&lt;br /&gt;
* Сначала выполняется __init.&lt;br /&gt;
* Заетм идёт, load. Если сохранялись какие-то изменения.&lt;br /&gt;
* Потом происходит net_spawn&lt;br /&gt;
* Потом идёт update - бинд.&lt;br /&gt;
* Потом при сохранении происходит save.&lt;br /&gt;
* Затем net_destroy при офлайн переходе.&lt;br /&gt;
* Потом по идее net_spawn и reinit. Дальше всё с третьего шага (не уверен, что второй шаг тоже пропускается)&lt;br /&gt;
&lt;br /&gt;
На этапе net_destroy и net_spawn происходит множество других функций класса bind вроде take_item_from_box (колбэк на взятие предмета в инвентарь из inventory_box - тайника), on_item_drop (колбэк при выбрасывании предмета) и т.п. Тем не менее, некоторые функции класса (кроме главных, которые я перечислял в этапах) могут быть использованы на других этапах, но на update обычно происходят проверки. Не буду сейчас останавливаться на колбэках и перейду к следующему этапу - разбор сохранения.&lt;br /&gt;
&lt;br /&gt;
==Разбор сохранений==&lt;br /&gt;
&lt;br /&gt;
На самом деле сохранения я буду разбирать прямо сейчас. очень хочу что-нибудь полегче. Например, treasure_manager.&lt;br /&gt;
Посмотрим, что тут у нас...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;function CTreasure:save(p)&lt;br /&gt;
	--' Сохраняем размер таблицы&lt;br /&gt;
	local size = 0&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		size = size + 1&lt;br /&gt;
	end&lt;br /&gt;
	p:w_u16(size)&lt;br /&gt;
	for k,v in pairs(self.treasure_info) do&lt;br /&gt;
		p:w_u16(v.target)&lt;br /&gt;
		p:w_bool(v.active)&lt;br /&gt;
		p:w_bool(v.done)&lt;br /&gt;
	end&lt;br /&gt;
end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По идее это save сохраняет всю указанную информацию объекте в sav файл сохранения в виде нет-пакета. Судя по некоторым строкам, которые, по идее могут кое-что прояснять... Особенно при вылете :) Например, &amp;quot;SAVE FILE IS CORRUPT&amp;quot;. Что же, попробую теперь разобрать загрузку:&lt;br /&gt;
&amp;lt;lua&amp;gt;--' Загружаем уровень сложности&lt;br /&gt;
local game_difficulty = reader:r_u8()&lt;br /&gt;
local load_treasure_manager = false      &lt;br /&gt;
if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
	game_difficulty = game_difficulty - 128&lt;br /&gt;
	load_treasure_manager = true           &lt;br /&gt;
end                                      &lt;br /&gt;
get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут явная загрузка уровня сложности. Слишком явная, судя по комментарию... Хватит лирики...  Разбираем!&lt;br /&gt;
* Сначала задаём переменной game_difficulty одну из переменных пакета. В данном случае переменная числовая.&lt;br /&gt;
* Присваиваем переменной load_treasure_manager булёвое (логическое) значение false.&lt;br /&gt;
* Проверяем, что если game_difficulty больше или равен 128, то:&lt;br /&gt;
** Вычитаем из game_difficulty 128&lt;br /&gt;
** Присваиваем переменной load_treasure_manager значение true&lt;br /&gt;
* Устанавливаем через консоль уровень сложности.&lt;br /&gt;
&lt;br /&gt;
Потом можно заметить:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
if load_treasure_manager == true then&lt;br /&gt;
	treasure_manager.load(reader)      &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это значит, что в будущем переменная load_treasure_manager будет играть особенную роль. По идее она отвечает за загрузку менеджера тайников. Точное значение сказать не смогу.&lt;br /&gt;
&lt;br /&gt;
Итак, какие же значения можно присваивать пакетным данным? Об этом сказано в ранее упоминаемом скрипте lua_help.script. А там... Лучше не буду писать, а то места много надо. Сами посмотрите. Я укажу лишь несколько значений:&lt;br /&gt;
* Булёвое. '''r_bool''' и '''w_bool'''&lt;br /&gt;
* Строковое. '''r_stringZ''' и '''w_stringZ'''&lt;br /&gt;
* Числовое. '''r_u8''' и '''w_u8'''&lt;br /&gt;
 Я не знаю точно, можно ли ставить (плавающую) запятую в числе, поэтому лучше берите целые числа где-то в области от -10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; до 10&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Практика==&lt;br /&gt;
&lt;br /&gt;
Итак. Теперь попробую попрактиковаться... Вы со мной... для начала изменим функции класса bind с именами до такого вида (полностью заменяйте текст функции, которую я вам даю:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:net_spawn(data)&lt;br /&gt;
	printf(&amp;quot;actor net spawn&amp;quot;)		&lt;br /&gt;
&lt;br /&gt;
	level.show_indicators()&lt;br /&gt;
&lt;br /&gt;
	self.bCheckStart = true&lt;br /&gt;
	self.weapon_hide = false -- спрятано или нет оружие при разговоре.&lt;br /&gt;
	weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.&lt;br /&gt;
&lt;br /&gt;
	if object_binder.net_spawn(self,data) == false then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	db.add_actor(self.object)&lt;br /&gt;
	&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		level.enable_input()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.weather_manager:reset()&lt;br /&gt;
--	game_stats.initialize ()&lt;br /&gt;
&lt;br /&gt;
	if(actor_stats.add_to_ranking~=nil)then&lt;br /&gt;
		actor_stats.add_to_ranking(self.object:id())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем настройки дропа&lt;br /&gt;
	death_manager.init_drop_settings()&lt;br /&gt;
	&lt;br /&gt;
	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Лучше редактировать сначала load, а потом save, т.к. по любому сначала идёт загрузка...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:load(reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.load(self, reader)&lt;br /&gt;
	printf(&amp;quot;actor_binder:object_binder.load(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
&lt;br /&gt;
	--' Загружаем уровень сложности&lt;br /&gt;
	local game_difficulty = reader:r_u8()&lt;br /&gt;
	&lt;br /&gt;
	local load_treasure_manager = false      &lt;br /&gt;
	if game_difficulty &amp;gt;= 128 then           &lt;br /&gt;
		game_difficulty = game_difficulty - 128&lt;br /&gt;
		load_treasure_manager = true           &lt;br /&gt;
	end                                      &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	get_console():execute(&amp;quot;g_game_difficulty &amp;quot;..game_difficulty_by_num[game_difficulty])&lt;br /&gt;
&lt;br /&gt;
	if reader:r_eof() then&lt;br /&gt;
		abort(&amp;quot;SAVE FILE IS CORRUPT&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stored_input_time = reader:r_u8()&lt;br /&gt;
	if stored_input_time == true then&lt;br /&gt;
		self.st.disable_input_time = utils.r_CTime(reader)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_load_all(self.object, reader)&lt;br /&gt;
	self.weather_manager:load(reader)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.load(reader)&lt;br /&gt;
	&lt;br /&gt;
	if load_treasure_manager == true then&lt;br /&gt;
		treasure_manager.load(reader)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	task_manager.load(reader)&lt;br /&gt;
	self.actor_detector:load(reader)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
А теперь save:&lt;br /&gt;
&amp;lt;lua&amp;gt;&lt;br /&gt;
function actor_binder:save(packet)&lt;br /&gt;
	&lt;br /&gt;
	local save_treasure_manager = true&lt;br /&gt;
	&lt;br /&gt;
	printf(&amp;quot;actor_binder:save(): self.object:name()='%s'&amp;quot;, self.object:name())&lt;br /&gt;
	object_binder.save(self, packet)&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем уровень сложности&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty() + 128)&lt;br /&gt;
	else&lt;br /&gt;
		packet:w_u8(level.get_game_difficulty())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--' Сохраняем данные об отключенном вводе&lt;br /&gt;
	if self.st.disable_input_time == nil then&lt;br /&gt;
		packet:w_bool(false)&lt;br /&gt;
	else&lt;br /&gt;
		packer:w_bool(true)&lt;br /&gt;
		utils.w_CTime(packet, self.st.disable_input_time)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--' save по-любому будет после новой игры. поэтому переменная у нас будет либо дефолтная (при net_spawn), либо загруженная (при load)&lt;br /&gt;
	packet:w_bool(db.storage[&amp;quot;rekongstor_boolean&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
	xr_logic.pstor_save_all(self.object, packet)&lt;br /&gt;
	self.weather_manager:save(packet)&lt;br /&gt;
&lt;br /&gt;
	sr_psy_antenna.save( packet )&lt;br /&gt;
	&lt;br /&gt;
	if save_treasure_manager == true then&lt;br /&gt;
		treasure_manager.save(packet)      &lt;br /&gt;
	end                                  &lt;br /&gt;
&lt;br /&gt;
	task_manager.save(packet)&lt;br /&gt;
	self.actor_detector:save(packet)	&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Я специально оставил комментарии, чтобы было легче разобраться в действиях. А теперь объяснения:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;lua&amp;gt;	--' проходит прежде всего. если данных в пакете нет, то по идее должен быть nil&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = reader:r_bool()&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут происходит загрузка данных из сохранённого пакета в переменную, которая существует на протяжении игры. Точно не знаю, когда она прерывается, но это не имеет особого значения.&lt;br /&gt;
&lt;br /&gt;
* Я не уверен, но сначала происходит load. Если он не нашёл данные в пакете, то они равны nil. В этом случае переменная принимает данные из пакета.&lt;br /&gt;
* Load может и не происходить, но и так данные будут равны nil, потому что им ничто не присвоено. А в этом случае просто load не происходит и переменная никак не трогается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lua&amp;gt;	--' В случае новой игры у нас этой переменной не будет. Иначе она загрузится из load&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == nil then&lt;br /&gt;
	db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if db.storage[&amp;quot;rekongstor_boolean&amp;quot;] == true then&lt;br /&gt;
		alife():create(&amp;quot;af_medusa&amp;quot;,vector():set(0,0,0),1,1,self.object:id())&lt;br /&gt;
		db.storage[&amp;quot;rekongstor_boolean&amp;quot;] = false&lt;br /&gt;
	end&amp;lt;/lua&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала происходит Load, но его я уже объяснил. Сейчас я объясняю net_spawn.&lt;br /&gt;
&lt;br /&gt;
Первое действие - проверка на существование переменной. Если мы начали новую игру, то тогда переменная равна nil, т.к. load её ещё не знает и мы её ещё не объявляли. А если переменной не существует, то мы ей объявляем значение true и она уже не nil, а принимает логическое значение.&lt;br /&gt;
&lt;br /&gt;
Второе действие. Если у переменной логическое значение равно true, то спавним артефакт медуза в инвентарь ГГ и объявляем значение false. Если было значение false, то не спавним. Как это работает? &lt;br /&gt;
* Мы начали новую игру&lt;br /&gt;
* ''(Возможно, идёт загрузка пакета и переменной, которая имеет значение nil. Мы опять присваиваем значение nil, т.е. ничего не меняется.)''&lt;br /&gt;
* Идёт проверка. Т.к. переменная = nil, то ей присваивается true.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = true, То спавним артефакт (а вообще, можно произвести любое действие) и '''присваиваем переменной значение false'''&lt;br /&gt;
*** Больше ничего  не происходит - т.е. идёт бинд update&lt;br /&gt;
* Мы сохраняем игру (переходим на др. уровень)&lt;br /&gt;
* Идёт сохранение всех переменных, в том числе и нашей, а она равна false&lt;br /&gt;
&lt;br /&gt;
* Загружаем игру (загрузка др. уровня)&lt;br /&gt;
* Идёт загрузка пакета и переменной, которая имеет значение nil. Мы присваиваем значение false, т.е. то, которое было сохранено.&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, то ей ничего нового не присваивается (действие присваивания пропускается)&lt;br /&gt;
* Идёт проверка. Т.к. переменная = false, игра обходит действие и не происходит спавна и присвоения переменной false.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вот и всё. У меня скрипт нормально работает и спавнится только один артефакт. А теперь спросите, зачем это нужно? Значит вспоминаем не любимые многими модмейкерами инфопоршни. Именно с ними многие мучались при создании квестов. Сейчас я буду пробовать использование этих новых переменных, которым я пока дал название Info_Scripts в различных направлениях. Сейчас я знаю, что инфопоршни можно использовать с диалогами, квестами, энциклопедией и самими скриптами. В данном примере мы рассмотрели запрет на повторение действия без инфопоршня, но это было намного сложнее, нежели если бы мы создали инфопоршень. Тем не менее, это подробный разбор для отдельного случая. В последующих изменениях будет улучшена система выдачи этого добра и будет всё упрощено, в лучшем случае, до одной строчки. Но сначала надо создать скрипт, обрабатывающий всю эту информацию.&lt;br /&gt;
&lt;br /&gt;
==Различия и сходства Infoportion и Infoscript==&lt;br /&gt;
Чем отличается Infoportion от Infoscript:&lt;br /&gt;
* Получается из xml файла&lt;br /&gt;
* Относительно лёгкое использование в диалогах&lt;br /&gt;
* Относительно лёгкое использование в стандартных заданиях&lt;br /&gt;
* Помимо булёвых значений, может содержать информацию для выдачи статьи энциклопедии и/или задания&lt;br /&gt;
* Сложное использование в нестандартных заданиях, но есть возможность диалогов&lt;br /&gt;
&lt;br /&gt;
Чем отличается Infoscript от Infoportion:&lt;br /&gt;
* Получается из переменной скрипта&lt;br /&gt;
* Помимо булёвого значения, может принимать строковые и числовые&lt;br /&gt;
* '''Дальше не проверенная, но теоретически возможная информация:'''&lt;br /&gt;
** Сложное использование в диалогах (изучается сложность, направление на лёгкость) или лёгкий аналог&lt;br /&gt;
** Сложное использование в стандартных заданиях (изучается сложность, направление на лёгкость)&lt;br /&gt;
* Относительно лёгкое (при использовании упрощённого скрипта) использование при создании нестандартных квестов, но диалоги, скорее всего, придётся заменить&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В чём их сходства?&lt;br /&gt;
* Оба могут использоваться в качестве булёвого значения&lt;br /&gt;
* Оба загружаются из файла сохранения (обычная переменная на такое не способна)&lt;br /&gt;
* Оба могут использоваться в нестандартных заданиях&lt;br /&gt;
* Оба могут использоваться в стандартных заданиях и диалогах&lt;br /&gt;
&lt;br /&gt;
===Проблема со стандартными заданиями и диалогами===&lt;br /&gt;
Есть такие теги, как infoportion_complete и infoportion_fail. Они оба обращаются к отдельно взятому инфопоршню. В диалогах почти также - has_info и dont_has_info. Это всё проверки на существование у игрока инфопоршня. Если такой будет, то задание либо выполняется, либо проваливается. Диалог/реплика либо присутствует, либо отсутствует. Но есть и такие теги, как precondition. Он, если вернёт false, то диалог или его реплика будут отсутствовать, если true, то наоборот. В заданиях теги такие - function_complete и function_fail. Они отвечают за возвращение функции true и false. При выполнении условий (возвращение функцией true), задание выполняется или, соответственно, проваливается. Но они обращаются лишь к функции, а вот какой инфоскрипт мы хотим взять, он умалчивает. Поэтому, пока придётся обходиться проверкой наличия инфоскрипта отдельно - через конкретное содержание функции. Но я попробую найти зацепки у диалогов и/или заданий, через которые можно получить уникальную информацию и послать её в функцию. Но это уже мои проблемы.&lt;br /&gt;
&lt;br /&gt;
===Что такое нестандартные задания?===&lt;br /&gt;
Это задания, которые регулируются через скрипт. О них я напишу в виде продолжения к этой статье. Они будут использоваться по такому типу:&lt;br /&gt;
* Мы в зоне выдачи задания?&lt;br /&gt;
* Мы согласились на выполнение задания?&lt;br /&gt;
* Нам выдали задание?&lt;br /&gt;
* Мы в зоне выполнения подзадания / у нас есть предмет для выполнения подзадания?&lt;br /&gt;
* Мы выполнили подзадание?&lt;br /&gt;
* Мы в зоне выполнения задания? &lt;br /&gt;
* Наше подзадание выполнено?&lt;br /&gt;
* Закончить выполнение задания.&lt;br /&gt;
** Выдать награду в виде денег, ранга или любой другой вещи, которые можно придумать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
В общем, у него есть свои плюсы. Например, можно легче сделать задание проверки определённого места в игре. Но минус один и причём большой. Нестандартные задания не могут занестись в КПК и отображаться при нажатии TAB. Но можно ставить метки на карты или, хотя бы, выводить информацию о задании в виде диалоговых окон или сноске на худ, что уже является неплохим утешением. Т.е. можно попробовать придумать специальный предмет, который собирает нестандартные задания и умеет с ними обращаться (например, выносить суть подквеста в худ). &lt;br /&gt;
&lt;br /&gt;
===Заключение===&lt;br /&gt;
Тем не менее, и тут у каждого свои плюсы и, чтобы вывести это новую небольшую технологию об использования инфоскриптов и нестандартных заданий на новый уровень развития, сократить разрыв с привычными инфопоршнями или вовсе обогнать их, придётся ещё поработать, повторить или узнать многие вещи, создать сложные скрипты, которые на выходе дают возможность обращения к ним лишь одной командой, придумать аналоги, вроде нестандартных квестов и получить обширное использование этой упрощённой технологии среди модмейкеров, а если повезёт, то и у разработчиков.&lt;br /&gt;
&lt;br /&gt;
Ждите новых статей по инфоскриптам!&lt;br /&gt;
&lt;br /&gt;
'''Я думаю, что эта статья достойна [[Обсуждение:Разбор Bind или новая замена Infoportions|обсуждения]]!'''&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
 '''Скрипт bind_stalker с одиночной выдачей &amp;quot;Медузы&amp;quot;'''&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.rar *.RAR (4087 Б)]&lt;br /&gt;
 [http://intreface.narod.ru/bind_stalker.script *.SCRIPT (15476 Б)]&lt;br /&gt;
&lt;br /&gt;
==Автор==&lt;br /&gt;
[[Участник:Rekongstor|Rekongstor]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:A-Life</id>
		<title>Категория:A-Life</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:A-Life"/>
				<updated>2011-01-09T14:44:37Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В данной категории содержатся статьи о работе с системой симуляции жизни A-Life.&lt;br /&gt;
&lt;br /&gt;
Основная статья [[Логика_NPC|Логика NPC]]&lt;br /&gt;
[[Категория:Конфигурационные_файлы]]&lt;br /&gt;
[[Категория:Скрипты]]&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:56:30Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
-----&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;br /&gt;
-----&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:56:18Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
-----&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:56:02Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
-----&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
-----&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:54:34Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
-----&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;br /&gt;
-----&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:54:00Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:53:51Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:53:30Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:120%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:53:20Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#000000&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:53:11Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEEEE;color:#FFFFFF&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:53:04Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#EEEED1;color:#FFFFFF&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:52:21Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000;color:#FFFFFF&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:51:39Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000;color:#FFFFFF&amp;quot;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:51:26Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000|black (0 0 0);color:#FFFFFF&amp;quot;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:51:15Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000&amp;quot;|black (0 0 0);color:#FFFFFF&amp;quot;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:51:06Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000&amp;quot;|black (0 0 0);&amp;quot;color:#FFFFFF&amp;quot;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:50:29Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000&amp;quot;|black (0 0 0)|&amp;quot;color:#FFFFFF&amp;quot;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:49:42Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000&amp;quot;|black (0 0 0) &amp;quot;color:#FFFFFF&amp;quot;&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:48:50Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#000000&amp;quot;|black (0 0 0)&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	<entry>
		<id>http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor</id>
		<title>Участник:Rekongstor</title>
		<link rel="alternate" type="text/html" href="http://stalkerin.gameru.net/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Rekongstor"/>
				<updated>2011-01-09T11:48:10Z</updated>
		
		<summary type="html">&lt;p&gt;Rekongstor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Моё резюме:==&lt;br /&gt;
&lt;br /&gt;
Лучше буду говорить, что я не умею:&lt;br /&gt;
{||border=0 cellpadding=&amp;quot;3&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:89%;text-align:left;line-height:1em;width:98%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;background-color:#828282;color:#FFFFFF&amp;quot;|&lt;br /&gt;
* Gulag_... - не пробовал серьёзно работать с ними. &lt;br /&gt;
* Слабые знания net_packet&lt;br /&gt;
* .efd&lt;br /&gt;
* Пока не делал персонажей (3ds max)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Rekongstor</name></author>	</entry>

	</feed>