Разбирался я в игре с нуля. Сначала я ютился на островке, куда попал после спавна. Отстроил домик, который постоянно сносили криперы, кое-как пережидал ночи, пока не обнаружил овец неподалёку на материке (для крафта кровати). Количество смертей шло на десятки...
Потом кое-как освоился, разработал сеть штреков, обнаружил пару каньонов. И стало мне тесновато на острове, решил посмотреть мир. Почитал про карты и пошёл по континенту, поплыл по морям-океанам. Повесил на стене составную карту мира, где флагами отмечал деревни. Много проблем было с вымиранием жителей в деревнях после их открытия. А деревни мне нравилось отстраивать, чтобы там куча жителей была, станков и живности. Стало проблематично учитывать, в какой деревне какие ресурсы, животные, где какие станки поставил, какие забыл. Начал на бумажке записывать. А, ещё давал деревням названия, правда, не сразу. И координаты стал записывать - ещё позже. Когда бумажек стало две и на них кроме точно обозначенных было с десяток анонимных деревень, я сказал "хватит это терпеть" и засел за конфигуратор.
Итак, предлагаемая вашему внимание серьёзная бизнес-разработка предназначена для ведения учёта деревень с их подробными характеристиками и всевозможной полезной игровой инфой. В частности, параметры деревни включают в себя:
- Наименование
- Координаты
- Принадлежность к карте
- Список станков
- Список ресурсов
- Список животных
- Доп.реквизиты
- Присоединяемые файлы
Конфигурация разработана на базе БСП 3.0.2 и включает в себя следующие подсистемы (не все, но что вспомню):
- БазоваяФункциональность
- Администрирование
- ЗаметкиПользователя
- Свойства
- ВариантыОтчетов
- Печать
- ПодключаемыеКоманды
- РаботаСФайлами
Хватит слов, сдёрнем уже покровы с шедевра:
Обращу внимание на принадлежность деревень картам. Карты идентифицируются по своему номеру и координатам. Это координаты от верхнего-левого угла составной карты мира. Зачем нужны координаты? Допустим, позвал нас дух приключений вверх (или влево) открывать новые миры. Присоединяем новые карты и что получается? Все номера остальных карт сдвинулись. Ну, тут или уходить в минусовые координаты относительно некоего центра, либо сделать функцию сдвига номеров всех карт вправо или вниз. Я выбрал второй вариант. Правда, я его ещё не реализовал. Ждите в следующих версиях.
Также, имеется отчёт с корректным расположением карт и списком деревень на них:
Проект выгодный и сулит массу дивидендов (нет), поэтому предлагаю всем неравнодушным присоединяться к нему на безвозмездной основе.
Эта шутливая конфигурация распространяется без ограничений. Она может быть интересна учебным заведениям для демонстрации работы с БСП и применения механизмов платформы в понятной для детей/подростков форме (я надеюсь). После майского апдейта это пособие дополнилось целым спектром объектов и функций по работе с двоичными данными.
Высказывайте свои пожелания, я попробую их реализовать или готов смержить с вашими модификациями этой конфигурации.
Раздел "Администрирование" я не вычищал, там несколько битых ссылок на отсутствующую функциональность. Это поправлю в следующих версиях.
Это будет эпичный рассказ!
У карт прошлого релиза было всего несколько реквизитов - код и координаты на карте мира. Я задумался: наверняка карта, при открытии её в игре, не собирается по точкам по цвету чанков, а где-то хранится картинкой. Полез по папкам - нашёл в сетевой игре папку world\data и в ней кучу файлов с названиями вроде map_N.dat . Открыл - вроде бред внутри. Полез искать по интернетам "формат карт minecraft". Узнал, что карты хранятся в упакованном GZip виде. Изучил возможности платформы - на deflate они останавливались как лет 5 назад, так и до сих пор ситуация не улучшилась. Полез по публикациям Инфостарта, нашёл довольно древнюю публикацию, которую, внезапно оказалось, я уже скачивал когда-то. Скачал ещё раз, попробовал тестовой обработкой распаковать один из файлов - получил какие-то данные. Сохранил данные в файл и принялся рассматривать его HEX-редактором. Там встречались осмысленные строки - это были названия деревень (я в каждой деревне ставлю именованный флаг). Нашёл описание формата файла - NBT. Нашёл даже NBT Explorer, который натравил на карту и увидел дерево её данных.
Про потоки в 1С я уже давно в теме, поэтому засел писать парсер. Разгадка формата не давала заснуть раньше пяти утра. Я получил иерархическую структуру содержимого файла и сделал функцию загрузки данных из файлов. У карт появилась увесистая пачка реквизитов, включая мир, координаты центра, масштаб и много прочего.
В процессе разработки удалось значительно расширить свои знания по возможностям платформы в области чтения данных, потоков и различных преобразований с двоичными данными. Выяснилось, что ЧтениеДанных не имеет возможности считывания знаковых (signed) чисел, а только беззнаковых (unsigned), однако это решилось небольшой хитростью с вычитанием старшего бита (см.код). Вдобавок, оказалось, представление платформы 1С об UTF разительно отличается от принятого стандартом RFC 3629: она читает даже алфавитные символы английского алфавита по два байта (с кодировкой), хотя по стандарту они идут по одному байту. В результате считывание строк из потока с помощью ЧтениеДанных.ПрочитатьСимволы() приводило к считыванию лишних байтов в тех случаях, когда строка содержала символы разных кодировок (eng+rus). Решил данную проблему созданием отдельного потока ограниченной длины и скармливал его этому же методу - всё равно больше положенного уже не прочитает.
Итак, после преодоления всех препон я получил данные по картам в справочнике "Карты". Оставался какой-то тег colors объёмом ровно 16Кб. Надо отметить, что к тому времени я ещё не обнаружил на просторах интернета описание формата карт Майнкрафт. Если бы оное событие произошло пораньше, эта история была бы намного короче. Я получил содержимое тега и сразу заподозрил неладное: значения байтов были ограничены, явно из какого-то набора. Я зашёл в игру, заскринил карту, вырезал её в редакторе, посчитал количество точек: 128х128. Перемножение даёт как раз 16Кб. Я обратил внимание, что точки карты с одинаковым цветом примерно совпадали с байтами с одинаковыми значениями. Значит, точно существует некая таблица цветов! Тут уже я начал искать именно "таблицу цветов карт Майнкрафт" и нашёл её на том же сайте.
Возиться с алгоритмами упаковки графических форматов я не хотел и сразу зацепился за формат BMP - со школы известно, он без сжатия. Обнаружил описание формата - вариант с таблицей цветов (8 или 16 бит на пиксель) мне как раз подходил, попытался создать заголовок. В процессе осенило, что все изображения карт будут 128х128 и таблица цветов у них будет одинаковая. Создал произвольное изображение указанного размера, сохранил, проверил соответствие формату и отрезал от него заголовок. Для создания таблицы цветов сделал обработку, идентичную примеру на Java. Единственное, в примере используется таблица цветов старой версии, надо перебить с сайта актуальную. Записал бинарник таблицы цветов. Склеил в 1С с заголовком BMP и полученный бинарник сохранил в макет. Осталось только объединять это с данными тега colors...
Изображение очень напоминало оригинальное, но всё же отличалось гаммой и рельефом. Первое решилось, когда вспомнил про big-endian и переставил байты в таблице цветов с RGB на GRB. А вот с ландшафтом пришлось подумать. В формате BMP подразумевается массив байтов сверху-слева и далее построчно. В описании формата карт же говорится, что там идут строки снизу вверх. Получается, мне данные картинки нужно разрезать на части по 128 байт и склеить от последней к первой. Разработчики очень порадовали методом ЧтениеДанных.РазделитьНаЧастиПо(), который в одну строку делал операцию разделения. Склеил полученные части, соединил с заголовком и таблицей цветов - вуаля! Оставалось только немного разобраться с программным интерфейсом подсистемы присоединённых файлов БСП и функция загрузки данных карт пополнилась и загрузкой изображения карты.
Теперь мне не нравилась реализация загрузки: я создавал таблицу значений, куда закидывал прочитанные данные с указанием уровня вложенности. Это было некрасиво, т.к. приходилось вставлять куски кода адаптации под загрузку конкретно карт. Механизм становился не универсальным. Выходит, мне нужна сущность, которая бы хранила данные в объектном виде. Выбор сразу пал на XDTO. Сделал отдельный пакет, сделал в нём объект map с детальным описанием всех реквизитов. Оставалось только сделать механизм по его заполнению. Взял за основу предыдущую реализацию: заполнял в процедуре реквизиты объекта, вызывал её рекурсивно в случае чтения объекта, а когда встречал список, вызывал отдельную процедуру загрузки списка. Таким образом я на входе передаю тип объекта XDTO, который мне надо заполнить, и ЧтениеДанных, а на выходе получаю заполненный объект XDTO, из которого удобно производить заполнение сущностей 1С.
Для пытливых умов оставил в справочнике "Карты" две формы - первая была менее приспособлена к заполнению из неё объектов 1С, поэтому актуальной является вторая.
Теперь в планах сделать карту мира из присоединённых файлов карт.
*Маленькая хитрость: карты сокровищ тоже можно загружать, а это значит, что станут известны координаты центра - точки, где лежит сокровище.