В Homeworld 2 достаточно мало многопользовательских карт. Безусловно, существующие играбельны и прекрасны, но, тем не менее, их мало: при том, что никакой геометрии уровням не нужно, кроме как расставить кое-какие ресурсы, фоны начинают приедаться. Здесь мы попытаемся исправить эту оплошность и создать пару-тройку своих карт.
Подготовка[]
Создайте в корневой папке вашего Homeworld 2 (то есть, там где он установлен - в дальнейшем, %Homeworld2_root%) такую структуру каталогов:
%Homeworld2_root%\Data\LevelData\multiplayer\deathmatch\
Это нужно потому, что в homeworld2.big архиве многопользовательские карты находятся именно по такому пути. К сожалению, разработчики очень спешили сделать игру и не продумали этот момент для рядовых игроков.
Далее, нужно создать *.level-файл: простой текстовый файл, только расширение поменять. В сущности, *.level-файл, в представлении движка Homeworld 2, является скриптом Lua.
Назвать его следует аналогично уже существующим именованиям: то есть, маленькими буквами, количество игроков + название карты, где все пробелы заменены на знаки подчёркивания. Что-нибудь в этом роде:
\LevelData\multiplayer\deathmatch\2p_my_first.level
Конечно, назвать можно как угодно, необязательно досконально выполнять вышеозначенные указания, но всё же лучше следовать правилам хорошего тона.
Редактирование *.level-файла[]
Первым делом надо внести информацию о названии карты. Эта информация будет видна в меню выбора карты.
levelDesc = "$9000" -- название карты можно локализовать, но об этом смотрите в другом мануале;
Игроки[]
Следующие строки посвящены непосредственно игрокам:
maxPlayers = 2 -- здесь пишем количество игроков; player = {} -- инициализируем массив-таблицу скриптового языка Lua; player[0] = { -- инициализация первого игрока; id = 0, name = "", -- название расы, используется в скриптах; resources = 0, -- начальные ресурсы по умолчанию; raceID = 1, startPos = 1, -- номер стартовой позиции; } player[%n%] = {...} -- инициализация второго, третьего итд игрока, главное, чтобы не выходило за пределы maxPlayer;
Без понятия, почему существуют отдельно id и raceID, видимо, они нужны для разных функций. В любом случае, при инициализации нового игрока просто увеличивайте их на 1.
Объекты на карте[]
Всё, что находится на карте (или должно появиться там) прописывается в двух функциях: или DetermChunk(), или NonDetermChunk().
Начало координат находится в центре карты. Это значит, что координаты для объектов могут быть отрицательными.
Единицы измерения - метры.
Функция DetermChunk()[]
function DetermChunk() ... end
Объекты, помещённые в этой функции, игрок может или "пощупать" камерой, или видеть как объекты в менеджере сенсоров.
Стартовая позиция[]
Пропишите для каждого нового игрока (хотя можно попробовать создать стартовых позиций больше, чем игроков):
addPoint( "StartPos0", {X, Z, Y}, -- координаты; {A, B, C} -- на эти углы (в градусах), относительно разных координат будут повёрнуты корабли в начале игры; )
Примечание: при указании углов, имеет смысл приравнять к нулю значения A и C. Их изменение влияет на наклон кораблей, т.е. можно "положить" флагман хиигярян или, наоборот, поставить торчком флагман вэйгров, но, увы, ненадолго. Ещё при телепортации они начнут выравниваться и вскоре примут надлежащее им положение. А вот параметр B влияет на то, в какую сторону будут повёрнуты корабли: её рекомендуется поменять так, чтобы флагманы были развернуты друг к другу "лицом" - или просто к центру.
Ресурсы[]
В игре существуют два типа ресурсов: астероиды и обломки кораблей. Но, хоть по методу доставки и источнику происхождения они разные, по сути они достаточно одинаковы.
Прописываются они так:
%имя_метода%( -- здесь вызывается метод, ответственный или за астероиды, или за обломки; "Type", -- тип астероида или обломка; {X, Z, Y}, -- координаты ресурсины; RU, -- количество ресурса (указанная цифра означает процент ресурса в объекте, от максимального количества ресурса, характерного для объекта данного размера); A, B, C, -- cкорее всего, это углы вращения; 0 -- этот неизвестный параметр везде такой; )
- Астероид
- Чтобы задать астероид, нужно использовать метод addAsteroid().
- Названия типов астероидов можно найти в %homeworld2.big_decompiled%\resource\asteroid\*.
- Обломок
- Чтобы задать перерабатываемый обломок, нужно использовать метод addSalvage().
- Названия типов обломков можно найти в %homeworld2.big_decompiled%\resource\salvage\*.
При этом нужно помнить, что, скорее всего, чем меньше цифра, тем меньше объект.
Корабли[]
Корабли - это не только истребители, корветы и прочие боевые космолёты, но также всякие крупные обломки, не поддающиеся переработке.
Для добавления пропишите:
addSquadron( "SquadronType", -- задаёт тип объекта; "SquadronType", -- задаёт тип объекта (возможно, подтип - пока непонятно); {X, Z, Y}, -- координаты; -1, -- этот неизвестный параметр везде такой; {A, B, C}, -- есть большое подозрение, что это углы вращения; 0, 0 -- этот неизвестный параметр везде такой; )
Названия для SquadronType берутся из %homeworld2.big_decompiled%\ship\*. Большинство декоративных мегалитов находится в папках с префиксом meg_*.
Облака[]
В игре существуют три типа облаков, но вызываются они, в принципе, одинаково:
%имя_метода( "Surface", -- возможная поверхность (???) облака; "Type", -- тип облака; {X, Z, Y}, -- координаты; {R, G, B, 1}, -- R, G, B - устанавливает RGB-цвет (0=0, 1=255); 0, -- какой-то неизвестный параметр; Size -- размер; )
- Виды поверхности облаков:
- Nebula4_OLD1 -- использовалась для туманности;
- polySurface1
- ... +
- polySurface13
- Обычные облака -- просто украшательство;
- Чтобы задать обычное облако, нужно использовать метод addCloud().
- Названия типов обычных облаков можно найти в %homeworld2.big_decompiled%\cloud
- Пылевые облака -- сенсоры не прощупывают эти облака; также, по слухам, внутри пылевого облака не работают ионные лучи;
- Чтобы задать пылевое облако, нужно использовать метод addDustCloud();
- Названия типов пылевых облаков можно найти в %homeworld2.big_decompiled%\dustcloud;
- Туманности -- в туманностях корабли получают повреждения от радиации;
- Чтобы задать туманность, нужно использовать метод addNebula().
- Названия типов туманностей можно найти в %homeworld2.big_decompiled%\nebula
Задание размера карты[]
Для задания размера пропишите:
setWorldBoundsInner( {0, 0, 0}, -- этот неизвестный параметр везде оставляется по нулям (угол зрения???); исключение - карта Terah, где первое число - -4.4; {X, Z, Y} -- X, Z, Y указывают половинную длину, высоту и ширину карты; )
Почему-то этот параметр на всех официальных картах написан самым последним - уже после установки всех "пылевых дорожек", астероидов, кораблей итд. Наверное, так надо.
- Размеры карт для 2ух игроков:
- {37171.79, 37171.79, 37171.79,} -- Hostilities End, "Конец войны";
- {19497.82, 19497.82, 19497.82,} -- Kharam Wreck, "Обломки Кхарама";
- {26469.53, 26469.53, 26469.53,} -- Shields, "Щиты";
- {70720.39, 28325.45, 70720.39,} -- Jadeth;
- Размеры карт для 3ёх игроков:
- {23348.13, 12152.93, 23348.13,} -- Dante's Requiem, "Реквием Данте";
- Размеры карт для 4ёх игроков:
- {19497.82, 19497.82, 19497.82,} -- Kharam Wreck, "Обломки Кхарама";
- {37558.01, 26018.71, 37558.01,} -- Rings of Hraal, "Кольца Храали";
- Размеры карт для 5 игроков:
- {26747.51, 26747.51, 26747.51,} -- Silumin Training Grounds, "Полигон "Силумин"";
- Размеры карт для 6 игроков:
- {59455.26, 59455.26, 59455.26,} -- Terah, "Фарра" (библейский персонаж, отец Авраама);
- {30688.75, 56836.1, 36820.43,} -- Imposed Cosmos "Навязанное мироустройство";
- {50867.39, 39196.35, 61030.81,} -- Crimson Bond, "Повязанные кровью";
- {36978.29, 9656.09, 26687.21,} -- Sarum;
Примеры размеров оригинальных мультиплеерных карт. Сотые доли в размерах говорят о том, что их задавали не совсем ручками...
Функция NonDetermChunk()[]
function NonDetermChunk() ... end
Объекты, помещённые в этой функции, игрок или не "пощупает" камерой, или не видит как объекты в менеджере сенсоров.
"Галька"[]
Обнаруживается сенсорами в виде небольших коричневых пятнышек, но ничего не делает.
Для добавления гальки пропишите:
addPebble( "PebbleType", -- тип "гальки"; {X, Z, Y}, -- координаты; 0, 0, 0 )
Название типов "гальки" можно найти в %Homeworld.big_decompiled%\pebble\* (короче, там от pebble_0 до pebble_2).
Параметры карты[]
В конце NonDetermChunk() обычно идут всякие интересные параметры:
fogSetActive(1) -- вкл/выкл "тумана" (???); если выключить (0), то все остальные fogSet* можно стирать; fogSetStart(10) fogSetEnd(20000) fogSetColour(r,g,b,1) -- цвет "тумана"; значения получаются путём деления на 255 и округления до .000001; fogSetType("linear") fogSetDensity(0.15) setGlareIntensity(0) -- неизвестный параметр, везде такой; setLevelShadowColour(R, G, B, 1) -- цвет теней уровня, обычно ставят по нулям; loadBackground("X") -- выбор картинки для фона; setSensorsManagerCameraDistances( -- минимальное и максимальное отдаление камеры в менеджере сенсоров; MIN, -- обычное значение 10к-12к; MAX) -- чем меньше карта, тем меньше ставят; для маленьких - от 45к, для больших и вертикальных карт - 60к и выше; setDefaultMusic("Data:sound/music/Y/Z") -- выбор музыки по умолчанию для уровня;
- X - фон карты. Может быть: white (белый), black (чёрный), m01 - m15 (задники кампании).
- Y - папка с фоновой музыкой. Может быть Ambient (обычная музыка) или Battle (музыка, проигрываемая во время битв)
- Z - музыкальный трек. Для Ambient: amb_01, amb_02, amb_03, amb_04, amb_05, amb_06, amb_07, amb_08, amb_09, amb_10, amb_11, amb_12, amb_13 and amb_14. Для Battle: battle_01, battle_04, battle_04_alt, battle_06, battle_keeper, battle_movers, planet_killers, Battle_sajuuk and bentus_arrival.
Использование скриптов[]
Как уже говорилось, *.level-файлы - обычные компилируемые *.lua-файлы, а значит в них можно использовать скриптовую магию.
Например, можно не писать сотню процедур добавления астероидов, если можно сделать просто цикл:
for i=1,100 do ...<процедурки>... end
В качестве примера неполный код кольца из астероидов, расположенного параллельно плоскости xOz т.е. горизонту (у этих буржуев ось Z вбок направлена).
Радиус кольца - R, координаты центра x0, y0, z0:
R = ... --радиус круга; x0 =... --координата X; y0 =... --координата Y (причём y0 и обозначает высоту кольца над плоскостью xOz); z0 =... --координата Z; x = x0 - R --точку в позицию начала; z = 0 --инициализируем переменную z; repeat x = x + 100 --это для примера. чем меньше будет прирост переменной, тем плотнее будет кольцо; z = sqrt(R*R - (x - x0)*(x - x0)) + z0 --уравнение полукольца в координатах, подумайте над тем, как получить полное; addPebble("Pebble_0", {x, z, y0}, 0, 0, 0) --здесь это тоже для примера, функцию можете любую выставить; until x>=x0+R --завершить, когда точка в позиции конца; i=0 --Готово!
Создание фона карты[]
В качестве темы для фона карты можно использовать что угодно - пылающий закат, подводный мир, микрокос, 3Д-фракталы, фотографии космоса, пещеры, можно даже сделать свою сферу Дайсона или хотя бы использовать в качестве фона вашу кухню. Будут "крысиные бои" Хоумворлда.
//Нужно написать как это сделать )...
Ссылки[]
- Руководство по созданию карт - оригинальный текст;
- Создание карт - тема на хв.су;