В этой теме на конкретных примерах (Уроках) разбирается весь процесс создания мода.
Правила работы в теме: Любой пользователь обладающий опытом и знаниями в модостроение, создает урок по определенной теме (отражено в задаче урока), после этого описывает выполнение поставленной задачи в виде отдельного файла и (или) напрямую в своем посте спрятав его под спойлер. В дополнении к уроку желательно выложить содержимое папки gamedata с выполненным уроком, чтобы пользователь скачав его мог проверить правильность выполнения урока самостоятельно. Обсуждение уроков ведется в теме: "Общие вопросы модостроения". Также в данной теме могут быть размещены дополнительные материалы помогающие пользователю освоить все аспекты модостроения.
1. Заголовок сообщения из которого понятно назначение поста (Урок, Справочная информация или другое) 2. Если это урок то он должен иметь четко обозначенную задачу и желательно иметь ссылку на файл с выполненным уроком, для того чтобы выполняющие его могли скачать и посмотреть выполнение урока на примере. 3. Придерживайтесь устоявшейся цветовой схемы: а) Путь к файлу и (или) имя файла - Зеленый б) Имя параметра, функции и т.п. в файле - Желтый в) Не рекомендуется использовать оранжевый - это цвет комментариев кураторов раздела и к тому же близок к цвету ссылок. 4. Куски кодов и конфигурационных файлов обязательно помещайте в контейнер
Код
Исходный текст файла
. 5. Выделение текста изменением размера шрифта, его типом на усмотрение автора, главное не перебарщивать.
Тема предназначена только для публикации уроков и справочной информации, вопросы в другой теме! Посты не отвечающие данному требованию будут перенесены в соответствующую тему или удалены!
Первое с чем сталкивается любой, кто решил модифицировать STALKER'а, будь это небольшая правка конфигурационных файлов или создание глобального мода - это распаковка игры. Поэтому первым делом рассмотрим распаковщики игры.
1. S.T.A.L.K.E.R Universal Extractor v1.2
Это универсальный распаковщик для ТЧ, ЧН, ЗП (включая патч v1.6.02). Программа полностью автоматизированна: достаточно указать что вы желаете распаковать (ТЧ, ЧН, ЗП) и директорию игры. Распакованные архивы появляются в корне игры в папке UEgamedata (с целью предотвращения замены файлов, если у вас уже есть папка gamedata).
Если же нет необходимости распаковывать всю игру, а только один из db-файлов, можно воспользоваться одним из следующих инструментов:
2. S.T.A.L.K.E.R. Data Unpacker v1.0
Это распаковщик ТЧ. Программа проста в использовании, указываем db-файл и каталог для распаковки, запускаем и все.
3. ClearSky unpacker v1.3
Данный распаковщик предназначен для ЧН и ЗП. Работа с программой осуществляется из командной строки, однако более удобным является использование bat-файлов.
Итак, кидаем файлы из архива (converter.exe, Microsoft.VC80.CRT.manifest, msvcp80.dll, msvcr80.dll) в корень игры, создаём bat-файл, например unpack.bat, следующего содержания:
помещаем его туда же и запускаем. Распакованные файлы будут помещены в папку gamedata_unpack (также с целью предотвращения замены файлов, если папка gamedata уже имеется). Данный список архивов справедлив только для ЗП (в нём не перечисленны только архивы из каталога mp/), количество и наименование файлов например для ЧН будет другим, а при установке патчей появятся дополнительные архивы. Состав архивов также зависит от версии игры, например в английской версии (в том числе пиратках с русским текстом) в отличие от полностью русской версии (от GSC/1C) будет дополнительный архив, и в батник необходимо добавить еще одну строку
При распаковке патчей следует иметь в виду что в них файлы более новые, поэтому и их распаковка должна происходить позже, то есть строка с командой для распаковки патча, должна стоять ниже строк с командами распаковки основных архивов.
Если же нужно распаковать только один из архивов, оставляем в bat-файле только необходимые строки, например для распаковки только levels.db1, bat-файл должен содержать только 2-ю строку. Также при отдельной распаковке патчей и копировании их в каталог gamedata, необходимо подтвердить замену.
Вот и все, игра распакованна и все ресурсы игры доступны нам для редактирования, теперь все ограничивается лишь вашей фантазией и знаниями.
Будем рассматривать автоматическую установку, ибо не вижу смысла объяснять ручную. Открываем архив плагина из TC, просто нажимаем на архиве [Enter] и TC войдет в его внутренности. И сразу же предложит нам его установить, устанавливаем (стандартная папка подходит нормально "%COMMANDERPATH%\plugins\wcx\stalker\"). Далее перед нами выйдет окно "Файловые ассоциации" нажимаем ОК. Использование
Переходим в TC на какой нибудь gamedata архив и нажимаем стандартный хот-кей: [ctrl]+[PageDown] и мы уже в архиве (Мы можем открывать архивы ТЧ\ЧН\ЗП). Возможные действия внутри архива:
Инструкция 2. Адаптация модов
Одним из наиболее частых вопросов является просьба адаптировать тот или иной мод. Поэтому напишу небольшое объяснение как совместить один мод с другим. Рассмотрим, например, как установить Повелитель Зоны CoP v1.0 (далее ПЗ), предназначенный для чистого ЗП, на SGM 1.7.
Основной проблеммой при этом является то, что каждый из модов может содержать одни и теже модифицированные файлы, при замене которых часть функций может быть утерянна.
Итак, шаг 1. Мы имеем два каталога gamedata, перемещаем ПЗ в gamedata SGM, но без замены файлов. В результате из 14 файлов 10 оказались новыми и без проблем переместились, а 4 оказались модифицированными, с ними придется повозиться.
Шаг 2. Измененными у нас оказались gamedata\configs\ui\ui_mm_god_dlg.xml и sr_no_weapon.script, ui_main_menu.script, xr_conditions.script из каталога gamedata\scripts\
Берем первый файл game_tutorials.xml из SGM и тот же файл из ПЗ, открываем их с помощью программы WinMerge. Все изменения отмеченны цветом. Наша задача перенести все недостающее, либо согласовать то что измененно. Первое что мы видим - включение нового файла
Код
#include "ui\ui_mm_god_dlg.xml"
переносим данную команду в game_tutorials.xml из SGM. Следующие изменения видим в <intro_logo>, это ролики, которые мы видим при старте игры, они нам вообще не интересны, поэтому не будем их переносить.
Далее sr_no_weapon.script. Здесь мы видим что все внутренности функций action_no_weapon:switch_state(), action_no_weapon:zone_enter(), action_no_weapon:zone_leave(), и частично action_no_weapon:update() просто удаленны. Грубо конечно, но эффективно, поступим также.
Смотрим ui_main_menu.script и находим изменения в функциях main_menu:OnButton_load_clicked() и main_menu:OnKeyboard(), вносим их, то есть добавляем
Код
if dik == DIK_keys.DIK_F1 then ... end
и
Код
god.key_binder(dik, keyboard_action, self)
Но, в SGM F1 уже используется, поэтому для вызова ПЗ используем другую клавишу, например F6. Ну и наконец, проделываем то же с xr_conditions.script
Вот и все, хотя освещены далеко не все проблеммы, которые могут возникнуть, но если включить мозги, все легко решается. Главное проявить терпение, и желательно не ошибаться и не путаться в файлах.
Несколько "полезностей" и "удобностей" (автор Andrew53, tracker, denis2000, XOBAH)
Мы хотим не дёргать файл меню, а сложить обработчики клавиш в свой скриптовый файл. Заходим в каталог \gamedata\scripts\ и создаём там файл sh.script В этот файл добавляем три функции для обработки клавиш f6, f7, f8.
Код
function for_ui_main_menu_f6() end function for_ui_main_menu_f7() end function for_ui_main_menu_f8() end
В эти заготовки можно воткнуть любые функции. Например спавна:
Код
function for_ui_main_menu_f6() create("zat_sh_nikitka_skadovsk",db.actor:position().x+3,db.actor:position().y,db.actor:position().z,db.actor:level_v ertex_id() ,d b.actor:game_vertex_id()) end function for_ui_main_menu_f7() give_object_to_actor("repair_arms_box") give_object_to_actor("guidebook_mono") end function for_ui_main_menu_f8() give_object_to_actor("medkit_elite") give_object_to_actor("wpn_gauss") end
Теперь дело за малым. Надо прописать эти функции в файл меню. Открываем его, находим:
Код
elseif db.actor~=nil and dik==DIK_keys.DIK_F5 then self:mod_options()
и ниже добавляем:
Код
elseif db.actor~=nil and dik==DIK_keys.DIK_F6 then sh.for_ui_main_menu_f6() elseif db.actor~=nil and dik==DIK_keys.DIK_F7 then sh.for_ui_main_menu_f7() elseif db.actor~=nil and dik==DIK_keys.DIK_F8 then sh.for_ui_main_menu_f8()
Обратите внимание, что перед названием функции стоит имя файла, в котором она расположена, а разделяет их точка.
полне возможно, некоторые из вас, просматривая ui_main_menu.script в SGM, видели вызов функции waypoint_editor() (по клавише W, при входе в игру с параметром -test). Эта функция привлекательна тем, что может существенно облегчить работу начинающим и не очень мододелам.
Например, нам необходимо создать путь для патруля (см. урок 5 в КМБ). Что для этого необходимо, конечно же координаты точек. Теперь получить их стало действительно легко. Итак, нажимаем ESC-W (запущенной в режиме -test), записываем точку, идем дальше, и повторяем запись, столько, сколько нам необходимо точек. Выходим из игры и, в корне игры лежит файлик waypoint.txt, а в нем, координаты и вертексы каждой из записанных нами точек (следует только учесть, что для создания замкнутого пути, нужно вручную добавить в конце еще одну точку, иначе НПС, пройдя весь маршрут, просто остановится).
Естественно, как частный случай использования данной функции - снятие координат любой статичной точки, с записью их в файл.
*Ну и маленькое отступление. Чтобы функцию можно было вызвать в игре запущенной в обычном режиме просто перенесите её вызов выше, например сюда:
elseif dik==DIK_keys.DIK_W then --/Специальный редактор, точек путей. self.OnButton_return_game() sgm_flags.bool_is_ui_disabled=true run_dynamic_element(ui_mod_elements.waypoint_editor(),false)
end
Как найти персонажа, его диалоги и вооружение в огромной куче файлов? Давайте найдём Громобоя.
Открываем \gamedata\configs\text\rus\ с помощью TotalCommander. В этом каталоге лежат все (наши, человеческие) названия, имена и др. Жмём Alt-F7. Открывается окно поиска. Ставим галочку "С текстом" и в строке вводим Громобой. Находим один файл \gamedata\configs\text\rus\SGM_character_names.xml Открываем его и уже в нём ищем слово Громобой. Нашли.
id его имени jup_stalker_gromoboy_name. Значит живёт он на Юпитере, состоит в сталкерах. _name - говорит о том, что это - идентификатор имени. А мы знаем, что в секции после персонального id расписан id его имени. Все НПС расписаны в \gamedata\configs\gameplay\. Их файлы начинаются с character_desc_. Можно их все проверить, Alt-F7, "С текстом" и в строке вводим jup_stalker_gromoboy_name. Находим: \gamedata\configs\gameplay\character_desc_sgm.xml. Открываем нотепадом++ и ищем там jup_stalker_gromoboy_name. Находим:
Вот так мы можем найти любого НПС, изменить его инвентарь, визуал, логику и т.д.
Как найти определенный предмет? Давайте найдём Детектор «Велес».
Открываем \gamedata\configs\text\rus\ с помощью TotalCommander. Жмём Alt-F7. Открывается окно поиска. Ставим галочку "С текстом" и в строке вводим Велес. Находим несколько файлов. Открываем каждый и ищем уже в них нужный фрагмент. Приблизительно такой.
id его имени st_detector3. Теперь в папке \gamedata\configs\ Ищем файлы содержащие строку st_detector3 Находим: \gamedata\configs\misc\devices.ltx, вторым файлом окажется st_items_equipment.xml в котором мы и нашли идентификатор имени предмета. Открываем нотепадом++ и ищем там st_detector3 Находим:
Первое название секции выше inv_name = st_detector3 - это секция [detector_elite] и есть имя предмета по которому его можно положить в рюкзак или в тайник. Вот так мы можем найти любой предмет, изменить его параметры, визуал и т.д.
Часто возникает необходимость групповой обработки файлов, например при конвертировании или других операциях. Это легко делается с помощью bat-файлов, но при количестве файлов например в 50 и более, вписать все их достаточно сложно. Откроем папку с файлами в Total Commander'е, выделим все необходимые файлы и нажмем F11. Теперь в буфере обмена мы имеем названия всех выделенных файлов.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 1 Задача: Создание нового игрового персонажа.
Итак, чтобы создать нового персонажа необходимо:
1.Создать файл описания персонажа, создадим файл character_desc_sh_zat.xml в каталоге \gamedata\configs\gameplay\ и пропишем в него параметры НПС: ID, ID имени, класс, визуал, голос, набор стволов и вещей в рюкзаке и прочее.
Для этого скопируем секцию любого НПС из любого character_desc_*.ltx в свой character_desc_sh_zat.xml, и подкорректируем эту секцию:
id - идентификатор, единственный и неповторимый. Давайте назовём его Никитка. Потому меняем id на zat_sh_nikitka_skadovsk. Имя (). Ставим имя zat_sh_nikitka_skadovsk_name. Класс () совпадает с id потому: zat_sh_nikitka_skadovsk. Клан (). Нам нужен сталкер, значит stalker. Мы поставили класс zat_sh_nikitka_skadovsk. Классы тоже должны быть описаны, этим далее и займемся.
2.Создать файл описания классов (мы создали sh_profiles.xml) в каталоге \gamedata\configs\gameplay\ и внести туда класс персонажа.
3.Вставить имена этих двух файлов в соответствующие параметры файла \gamedata\configs\system.ltx который скопируем из распакованных ресурсов игры.
Первый параметр specific_characters_files. В этом параметре перечислены все файлы, которые игра открывает и считывает всех действующих лиц. Идём в конец строки, ставим запятую после последнего параметра, и прописываем свой character_desc_sh_zat. И выше строчки specific_characters_files есть парметр files, где после npc_profile или иных, в к конце, поставим запятую и допишем свой файл профилей sh_profiles
4.Всё. НПС создан. Осталось только "вживить" его в игру. Для этого опишем секцию его спавна. Создим файл с секцией спавна персонажа (мы создали sh_stalkers.ltx) в каталоге \gamedata\configs\creatures\.
Пока что мы прописали ему бессмертие и пацифизм! А теперь посмотрим что получилось. Чтобы заспавнить нашего персонажа по нажатию F6 в главном меню в файле из распакованных ресурсов ui_main_menu.script ищем строчки
Код
if dik == DIK_keys.DIK_Q then self:OnMessageQuitWin()
и дописываем ниже:
Код
elseif db.actor~=nil and dik==DIK_keys.DIK_F6 then local p=vector(),lv,gv p.x=db.actor:position().x+3 p.y=db.actor:position().y p.z=db.actor:position().z lv=db.actor:level_vertex_id() gv=db.actor:game_vertex_id() alife():create("zat_sh_nikitka_skadovsk",p,lv,gv)
В игре жмём Esc-F6-Esc. Сзади ГГ в трёх метрах появится наше творение.
Урок 2 Задача: Задача: Изменить визуал созданного НПС, проверить тактики боя персонажа, научить его отвечать на приветствие.
В данном уроке мы будем изменять визуал и логику нашего НПС, проверим его боевые качества в разных типах боя: monolith, camper, zombied и в универсальном бою. Для изменения визуала (иначе внешнего вида) НПС достаточно изменить параметр в файле character_desc_sh_zat.xml, параметр должен равняться пути к файлу и имени файла без расширения 3D модели НПС относительно папки meshes Для изменения иконки НПС (которая отображается в том числе при разговоре) нужно менять параметр , параметр - это тег из файла configs\ui\textures_descr\ui_actor_portrets.xml в котором описаны иконки различных НПС.
Для изменения боевых качеств открываем gamedata\configs\scripts\sh\zat_sh_nikitka_skadovsk.ltx и убираем строки, отвечающие за невмешательство в бой (лучше закомментаоить)
Теперь понаблюдаем за боями. Вооружите бойца обычным МП-5 и дайте ему один обычный патрон для него. Затем через F5 отспавните нашего бойца и соперника для него. Наш - сталкер. Для него враг - бандит. А для ГГ - нет. Значит можно без помех поглядеть на бой. Не вооружайте нашего бойца убойным стволом. Он бессмертный - грохнет соперника - ничего не увидите. Выходим подальше от зон, блокирующих стволы и густонаселённых районов и делаем спавн по F6 таким образом:
Нас интересует три типа вооружения нашего бойца: дробовик, пистолет-пулемёт и снайперка. Ну и как я сказал раньше три типа боя : monolith, camper, zombied (без стандартного)
Вооружаем Никитку дробнем, ставим в логике тип боя "monolit" и наблюдаем. Ставим в логике тип боя "zombied" и снова наблюдаем. Меняем на "camper" и -опять наблюдаем аблюдаем. Выходим из игры. Теперь перевооружаем Никитку МП-5. И опять три вида боя. Затем тоже с СВД. Эти 9 комбинаций покажут различия.
Для того, чтобы посмотреть бои на разных дистанциях спавните врагов на разных расстояниях. И, наконец, методы "стравливания" врагов. Можно идти тремя путями: 1.Создать Никитку бандитом и спавнить его около сталкеров 2.Создать Никитку сталкером, скопировать его, создав персонажа Кенни, сделать Кенни бандитом и спавнить обоих недалеко друг от друга 3.Создать Никитку сталкером, и спавнить его с бандитом из игры недалеко друг от друга.
Обратите внимание combat_type =без типа боя - значит будет бой по умолчанию.
Для тех, кто проверил комбат, вставляем в файл логики \gamedata\configs\scripts\sh\zat_sh_nikitka_skadovsk.ltx возможность поболтать с ГГ
Приветствие я взял от Николая, чтоб истории разные рассказывал. Можно и обычную секцию [meet] заделать. Для нас главное параметр use=true. Это значит когда ГГ его юзнет - возникнет диалог. Можно даже поторговать с Никиткой, пока у него деньги есть
Урок 3а Задача: Спавн НПС при помощи скрипта в начале новой игры (а) и по дополнительному условию (б).
Для спавна НПС через скрипт для начала создадим этот скрипт my_spawn.script в папке gamedata\scripts такого содержания:
Код
function spawn_sh_nikitka() if not has_alife_info("spawn_sh_nikitka_complite") then local p=vector(),lv,gv p.x = 245.037811 p.y = 16.290030 p.z = 504.355347 lv = 1385133 gv = 6 alife():create("zat_sh_nikitka_skadovsk",p,lv,gv) give_info("spawn_sh_nikitka_complite") end end
Итак function spawn_sh_nikitka() - функция для спавна персонажа zat_sh_nikitka_skadovsk (входящих параметров не имеет), далее if not has_alife_info("spawn_sh_nikitka_complite") then ... end - проверка что НПС спавниться только один раз, проводится при отсутствии инфопорции spawn_sh_nikitka_complite далее обычный спавн какой мы использовали при спавне по горячей клавише F6, затем выдача инфопорции spawn_sh_nikitka_complite - которая будет означать что спавн уже произведен. Теперю вызовем функцию спавна из скрипта bind_stalker.script ищем в нем функцию actor_binder:net_spawn(data) и добавим после
Код
benchmark.main()
вызов
Код
my_spawn.spawn_sh_nikitka()
- <Имя файла скрипта>.<Имя функции>. Почему именно функция actor_binder:net_spawn(data) - потому что она исполняется каждый при загрузки новой или сохраненной игры.
Теперь добавим условие при выполнении которого будет появлятся НПС (а не сразу после начала новой игры). Например при наличии инфопорции zat_b14_recon_place - которая означает что ГГ получил задание у Бороды на обследования Земснаряда
Код
function spawn_sh_nikitka() if not has_alife_info("spawn_sh_nikitka_complite") then if has_alife_info("zat_b14_recon_place") then local p=vector(),lv,gv p.x = 245.037811 p.y = 16.290030 p.z = 504.355347 lv = 1385133 gv = 6 alife():create("zat_sh_nikitka_skadovsk",p,lv,gv) give_info("spawn_sh_nikitka_complite") end end end
И вызывать нашу функцию будем уже из функции actor_binder:update(delta) вызов из функции actor_binder:net_spawn(data) - удалите или закоментируйте. Функция actor_binder:update(delta) выполняется переодически во время всей игры, таким образом с той же переодичностью наш скрипт будет проверять не наступили ли условия спавна.
Урок 4 Задача: Спавн НПС в отряде в начале новой игры (а) и по дополнительному условию (б) -как это принято в ЗП.
Спавн одиночного НПС - очень редкое явление в Зове Припяти и Чистом Небе - в этих играх спавн происходит целыми отрядами, с другой стороны никто не запрещает отряду иметь в своем составе всего одного бойца. Давайте так и поступим заспавним отряд из одного-единственного нашего Никитки. Теперь ограничения - отряд (или как его в игре именуют сквад "squad") может быть заспавнен только на смарте - специальной области локации, которая обладает своей логикой и является точкой размещения или целью отрядов. Создадим файл gamedata\configs\misc\squad_descr_sh.ltx в котором припишем наш новый сквад:
Итак сквад с именем секции и стори-ид zat_sh_nikitka_skadovsk_squad, принадлежит группировке stalker, состоит из НПС zat_sh_nikitka_skadovsk и имеет желание скорее попасть на смарт по имени zat_a1 - смарт возле точки первого появления ГГ.
Зарегистрируем наш файл сквадов squad_descr_sh.ltx в общем файле сквадов gamedata\configs\misc\squad_descr.ltx (нужно извлечь из распакованных ресурсов) дописав после
Код
#include "squad_descr_underpass.ltx"
строку
Код
#include "squad_descr_sh.ltx"
Теперь нужно поставить наш сквад на стартовую позицию при начале новой игры - это совсем просто возьмите файл из ресурсов игры gamedata\configs\misc\simulation.ltx и в секции [start_position_zaton] пропишите
Код
zat_sh_nikitka_skadovsk_squad = zat_a1
Все стартовая позиция определена.
Теперь спавн сквада при определенном условии (закоментируйте стартовую позицию нашего сквада). Обычно спавн при определенном условии делают в логике рестриктора - специальная точка локации (или область) обладающая своей логикой, но не предназначенная для занятия сквадами. Новый рестриктор создавать не будем, а воспользуемся логикой существующего (в котором в часности происходит спавн сталкеров пытающихся отнять артефакт на Земснаряде). Его логика gamedata\configs\scripts\zaton\zat_b14_spawner.ltx - возьмите из ресурсов игры. Добавим в секцию [sr_idle@artifact] строку
где on_info3 - тип события (выдача инфопорции) {+zat_b14_recon_place -spawn_nikitka} - условие в данном случае инфопорция zat_b14_recon_placeвыдана, а spawn_nikitka - нет, %=create_squad(zat_sh_nikitka_skadovsk_squad:zat_a1) +spawn_nikitka% - действия create_squad(zat_sh_nikitka_skadovsk_squad:zat_a1) собственно создать сквад zat_sh_nikitka_skadovsk_squad на смарте zat_a1, +spawn_nikitka - выдать инфопорцию. Опять инфопорция spawn_nikitka - предназначена для однократного выполнения спавна. К стати create_squad - это функция create_squad(actor, obj, p) из скрипта xr_effects.script.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 5 Задача: Запустить Никитку на патруль (через all.spawn), исследовать в движении и при остановке.
Дря решения этой задачи нужно определить 4 точки (3 на патруль, 1 на взляд) и вести эти точки с модификаторами поведения в all.spawn.
Переименуйте папку gamedata с модом Николая, например, gamedata_sgm. Скопируйте папку gamedata из архива в каталог с игрой. Инсталлируйте Perl. Для чего зайдите в каталог \gamedata\spawns\ и запустите ActivePerl-5.10.0.1004-MSWin32-x86-287188.msi. Декомпилируйте all.spawn, запустив decompile.bat. Если всё прошло успешно в каталоге появятся дополнительные файлы. К ним вернёмся позже.
*Обратите внимание на изменения с уроком 3. Обратите внимание на перенос всех своих функций в отдельный скрипт. В том числе и изменение в файле меню. Кроме того внимательно посмотрите функцию hud_stats(). С её помощью выводится координаты на худ.
Запускаем игру, начинаем новую на новичке. Если всё сделано правильно на экране появятся координаты ГГ. Нам надо выбрать 4 точки. Я выбрал первую у камня, в центре "языка", вторую и третью ближе к краям обрыва так, чтобы получился треугольник. Не делайте большой треугольник: трудно будет следить за перцем. Эти три точки будут точками маршрута. Перец должен ходить по кругу от одной точки до другой. Четвёртая точка будет в центре треугольника. Туда перец будет глядеть при остановке. Ну, вперёд! Тщательно записывайте координаты на бумаге. Если точки сняты открывайте файл \gamedata\spawns\way_zaton.ltx и переходите в самый конец. Нам надо создать патрульный путь. Для этого опишем именованный путь и 4 точки, три из которых свяжем между собой. У меня получилось так (большеват треугольник):
links = определяет к какой следующей точке пойдёт перец, достигнув текущую. name = wp00|a=raid за именем точки поставим состояние тела при перемещении (только из раздела "ходячие состояния"). Список состояний можно взять в gamedata\scripts\state_lib.script. flags = 0x1 - флаг взгляда на точку взгляда в конечной точке маршрута. Если флаги на точке маршрута и на точке взгляда совпадают, перец остановится и несколько секунд будет смотреть туда. Компилируем all.spawn. Если всё правильно создастся new.spawn. Удалить старый файл спавна и переименовать new.spawn в all.spawn не составит труда. Пришлось переделать логику паренька.
Из особенностей можно отметить три вещи: path_walk = zat_nikitka_way - созданный нами маршрут [smart_terrains] none = true - обязательная секция, что бы перс не попал в гулаги, наплевав на наши задания commander = true - будет говорить, иначе посылать к старшему. Всё. Запускаем игру, опять стартуем новую, иначе все изменения в all.spawn не применятся. Esc-F6-Esc и парень должен появиться и ходить по маршруту. Да, оденьте его поярче: легче следить. Задание. Вам надо проверить все виды состояний тела при движении и остановке. Пусть присаживается в конечной точке, например. Бежит по маршруту, переходит на шаг, и на гусиный шаг. Отработав маршрут из 3 точек, переходите на 5-7. На 1-2 точки не ставьте флажки взгляда, поглядите чего будет.
Урок 6 Задача: Создадим новый клан "Падонки" (враждебный к ГГ и нейтральный остальным). Один сквад из 5 бойцов на единственном смарте. Условием рождения будет смерть предыдущего сквада. Запустим их на маршрут по Затону.
Копируем из распакованной игры \gamedata\configs\creatures\game_relations.ltx и правим его. Сначала добавляем наш новый клан, в параметре communities = ставим запятую и пишем название (порядок должен совпадать с communities_relations)
Код
communities = ... zombied, 10, padonki, 11
Затем прописываем отношения (редактируется как строка, так и столбец)
По этой таблице ясно, что враги для падонков - ГГ и зомби. Последнее, что надо сделать - добавить их в таблицу симпатий
[communities_sympathy] actor = 0.0 bandit = 0.0 dolg = 0.0 ecolog = 0.0 freedom = 0.0 killer = 0.0 army = 0.0 monolith = 0.0 monst er = 0.0 stalker = 0.0 ;0.01 zombied = 0.0 padonki = 0.0[/color]
Переходим к секциям спавна \gamedata\configs\creatures\spawn_sections_sh.ltx. Нам нужно сделать пять мужиков на Затоне, открываем \gamedata\configs\gameplay\character_desc_sh_zat.xml, берем Никитку в буфер обмена и копируем его 5 раз. Первого обзываем zat_sh_padonok_leader, остальных - zat_sh_padonok_1,...zat_sh_padonok_4. Изменяем теги имён, класс, вооружение, визуалы (по вкусу), но самое главное ставм коммунити - padonki. Например так:
Открываем gamedata\configs\misc\squad_descr.ltx и добавляем после #include "squad_descr_underpass.ltx" строку #include "squad_descr_sh.ltx" Открываем \gamedata\configs\misc\simulation_objects_props.ltx и в самый конец дописываем разрешение игре самостоятельно гненрить сквад:
*Почему номер 6464? А потому что перед ним последним был 6463. А почему пишем в файле тоннеля? А потому, что число в [] уникальное и проще писать за максимальным [].
Конфигурация смарта указана в файле scripts\zaton\smart\zat_sh_padonki_smart.ltx. Компилируем all.spawn и создаём \gamedata\configs\scripts\smart\zat_sh_padonki_smart.ltx. А туда прописываем простейшую логику
id сквада, последний указанный в ЗП - 58, значит возьмём 59.
Ну и последнее действие, чтобы сквад ожил: в файл \gamedata\configs\misc\squad_behaviours.ltx надо внести наших пацанов. Вносим их между Монолитом и зомбями:
Стартуем новую игру и наши бездельники будут сидеть под горкой, лениво отстреливаясь от всякой живности.
Урок 6а Задача: "Оживить" созданный сквад Падонков (целевые смарты и логика поведения на смарте).
I. Целевые смарты 1. Безусловное указание целевого смарта Если в файле squad_descr_sh.ltx добавить строку target_smart = <Имя смарта>, то Падонки после спавна на своем родном смарте сразу-же пойдут занимать указанный смарт, если на этом смарте присутствует другой сквад враждебный к Падонкам, то Падонки атакуют их, если на смарте присутствуед дружественный или нейтральный сквад то Падонки просто разместятся на смарте без конфликта, если же смарт пустой то они просто станут его единоличными хозяевами. Например занять смарт "Цеха подстанции":
Код
target_smart = zat_b103_merc_smart
2. Условное указание целевого смарта target_smart = {Условие1} <Имя смарта1>, {Условие2} <Имя смарта2>, {Условие3} <Имя смарта3>, <По умолчанию> В данной конструкции следует учитывать, что выбирается первое встреченное выполненное условие. Тоесть если окажется что Условие1 и Условие2 выполняются, то целевым смартом станет смарт1. Если не выполнено ни одного условия, то целевым становится смарт по умолчанию (может быть не указан - цели нет). Пример:
где zat_b14_recon_place - это инфопорция передаваемая персонажу когда он соглашается разведать "странное сияние", zat_b7 - смарт "Шевченко". Как это работает: игра сначала проверит первое условие, если соответствующий квест не брали, то будет проверятся второе условие, а оно по умолчанию, значит Падонки пойдут на Цеха, как только будет взят квест на "странное сияние", Падонки ломанутся на "Шевченко", до этого они вполне могут успеть захватить "Цеха подстанции".
II. Маршрут передвижения сквада по смартам 1. однонаправленный target_smart = <Имя смарта1> : <Имя смарта2> : <Имя смарта3> : <Имя смарта4> Сквад начнет движение со смарта №1 и закончит на смарте №4, по пути вступая в перестрелки с хозяевами смартов враждебными к скваду. Так же сквад будет атаковать врагов близко подошедших к скваду и обчищать трупы поверженных врагов. Пример:
Код
target_smart = zat_b7:zat_a1:zat_b12
2. кольцевой target_smart = <Имя смарта1> : <Имя смарта2> : <Имя смарта3> : <Имя смарта4>: loop Сквад начнет движение со смарта №1 и достигнув смарта №4, повернет на смарт №1 и далее по кольцу. Пример:
Код
target_smart = zat_b7:zat_a1:zat_b12:loop
III. Логика поведения на смарте: В целом логика поведения на смарте определяется путями прописанными в all.spawn в разделе way_<имя локации>.ltx, с учетом одной тонкости имена секций не произвольные, а начинаются с названия смарта и имени задачи. Как у всякого правила есть исключения. Исключением здесь служит секция [exclusive] в которой задаются ссылки на дополнительную логику НПС (об этом детальнее в другом уроке). Пример:
Стоит учесть, что у меня координаты смарта Падонков такие:
Код
position = 230.806,15.650,484.682 game_vertex_id = 6 level_vertex_id = 1359849
Рассмотрим несколько случаев:
1. Сталкер ходит по маршруту охранником (воспользуемся точками пути созданными для Никитки) Просто создадим секции [zat_sh_padonki_smart_guard_1_walk],[zat_sh_padonki_smart_guard_1_look] скопировав в них соответствующее содержимое секций пути Никитки 2. Сталкер стоит и смотрит в бинокль (не забудте добавить оный в инвентарь НПС) Сталкер стоит на точке walker_1_walk и смотрит бинокль в направлении walker_1_look.
4. Сталкер сидит на точке, укладывается спать, встает, чтото ищет и т.д. при этом не уходя с указанного места. Не сходя с точки walker_3_walk, случайным образом выбирается несколько типовых анимаций указанных в точках walker_3_look.
Сталкер смотрит в направлении точки guard_2_look_р0 в бинокль в течении 30 сек. Сталкер с равной вероятностью выбирает какая будет следующая точка из р1 и р2
Сталкер сидит на "ass" и смотрит в направлении точки guard_2_look_р1 в течении 20 сек. Сталкер с равной вероятностью выбирает какая будет следующая точка из р2,р3 и р0
Сталкер сидит на "ass" и смотрит в направлении точки guard_2_look_р1 в течении 20 сек. (точки Look с предыдущей позицией совпадают) Сталкер с равной вероятностью выбирает какая будет следующая точка из р3 и р1
С вероятностью 40% сталкер смотрит в направлении точки guard_2_look_р3 в бинокль в течении 10 сек. С вероятностью 60% сталкер сидит на корточках и смотрит в направлении точки guard_2_look_р2 в течении 5 сек. Сталкер с равной вероятностью выбирает какая будет следующая точка из р0 и р2
Вот мы и раздали задания всем пятерым членам сквада Падонков. Учтите что вероятность выбора точки равна Рточки/(Сумму Р точек среди которых происходит выбор). Пример 0,4=40/(40+60) для точки guard_2_look_р3.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 7 Задача: Научить Никитку прерывать состояние патруля, общаться и торговать. Выдать квест, и рассчитаться за него.
Подправим, сначала \gamedata\configs\gameplay\character_desc_sh_zat.xml. Пусть именные у нас будут Никитка и главарь Падонков, а остальным личностям имя пусть придумывает игра. Для этого в тэги name у Падонков 1,2,3,4 ставим GENERATE_NAME_bandit. Далее создаём каталоги руссификации и пару файлов:
Первый \gamedata\configs\text\rus\sh_names.xml и забиваем туда имена перцев и имя нового клана
Второй \gamedata\configs\text\rus\sh_dialogue.xml, содержимое которого заполним позже. Теперь их надо зарегистрировать, что бы игра поняла где брать наши русики. Копируем из распакованной игры файл\gamedata\configs\localization.ltx и самой нижней строкой пишем: files = sh_dialogue, sh_names.
Теперь собственно диалоги. Создаём файл \gamedata\configs\gameplay\sh_dialogs.xml и подключаем наши диалоги в system.ltx. Находим секцию [dialogs] и дописываем свой файл: files = dialogs, dialogs_zaton, dialogs_jupiter, dialogs_pripyat, sh_dialogs Всё. техническая часть сделана, осталась творческая. Придумываем имя диалога, например nikitka_first_dialog, открываем описание Никитки в \gameplay\character_desc_sh_zat.xml и после секции supplies прописываем nikitka_first_dialog Теперь о самом диалоге. В нём будет три фразы "Ты кто?" (ГГ), "Я -Никитка" (Никитка) и "Ладно" (ГГ). Они будут идти друг за другом. Каждая фраза имеет свой уникальный внутри диалога ид. Диалог начинается с меньшего ид. После фразы идёт тег next, указывающий переход на следующую фразу. Последним будет фраза ГГ и функция dialogs.break_dialog. Всё просто:
ГГ спрашивает и передаёт очередь Никитке, тот отвечает и передаёт очередь ГГ, ГГ отвечает и заканчивает диалог. А тепрерь пришла пора заполнять \gamedata\configs\text\rus\sh_dialogue.xml
Не забываем, что Никитка находится под логикой. Для того, что бы он исполнил свой диалог надо откорректировать его логику. Открываем \gamedata\configs\scripts\sh\zat_sh_nikitka_skadovsk.ltx и разглядываем секцию meet. дописываем логику общения:
[meet] abuse = false allow_break = false ;не разрешаем ему прерывать диалог meet_on_talking = false ; не разрешаем ему начинать разговор trade_enable = true ; разрешаем ему торговать с ГГ close_distance = 5 ; на расстоянии 5 метров от ГГ close_anim = guard_na ; должен встать в позу охранника close_victim = actor use = {=actor_has_weapon} false, true ; на откликнется, если у ГГ нет в руках ствола snd_on_use = {=actor_has_weapon} meet_hide_weapon, nil ; если у ГГ ствол - попросит убрать
Запускаем новую игру, спавним Никитку по F6, подходим, разговариваем, торгуем.
Урок 7d Задача: "Оживить" созданный сквад Падонков, специальная (эксклюзивная) логика поведения на смарте.
Не интересно если созданный сквад, хотя и живет разнообразной жизьнью на смарте никак не взаимодействует с окружающим миром и в особенности с главным героем. Поэтому пусть главарь подонков выдает герою квест и награду за его выполнение. Для упрощения задачи главарем сделаем Никитку. Для этого правим файл character_desc_sh_zat.xml, для того чтобы сделать никиту членом группировки Падонки:
Далее включаем Никиту в созданный нами в 6-м уроке сквад падонков, первым в список npc="" и зададим целевой смарт равным стартовому смарту (иначе специальная логика работает некорректно). Все манипуляции производятся в файле: squad_descr_sh.ltx
Выдача денежной награды параметр reward_money, выдача предметов reward_item = <список предметов разделенных : >
Мы даем награду через описатели квестов, значит уберите выдачу награды через скрипт dialogs.script, для этого в файле sh_dialogs.xml удалите строку:
Код
<action>dialogs.zat_sh_quest_transfer</action>
Дя выдачи большого количества одинаковых предметов, всетаки удобнне использовать скрипт dialogs.script, а для выдачи денег и предметов в небольших количествах описатели квестов.
Добавим в логику смарта zat_sh_padonki_smart.ltx эксклюзивную логику лидера падонков:
Это все тотже путь Никитки из предыдущих уроков. Обратите внимание на структуру названия секции: <Имя смарта>_<Имя эксклюзивной логики НПС>_<тип точек>
Теперь собственно создадим файл \gamedata\configs\scripts\zaton\zat_sh_padonki_leader.ltx такого содержания (это логика Никиты из файла zat_sh_nikitka_skadovsk.ltx, с важными изменениями):
Секция логики содержит дополнительное расширение @leader, затем в секции [logic@leader] есть проверка НПС на то что он действительно тот самый Никитка: suitable = {=check_npc_name(zat_sh_nikitka_skadovsk_leader)} иначе логика может быть принята любым НПС на смарте, точки пути и направления взгляда НЕ содержат в начале имени смарта, а только <Имя эксклюзивной логики НПС>_<тип точек>
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Для переноса локации нам потребуется программа от АМК, предназначеная для объединения гейм графов.
Для удобства создаем две папки CoP и SoC. В CoP помещаем gamedata с папкой all.spawn от ЗП (алл.спавн распакованный). В SoС помещаем gamedata\levels\нужная_локация_для_подключения и gamedata\game.graph от ТЧ.
Запускаем программу. Появится два окна. В левом окне открываем game.graph от ТЧ, в правом окне section4.bin из all.spawn ЗП. Эти данные берем из созданных папок CoP и SoC. Для того, чтобы перенести локацию в ЗП выделяем нужную локацию в левом окне и нажимаем соответствующую стрелку. В правом окне появится эта локация. Жмем "Сохранить".
Теперь в папке CoP переименовываем section4.bin.new в section4.bin. Далее необходимо узнать с какого номера начинаются геймвертексы вашей локации. Потом в файле alife_ваша_локация.ltx подогнать геймвертексы к новым. Сравнить секции спавна ТЧ с ЗП, если есть какие различия привести в соответствующий вид нужные секции. Затем в папке SoC\gamedata\levels\ваша_локация переименовываем level.ai10 в level.ai (это если локация из ТЧ). Все подключение готово. Осталось в алл.спавне прописать переход на новую локацию и собрать гейдату с этой локой.
*Если локация скомпилирована на СДК ТЧ, то скорее всего надо будет править лайтмапы. Вот небольшая инструкция от Макрона как это можно сделать:
Инструкция для мапперов по фиксу слишком черных теней на уровнях от ЧН в случае переноса их на ТЧ без перекомпиляции: Наша задача - чтобы в r1 и r2 не было некрасивых жутко черных теней. Работаем через программу paint.net (требует установленного .Net Framework v2.0), может и через фотошоп можно - не знаю. В папке с уровнем будем редактировать лайтмапы: lmap*_1.dds - снижаем контраст на 15 единиц и сохраняем в формате dxt5 без мипмапов lmap*_2.dds переделывать сложнее - задача сделать менее прозрачным. Пересохраняем как dds в формате R5G6B5, прозрачность исчезнет совсем. Открываем снова и меняем прозрачность с 255 до 30, затем снижаем контраст на 15 единиц, сохраняем в формате dxt5 без мипмапов
Распаковываем all.spawn и добавляем в конец alife_имя_уровня.ltx:
Код
[9999] - уникальный ID ; cse_abstract properties section_name = level_changer name = new_perehod - уникальное имя position = x, y, z - координаты перехода direction = 0,0,0 cse_abstract__unk1_h16 = 0x1 ; cse_alife_object properties game_vertex_id = 368 - game_vertex distance = 0 level_vertex_id = 8520 - level_vertex object_flags = 0xffffff3e ; cse_shape properties shapes = shape0 shape0:type = box shape0:axis_x = 1.25219917297363,0,0 shape0:axis_y = 0,3.09340000152588,0 shape0:axis_z = 0,0,1.25219917297363 shape0:offset = 0,0,0 ; cse_alife_space_restrictor properties restrictor_type = 3 ; cse_alife_level_changer properties dest_game_vertex_id = 1187 - game_vertex локации на которую делаем переход dest_level_vertex_id = 212769 - level_vertex локации на которую делаем переход dest_position = 39.396331787109,0.48722490668297,-299.7674505469 - координаты появления ГГ на новой локации dest_direction = 0,0,0 - поворот ГГ dest_level_name = new_level - на какую локацию будет переход dest_graph_point = start_actor_01 silent_mode = 1 ; se_level_changer properties
Сборка gamedata скорее всего заключается в следующем: 1) Копирование папки SOC\gamedata\levels\Новая_локация в папку с игрой gamedata\levels\ 2) Копирование файлов way_новая_локация.ltx и alife_новая_локация.ltx из распакованного all.spawn'A SoC в папку расспакованного all.spawn'a CoP 3) Добавление 2 строк в файл all.ltx расспакованного all.spawn'A CoP'A ==> Строка №1: Секция [alife]После строки alife_jupiter_underground.ltx Добавляем alife_новая_локация.ltx Строка №2 Секция [way]После строки way_zaton.ltx Добавляем way_новая_локация.ltx Сохраняем изменения в файле и пакуем all.spawn
*game_vertex, level_vertex, position - добавленной локации можно посмотреть в файле alife_добавленная_локация.ltx
Урок 8а Задача: Удалить ненужные секции из alife_*.ltx
Введение. Нам понадобятся инструменты: Notepad++, MS Excel (в OOorg тоже работает, но в MS Excel лучше, а мб привычнее) Итак, вы перенесли локацию, но большинство секций из стандартного комплекта вам не нужно. Удалять в ручную муторно и долго, очень долго. Давайте откроем alife вашей локации программой NotePad++ (далее как Блокнот). Мы будем работать с окном замены, поэтому перейдем в него: Поиск>Замена ([ctrl]+[h]).
Конвертируем файл для экспорта в MS Excel Режим поиска - Найти - Заменить на - Описание действия
Режим: Регуляр. выражен. (и новые строки) - Найти: ";+\r\n" - Заменить на: "" - Удаляем строки (вида ";;;;;;;;;;;;;;;;;;;;;;;;;;;", разделяющие секции alife-файла после декомпилирования all.spawn. Если у Вас нет таких строк - можете пропустить этот шаг Режим: Регуляр. выражен. (и новые строки) - Найти: "\r\n\r\n" - Заменить на: "\r\n" - Удаляем лишние пропуски между строчками. Повторять пока не будет находить текст для замены Режим: Регуляр. выражен. - Найти: "^(.*)$" - Заменить на: "##\1" - Пишем в начале каждой строки ## Режим: Регуляр. выражен. - Найти: "##\[(\d+)\]" - Заменить на: "#+#[\1]" - Заменяем ## в начале каждой строчки с цифровым названием секции (что свойственно для секций alife-файлов) на #+#. Если Вы работаете с way-файлом, то искать нужно: "##\[(\w+)\]" Режим: Расширенный - Найти: "\r\n##" - Заменить на: "\t##" - Отделяем строки секций табуляцией
Все мы разобрали alife для дальнейшего импорта в Excel. Для примера привожу две секции:
Работаем в MS Excel Выделяем все содержимое файла ([ctrl]+[a]) и копируем его ([ctrl]+[v]) в Excel. В экселе опять все выделяем и переходим в Данные>Фильтр На первой строчке мы увидим стрелочки в левом краю ячеек. Нажимаем на стрелочку в ячейке section_name и снимаем оттуда все галочки (Клик по "Выделить все"). Вот скриншот. Теперь наша задача отметить только те секции, которые нам нужны. Я оставляю себе только campfire, lights, breakable и climable objects. Выделили, нажали ОК. Теперь остались только нужные секции, опять выделяем все хоткеем и переносим в наш файл копированием Если работаете с way-файлом, то сортируйте по первому столбику (по названи секции)
Конвертируем в файл для ACDC Режим поиска - Найти - Заменить на - Описание действия
Режим: Регуляр. выражен. - Найти: "\t+" - Заменить на: "" - Удаляем лишнюю табуляцию в конце секций Режим: Регуляр. выражен. - Найти: "#+#" - Заменить на: "" - Удаляем #+# перед секциями Режим: Регуляр. выражен. (и новые строки) - Найти: "\t##" - Заменить на: "\r\n" - Удаляем табуляцию и ## перед строчками Режим: Регуляр. выражен. (и новые строки) - Найти: "\r\n\r\n\r\n" - Заменить на: "\r\n" - Удаляем лишние пустые строчки. Повторять пока не будет находить текст для замены
Все готово для сборки All.spawn
Урок 9 Задача: Создание телепорта внутри локации.
Создадим телепорт, который будет перебрасывать ГГ на Скадовск.
Для начала нам нужны три точки: место телепорта, место "приземления" и точка взгляда после приземления. Заходим в игру, координаты, левелвертекс и геймвертекс ГГ у нас отражаются вверху экрана, потому смело двигаем к нужным точкам. Первую я выбрал между камней, на площадке, где стартует ГГ. Тщательно пишем координаты и вертексы. Вторую точку я выбрал внутри Скадовского, внизу на решётке. Точку взгляда я решил разместить около входной двери, что бы ГГ при "приземлении" смотрел прямо на дверь. После того как координаты всех трёх точек сняты выходим из игры.
Открываем каталог \gamedata\spawns\ и находим там файл way_zaton.ltx. Это файл точек на Затоне. Открываем его и в самый конец дописываем точку "приземления" и точку взгляда. Вспоминаем, что точки именные. Именуем их по своим правилам: лока_школа_номер_путь\взгляд. Значит, точка "приземления" будет у нас zat_sh_1_teleport_walk, а взгляда - zat_sh_1_teleport_look. Итак:
Теперь сам телепорт. Конечно его лучше прописывать в файле, относящемся к локации, но я для простоты пропишу его в файл с максимальным ИД - \gamedata\spawns\alife_jupiter_underground.ltx В предыдущем занятии мы использовали ИД - 6464, значит для нашего телепорта используем 6465.
Обратите внимание, что мы прописали телепорту логику в (ещё не созданном файле) zat_sh_1_teleport.ltx. Попозже мы пропишем эту самую логику. Если остановиться на этом, то телепорт будет, работать тоже будет, но будет невидим. Давайте теперь присвоим ему визуал
Компилируем all.spawn с нашими изменениями. Теперь переходим к логике. Создаём файл \gamedata\configs\scripts\sh\zat_sh_1_teleport.ltx и забиваем в активную секцию точку переноса и точку взгляда из way_zaton.ltx:
Всё. Начинаем новую игру, идём в телепорт, оказываемся на Скадовском.
Телепорт, как любой объект обладающий собственной логикой может быть достаточно интерактивен в своих действиях. Создадим телепорт который будет отправлять игрока на "Скадовск" только если он не вооружен, а если с оружием на перевес выбросит в аномалию. Для этого изменим файл логики телепорта zat_sh_1_teleport.ltx следующим образом:
Урок 10 Задача: Прикрутить локацию из ЧН к SGM1.7.
Чтобы "прикрутить" локацию необходимы полностью распакованные ЧН и ЗП.Из инструментов необходимы Perl, компилятор\декомпилятор all.spawn с файлами - справочниками от Николая, желательна Java и прога от Колмогора для пересчёта вертексов в alife_ и way_ файлах. Прогу для переноса локаций от АМК. Ну и самое главное - SGM1.7 с фиксом от 31.08.2010. Нет! Самое главное - внимание к тому, чего будем делать. Неверные ходы выбрасывают куски текстов из файлов all.spawn. За основу берём урок БАТЯ-STALKER http://stalkerin.gameru.net/wiki....K_Team.
Кладём из архива папку ggEditor_01 в любое место на диске. Заходим в папку с программой ggEditor_01. Создаем там папки Cs и Cop. В каждой из созданных папок создаём папки gamedata. В папке ggEditor_01/Cs/gamedata создаём ещё одну папку levels. И уже в эту папку кладём нужную локу из распакованного ЧН. Я положил darkvalley. В папку ggEditor_01/Cs/gamedata кладём all.spawn от ЧН и файлы с компилятором\декомпилятором от ЧН.
В папку ggEditor_01/CoP/gamedata кладём all.spawn от SGM 1.7 и файлы с компилятором\декомпилятором от ЗП. Не забудьте, что компилятор\декомпилятор должен быть с правками от Николая. Хотя в файлах примера уже всё добавлено, можете не заморачиваться.
Декомпилируем all.spawn от ЧН и ЗП и запускаем ggEditor.exe. В левом окошке открываем файл \ggEditor_01\CS\gamedata\graph.bin, в правом - \ggEditor_01\CoP\gamedata\section4.bin. В левом окошке появляются все доступные графы от ЧН, в правом от ЗП. В левом окне выбираем darkvalley и жмём кнопку переноса графа вправо. darkvalley копируется в правое окно. Последовательно и однократно нажимаем кнопки "сохранить" в левом и правом окошках. Вобще-то сохранение в левом окне нужно для ТЧ, но я всё равно жал на кнопку: хуже-то не будет :)))
Что мы получили? В папке \ggEditor_01\CoP\gamedata\ появился новый гейм граф section4.bin.new для ЗП, включающий в себя граф с Тёмной долины. Убиваем \ggEditor_01\CoP\gamedata\section4.bin и переименовываем section4.bin.new в section4.bin
Закрываем ggEditor.exе. Копируем файлы \ggEditor_01\CS\gamedata\alife_l04_darkvalley.ltx и \ggEditor_01\CS\gamedata\way_l04_darkvalley.ltx в папку \ggEditor_01\CoP\gamedata\ и открываем \ggEditor_01\CoP\gamedata\all.ltx на редактирование.
Изменяем число лок до шести (level_count = 6) и добавляем в секции [alife] и [way] только что скопированные файлы:
[header] ; don't touch these version = 10 guid = 9c75ae88aaf7b54a81a72e0a5b4017a1 graph_guid = ca7a121259ed3f4484fe40b98321e746 level_count = 6
Сохраняем \ggEditor_01\CoP\gamedata\all.ltx. Открываем \ggEditor_01\CoP\gamedata\acdccop.pl и добавляем свою локу:
package levels; use strict; use constant levels_info => ( { gvid0 => 934, name => 'darkvalley' }, { gvid0 => 883, name => 'jupiter_underground' }, { gvid0 => 857, name => 'labx8' }, { gvid0 => 666, name => 'pripyat' }, { gvid0 => 317, name => 'jupiter' }, { gvid0 => 0, name => 'zaton' }, );
Сохраняем \ggEditor_01\CoP\gamedata\acdccop.pl.
Кстати, а чего за магическое число 934 уже стояло в \ggEditor_01\CoP\gamedata\acdccop.pl? А это стартовый гейм граф новой локи. Проверяем. Запускаем \ggEditor_01\CoP\gamedata\ggtool.bat и в появившемся окошке видим, что граф Тёмной долины начинается с 934. А зачем нам это надо?
Вот тут начинается самая кропотливая работа. Открываем \ggEditor_01\CoP\gamedata\alife_l04_darkvalley.ltx и его разглядываем. Первое. В самой первой секции видим: game_vertex_id = 743, что меньше отведённого нам минимального значения 934. Второе. Секции начинаются с [4426], что явно перекроется с имеющимися в ЗП. Третье. Есть куча объектов, которые не поддерживаются или не описаны в ЗП.
Начинаем вычикивать смарттеррейны, смартковеры (самое обидное), сталкеров, сквады и рестрикторы. С рестрикторами может я и погорячился. Все остальные объекты: костры, лестницы, лампы, бочки и т.д оставляем.
Далее с помощью поиск-замены меняем все [ на [1 и нумерация секций начнётся с [14426]. Если вы ковыряли ЗП то видели, что максимальная секция ЗП заканчивается где-то на уровне 7500. Значит наша [14426] не перекроется с секциями ЗП.
Теперь надо изменить гейм вертексы. Минимальное значение в имеющемся файле 743, надо 934. Значит гейм вертекс каждого объекта надо увеличить на 191. Ручками перебивать каждый вертекс - работа для мазохистов. Поэтому воспользуемся прогой Vertex_Parser2.jar от Калинина. Она проста в применении, но для неё нужна Java. Я подумал: что лучше? Ручками колотить или скачать и установить Java? Решил скачать и установить. Запустить и получить правленные alife_ и way_.
Для сборки all.spawn не хватает только одного: решения как попадать в Тёмную долину.
Предложенный метод я не сильно понял. Нет, в теории он прост как валенок: надо начать игру в новой локе. Но сколько бы я не пробовал мой ГГ постоянно выпадает за пределы локи;(((
Но я нашёл выход, суетливый, правда, но действенный. Открываем \ggEditor_01\CoP\gamedata\alife_zaton.ltx и ищем = actor. Находим секцию:
[982] ; cse_abstract properties section_name = actor name = zaton_actor position = 256.240051269531,19.8124237060547,550.824279785156
И изменяем position, game_vertex_id, level_vertex_i, upd:position на значения из первой секции файла \ggEditor_01\CoP\gamedata\alife_l04_darkvalley.ltx, причём значения position и upd:position должны совпадать. Да, сохраните исходные значения: их потом надо будет вернуть.
Всё! Можно компилировать all.spawn. Компилируем, переименовываем, кладём с заменой в папку spawns мода. Теперь можно заняться подтыканием локи в ЗП.
Копируем из распакованной ЗП файлы game_graphs.ltx, game_levels.ltx и game_maps_single.ltx в \gamedata\configs\. Открываем game_graphs.ltx и вносим инфу об новой локе: [location_0] 000 = "..." 001 = "sim_smart_1" 002 = "sim_smart_2" 003 = "sim_smart_3" 004 = "sim_smart_4" 005 = "sim_smart_5" 006 = "sim_smart_6" 007 = "sim_smart_7" 008 = "sim_smart_8" 009 = "sim_smart_base" 010 = "darkvalley" ..........................
Так, текстуры локи. Переносим их из ЧН. Открываем CS\resources\textures\terrain\ и все файлы, имеющие в своём названии darkvalley перегоняем в S.T.A.L.K.E.R. - Зов Припяти\gamedata\textures\terrain\.
Собственно уровень. Всю папочку \ggEditor_01\CS\gamedata\levels\ переносим в S.T.A.L.K.E.R. - Зов Припяти\gamedata\levels\.
Уф! Последние приготовления: сразу добавьте выод координат на экран и запишите координату любого предмета из \ggEditor_01\CoP\gamedata\alife_l04_darkvalley.ltx Например натовской коробки:
[14774] ; cse_abstract properties section_name = physic_destroyable_object name = val_physic_destroyable_object_0030 position = 150.124160766602,10.3052711486816,-277.891357421875
Остаётся только прописать в файл меню S.T.A.L.K.E.R. - Зов Припяти\gamedata\scripts\ui_main_menu.script телепортацию ГГ на эту коробку. Добавляем на F8:
elseif db.actor~=nil and dik==DIK_keys.DIK_F8 then db.actor:set_actor_position(vector():set(150.124160766602,10.3052711486816,-277.891357421875))
Пробуем. Старт новой игры. У меня вывалилось! Но лог любезно сообщил, что гаме нехватает анимации фаербола, который носится по эстакаде. Переносим недостающее из раскрытог ЧН в соответствующие каталоги ЗП.
Старт новой игры и ГГ попадает в какой-то кисель. Только дождик льёт с неба. Так, выпали в осадок за край карты. Esc-F8-Esc и ГГ волшебным образом переносится на лестницу котельной(?). Мы дома. Бегаем по локе. Костры горят, лампы светят, по лестницам можно лазить. Но. Аномалии не кусают, двери есть, но не юзаются, ящиков куча, но в них пусто. Эх! Зачем же мы рестрикторы снесли? Ну ладно. забегаем на базу Свободы. Так и ждём: "Буду ия к тибе винимательный!". Ашота нет. Ну это дело наживное. А пока можно обустраиваться. А с чего обустраиваться? С левелченджеров, ясен пень!
Бродим по локе, ищем два укромных места для входа и выхода. Находим, делаем скрины с координатами или записываем их. Всё выходим из игры. Восстанавливаем \ggEditor_01\CoP\gamedata\alife_zaton.ltx, чтобы стартовать с Затона. Можно компилировать all.spawn. Компилируем, переименовываем, кладём с заменой в папку spawns мода. Стартуем новую игру. Ищем на Затоне два укромных местечка для перехода и возврата в Тёмную долину. Находим, делаем скрины с координатами или записываем их. Всё выходим из игры.
Осталось последнее: прописать левелченджеры. Открываем \ggEditor_01\CoP\gamedata\alife_zaton.ltx и alife_jupiter_underground.ltx. В последнем ищем максимальный номер секции. У меня - [7754]. Так значит в файле затона дописываем секцию [7755]. Не буду утомлять длинным описанием секции, главное, что сначала ставятся координаты откуда прыгаем, а в конце - куда.
Можно компилировать all.spawn. Компилируем, переименовываем, кладём с заменой в папку spawns мода. Стартуем новую игру. Мчимся к базе бандитов, обходим её по внешней стороне слева, идём вдоль забора. И, в самом конце, где забор сворачивает налево, рядом с деревом, игра замирает. А потом идёт загрузка нового уровня. Как с него выйти не скажу. Пользуйтесь меню и F8 подставляя нужные координаты:
elseif db.actor~=nil and dik==DIK_keys.DIK_F8 then db.actor:set_actor_position(vector():set(150.124160766602,10.3052711486816,-277.891357421875))
Кстати, совершенно шикарный метод поика СГМ тайников. Дарю!
На сегодня всё. Радость от достигнутого омрачает карта: она налезла на Затон. Но это уже совсем другая история.
Урок 11 Задача: Добавление или изменение иконки оружия, брони, продукта и т.д.
Прикрутим к АК-74 его иконку (будем считать, что АК-74 не было в сталкере и мы его добавили). Так же будем считать, что иконку ты уже нарисовал, как нарисовать новую иконку читай тут. Итак, для вычисления координат иконки, дабы не считать их вручную, качаем очень полезную в этом деле программу. Открываем наши иконки:
Мы видим знакомую нам сетку размерами 50х50 пикселей.По ней и вычисляются координаты. Но сначала нам нужно определить, сколько клеток иконка занимает в ширину и сколько в высоту.Считаем.Мне считать не нужно, так как все стандартные иконки штурмового оружия занимают в игре 5 клеток в ширину и 2 в высоту.Запоминаем эти результаты, дальше они нам пригодятся. Теперь самое сладкое.Нам надо определить координаты нашей иконки в сетке.Когда я только начал заниматься этим делом, долго не мог допереть, как эти самые координаты вычислить и записать, поэтому говорю сразу - не надо узнавать координаты самой иконки, надо узнать, координаты клетки, которая находится справа над самой иконкой.Сами координаты можно посмотреть, наведя на эту клетку мышь, они отобразятся внизу. Итак, коорддинаты нашей клетки - 5 по x (ширина) и 5 по y (высота).Хехе, красиво то как.
С "узнаванием" покончено, переходим к завершающей части. Открываем конфиг нашего "ствола", в моем случае w_ak74.ltx и правим там следующие строчки таким образом (а если оружие новое - то не правим а дописываем эти строчки):
Код
inv_grid_width = 5 (Это размер иконки в ширину, если помнишь у меня он 5 клеток) inv_grid_height = 2 (Размер иконки в высоту, у меня он 2 клетки) inv_grid_x = 5 (Координаты иконки по x) inv_grid_y = 5 (Координаты иконки по y)
Ну вот и все, идем в игру и любуемся новой иконкой нашего оружия.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 12 Задача: Создать тайник на Затоне и выдать указатель на него в качестве награды за выполнение квеста.
Пускай указатель на тайник выдаст Никитка за выполнение квеста на уничтожение химеры. Для начала нужно создать спейс рестриктор тайника в распакованном all.spawn файл alife_jupiter_underground.ltx
Код
[6470] ; Рестриктор тайника Никиты ; cse_abstract properties section_name = space_restrictor name = zat_hiding_place_nikita position = 304.5137,19.9218,533.2040 direction = 0,0,0
Где zat_hiding_place_nikita - имя тайника. Спейс рестриктор ссылается на файл secret_zaton.ltx в котором описаны тайники с содержимым. И наполнение для тайника - Гроза плюс пачка патронов:
Код
[6471] ;; Гроза в тайнике Никиты ; cse_abstract properties section_name = wpn_groza name = zat_hiding_wpn_groza_nikita position = 304.5137,19.8218,533.2040 direction = 8.29999989946373e-005,1.57196998596191,-1.54886198043823
[6472] ;Патроны для грозы в тайнике Никиты ; cse_abstract properties section_name = ammo_9x39_ap name = zaton_hiding_ammo_9x39_ap_nikita position = 304.5137,19.7218,533.2040 direction = 0,0,0
Обратите внимание, что тайник будет создан в начале игры и найти его можно до передачи указателя. Также оба предмета в тайнике ссылаются на имя тайника zat_hiding_place_nikita для того, чтобы при подборе предметов игра узнала о нахождении соответствующего тайника.
В файле описателе тайников, на Затоне secret_zaton.ltx нужно упомянуть свой тайник:
Выдадим указатель на тайник в скрипте, dialogs.script добавив в конец:
Код
function nikita_give_reward_to_actor(first_speaker, second_speaker) treasure_manager.get_treasure_manager():give_treasure("zat_hiding_place_nikita") end
Пропишем в фале диалога, sh_dialogs.xml вызов функции выдачи тайника в диалоге:
[zombie_vision_free] min_view_distance = 0.5 ;-- коэффициент, который множится на eye_range, в зависимости от угла max_view_distance = 1.0 ;-- коэффициент, который множится на eye_range, в зависимости от угла visibility_threshold = 80.0 ;-- значение, при достижении суммой которого объект считается видимым always_visible_distance = 0.2 time_quant = 0.005 decrease_value = 0.01 ;-- значение, на которое уменьшается вес, если объект попал в фрустум, но отсёкся по каким-то причинам velocity_factor = 1.0 luminocity_factor = 0.7 ;-- фактор освещения (только для Актёра) transparency_threshold = 0.4
[zombie_vision_danger] min_view_distance = 0.7 ;-- коэффициент, который множится на eye_range, в зависимости от угла max_view_distance = 1.0 ;-- коэффициент, который множится на eye_range, в зависимости от угла visibility_threshold = 40.0 ;-- значение, при достижении суммой которого объект считается видимым always_visible_distance = 0.2 time_quant = 0.001 decrease_value = 0.01 ;-- значение, на которое уменьшается вес, если объект попал в фрустум, но отсёкся по каким-то причинам velocity_factor = 1.0 luminocity_factor = 0.7 ;-- фактор освещения (только для Актёра) transparency_threshold = 0.4
Отредактировать текстуру ui_actor_monsters_pda_1.dds вставив картинку монстра в соответствующее место указанное в файле ui_monsters_pda.xml
Для того, чтобы зомби отличались по ранжиру, нужно ввести ранг для каждого вида зомби описанного в файле m_zombie.ltx, затем проверять ранг зомби в файле xr_statistic.script в функции function set_best_monster(obj) кодом типа
Код
elseif(community=="zombie") then if(rank==6) then community = community.."_strong" else community = community.."_weak" end
Соответственно для каждого из видов зомби можно сделать свою картинку в файле pda.script добавив
Текстуры оружия и прицела (ссылаются модели оружия и прицела) на какую текстуру ссылается та или иная модель лучше смотреть в MilkShape 3D: Tools-> Model Information V1.7
Код
gamedata\textures\wpn\wpn_aug_a3_1.dds gamedata\textures\wpn\wpn_aug_a3_1_bump#.dds gamedata\textures\wpn\wpn_aug_a3_1_bump.dds gamedata\ textures\wpn\wpn_aug_a3_2.dds gamedata\textures\wpn\wpn_aug_a3_2_bump#.dds gamedata\textures\wpn\wpn_aug_a3_2_bump.dds gam e d a t a \ t e x t u r e s\ wpn\wpn_aug_a3_mag.dds gamedata\textures\wpn\wpn_aug_a3_mag_bump#.dds gamedata\textures\wpn\wpn_aug_a3_mag_bump.dds gamedata\texture s\w pn \wpn_scope_leupold_mark4_1_3_x14_CQT.dds
Текстура прицельной сетки (ссылается файл с настройками прицела)
Удалим/закоментируем ссылки на секции отсутствующие в оригинальной игре
Код
;cost_wpn_aug, mod_aug - из [wpn_aug] ;ammo_5.56x45_gd - из ammo_class ;ammo_box_10_m209 - из grenade_class ;wpn_addon_silencer_5.56x45 - из silencer_name
Добавим переменную базовой стоимости
Код
cost = 6000
Добавим в файл ui_icon_equipment.dds при помощи фотошопа или аналогичной программы иконки оружия и прицела скопированные из аналогичного файла мода. Прописав ссылки на иконки inv_grid_x, inv_grid_y, для ствола и прицела ссответственно.
Теперь для пробы можно добавить ствол и прицел (wpn_aug, wpn_addon_scope_leupold) в стартовый инвентарь и попробовать в действии. Добавление ствола в другой мод может отличаться от добавления на чистую игру, но лишь файлами которые нужно корректировать. Последний штрих добавить названия и описания ствола и прицела.
1. Секция настроек прицела находиться не в weapons.ltx а в отдельном файле для прицелов w_scopes.ltx 2. Базовая стоимость вынесена из файла настроек ствола в файл costs.ltx 3. Некоторые ссылки на секции (файл w_aug.ltx) отсутствующие в оригинальной игре можно не удалять, если в моде они есть.
Урок 14а Задача: Добавление введенному оружию дерева апгрейдов.
Сделаем для ствола AUG дерево апгрейдов с одной веткой:
1 этап, 1 элемент ---> 2 этап, 1 элемент/2 этап, 2 элемент ---> 3 этап, 1 элемент
На первом этапе один апгрейд, на втором два взаимоисключающих апгрейда и на третьем опять один. В файле gamedata\configs\weapons\w_aug.ltx пропишем этапы первой ветки аплейтов:
Как и договаривались в первой колонке одна ячейка, во второй две, в трктьей опять одна. В секции ячейки (cell) x,y - координаты левого верхнего угла иконки, point_x, point_y - координаты точки-указателя места апгрейда на картинке с оружем.
В файл gamedata\configs\weapons\weapons.ltx добавим ссылку на файл описания апгрейдов AUG:
Код
#include "upgrades\w_walther_up.ltx" #include "upgrades\w_wincheaster1300_up.ltx" ;--Добавлен конфиг апгрейдов AUG #include "upgrades\w_aug_up.ltx"
В файл gamedata\configs\misc\inventory_upgrades.ltx добавим указатель на ствол:
Код
wpn_ak74u_snag wpn_fort_snag ;--Добавлена возможность апгрейдов AUG wpn_aug
В файл gamedata\configs\item_upgrades.ltx добавим ссылку на файл описания апгрейдов AUG:
Код
#include "weapons\upgrades\w_wincheaster1300_up.ltx" #include "weapons\upgrades\w_protecta_up.ltx" ;--Добавлен конфиг апгрейдов AUG #include "weapons\upgrades\w_aug_up.ltx"
Теперь займемся самим файлом gamedata\configs\weapons\upgrades\w_aug_up.ltx в котором будут содержаться описания апгрейдов оружия. Сначала пропишем этапы апгрейда с указанием содержащихся в них элементов апгрейда:
Код
[up_gr_firstab_aug] elements = up_firsta_aug
[up_gr_firstcd_aug] elements = up_firstc_aug, up_firstd_aug
[up_gr_firstef_aug] elements = up_firste_aug
Выше этих строк нужно прописать конфигурации самих элементов:
где, scheme_index - колонка, ячейка (счет с нуля!) для иконки в схеме апгрейда known - извстен или нет апгрейд механикам effects - следующий апгрейд в линейке апгрейдов (апгрейд может содержать несколько элементов) section - секция описывающяя изменения параметров оружия при установке апгрейда property - секция описывающая в файле upgrades_properties.ltx свойство апгрейда. precondition_functor - функция проверки возможности апгрейда (делает его механик, хватает ли денег, нет доп условий и т.п.) precondition_parameter - логическое выражение разрешающее апгрейд? (возможно параметр не анализируется) effect_functor - функция оплаты выполненного апгрейда prereq_functor - функция отображения нужных сдедств для апгрейда prereq_tooltip_functor - функция не используется (отображение нужного инструмента?) name - имя элемента апгрейда description - описание элемента апгрейда icon - иконка элемента апгрейда
Еще выше вставим секции параметров апгрейда:
Код
[up_sect_firsta_aug] ;Надежность(1)10% ;--------------- cost = 700 value = +10
;увеличение дисперсии в процентах при максимальном износе fire_dispersion_condition_factor = -1 ;15 ;шанс осечки при изношености больше чем misfireStartCondition misfire_start_prob = -0.0007 ;шанс осечки при изношености больше чем misfireEndCondition misfire_end_prob = -0.012 ;0.03.03
[up_sect_firstc_aug] ;Настильность(2)20% ;------------------ cost = 1050 value = +20
bullet_speed = +85 fire_dispersion_base = -0.02
[up_sect_firstd_aug] ;Скорострельность(2)15% ;---------------------- cost = 1050 value = +15
rpm = 100
[up_sect_firste_aug] ;Надежность(3)30% ;--------------- cost = 1300 value = +30
;увеличение дисперсии в процентах при максимальном износе fire_dispersion_condition_factor = -1 ;15 ;увеличение изношености при выстреле очередью condition_queue_shot_dec = -0.0003 ;0.0013 ;увеличение изношености при одиночном выстреле condition_shot_dec = -0.0003 ;0.0011 ;шанс осечки при изношености больше чем misfireStartCondition misfire_start_prob = -0.0025 ;шанс осечки при изношености больше чем misfireEndCondition misfire_end_prob = -0.025 ;0.03
В которых собственно указыватся их стоимость cost, влияние на интегрированный параметр (скорострельность, точность и т.п.) value и собственно сами параметры оружия которые меняються на указанную величину.
Теперь можно прописать возможность апгрейда механнику, на пример Кардану:
Код
;--Добавлена возможность апгрейдов AUG wpn_aug
...
[zat_a2_stalker_mechanic_upgr]
;--Кардан делает все апгрейды AUG up_sect_firsta_aug = true up_sect_firstc_aug = true up_sect_firstd_aug = true up_sect_firste_aug = true
Нужно зарегистрировать свое оружие в файле configs\mp\mp_ranks.ltx выбрав при этом секцию соответствующую классу оружия. Добавлять оружие нужно в параметр available_items, просто дописав его через запятую.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
1. находим модели ствола с нужным коллиматором . 2. Импортируем их в 3Д редактор ( например в милку, в ней проще всего). 3. Удаляем все ненужное и приподнимаем прицел (чтоб не мешался пока) 4. Подгружаем модель нужного ствола ( например ЛР300) 5. Удаляем штатный прицел. 6. Устанавливаем на место коллиматор, чтобы сделать съемным привязываем к кости wpn_scope, не съемным - к body. 7. Экспортируем в формат СДК. 8. Делаем в СДК модель худ и мировую модель. 9. Экспортируем в формат ОГФ П.С. Если прицел съемный, надо отдельную модель прицела через СДК сделать, но это уже проще)
Общие положения Сегодня мы разберем то, каким образом можно редактировать оружие в игре - от характеристик до описания. Характеристики оружия хранятся здесь: ...\S.T.A.L.K.E.R\gamedata\config\weapons\w_[...].ltx
Разбор структуры конфига
Возьмем, для примера, конфиг w_g36.ltx. Он делится на разделы:
Первый раздел Здесь хранится общая информация о оружии - его класс, тип, ссылки на спавн и т.д. Нас интересуют следующие строки:
description = enc_weapons1_wpn-g36 - ссылка на string_id, из которого игра подгружает описание этого оружия. ef_main_weapon_type = 2 - основной тип, к которому принадлежит оружие ef_weapon_type = 6 - подтип, к которому принадлежит оружие sprint_allowed = true - возможность спринта с этим оружием(false-выкл, true-вкл) Второй раздел Содержит модификаторы, которые даются к углу зрения/дальности обзора NPC, держащего это оружие в руках:
holder_range_modifier = 1.85 - во сколько раз увеличивается eye_range holder_fov_modifier = 0.3 - во сколько раз увеличивается eye_fov Третий раздел Содержит данные о самом оружии, его некоторых характеристиках:
cost = 18000 - базовая цена (торговцы умножают её на некоторый коэффициент) weapon_class = assault_rifle - класс оружия (здесь - штурмовая винтовка) ammo_mag_size = 30 - размер магазина ammo_class = ammo_5.56x45_ss190, ammo_5.56x45_ap - типы используемых патронов grenade_class = ammo_m209 - тип используемых гранат fire_modes = 1, -1 - режимы ведения огня hand_dependence = 1 - засивимость о рук (?) - возможно, речь идет о качании ствола single_handed = 0 - держится ли только в одной руке slot = 2 - слот в инвентаре animation_slot = 2 - вид анимации (для пистолета/для винтовки) inv_name = wpn-g36 - ссылка на имя, отображаемое в инвентаре, тоже берется из string table, как и описание inv_name_short = wpn-g36 - короткое имя; в данном случае используется то же самое inv_weight = 3.6 - вес inv_grid_width = 5 - координаты первого угла иконки по x inv_grid_height = 2 - координаты первого угла иконки по y inv_grid_x = 0 - координаты второго угла иконки по x inv_grid_y = 10 - координаты второго угла иконки по y Четвертый раздел В четвертом разделе хранится информация о износе/отдаче оружия. Практически все параметры там снабжены комментариями, поэтому приведу лишь самые интересные:
cam_relax_speed = 5.7 - скорость возврата в исходное положение cam_dispersion = 0.2 - увеличения угла (в градусах) с каждым выстрелом fire_dispersion_condition_factor = 5 - увеличение дисперсии в процентах при максимальном износе misfire_probability = 0.003 - вероятность осечки при максимальном износе misfire_condition_k = 0.05 - порог (в данном случае - 5%), после которого оружие может заклинивать condition_shot_dec = 0.0002 - увеличение износа при каждом выстреле Пятый раздел Здесь хранится множество параметров, из которых наиболее интересны эти:
hit_power = 0.50, 0.54, 0.57, 0.60 - сила выстрела hit_impulse = 105 - импульс пули (сила, которую летящая пуля передает жертве, влияет на поведение ragdoll-тела) hit_type = fire_wound - тип причиняемых повреждений, в данном случае - пулевые ранения (параметр в синглплеере ни на что не влияет) fire_distance = 600 - максимальная дистанция для выстрела bullet_speed = 925 - начальная скорость пули hud = wpn_g36_hud - внешний вид оружия Шестой раздел position = -0.026, -0.132, 0.0 - позиция по отношению к игроку (?) orientation = 0, 0, 0 - направление, в которое смотрит ствол (?) Седьмой раздел Содержит описания визуальной стороны оружия и некоторые другие параметры:
startup_ammo = 90 - как нетрудно догадаться, стартовое количество патронов (в синглплеере ни на что не влияет) visual = weapons\g36\wpn_g36.ogf - модель оружия, используемая NPC, а также игроком при виде от третьего лица ph_mass = 4 - физическая масса, используемая при расчетах scope_status = 1 - ситуация со съемным прицелом silencer_status = 0 - ситуация со съемным глушителем grenade_launcher_status = 0 - ситуация с подствольным гранатометом Параметры: 0 - нет, новый прикрепить нельзя 1 - уже есть, несъемный 2 - нет, но можно установить новый zoom_enabled = true - есть ли зум (прицеливание) scope_zoom_factor = 33.3 - какой зум дает прицеливание (здесь - 1.8х) scope_texture = wpn\wpn_crosshair_g36 - текстура прицельной сетки shell_point = 0.15, 0.0, -0.05 - точка вылета гильз shell_dir = 0.0, 1.0, 0.0 fire_point = -0.000000,0.062000,0.134000 - точка выстрела fire_point2 = 0.30, 0.00, 0.05 - точка выстрела (2) fire_bone = wpn_body orientation = 0, 0, 0 - направление position = 0, 0, 0 - позиция visual = weapons\g36\wpn_g36_hud.ogf - модель, отображаемая у нас в руках Изменение описаний Описания оружия хранятся в файле: ...\S.T.A.L.K.E.R\gamedata\config\text\rus\string_table_enc_weapons.xml
В нем хранятся строки с названиями и описаниями, на которые ссылаются конфиги оружия. Например, тот же G36 ссылается сюда:
[...] <string id="enc_weapons1_wpn-g36"> <text>Штурмовая винтовка немецкого производства, представляющая собой первоклассный образец современного оружия - лёгкого, надёжного и эргономичного.\n Боеприпасы:\n обычный 5,56x45 мм SS109,\n бронебойный 5,56x45 мм АР.</text> [...] <string id="wpn-g36"> <text>ГП37</text> [...]Меняя их содержимое, мы меняем описания/названия данного оружия.
Изменение патронов Параметры патронов хранятся в файле:
Найдем, например, раздел, отвечающий за патроны к тому же G36 (о них мы узнали из параметра ammo_class), и разберем, что означает каждый параметр:
visual = weapons\ammo\ammo_556x45_ss190.ogf - модель коробки с патронами description = enc_weapons1_ammo_ammo-5.56x45-ss190 - ссылка на string_id, из которого игра подгружает описание этого типа патронов cost = 320 - стоимость одной коробки box_size = 30 - количество патронов в одной коробке inv_name = ammo-5.56x45-ss190 - ссылка на string_id, содержащий имя для инвентаря inv_name_short = ammo-5.56x45-ss190_s - ссылка на string_id, содержащий краткое имя для инвентаря inv_weight = 0.33 - вес inv_grid_width = 2 - координаты первого угла иконки по x inv_grid_height = 1 - координаты первого угла иконки по y inv_grid_x = 14 - координаты второго угла иконки по x inv_grid_y = 11 - координаты второго угла иконки по y
k_dist = 1 - коэффициент дальности, сама дальность - в стволе, тупо расстояние. k_disp = 2.5 - кучность, завязана с кучностью в стволе k_hit = 1 - убойность, завязана с убойностью в стволе k_impulse = 1 - чисто наскока эффектно ногами непись дрыгнет во время кердыка k_pierce = 1 - коэффициент наскока испорится броня при попадании
impair = 1 - коэффициент износа ствола от пули buck_shot = 1 - кол-во составляющих в пуле (напр картечь - 4, пуля - 1) tracer = on - является ли патрон трассирующим (on/off) wm_size = 0.05 - визуальный размер дырки на стене от пули
Для обычного монитора: секция худа(в руках актора) aim_hud_offset_pos= x,y,z;положение механического прицела. смещение вбок влево(-) вправо(+)/вверх(+) вниз(-)/вперед(+)назад(-), здесь совмещаем мушку и целик (+ и - относится к положению целика)
aim_hud_offset_rot= y,x,z ;смещение угла механ прицела. вверх(-)вниз(+)/влево(-) вправо(+)/вокруг оси, здесь подгоняем мушку под место, куда попадает пуля(смещается линия прицеливания).
Для широкоформатного: секция худа(в руках актора) aim_hud_offset_pos_16x9 = x,y,z;положение механического прицела. смещение вбок влево(-) вправо(+)/вверх(+) вниз(-)/вперед(+)назад(-), здесь совмещаем мушку и целик (+ и - относится к положению целика)
aim_hud_offset_rot_16x9 = y,x,z ;смещение угла механ прицела. вверх(-)вниз(+)/влево(-) вправо(+)/вокруг оси, здесь подгоняем мушку под место, куда попадает пуля(смещается линия прицеливания).
После правки запускаем игру и смотрим, потом выходим из игры правим, опять запускаем и смотрим. Муторно конечно но другого пути нет.
--[Телохранители]----[Добавлены два телохранителя]-- {"zat_stalker_bodyguard","st_bodyguard_name",sgm_flags.spot_actor_guard,"its_bodyguard",2100}, {"zat_stalker_bodyguard2","st_bodyguard_ name",sgm_flags.spot_actor_guard,"its_bodyguard",2100}, {"zat_stalker_bodyguard3","st_bodyguard_name",sgm_flags.spot_actor_g u a r d , " i t s _ b od yg uard",2100}, {"zat_bandit_bodyguard","st_bodyguard_name",sgm_flags.spot_actor_guard,"its_bodyguard",2300}, {"jup_freedom_bodyguard","s t_bo dyguard_name",sgm_flags.spot_actor_guard,"its_bodyguard",3600}, {"jup_army_bodyguard","st_bodyguard_name",sgm_flags.spot_ a c t o r _ g u a r d, "its_b odyguard",4000}, {"jup_killer_bodyguard","st_bodyguard_name",sgm_flags.spot_actor_guard,"its_bodyguard",3800}, {"pri_army_body guar d","st_b odyguard_name",sgm_flags.spot_actor_guard,"its_bodyguard",5000}, {"pri_monolith_bodyguard","st_bodyguard_name",sg m _ f l a g s . sp ot_act or_guard," its_bodyguard",6000},
Код
--Добавлены два телохранителя-- function check_minetrap_exception(npc) if r_mod_params("bool","create_mines_permition",true)==true and not has_alife_info("opt_deactivate_minetrap") then local pre_mt_exceptions=npc:profile_name()=="zat_b38_stalker_hunter" or npc:profile_name()=="zat_b30_owl_stalker_trader" or npc:profile_name()=="zat_b5_stalker_commander" or npc:profile_name()=="zat_b18_noah" or npc:profile_name()=="pri_a17_military_colonel_kovalski" or npc:profile_name()=="pri_a15_military_recon_leader" or npc:profile_name()=="pri_a22_military_merkulov" or npc:profile_name()=="pri_a15_sokolov" or npc:profile_name()=="pri_a15_sokolov_sci" or npc:profile_name()=="jup_b218_vano_in_suit" or npc:profile_name()=="pri_a21_sentry_lieutenant_stecenko" or npc:profile_name()=="jup_b207_merc_illicit_dealer" or npc:profile_name()=="jup_b220_trapper" or npc:profile_name()=="jup_a10_stalker_vano" or npc:profile_name()=="jup_b6_stalker_prisoner" or npc:profile_name()=="jup_b25_freedom_flint" or npc:profile_name()=="zat_b33_stalker_snag" or npc:profile_name()=="zat_b7_stalker_raider_leader" or npc:profile_name()=="zat_b42_mayron" or npc:profile_name()=="jup_b15_zulus" or npc:profile_name()=="jup_b19_freedom_yar" or npc:profile_name()=="zat_b215_stalker_guide" or npc:profile_name()=="zat_b20_noah_teleport" or npc:profile_name()=="zat_b53_artefact_hunter_1" or npc:profile_name()=="zat_b44_stalker_barge" or npc:profile_name()=="zat_b53_artefact_hunter_2" or npc:profile_name()=="pri_b305_strelok" or npc:profile_name()=="zat_b106_stalker_garmata" or npc:profile_name()=="pri_a28_evac_com" or npc:profile_name()=="jup_b219_zulus" or npc:profile_name()=="zat_b106_stalker_crab" or npc:profile_name()=="zat_stalker_elbrus" or npc:profile_name()=="zat_stalker_bodyguard" or npc:profile_name()=="zat_stalker_bodyguard2" or npc:profile_name()=="zat_stalker_bodyguard3" or npc:profile_name()=="zat_bandit_bodyguard" or npc:profile_name()=="zat_accompany_stalker" or npc:profile_name()=="zat_postman_stalker" or npc:profile_name()=="jup_freedom_bodyguard" or npc:profile_name()=="jup_follower_scientist_1" or npc:profile_name()=="pri_army_bodyguard" or npc:profile_name()=="zat_b106_stalker_gonta" if pre_mt_exceptions then return false end return true end return false end
В файл sgm_world.script добавим спавн телохранителей в начале игры:
Код
if level_name=="zaton" then if (not has_alife_info("zat_mod_npcs_spawner")) then create("zat_stalker_bodyguard",105.417,-1.338,179.173,1148335,316)
В файле xr_effects.script внесем следующие изменения:
Код
--Добавлены телохранители--- function bodyguard_command_4(actor,npc) news_manager.send_tip(db.actor,game.translate_string("st_bodyguard_commands_tip").." «"..npc:character_name().."» - "..game.translate_string("st_bodyguard_command_4_tip"),0,"bodyguard",6000,nil,"st_add_info_title") disable_info(npc:profile _ n a m e ( ) . . " _ st and_and_fire") disable_info(npc:profile_name().."_nofire") disable_info(npc:profile_name().."_stop") d is abl e_i nfo (np c:p rof ile_na me().."_release") disable_info(npc:profile_name().."_pursue") remove_spot_on_map(npc:id(),sgm_flags.spot_a ct or _g ua rd ) i f npc:profile_name()=="zat_stalker_bodyguard" then respawn_zat_stalker_bodyguard() elseif npc:profile_name()=="zat_stalker_bodyguard2" then respawn_zat_stalker_bodyguard2() elseif npc:profile_name()=="zat_stalker_bodyguard3" then respawn_zat_stalker_bodyguard3() elseif npc:profile_name()=="zat_bandit_bodyguard" then respawn_zat_bandit_bodyguard() elseif npc:profile_name()=="jup_freedom_bodyguard" then respawn_jup_freedom_bodyguard() elseif npc:profile_name()=="jup_army_bodyguard" then respawn_jup_army_bodyguard() elseif npc:profile_name()=="jup_killer_bodyguard" then respawn_jup_killer_bodyguard() elseif npc:profile_name()=="pri_army_bodyguard" then respawn_pri_army_bodyguard() elseif npc:profile_name()=="pri_monolith_bodyguard" then respawn_pri_monolith_bodyguard() end end function respawn_zat_stalker_bodyguard(actor,npc) create("zat_stalker_bodyguard",105.417,-1.338,179.173,1148335,316) d i sa bl e_ in fo (" za t_ st alke r_bodyguard_init") disable_info("zat_stalker_bodyguard_danger") end
--Добавлена функция респавна двух телохранителей-- function respawn_zat_stalker_bodyguard2(actor,npc) create("zat_stalker_bodyguard2",109.7,-1.338,177.8,1155250,316) d i sa bl e_ in fo (" za t_ st al ker_ bodyguard2_init") disable_info("zat_stalker_bodyguard2_danger") end
function respawn_zat_stalker_bodyguard3(actor,npc) create("zat_stalker_bodyguard3",116.8,-1.338,180.1,1165990,316) d i sa bl e_ in fo (" za t_ st al ker_ bodyguard3_init") disable_info("zat_stalker_bodyguard3_danger") end
В файле sgm_dialogs.script внесем следующие изменения:
Код
if npc:profile_name()=="zat_stalker_bodyguard" then xr_effects.respawn_zat_stalker_bodyguard() elseif npc:profile_name()=="zat_stalker_bodyguard2" then xr_effects.respawn_zat_stalker_bodyguard2() elseif npc:profile_name()=="zat_stalker_bodyguard3" then xr_effects.respawn_zat_stalker_bodyguard3() elseif npc:profile_name()=="zat_bandit_bodyguard" then xr_effects.respawn_zat_bandit_bodyguard()
Урок 17 Задача: Создание лагеря для НПС.
Для создания полноценного лагеря в котором звучит музыка и шутки-прибаутки, нужно создать смарт в распакованном all.spawn:
Код
[6464] ; cse_abstract properties section_name = smart_terrain name = zat_sh_padonki_smart position = 230.806,15.650,484.682 direction = 0,0,0
Теперь сквад попав на смарт будет отдыхать по полной программе, НПС займут места и будут травить анекдоты, музицировать при условии что их группировка прописана в файле sound_theme.script, а в звуковые схемы из файлов script_sound.ltx, script_sound_music_and_stories.ltx с параметром avail_communities также прописана новая группировка. И к стати чтобы НПС играл на музыкальных инструментах нужно чтобы этот самый инструмент был у него в инвентаре.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Где st_capture_meal_controller_name - название препарата, st_capture_meal_controller_description - описание препарата, нужно добавить в соответствующий файл для коректного отобрадения этих параметров. Основные настройки препарата: capture_meal_radius - максимальный радиус на котрором происходит захват, capture_meal_control - время в сек необходимое для захвата, capture_meal_charge - время в сек действия препарата после распаковки, если за это время не захватить контроллера то препарат будет использован в пустую, capture_meal_target - монстр на которого действует препарат.
Добавить препарат в продажу на пример Бороде, файл trade_zat_a2_barmen.ltx:
Включить вывод иконки контроллера на худ в файле sgm_huds.script:
Код
release_hud("hud_monster_capture_wnd") --------------Вывод на худ иконки захваченного контроллера---------------------------------- release_hud("hud_monster_capture_icon_controller")
release_hud("hud_mo nste r_capture_icon_chimera")
Изменить файл sgm_modules.script для отработки захвата следующим образом:
Код
elseif find_in_string(m_community,"chimera") then m_prefix="_chimera" --Добавить контроллра к захваченным-- elseif find_in_string(m_community,"controller") then m_prefix="_controller"
end
Код
elseif sgm_functions.read_variable("capture_meal_chimera_target") then sgm_flags.string_capture_monster_target="chimera" --Установка флага о захвате контроллера-- elseif sgm_functions.read_variable("capture_meal_controller_target") then sgm_flags.string_capture_monster_target="controller"
end
Код
if m_cap_charge<=0 then disable_info("capture_meal_active") release_hud("hud_monster_capture_wnd") rel eas e_hud("hud_monster_capture_icon_chimera") release_hud("hud_monster_capture_icon_gigant") release_hud(" hu d_monster_capture_icon_boar") release_hud("hud_monster_capture_icon_dog") release_hud("hud_monster_cap tu re_icon_flesh") release_hud("hud_monster_capture_icon_tushkano") release_hud("hud_monster_capture_icon _p seudodog") release_hud("hud_monster_capture_icon_snork") --Отображение на худе иконки захватываемого контроллера-- release_hud("hud_monster_capture_icon_controller")
Код
if m_cap_control<=0 then sgm_flags.value_capture_meal_monster_id=m_id object:kill(object) disa ble _info("capture_meal_active") release_hud("hud_monster_capture_wnd") release_hud("hud_monster_cap tu re_icon_chimera") release_hud("hud_monster_capture_icon_gigant") release_hud("hud_monster_captur e_ icon_boar") release_hud("hud_monster_capture_icon_dog") release_hud("hud_monster_capture_icon_fl es h") release_hud("hud_monster_capture_icon_tushkano") release_hud("hud_monster_capture_icon_pseud od og") release_hud("hud_monster_capture_icon_snork") --Отображение на худе иконки захватываемого контроллера-- release_hud("hud_monster_capture_icon_controller")
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 19 Задача: Создание динамических аномалий из ЗП.
Данный урок адресован тем, кто желает видеть в своем моде перемещающиеся аномалии, из ЗП. Конфиги этих аномалий можно найти в gamedata\configs\zones\
fireball_zone - огненная аномалия (Затон. В пещере под сгоревшим хутором и в аномалии "Цирк"); fireball_electric_zone - электра (Юпитер, в ж/д вагоне юго-восточнее бункера ученых и в тоннеле около "Копачей"); fireball_acidic_zone - хим аномалия (Припять. Аномалия "Лоза").
Итак, прежде всего создаем anm-файл, кидаем в gamedata\anims\camera_effects\scenario_cam\имя_локации\. Затем распакуем all.spawn, и создадим в alife-файле нужной локации секцию аномалии.
Код
[num]; свободный номер ; cse_abstract properties section_name = fireball_zone ; имя секции, другими словами тип аномалии name = fireball_zone_test ; имя объекта position = x, y, z ; координаты начальной точки, из которой аномалия начнет свой путь direction = 0,0,0
; cse_alife_object properties game_vertex_id = num ; gvid начальной точки distance = 0 level_vertex_id = num ; lvid начальной точки object_flags = 0xffffff3e
; cse_motion properties motion_name = camera_effects\scenario_cam\*.anm ; anm файл описания пути перемещения аномалии
; se_zone_torrid properties
* путь в anm-файле должен начинаться с точки, позициция которой указанна в all.spawn'е. ** желательно чтобы путь движения аномалии был закальцован. И... вот собственно и все. Запаковываем all.spawn, запускаем игру.
Рассматриваемые аспекты: Все основные параметры бустеров Создание иконки для нового бустера (+видео) Изменение пути к текстуре модели посредством использования WinHEX (только Видео) Собственно, создание бустера Урок 21 Задача: Создание 3D модели объекта "Яблоко" и текстур к нему. Файл с заданием
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014
Урок 22 Задача: Упаковка файлов мода для ЧН или ЗП в db-архив.
Как вы наверное знаете, для ТЧ, эту операцию можно проделать с помощью конвертера от товарища Бардака, используемую также для распаковки игровых ресурсов, или с помощью программы DB Packer 1.0. А вот для ЧН и ЗП, как оказалось, по данному вопросу в сети информации нет, или я плохо искал. Но, вспомнив про map_compressor, который идет в составе SDK, и немного поэксперементировав, я написал данный урок. Постарался описать все как можно подробнее, если возникнут вопросы, обращайтесь в личку.
Итак, мы делаем мод, следовательно в директории игры у нас есть папка gamedata, со всеми нашими правленными файлами.
Кидаем в корень игры, рядом с папкой gamedata файлы map_compressor'а (BugTrap.dll, build_map.ltx, compress_map.cmd, xrCompress.exe, xrCore.dll).
Откроем файл build_map.ltx. Что нам в нем необходимо подправить: Секция: options. Параметр exclude_exts - это расширения файлов которые игнорируются при упаковке. Например, если у вас в gamedata'е есть txt-файлы, с вашими заметками, то при упаковке они не попадут в архив (так сказать в чужие руки). Так же это очень удобно для разделения по нескольким архивам файлов одного типа. Следующие секции: include_folders и exclude_folders. Это перечень всех папок, которые будут включенны в состав архива, и проигнорированны соответственно. Например, запишем в первой из них textures = true, во второй textures\act = true. И в нашем архиве окажутся все текстуры из папки textures, кроме подпапки act, расположенной в ней. Секция-загололовок: header - содержит служебную инфомацию. Параметр entry_point желательно не изменять. * Параметр auto_load, должен равняться true, иначе архив не будет читаться движком.
В ходе экпериментов оказалось, что файлы, расположенные непосредственно в папке gamedata (например particles.xr, shaders.xr и др.), незапаковываются. Решение таково - создадим в build_map.ltx, между секциями exclude_folders и header новую секцию include_files, и по аналогии пропишем в неё наши файлы:
Теперь откроем файл compress_map.cmd и так же немного изменим его. Поменяем название папки for_levels на gamedata.
С приготовлениями все. Запускаем compress_map.cmd и ждем окончания процесса упаковки. Посмотреть результаты работы упаковщика можно в файле engine.log. Файлы компрессора нам более не нужны, и их можно удалить. Переименовываем полученный архив (он появится здесь же в корне игры), как нам понравится, например в mod.db, и... А куда же его лучше положить?
В результате экпериментов, я узнал что, чтение архивов происходит в том порядке, в каком это указанно в файле fsgame.ltx:
Поэтому, если мы в этот файл добавим еще одну строку, то создадим все условия для правильного порядка загрузки файлов мода. Вот эта строка:
Код
$arch_dir_mods$ = false| true| $fs_root$| mods\
Теперь осталось создать в корне игры папку mods, и поместить туда наш архив. Вот собственно и все, можно запускать игру.
P.S. Все эксперименты делались на ЗП. Экспериментальный мод содержал: дополнительную локацию, новые текстуры, скрипты, модели, файлы анимации камеры, all.spawn, правленный gamemtl.xr. Ни каких проблемм обнаруженно не было. Распаковка с помощью конвертера от Бардака показала полную идентичность исходной, подготовленной к упаковке gamedata'ы и распакованной. Так же проведенна проверка на ЧН.
IP-адрес: Страна: Российская Федерация Город: Москва Дата регистрации: 25.10.2014