Мини гайд на работу с файлами игры и текстурами

iCevbyt

Keltir
Messages
7
Reaction score
10
Нижеследующее графоманство только для тех, кто ранее совсем не знал, как можно хоть что-то в клиенте игры поменять, но у кого очень уж чешутся руки...



Нам потребуется:

Графический редактор - Paint.NET https://paintnet.ru/download/
Тестовый редактор - Notepad++ https://notepad-plus-plus.org/downloads/
Программа для сравнения файлов - WinMerge https://winmerge.org/downloads/?lang=ru

Утилита для декодирования Л2 протоколов - l2encdec https://mega.nz/file/PlZhUBBY#JDKTFOzh8F8Ue3mIvHwItW8_ynajd4eUqJlKui5pbHU
Утилита для просмотра и экспорта текстур - umodel https://mega.nz/file/615xTQjJ#xQLSGD6RggvnOyOjJ0yIU5RiJlNCXeu3e_vZZMFaBv0
Утилита для замены текстур в пакетах - l2tool https://mega.nz/file/X0wRyC4B#iFiJ6ZyR8k-eBSwN1pCSs_oihRvUjnANrF7kEo49rnY
Утилита для работы с объектами под движок Unreal2 - UnrealEd https://mega.nz/file/egBFzZ7Q#zGORMvNB_jbIqjHYiMTqPLxItRfEZiTkEpdZQB4HbTk


0/ Договоримся, что работать будем с папками и файлами, не содержащими пробелы в названиях, без кириллицы/иероглифов и тп.


1/ Начнем с самого простого, дабы почувствовать силу

Скажем, нашему спойлеру в силу возраста тяжело вчитываться в системный чат и искать там заветную строчку "The Spoil condition has been activated."
Хотим, чтобы она выделялась как-то...

Нам нужен файл SytemMsg-e.txt из папки System с игрой
Копируем его в папку с утилитой l2encdec, ставим курсор в полянку "путь" в проводнике
1763710049986.png
и пишем туда cmd
1763710069660.png
Жмем enter, запускается командная строка, директория выбрана сразу та, где лежат наши утилиты. Это удобно.

Выполняем команду l2encdec.exe с параметрами -d <путь к файлу>
l2encdec.exe -d SystemMsg-e.txt
1763710101833.png

С помощью клавиши Tab можно перебирать файлы из текущей директории, подходящие под введенную маску имени файла, например, ввели первые два символа l 2 с клавиатуры и вместо того чтобы дальше вводить e n c d e c просто нажали Tab, аналогично - ввели первые 3 буквы sys, нажали Tab, подставилось полное имя файла, это вместо того чтобы вводить имя файла целиком, тратить время и иметь риск опечатки. Tab можно жать несколько раз, прокручивая файлы по порядку. Если пропустили - Shift+Tab, чтобы листать в обратном направлении


Обращаем внимание на версию 211, запоминаем это число (для других хроник и других регионов будет указана другая версия).
Появился раскодированный файл dec-SystemMsg-e.txt

Его открываем в текстовом редакторе Notepad++
Часто удобно бывает настроить Вид -> Перенос строк.

Жмем Ctrl+F (это диалог поиска), вводим Spoil, жмем "Найти все в текущем документе"
1763710297378.png

Внизу список всех совпадений. По нашему сценарию нас интересуют 2 строчки - "Спойл успешно прошел" и "Уже проспойлено"

Заменим в них сообщение msg на что-то более визуально выделяющееся, например, пусть выглядит так:
msg_begin id=612 group=[none] msg=[/////////// SPOIL ACTIVATED \\\\\\\\\\\\] msg_end
msg_begin id=357 group=[none] msg=[/////////// ALREADY SPOILED \\\\\\\\\\\\] msg_end

Сохраним файл.

И обратно закодируем в формат, ожидаемый клиентом, выполнив:
l2encdec.exe -e 211 dec-SystemMsg-e.txt

Повился файл enc-dec-SystemMsg-e.txt; переименуем его в SystemMsg-e.txt (если оригинальный systemMsg-e не удалили - удалите, иначе не даст сохранить в эту же папку) и перенесем в папку с игрой с заменой старого файла (или переименуем предварительно старый файл, бекапа для..).

Запускаем клиент и смотрим результат. Довольствуемся выполненным.

Пока редактировали строки со спойлом, могли заметить, что для некоторых событий есть служебные параметры $s1 $s2 и тд, например:
msg_begin id=299 group=[none] msg=[$s1 picked up $s3 $s2.] msg_end

Это переменные, клиент подставит вместо них полученные от сервера значения. В нашем случае
$s1 - имя игрока
$s2 - название предмета
$s3 - количество
В других сообщениях переменные другие, но по контексту всегда достаточно просто догадаться, что именно там будет подставляться.


Пример файла, как можно поменять сообщения тут. Или, если хочется такой же чат, как у про-игроков, то тут


2/ Движемся дальше...
Представим, что наш гном не просто подслеповат, а вообще дальтоник, и в очередной раз успел "урвать" на рынке gemstone D по 13к, думая, что покупает SoP-ы (каждый же так попадал, да? ведь так, да?)

Решительно исправим этот момент, покрасив иконку гема в синеватый оттенок..

Ищем в папке system файл Itemname-e.txt, раскодируем его, и найдем там Gemstone D.
Посмотрим его ID-шник, id=2130

Кстати, name=[Gemstone D] Это имя отображаемое в инвентаре, а description=[] Это описание предмета, если оно есть (в нашем случае нет).

И их тоже можно поменять... Скажем, путаетесь вы в иконках свитков воскрешения, а название не влезает целиком, и приходится читать описание... Можете поменять название

было
item_name_begin id=4959 name=[Harbor Event - Scroll of Resurrection] description=[A magic scroll that resurrects a dead player and restores all his/her experience] item_name_end
item_name_begin id=4960 name=[Harbor Event - Scroll of Resurrection 20%] description=[A magic scroll that resurrects a dead player and restores 20% of his/her experience] item_name_end

Изменим имя name=[Harbor Event - Scroll of Resurrection] на [Blessed Scroll of Resurrection], а name=[Harbor Event - Scroll of Resurrection 20%] на [20% Scroll of Resurrection]

Сохраним изменения, кодируем файл (снова протокол 211), заменяем файл в папке игры.

Запускаем клиент и смотрим результат. Довольствуемся выполненным..


Возвращаемся к нашему гему, раскодируем файл etcitemgrp.txt, и найдем там поиском id=2130

item_begin object_id=2130 object_name=[gemstone_d] drop_type=0 drop_anim_type=3 drop_radius=2.7 drop_height=5 drop_mesh={[dropitems.drop_sack_m00]} drop_texture={[dropitemstex.drop_sack_t00]} icon={[icon.etc_crystal_ball_silver_i00]} mesh={[none]} texture={[none]} crystallizable=0 drop_sound=[ItemSound.itemdrop_etc_sack] equip_sound=[none] etcitem_type=material weight=2 consume_type=consume_type_stackable material_type=liquid crystal_type=none durability=0 item_end

смотрим на параметр icon={[icon.etc_crystal_ball_silver_i00]}
текстура иконки лежит в файле icon, название текстуры etc_crystal_ball_silver_i00
Запомнили.

Запускаем программу для замены текстур l2tool (для этого дважды кликаем на батник l2tool_starter.bat) (нужна установленная java runtime машина, предложит поставить, если еще нет, ну или самим https://www.java.com/en/download/manual.jsp).

Указываем пакет - icon.utx из папки с игрой из папки sysTextures
Начинаем вбивать имя etc_crystal_ball.. и выбираем нужную нам текстуру из выпадающего списка. Обращаем внимание на расширение
.dxt1, именно этот протокол сжатия нам нужно будет указать в дальнейшем. Можем посмотреть с помощью кнопки View, или сразу выгружаем с помощью кнопки Export в удобную для нас папку (напоминаю, про пункт 0/ - не пользуемся папками, в названиях которых есть пробелы или кириллица)
1763711563632.png

Открываем экспортированный файл редактором Paint.NET

С помощью инструмента "Выбор области овальной формы", выделяем наш гем (чтобы не трогать фон), используя инструмент "Кривые" из раздела "Коррекция", выкручиваем синюю составляющую вверх, а яркость убавим, чтобы на цвет соски Д было похоже...
1763711484135.png

Сделали, сохраняем в формате .dds (или .tga) под таким же именем, а вот метод сжатия меняем с dxt3, который по умолчанию предлагает Paint, на dxt1

В утилите l2tool через нижнее диалоговое указываем путь до файла и жмем Replace.
1763711589454.png


Запускаем клиент и смотрим результат. Довольствуемся выполненным.

... и да... и нет... Способ, конечно, рабочий, но топорный, в следующем примере, разберемся почему.

Заглянем снова в файл etcitemgrp, и поиском найдем все etc_crystal_ball_silver_i00
Их нашлось аж 5 штук
1763711665971.png

Т.е. мы заменили 1 текстуру, а эта текстура использовалась для 5 разных предметов. Конкретно в нашем примере, это не Бог весть какие квестовые итемы, притом с проходных квестов.. так что пойдет и так. Но может быть потребность внести точечное изменение, путем добавления новой текстуры (модели, анимации, звука и тп)


3/ Итак, еще один сценарий и вводная - Не нравится нашему герою, как на людишках-магах смотрится композит. Отвратительно смотрится... и даже с С3 текстурами, ибо в С3 он такой же как в С1 [в этом примере работать будем с установленным патчом С3 и непосредственно с его файлами].

Пусть уж лучше на Full Plate будет походить. Но, дабы их различать, уберем подстежку, стилизованную под шахматную доску, добавим стального оттенка и больше золота в узоры, да и сами узоры сделаем более похожими на композит эльфийской работы. В общем поставим хорошее такое ТЗ нашей знакомой 2D-3D дизайнерше, а если таковой нет... то, во-первых, это Ваш большой косяк в жизни, а во-вторых, как-нить сами уж накалякаем...

Ессно не с нуля модель рисовать будем, оставим каркас (mesh) в точности как у ФП, а саму текстуру достанем из пакета из патча С3.

Сперва посмотрим, где такая лежит:
Раскодируем armorgrp.txt
Найдем поиском full_plate

item_begin object_id=356 object_name=[full_plate_armor] body_part={CHEST} drop_type=0 drop_anim_type=3 drop_radius=9.5 drop_height=6 drop_mesh={[dropitems.item_cloth_jacket_m00]} drop_texture={[DropItemsTex.MMagic_m005_t01_u1]} icon={[icon_c3.armor_t62_ul_i00];[icon_c3.armor_t62_u_i00];[icon_c3.armor_t62_l_i00]} mfighter_mesh={[fighter.mfighter_m008_u];[fighter.mfighter_m008_l]} mfighter_texture={[mfighter_c3.mfighter_m008_t62_u];[mfighter_c3.mfighter_m008_t62_l]} ffighter_mesh={[fighter.ffighter_m008_u];[fighter.ffighter_m008_l]} ffighter_texture={[ffighter_c3.ffighter_m008_t62_u];[ffighter_c3.ffighter_m008_t62_l]} mmagic_mesh={[magic.mmagic_m008_u];[magic.mmagic_m008_l]} mmagic_texture={[mmagic_c3.mmagic_m008_t62_u];[mmagic_c3.mmagic_m008_t62_l]} fmagic_mesh={[magic.fmagic_m008_u];[magic.fmagic_m008_l]} fmagic_texture={[fmagic_c3.fmagic_m008_t62_u];[fmagic_c3.fmagic_m008_t62_l]}.......


Видим название пакета: для мужчины мага mmagic_texture={[mmagic_c3. (для женщины fmagic_c3)
Название текстуры: верх mmagic_m008_t62_u (для мужчины); _l низ (ботинки _b, перчатки _g, _ul верх-низ вместе, но тут, несмотря на то, что компот и ФП как раз цельные, текстуры все же отдельные, а вот в иконках такое используется, см icon={)

Воспользуемся утилитой umodel, запускаем утилиту с параметрами -export <путь к файлу> (файл mmagic_c3.utx из директории SysTextures, как и в самом 1-ом примере гайда, скопируем в папку с утилитой ради удобства)
1763712004173.png

Открываем файл MMagic_m008_t62_u_ori.png (ori - слой текстуры, sp - слой отражений) в Paint.NET, редактируем его в силу кривизны рук, например, так:
1763712034935.png

Сохраняем в формате dds, сжатие dxt1/dxt3, под новым названием (как видно на скриншоте выше, наши доработки на полноценную новую текстуру ну никак не тянут, можно даже сказать почти халтура, а значит и больше, чем литеры "а" в имени, он не заслуживает..) mmagic_m008_t62a_u_ori.dds

Вообще композит t61, и стоило бы называть t61a, чтобы в будущем не запутаться при поиске.. но уже поздно, да и не суть

Теперь запускаем Unreal Editor. По умолчанию открывается инструмент Texture Browser (он нам и нужен).
1763712226557.png

File -> Open -> выбираем mmagic_c3.utx
В фильтрах выбираем блок UpBody, ищем FP верх, низ mmagic_m008_t62
File -> Import, выбираем наш отредактированный файл (если работали с файлом отражений и бликов, то импортируем еще и _sp. в этом конкретном примере отражения не трогали, просто скопировали под новым названием)

Создадим шейдер, который обработает блики и прозрачность (со слоем прозрачности мы не работали вообще сейчас, но движок поддерживает, вот кстати ссылочка на хороший гайд, правда на собачьем языке )

File -> New
Имя задаем для единообразия без суффикса (в нашем примере - это MMagic_m008_t62а_u, файл текстур называется MMagic_m008_t62а_u_ori, блики - MMagic_m008_t62a_u_sp).
1763712489408.png

И настраиваем параметры, вставляя имена файлов (texture, map и программа подставит сама) (значение twosided = true не забываем выставить). Параметры для бликов (EnvMap2) скопированы от FP (подсмотреть их можно, выбрав шейдер (он подсвечивается красной рамкой) и нажав правой клавишей -> Properties). В общем делаем так, чтобы было аналогично оригинальному FP
1763712465381.png

Закрываем диалог.
Проделываем аналогичные действия для нижней части брони mmagic_m008_t62_l.

И сохраняем пакет (можно переименовать, например, в mmagic_c3a.utx). Помещаем его в папку с игрой в SysTextures.

Возвращаемся к файлу armorgrp, меняем там (обрати внимание! "там" - это в описании композита object_id=60 object_name=[composite_armor]. FP мы смотрели ранее только потому, что его текстуры брали за основу) ссылки на наш новый пакет и на текстуры:

Вместо item_begin object_id=60 object_name=[composite_armor] body_part={CHEST} drop_type=0 drop_anim_type=3 drop_radius=9.5 drop_height=6 drop_mesh={[dropitems.item_cloth_jacket_m00]} drop_texture={[DropItemsTex.MMagic_m005_t01_u1]} icon={[icon_c3.armor_t61_ul_i00];[icon_c3.armor_t61_u_i00];[icon_c3.armor_t61_l_i00]} mmagic_mesh={[magic.mmagic_m006_u];[magic.mmagic_m006_l]} mmagic_texture={[mmagic.mmagic_m006_t45_u];[mmagic.mmagic_m006_t45_l]}

Стало mmagic_mesh={[magic.mmagic_m008_u];[magic.mmagic_m008_l]} mmagic_texture={[mmagic_c3a.mmagic_m008_t62a_u];[mmagic_c3a.mmagic_m008_t62a_l]}


Запускаем клиент, создаем мага, качаем до 40, одеваем в композит, смотрим результат... Довольствуемся выполненным!


Ну что ж.. Красиво стелишь, скажете вы.

А нет, про тот самый нюанс я тоже напишу.
И заключается он в том, что чем больше изменений вы внесете, чем больше файлов переделаете для удовлетворения чувства прекрасного либо просто удобства для - тем больше трудозатрат вам будет требоваться после каждого апдейта оригинального клиента (выявить изменения можно с помощью программы winmerge, ссылка вверху поста, нажимаем "Открыть", скармливаем 2 файла (наш и от оригинального клиента), нажимаем "Сравнить", выставляем одинаковую кодировку внизу под каждым файлом). И тем больше несовместимостей будет всплывать со сторонними патчами. Без актуализации ваших доработок со временем у вас появятся черные иконки вместо новых предметов, вместо новой шапки - откушенная половина лица, а вместо рождественнской елки и носочков с подарками - только их тень. Для дешевой же актуализации нужна автоматизация, сиречь снова трудозатраты...

Впрочем, если вы прочитали столько букв, то руки у вас и впрямь чешутся.. ну.. дерзайте. успехов!
 
Last edited:
Для дешевой же актуализации нужна автоматизация
Или же связывать с администрацией со своими предложениями, помогать им с правками клиента, чтобы в итоге эти правки все были в дефолтном клиенте проекта. И тогда не нужно каждый апдейт что-то обратно править, а заодно и у остальных всё будет так же смотреть в клиенте... =)
 
Нам потребуется:
Потрясающий гайд для новичков, да, не без нюансов которые тут не описаны (мипмэпы например, а они очень важны), но для разгона настроя тех, кто хочет нырнуть и не решается - самое то, автор молодец. 🐥
 
Да, настолько подробный гайд - это круто. А настолько подробный гайд по вытягиванию моделей с анимациями не завалялся где-то?
 
До анимаций я пока не добрался, да и просто по части порекомендовать какую-нить толковую статью или тему, увы, не могу
 
А можно ли сделать, например, чтобы тот же компот выглядел как Nightmare Heavy Set?
Можно... Nightmare уже добавлен в патче С3. Тут ничего рисовать, править и выдумывать самому не надо.
Раскодировать, скопировать 3 строчки с другой брони в нужную, закодировать.

1763729995010.png


Только сразу предостерегу...оно вам точно надо? А-сэты смотрятся очень вычурно, зачем тогда заморачиваться и крабить на Б?..
 
gUQjsV3xMmlDORJeRdFF1LsrzRYoFNhTVOhaGWhS.jpg
 
Кстати, о стенке замка, серьезный вопрос - подскажите, кто знает, где искать текстуры ворот?
Хочется сделать последнюю стадию, когда створка уже почти окончательно сломана, наоборот менее разрушенной, а то там торчит совсем 1 доска уж, да и та у самого края, и народ часто ее не замечает и ломится в невидимую преграду, негодуя...
 
Кстати, о стенке замка, серьезный вопрос - подскажите, кто знает, где искать текстуры ворот?
Хочется сделать последнюю стадию, когда створка уже почти окончательно сломана, наоборот менее разрушенной, а то там торчит совсем 1 доска уж, да и та у самого края, и народ часто ее не замечает и ломится в невидимую преграду, негодуя...
наверное это в НПЦ где-то. Если не ошибаюсь, то ворота и стенки разрушаемые -- это НПЦ в игре.
 
Спасибо за гайд,дочитал до конца и сделал только один выввод: как же сложно всё это и как много работы нужно чтобы добавить изменения в ц1... это конская работа!
 
Спасибо за гайд,дочитал до конца и сделал только один выввод: как же сложно всё это и как много работы нужно чтобы добавить изменения в ц1... это конская работа!
А это только клиент. Представь, что там в серверной части ещё, когда пытаешься квест добавить или шмотку новую в базу...
 
Back
Top