World Editor - маловато будет. Давайте курить формат карт., Дополнительные утилиты для картографии? |
Здравствуйте, гость ( Вход | Регистрация )
World Editor - маловато будет. Давайте курить формат карт., Дополнительные утилиты для картографии? |
Ather |
9.9.2015, 15:00
Сообщение
#11
|
Word-O-Lak
Группа: ВетераныСообщений: 1 476 Регистрация: 24.7.2009 Из: Витебск Пользователь №: 3 719 |
Впринципе написать конвертер не слишком сложно, если будут полные данные чего во что конвертировать. Ибо на реверс инжиниринг времени у меня нет, а на формулировку алгоритма найдется.
-------------------- А зачем вникать в умные мысли? Главное — уметь их цитировать! © Я
Всякая экономия в конечном счете сводится к экономии времени. © К. Маркс 3-е местоКонкурс прозы №3 «Таинственная» наградаКонкурс прозы №3 2-е местоКонкурс прозы №5 2-е местоКонкурс прозы №6 2-е местоКонкурс прозы №7Cамый последний конкурс на нашем Форуме На мотив песни Черный ворон: Бееедный аааффтаар, что ж ты бьееешьсяаа Да об стееену головооой. Ты мозгооов не набереееешься, Выпей йааадуу, ты тупооой!.. © Баш Не принимайте на свой счёт! |
Saruman |
11.9.2015, 2:27
Сообщение
#12
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
Немного пошерстил английские форумы по данной теме - первое ощущение такое, что найти где в *.mob файлах зашиты координаты - не проблема, и соответственно "подвинуть" объекты, поменяв соответствующим образом координаты - тоже не самая большая проблема, если знаешь куда переезжает сектор.
Но вот "клонировать" сектор, я так понимаю, несколько сложнее т.к. у каждого .mob должен быть свой уникальный идентификаторы, который прописан как в внутри файла, так и в его имени, и соответственно для клонирования нужен механизм, который будет создавать новые идентификаторы так, чтобы движок ими не подавился. В выходные попробую еще пошарить по ресурсам и попрововать поискать оффсеты координат в .mob-файлах (насколько понял, они находятся в разных местах для файлов разных типов объектов). -------------------- |
Saruman |
13.9.2015, 21:18
Сообщение
#13
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
Немного разобрался с .mob файлами - нашел offset'ы координат на карте:
Код NPC: x: 4f 64 71 7a y: 53 68 75 7e Items x: 4b y: 4f В случае с items имеют место также что-то вроде микро-координат внутри тайла - до конца в них не разобрался, но объекты двигаются корректно правкой основных координат и без их редактирования. Запись координат в .mob файлах начинается указанного offset, при этом форма записи в шестнацатиричном формате инвертирована по байтам: Код 4094 (цесятеричная координата в редакторе) -> 0FFE (шестнацатиричное представление координаты) -> FE0F (координата, записанная в .mob файле) то есть порядки записываются начиная с нижних и заканчивая верними, но при этом в рамках одного байта порядок сохраняется. Также лично для себя разобрался в записи координат сектора названии файла: Код Filename.sec = hex_to_dec(dec_to_hex((Sector_Y * 4) div 16) * 0x10000000 + dec_to_hex((Sector_Y * 4) mod 16) * 0x1000000 + Sector_X) где Sector_X, Sector_Y - десятеричные координаты сектора (начиная с 0), div, mod - соответственно целая часть и остаток от деления нацело, dec_to_hex и hex_to_dec - соответственно перевод из десятеричной в шестнадцатиричную систему счисления и наоборот. Теперь нужно разобраться в записях .sec файлов, найти где и как хранятся координаты статических объектов и найти их offset'ы и порядок записи. Также остается открытым вопрос генерации GUIDов. -------------------- |
T'e'MHbIu` |
13.9.2015, 22:26
Сообщение
#14
|
Мифотворец
Группа: СвоиСообщений: 1 440 Регистрация: 23.11.2006 Пользователь №: 72 |
Сильное колдунство
Цитата Теперь нужно разобраться в записях .sec файлов Дык.. не оно? (из ссылки парой постов выше) Исходный код Arcanum Sector file (.sec) format. Extracted from ToEE WB sources and WorldEd. Uint32 lights_count LIGHT lights[lights_count] //each light seems to be 48 bytes long Uint32 tiles[4096] Uint32 roofs[256] Uint32 placeholder for now don't know about what info tiles array holds For now I got how you can get tile art file from tile Uint32. Base tiles are divided into 4 groups by 2 parameters: is_flippable and is_outdoor. Plus there is special group which connects tile to tile, like dirt to grass transitition. Art prefix is defined in /art/tile/tilename.mes file. It's commented so I won't copy this here. Group starts from 0, 100, 200, 300 and 400, for each group indexes are started from 0. So i.e. tile with id 101 in tilename.mes will have tile_id = 1 (we'll need this later) It seems that there are like 2 versions of tiles, first one with 4 most significant bits = 11 (v1) and other with this 4 bits = 0 (v2). Table below shows how you can get data for both versions: Data v1 v2 outdoor d >> 25 & 1 d >> 8 flippable d >> 26 & 1 d >> 7 & 1 tile_id d >> 11 & 0x3F d >> 22 & 0x3F Art name is generated from tile prefix or 2 prefixes if this is connecting tile and 2 chars. Chars are based on numbers extracted from tileid, for v1 they, however, are always 0. We'll need two arrays for v2 numbers: 0x0, 0x1, 0x2, 0x9, 0x4, 0x5, 0xC, 0xD, 0x2, 0x9, 0xA, 0xB, 0xC, 0xD we'll call this array char_2_array since we'll need it later 0x0, 0x1, 0x8, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x3, 0xA, 0xB, 0x6, 0x7, 0xE, 0xF this one we'll name char_1_array For v2 char_2 if tile_id least significant bit is set number is char_2_array[d >> 12 & 0xF], otherwise d >> 12 & 0xF For v2 char_1 char_2 value is needed, if char_2_array[char_2 number] equals char_1_array[char_2 number] and least significant bit is set, value is (d >> 9 & 7) + 8, otherwise d >> 9 & 7 Char values are calculated like that: if char_1 number value >= 8, its value is decreased by 8 char_1 value is 'a' + char_1 number, i.e. if char_1 number = 0, char_1 will be 'a', 1 - 'b' for char_2 there is a string '06b489237ea5dc10' if char_2 number is 15 or 0, So first you should get which group you are dealing with, flippable and outdoor flags are: here should be unknown 48-byte long chunk, started with bytes 00 01 00 00 00 04 00 aa, but I found file where this doesn't hold =\ also WB uses this magic to find where the lights chunk is ended, just looking for this bytes and substracting 4096*4(size of tiles) here comes sector objects, which structure is undefined now, but objects can be looked-up by pattern: offset val 0x00 0x77 0x01 0x00 0x02 0x00 0x03 0x00 0x04 0x00 0x05 0x00 0x1c 0x00 0x1d 0x00 0x1e 0x00 0x1f 0x00 0x20 0x00 0x21 0x00 0x22 0x00 0x23 0x00 From each object we can now get following: offset size name 0x0C 2 bytes proto_id 0x34 4 bytes mob_type 0x3A + type_skip*4 - 1 4 bytes x_coord //type_skip see later 0x3E + type_skip*4 - 1 4 bytes y_coord type_skip depends on mob_type: mob_type mob_name type_skip 1 Portal 4 2 Container 4 3 Scenery 5 4 Projectile 5 5 Weapon 7 6 Ammo 7 7 Armor 8 8 Money 8 9 Food 8 10 Scroll 8 11 Key 9 12 Written 9 13 Generic 9 14 PC 11 15 NPC 13 16 Trap 13 17 Bag 9 -------------------- |
Saruman |
14.9.2015, 1:11
Сообщение
#15
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
Оно самое, осталось найти время чтобы потр***** с этим, плюс если дело пойдет надо что-то кодить. Я сначала думал сделать python-скрипты, но, видимо, лучше всё же будет что-то с графическим интерфейсом, так что надо будет освежить навыки.
-------------------- |
T'e'MHbIu` |
14.9.2015, 11:46
Сообщение
#16
|
Мифотворец
Группа: СвоиСообщений: 1 440 Регистрация: 23.11.2006 Пользователь №: 72 |
По сути, для гуя атрибутов не так уж много:
-Путь к каталогу "откуда" -Путь к каталогу "куда" (либо атрибут - "туда же") - 4 координаты "откуда" (выделяем прямоугольник двумя точками X1;Y1;X2;Y2) - 2 координаты "куда" (X;Y) - атрибут "копируем/переносим" Подумаешь, передать в командной строке 8-9 параметров По поводу GUIDов.. все-таки они довольно рандомны . Даже с координатами не коррелируют. Может, привязка к наносекундам, прошедшим с 1 января 1885 г? -------------------- |
Saruman |
25.7.2016, 20:01
Сообщение
#17
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
Апдейт (почти через год, но лучше поздно чем никогда) по GUID'ам в .mob-файлах:
Наткнулся на опен-сорсный исходный код на C# от World Builder для Temple of Elemental Evil, который был построен на модифицированном движке от Arcanum'а https://github.com/13xforever/toee-world-builder. Вот как там запилена генерация GUID'а (файл /src/ToEE World Builder/Helpers/MobHelper.cs): Код public static void GenerateGuid(out string s_GUID, out byte[] GUID) { var r = new Random(); var generator = new byte[16]; GUID = new byte[24]; s_GUID = "G_"; GUID[0] = 0x02; GUID[1] = 0x00; GUID[2] = 0x00; GUID[3] = 0x00; GUID[4] = 0x00; GUID[5] = 0x00; GUID[6] = 0x00; GUID[7] = 0x00; r.NextBytes(generator); GUID[11] = generator[0]; GUID[10] = generator[1]; GUID[9] = generator[2]; GUID[8] = generator[3]; GUID[13] = generator[4]; GUID[12] = generator[5]; GUID[15] = generator[6]; GUID[14] = generator[7]; for (int j = 16; j < 24; j++) GUID[j] = generator[j - 8]; for (int k = 0; k < 16; k++) { string s_Elem = generator[k].ToString("X"); if (s_Elem.Length == 1) s_Elem = "0" + s_Elem; if (k == 3 || k == 5 || k == 7 || k == 9) s_GUID += s_Elem + "_"; else s_GUID += s_Elem; } return; } Как можно видеть, генерация полностью рандомна, за исключением некоторого шаманства с байтами с 9го по 16ый. Остальной код проекта я не смотрел, но подозреваю, что если при генерации вдруг возникнет GUID, уже существующий у другого .mob-объекта (вероятность чего, по всей видимости, КРАЙНЕ МАЛА) - это легко будет проверить по списку всех .mob-объектов в модуле и при необходимости заново его сгенерировать. Предполагая, что данный софт работал (а судя по двум крупным релизам и неоконченной версии 3.0 это так), можно предположить что просто рандомных GUID'ов и проверки на совпадение будет достаточно для копирования .mob-объектов при выполнении copy-paste. -------------------- |
Saruman |
26.7.2016, 2:57
Сообщение
#18
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
Долго вглядывался в получающиеся sec-файлы и в ман Криптона:
Код here comes sector objects, which structure is undefined now, but objects can be looked-up by pattern: offset val 0x00 0x77 0x01 0x00 0x02 0x00 0x03 0x00 0x04 0x00 0x05 0x00 0x1c 0x00 0x1d 0x00 0x1e 0x00 0x1f 0x00 0x20 0x00 0x21 0x00 0x22 0x00 0x23 0x00 From each object we can now get following: offset size name 0x0C 2 bytes proto_id 0x34 4 bytes mob_type 0x3A + type_skip*4 - 1 4 bytes x_coord //type_skip see later 0x3E + type_skip*4 - 1 4 bytes y_coord type_skip depends on mob_type: mob_type mob_name type_skip 1 Portal 4 2 Container 4 3 Scenery 5 4 Projectile 5 5 Weapon 7 6 Ammo 7 7 Armor 8 8 Money 8 9 Food 8 10 Scroll 8 11 Key 9 12 Written 9 13 Generic 9 14 PC 11 15 NPC 13 16 Trap 13 17 Bag 9 Заметил, что 77 00 00 00 хорошо работает как маркер объекта - можно безошибочно найти все, не набрав мусора. Однако Криптон пишет, что нулевых байтов должно быть 5, а у меня во время экспериментов появляется только 3. Глядя на то, что должно быть координатами исходя из предложенных Криптоном оффсетов, создается впечатление что объекты в файле записаны в рандомном порядке - в двух соседних идентичных по наполнению секторах у первого объекта не совпал ни X, ни Y. Правда возможно я не на то смотрю - формулу оффсета я считал в десятичных числах, вначале конвертировав первое число, а возможно имелось в виду, что mob_type тоже - шестнадцатиричный и складывать нужно соответственно. Также не исключена кривая запись координат как в случае с координатами в .mob-файлах. Буду пробовать дальше. -------------------- |
Saruman |
28.7.2016, 2:18
Сообщение
#19
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
Начал с простого - взял пустую "водную" карту и начал смотреть на координаты простых статиков типа "дерево". Для них нашлись координаты (по всей видимости 4 байта длиною, как описал Криптон) со смещением в 71 и 75 байтов соответственно от первого байта статика со значением 77.
Манипуляции с этими значениями закономерно привели к тому, что статики "поплыли" в нужном направлении, и при изменении значения на n*64, n ∈ N оказывались в соотвествующих n секторах выше/ниже/левее/правее. Теперь предстоит поэкспериментировать с более сложными статиками типа стен, но достаточные для первых скриптовых экспериментов на Питоне или типа того результаты уже близко. -------------------- |
Saruman |
30.7.2016, 16:08
Сообщение
#20
|
Старатель
Группа: СвоиСообщений: 370 Регистрация: 5.3.2008 Из: Brooklyn, NY Пользователь №: 2 372 |
То же самое получилось совершить и со стенами - смещение для них оказалось 75 байтов для X и 79 байтов для Y соответсвенно. Попробовал вручную перенести сектор с находящимся в нём домом: переименовал .sec файл сектора с учётом его новых координат, пропатчил все координаты статиков в файле с учётом переноса в соседний сектор (на 64 по Х), результаты на скринах ниже. Теперь нужно поэкспериментировать с остальными статиками и распознаванием типа статика (верифицировать соображения Криптона), которое будет необходимо для автоматизации патчинга координат.
Эскизы прикрепленных изображений -------------------- |
Текстовая версия | Сейчас: 22.12.2024, 5:10 |