Russian Homeworld Wiki
Advertisement

В 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 -- этот неизвестный параметр везде такой;
)
  1. Астероид
    • Чтобы задать астероид, нужно использовать метод addAsteroid().
    • Названия типов астероидов можно найти в %homeworld2.big_decompiled%\resource\asteroid\*.
  2. Обломок
    • Чтобы задать перерабатываемый обломок, нужно использовать метод 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 -- размер;
)
  • Виды поверхности облаков:
    1. Nebula4_OLD1 -- использовалась для туманности;
    2. polySurface1
    3. ... +
    4. polySurface13


  1. Обычные облака -- просто украшательство;
    • Чтобы задать обычное облако, нужно использовать метод addCloud().
    • Названия типов обычных облаков можно найти в %homeworld2.big_decompiled%\cloud
  2. Пылевые облака -- сенсоры не прощупывают эти облака; также, по слухам, внутри пылевого облака не работают ионные лучи;
    • Чтобы задать пылевое облако, нужно использовать метод addDustCloud();
    • Названия типов пылевых облаков можно найти в %homeworld2.big_decompiled%\dustcloud;
  3. Туманности -- в туманностях корабли получают повреждения от радиации;
    • Чтобы задать туманность, нужно использовать метод addNebula().
    • Названия типов туманностей можно найти в %homeworld2.big_decompiled%\nebula
Задание размера карты[]

Для задания размера пропишите:

setWorldBoundsInner(
  {0, 0, 0}, -- этот неизвестный параметр везде оставляется по нулям (угол зрения???); исключение - карта Terah, где первое число - -4.4;
  {X, Z, Y} -- X, Z, Y указывают половинную длину, высоту и ширину карты;
)

Почему-то этот параметр на всех официальных картах написан самым последним - уже после установки всех "пылевых дорожек", астероидов, кораблей итд. Наверное, так надо.

  1. Размеры карт для 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;
  2. Размеры карт для 3ёх игроков:
    • {23348.13, 12152.93, 23348.13,} -- Dante's Requiem, "Реквием Данте";
  3. Размеры карт для 4ёх игроков:
    • {19497.82, 19497.82, 19497.82,} -- Kharam Wreck, "Обломки Кхарама";
    • {37558.01, 26018.71, 37558.01,} -- Rings of Hraal, "Кольца Храали";
  4. Размеры карт для 5 игроков:
    • {26747.51, 26747.51, 26747.51,} -- Silumin Training Grounds, "Полигон "Силумин"";
  5. Размеры карт для 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Д-фракталы, фотографии космоса, пещеры, можно даже сделать свою сферу Дайсона или хотя бы использовать в качестве фона вашу кухню. Будут "крысиные бои" Хоумворлда.

//Нужно написать как это сделать )...

Ссылки[]


Advertisement