PDA

View Full Version : Кампания за ВЭЙГР


~GOLEM~
01-01-2008, 05:11 AM
На другом форуме была эта тема но там немного кого из вас небыло.
Работка не сложная главное понять что там происходит с фалами.:confused:
Все есть ПРОБЛЕМА только с ДОСТУПОМ к РАЗРАБОТКЕ И ПОСТРОЙКЕ технологий и кораблей.

http://www.homeworld-rus.ru/forum/showthread.php?t=166 :eek:

:hw: Есть идеи, или решения говорите.:help:
По сути кампания останется таже только ха ВАЙГРОВ. Аналогично как в первом корочь.

Ten
01-01-2008, 06:59 PM
Чтобы сделать кампанию за Вэйгр (не называйте их вайграми, это очень обидно звучит :)), да и вообще – любую кампанию, нужно быть готовым к рутинной и кропотливой работе, которая займёт массу времени. Кампании (а их может быть столько угодно :)) хранятся в папке data:/leveldata/campaign/, для каждой кампании определяется свой campaign-файл и папка с таким же именем, в которой и хранятся её файлы. В ХВ2 две кампании, которые называются ascension и tutorial, причём, судя по всему, в exe-файл жёстко зашито, что первая это сингл, а вторая – обучение. Свою кампанию можно запустить с помощью ключа командной строки вида -campaign <имя_кампании>, например, -campaign ascension. К сожалению, в ХВ2 нет (или я не встречал) функции типа UI_StartCampaign("<имя_кампании>"), которую можно повесить на обработчик onMouseClicked кнопки, поэтому моддеры предпочитают изменить файл ascension.campaign так, чтобы он ссылался на их миссии. Очень не изящно, но по-другому никак.

Это краткая вводная :) Конечно, при готовой кампании за хиигарян задача упрощается, но всё равно придётся вручную менять скрипты каждой миссии. Поясню на примере 12ой, как самой простой. Живёт эта миссия в папке data:/leveldata/campaign/ascension/m12_rescue/ и состоит из следующих файлов:
teamcolour.lua – задаёт цвета кораблей, инверсионных следов и бэджи всех участвующих в миссии сторон. Что с ним делать я вчерась рассказывал :) Пожалуй, самый простой файл.

datfiles.lua – содержит ссылки на все dat-файлы миссии, в которых хранится её текст. Сами dat-файлы обычно лежат в языковом файле (English.big, French.big и т.д.) и представляют собой набор строк, каждой из которых сопоставлен числовой идентификатор. Если файл имеет расширение ucs, значит строки записаны в кодировке Unicode. Когда ты переводил ХВ2, то менял именно эти файлы. Тут тоже всё просто :)

referencefleet.lua – в нём задаётся кол-во ресурсов и корабли, с которыми, по мнению разработчиков, игрок должен перейти в эту миссию. Если флот игрока меньше, на карте становится больше ресурсов, чтобы дать возможность отстроится, если же флот игрока больше, у компьютерных оппонентов появляются дополнительные корабли. Файл тоже не сложный, и его можно оставить на потом.

ai#.lua – файлы искусственного интеллекта игрока номер # (0 это мы, 1 и т.д. - компьютер), заменяет ИИ по умолчанию. Какой-либо привязки к конкретным кораблям и технологиям хиигарцев я не обнаружил, ИМХО их можно не трогать.

player#reinforce.lua – файл восполнения потерь игрока номер #. В нём задаются корабли, которые AI может строить, и их "вес", т.е. важность (чем больше "вес" корабля, тем больше вероятность его появления). Для твоей задачи достаточно позаменять воягрские корабли их хиигарянскими аналогами. Это просто, так как файлы маленькие.

m12_rescue.level – карта миссии. В ней мы расставляем вражину, астероиды, космическую пыль («гальку»), ресурсы, туманности и т.д. Создаётся в Maya с помощью реликовского плагина LevelEd, но можно и с помощью редакторов карт, которые понаделали народные умельцы (MissionBoy, Latche of Sajuuk, Skuns Editor и т.д.). В крайнем случаем можно и вручную :) На форуме этому вопросу была посвящена отдельная тема. В твоём случае нужно просто позаменять воягрские корабли их хиигарянскими аналогами. Очень просто и не менее нудно, так как файл обычно не маленький.

m12_rescue.lua – собственно, управляющий файл, который и реализует сценарий миссии.
Последний файл – самый главный из всех перечисленных, поэтому остановимся на нём поподробнее. Скрипт миссии представляет собой конечный автомат, т.е. набор состояний и условия перехода между ними. Очень наглядный пример – спустя некоторое время к нам прибывает Макаан и начинает околачиваться по карте. Если мы ему нальём, он, довольный, удалится праздновать. Это и есть переход, его условие - «если у Флагшипа осталось меньше 20% брони, стать неуязвимым и быстренько слинять в гипер». Или выпрыгивает наш флот близ Кароса, всё спокойно и тихо, разве что материнка неуправляема. Проходит время, и к нам ломятся гости. Это тоже переход, в данном случае условие - «прошло N-ное кол-во времени». Более наглядный пример – сражались мы, сражались, а тут бац – и разнесли (или захватили, что тоже в сингле бывает :)) материнку, и миссия оканчивается. Сработало условие поражения – «если материнки у игрока не стало, завершить миссию с признаком поражения» (с дредноутом тоже самое).

И так далее. Перечислять можно долго, но общий принцип, думаю, понятен. Пишется этот конечный автомат, как и все скрипты ХВ2, на Lua, и крайне желательно хорошо знать этот язык, иначе вся затея теряет смысл и дальше мечты не продвинется. Приведу простой пример скрипта миссии из SCAR-документации к RDN Tools:

-- импортировать библиотечные файлы, которые содержат вспомогательные функции
dofilepath("data:scripts/SCAR/SCAR_Util.lua")

-- переменные могут быть определен вне процедур/функций, что делает их глобальными
obj_prim_newobj_id = 0

-- определение точки входа (OnInit), с которой и начинается выполнение
function OnInit()
-- добавить правило Rule_Init:
Rule_Add("Rule_Init")

-- поскольку OnInit не является правилом, нам не нужно его удалять
end

-- для стандартизации мы всегда определяем Rule_Init, с которого начинается ход миссии
function Rule_Init()
-- здесь мы определяем первое событие Разведотдела флота (англ. Intelevent)
Event_Start("intelevent_intro")

-- добавляем правила, которые определяют ход миссии
Rule_Add("Rule_PlayerLoses")
Rule_Add("Rule_PlayerWins")

-- не забыть удалить правило Rule_Init
Rule_Remove("Rule_Init")
end

-- это правило проверяет, уничтожен ли Mothership игрока
function Rule_PlayerLoses()
if ( SobGroup_Empty("Player_Mothership") == 1 ) then
-- провал нашего задания:
Objective_SetState(obj_prim_newobj_id, OS_Failed)

-- игрок проигрывает в этой миссии:
setMissionComplete(0)

Rule_Remove("Rule_PlayerLoses")
end
end


-- это правило проверяет, уничтожен ли Носитель противника
function Rule_PlayerWins()
if ( SobGroup_Empty("AI1_Carrier") == 1 ) then
-- успешное завершение нашего задания:
Objective_SetState(obj_prim_newobj_id, OS_Complete)

[I]-- игрок одерживает победу в этой миссии:
setMissionComplete(1)

Rule_Remove("Rule_PlayerWins")
end
end

-- ! Не забываем создать таблицу Events, в которой будут храниться события
Events = {}

-- это вводное событие Разведотдела флота
Events.intelevent_intro =
{
{
{"Sound_EnableAllSpeech(1)", ""},
{"Sound_EnterIntelEvent()", "" },
{"Universe_EnableSkip(1)", "" },
HW2_LocationCardEvent("Postmortem Tutorial", 5),
},

{
HW2_Letterbox(1),
HW2_Wait(2),
},

{
HW2_SubTitleEvent(Actor_FleetCommand, "This is a tutorial script", 5),
},

{
HW2_Wait(1),
},

{
{"obj_prim_newobj_id = Objective_Add("A new Objective", OT_Primary)", ""},
{"Objective_AddDescription(obj_prim_startresourcing_id, 'Description')", ""},
HW2_SubTitleEvent(Actor_FleetIntel, "Ive just issued a new objective", 4),
},

{
HW2_Wait(1),
},

{
HW2_Letterbox(0),
HW2_Wait(2),
{"Universe_EnableSkip(0)", ""},
{"Sound_ExitIntelEvent()",""},
},
}

Т.е. сначала мы определяем глобальные переменные, в которых храним признак того или иного состояния, потом определяем правила, в которых проверяются условия перехода между состояниями и выполнение связанных с ними действий, а потом события, точнее сообщения Разведотдела Флота, Командования Флота, Макаана, Талорна (который стал Собаном :D), т.е. все субтитры и спичи. Ключевым моментом является определение функции OnInit() (аналог main() в C/C++), с которой и начинается выполнение скрипта. Она добавляет необходимые правила в список, а движок игры каждый кадр проверяет этот список и вызывает все правила (которые, по сути, обычные функции), перечисленные в нём. Период вызова того или иного правила можно и изменить с помощью функции Rule_AddInterval("<название_правила>", <период_в_секундах>). А как только правило становится ненужным, его стоит удалить, чтобы не выполнить одинарное действие несколько раз или просто не расходовать лишние ресурсы системы.

Пример очень прост, скрипты миссий в ХВ2 намного длиннее, так как в реальных миссиях состояний обычно больше, спичей тоже, и чтобы обслужить всю эту махину требуется внушительное кол-во правил. Правила обеспечивают запуск NIS-видеовставок, разблокируют технологии и подсистемы, объединяют разрозненные воягрские группировки в альянс, включают/выключают кнопки управления кораблей (например, начисто лишают материнку нашего управления в 6ой миссии) и делают много чего ещё :)


Думаю, после этой небольшой заметки становится понятно, почему разработчики не стали делать отдельную компанию за Вэйгр. В ХВ1 обе противоборствующие расы были практически идентичны, а в ХВ2 они серьёзно различаются кораблями и технологиями. Необходимо как минимум взять все миссии за хиигарян и переделать их с учётом особенностей кочевников. Хорошо, что перехватчики/бомберы, эсминцы/крейсера и верфи/материнки есть у обеих рас, а как быть с ланс-файтерами, командными корветами и фрегатами силового поля? :) Древо технологий принципиально иное, про спичи я вообще скромно умолчу (не будет же Макаан вещать милым женским голосом? :D). Переделка займёт немало времени, и навряд ли принесёт ощутимую прибыть. А издатель обычно не любит, когда его деньги расходуются в пустую.

Если после этого у тебя не пропало желание создавать кампанию за воягров, предлагаю сначала всем кораблям хиигарян сопоставить их воягрские аналоги, за каждым составить список технологий, а потом нудно и упорно, в нескольких файлах каждой миссии заменять корабли и технологии хиигарян на воягров. А чтобы Макаан не вызывал опасение иными частотными характеристиками своего голоса, из файла EnglishSpeech.Big речи Каран необходимо вырезать.


Дерзай! :)