Создание модов для Quake III Arena.

Для того, чтоб начать писать что-то новенькое на Q3, у вас должны быть установлены следующие компоненты:

Quake3Arena либо TeamArena

Q3PointRelease_1.32.exe

Q3AGameSource_1.32.exe

Вам также потребуется компилятор. Я очень рекомендую MSVC++ 6.0. Потому, что даже исходники от ID Software идут с готовым проэктом и рабочим местом под MSVC++. Также вам потребуются batch-файлы, с помощью которых нужно создавать QVM-файлы. Так как те, что идут с исходниками от ID, ясное дело, не работают)).


Теперь, учитывая то, что мы умеем компилировать проекты и создавать QVM, можно приступить к созданию модов, для начала самых простых. С этой целью в этой статье мы рассмотрим создание пробного мода SlowRockets. Т.е будем изменять скорость ракет.

1. Сделайте копию исходного кода!

Очень удобно держать под боком нетронутую копию исходного кода. Представьте, что вы создавали мод, и запороли один из файлов исходного кода (сохранили, например, нежелательные изменения). Тогда вам понадобится BACKUP, верно? Конечно, можно заново установить Q3AGameSource, но это быстро надоедает. Поэтому, мы не будем создавать моды в папке С:\Quake3\source, а сохраним ее как копию. Мы будем делать моды в своих отдельных директориях. Например, создайте папку С:\Quake3\mymod.

Теперь просто скопируйте содержимое С:\Quake3\source в С:\Quake3\mymod. Все изменения относительно этого мода теперь делайте в этой папке. Вы можете иметь сколько угодно поддиректорий. Я часто разрабатываю несколько модов одновременно: quake3\mega-rail, quake3\bouncemod, и т.д.. Ограничение – лишь объем вашего винчестера.

2. Найдем что-нибудь интересное

Давайте откроем quake3\mymod\сode\quake3sdk.dsw. Разверните на весь экран, т.к. вам понадобится как можно больше места. Убедитесь, что у вас активирован проект ‘game’. Нажмите “File View” на панели слева, и найдите файл 'g_missile.c'. (двойной клик и он откроется в окне Редактора справа).

Перейдите к строке 621 (Tips: нажмите CRTL + G для быстрого перехода) и найдите функцию fire_rocket:

/*

=================
fire_rocket

=================

*/

gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir)

{

gentity_t *bolt;

VectorNormalize (dir);

bolt = G_Spawn();

bolt->classname = "rocket";

bolt->nextthink = level.time + 10000;

bolt->think = G_ExplodeMissile;

bolt->s.eType = ET_MISSILE;

bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;

bolt->s.weapon = WP_ROCKET_LAUNCHER;

bolt->r.ownerNum = self->s.number;

bolt->parent = self;

bolt->damage = 100;

bolt->splashDamage = 100;

bolt->splashRadius = 120;

bolt->methodOfDeath = MOD_ROCKET;

bolt->splashMethodOfDeath = MOD_ROCKET_SPLASH;

bolt->clipmask = MASK_SHOT;

bolt->s.pos.trType = TR_LINEAR;

bolt->s.pos.trTime = level.time - MISSILE_PRESTEP_TIME; // move a bit
on the very first frame

VectorCopy( start, bolt->s.pos.trBase );

VectorScale( dir, 900, bolt->s.pos.trDelta );

SnapVector( bolt->s.pos.trDelta ); // save net bandwidth

VectorCopy (start, bolt->r.currentOrigin);
return bolt;
}

Видно, что ракета наносит 100 вреда (от прямого попадания или от ближнего), и что радиус ближнего повреждения 120 юнитов. Строка 649 показывает, что ракета летит со скоростью 900 юнитов/сек. Также присутствует целая уйма констант используемых в данной функции (контсанты обычно написаны ПРОПИСНЫМИ буквами). Константы в основном имеют мнемоничные имена, поэтому легко угадать их назначение.

3. Наше первое изменение кода

Изменим значение строки 649 примерно так:

VectorScale( dir, 300, bolt->s.pos.trDelta );

Теперь сохраните код и создайте QVM. Затем вырежьте появившийся файл quake3\baseq3\vm\game.qvm и вставьте его в quake3\mymod\vm. Для того, чтоб Q3 увидел ваш новый QVM, нужно поместить папку VM в *.PK3, что на самом деле является обычным ZIP-архивом, только с новым расширением PK3.

Теперь запускайте игру с параметром:

C:\Quake3\quake3.exe +set fs_game mymod

И вы увидите – ваши ракеты стали намного медленнее.

1. Настройка MSVC

Ваша система должна быть настроена для работы с MSVC. Для этого откройте autoexec.bat и добавьте в конце следующие строки:

call C:\PROGRA~1\MICROS~2\VC98\BIN\vcvars32.bat

Где “MICROS~2” DOS-имя папки, куда установлен Microsoft Visual Studio. Если ваш VCVARS32.BAT расположен где-то еще то измените путь соответственно. Если он вообще отсутствует, тогда переустановите MSVC.

PATH=C:\WINDOWS;C:\WINDOWS\COMMAND; C:\QUAKE3\SOURCE\BIN;

Эта команда указывает на путь к инструментам компиляции при создании QVM.

2. Инсталяция

Ваш Quake3 и исходники должны быть по умолчанию установлены в C:\Quake3, т.к Q3AGameSource любит только эту директорию. Иначе вам придется переименовывать папки. После установки исходников вы должны увидеть папку C:\Quake3\source .

3. Открытие проекта

Если у вас установлен MSVC, то двойной клик по “C:\Quake3\source\code\ quake3sdk.dsw” откроет проект.

Слева на панели вы увидите список классов. Щелкните по FileView и вы увидите дерево. Заметьте в нем три проекта. ‘game’ наиболее интересный- он описывает то, как сервер запускает игру. 'cgame' содержит код Клиента, тогда как ‘ui’ (user inteface) содержит данные о пользовательском интерфейсе в игре(менюшки и т.д.)

Мы в большинстве случаев будем делать изменения в файлах исходного кода (*.с) и заголовочных файлах (*.h). Двойной клик по файлу в дереве проектов откроет окно Редактора. Попробуйте открыть некоторые файлы и просмотреть их. Не беспокойтесь, они выглядят не много страшными на первый взгяд, но не все так плохо)). Вот например одна функция из очень интересного файла g_weapon.c:

/*

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

ROCKET

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

*/

void Weapon_RocketLauncher_Fire (gentity_t *ent) {

gentity_t*m;

m = fire_rocket (ent, muzzle, forward);

m->damage *= s_quadFactor;

m->splashDamage *= s_quadFactor;

//VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta );

// "real" physics

}

Да! Это код, который выстреливает ракету всякий раз, когда вы нажимаете mouse1! В действительности наш код всего лишь вызывает функцию fire_rocket, затем преобразует повреждения от снаряда в соответствии с quad’ом. Найдите в исходниках функцию fire_rocket, чтоб подробней понять, как она работает. (Tips: вы можете использовать инструмент 'Find in Files, чтоб быстрее найти обьявленную функцию. )

4. Компилируем проект

Ok. В MSVC, выберите меню "Project" a"Set Active Project a 2 game". Чтоб скомпилировать проект 'game', выберите "Build qagamex86.dll (F7)" из меню "Build". Вы должны закончить с "0 error(s), 0 warning(s)" (пока же мы еще ничего не меняли….верно?). Файл qagamex86.dll должен появиться в вашей c:\Quake3\source\сode\Debug_TA” директории.

5. Создание QVM

Создать .qvm, или 'quake virtual machine' просто до безобразия)). (при условии, что среда программирования настроена правильно). Вы спросите, что такое .qvm? Я предпочитаю думать, что это «безопасная» замена для .dll. Он безопаснее, потому что не может делать вредные вещи, какие делают .dll (уничтожить винт например). Но нельзя сказать , что они 100% безопасны (запомните, что хакеры взломали JavaApplets с помощью переполнения стека virtual machine), но они намного безопаснее.

Теперь давайте создадим QVM. Зайдите в папку C:\Quake3\source\code\game и запустите файл game.bat (предварительно установив новые батч-файлы). Вуаля!! Новенький game.qvm появился в папке C:\Quake3\baseq3\vm. Таким же образом создаются файлы сgame.qvm и ui.qvm.

Ну вот вроде немного поднабрались опыта. А теперь давайте замутим наш первый мод………

Для cоздания мода потребуется сделать три идентичных изменения в коде. Это касается плазмы, базуки и BFG. Но чтоб не писать много раз одно и то же, я поясню лишь на примере базуки)).

1. Добавление нового флага

Откройте g_local.h в строке 32 и добавьте желтые строки:

#define FL_GODMODE 0x00000010
#define FL_NOTARGET 0x00000020
#define FL_TEAMSLAVE 0x00000400 // not the first on the team
#define FL_NO_KNOCKBACK 0x00000800
#define FL_DROPPED_ITEM 0x00001000
#define FL_NO_BOTS 0x00002000 // spawn point not for bot use
#define FL_NO_HUMANS 0x00004000 // spawn point just for bots
#define FL_ROCKETBOUNCE 0x00008000 //boncemod
#define FL_FORCE_GESTURE 0x00010000 // force gesture on client
#define FL_PLASMABOUNCE 0x00020000 //boncemod
#define FL_BFGBOUNCE 0x00040000 //boncemod

2. Внедрение команды "rbounce"

Теперь откройте g_cmds.c и добавьте код в районе строки 1548:

/*
= = = = = = = = = = = = = = = = =
Cmd_RBounce_f
= = = = = = = = = = = = = = = = =
*/
void Cmd_RBounce_f( gentity_t *ent ) {

char *msg; // message to player

ent->flags ^= FL_ROCKETBOUNCE;

if (!(ent->flags & FL_ROCKETBOUNCE))
msg = "Rocket Bounce OFF\n";
else
msg = "Rocket Bounce ON\n";
trap_SendServerCommand( ent-g_entities, va("print \"%s\"", msg));
}

Теперь идите к строке 1727 и добавьте:

else if (Q_stricmp (cmd, "setviewpos") == 0) Cmd_SetViewpos_f( ent ); else if (Q_stricmp (cmd, "rbounce") == 0) Cmd_RBounce_f( ent );

Это позволяет игроку включать и выключать отскок рокет в игре с помощью консольной команды "\rbounce". Команды для плазмы и BFG вводятся аналогично.

3. Изменяем физику рокет

Переходим к функции fire_rocket:

bolt = G_Spawn();
bolt->classname = "rocket";
if (self->flags & FL_ROCKETBOUNCE)
bolt->nextthink = level.time + 2500;
else
bolt->nextthink = level.time + 10000;
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_ROCKET_LAUNCHER;
if (self->flags & FL_ROCKETBOUNCE)
bolt->s.eFlags = EF_BOUNCE;
bolt->r.ownerNum = self->s.number;

Условие if (self->flags & FL_ROCKETBOUNCE) включил ли клиент FL_ROCKETBOUNCE. Если да, то рокета взорвется через 2.5 сек (вместо десяти, как обычно). Наиболее важная часть - добавление флага эффектов EF_BOUNCE к рокете. К счастью, эта функция была написана в ID Software и нам без усилий осталось лишь использовать ее)). Исследуйте bg_public.h в строке 221 для полного списка всех EF_ флагов.

Вот собственно и все. Если вы поняли как действуют команды, то без труда сможете добавить к списку плазму и т.д. Компилируйте ваш .qvm и наслаждайтесь!

Исследуя исходники, можно обнаружить, что в Quake 3 есть некоторый интрумент(оружием это назвать нельзя), который, однако, не используется в игре, хотя модель для него есть в пак0(хоть и без текстур).Это Grappling Hook. Не буду пояснять, что это такое - сами увидите когда откомпилируете ). Звуки и эффекты оно использует от шафта. Этот инструмент можно получить либо помещая его на своей новой карте, либо с помощью изменений кода.
Сначала убедитесь, что вы используете проект game, затем откройте файл g_client.c. Перейдите к функции void ClientSpawn(gentity_t *ent) и найдите эти строки:

client->ps.stats[STAT_WEAPONS] = ( 1 << WP_MACHINEGUN );
if ( g_gametype.integer == GT_TEAM ) {
client->ps.ammo[WP_MACHINEGUN] = 50;
} else {
client->ps.ammo[WP_MACHINEGUN] = 100;
}

Этот код дает игроку при респавне Пулемет и патроны(кол-во зависит от того, тимплей это или нет).

Чтобы дать Hook игроку(или любое другое оружие при респавне) добавьте следующую строку:

client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GRAPPLING_HOOK );

Поместите эту строку сразу после тех, где дается Пулемет. Заметьте, что мы используем оператор |= вместо =, как это сделано в оригинальном коде с пулеметом. Так как Пулемет добавляется ПЕРВЫМ, то мы можем использовать оператор присваивания =, но для дополнительных оружий мы должны использовать |= для того, чтоб добавление последующих оружий не замещало уже имеющееся. Если вы посмотрите на код ниже, то вы увидите, что , к примеру, Перчатка добавляется таким же способом, как я показал на примере с Hook'ом. Таким способом вы можете дать ироку при респавне любое оружие, меняя только WP_<название>.

Теперь откройте g_items.c. Так как мы собираемся использовать некоторые модели и эффекты для Hook'а, которого нет на карте, нам нужно загрузить его в кеш. Также понадобится загрузить шафт, так как мы будем использовать его луч в качестве эффекта. Найдите ф-ю void ClearRegisteredItems( void ) и добавьте к списку регестрируемых оружий:

// Grappling Hook
RegisterItem( BG_FindItemForWeapon( WP_LIGHTNING ) );
RegisterItem( BG_FindItemForWeapon( WP_GRAPPLING_HOOK ) );

Вот список всех оружий, которые вы можете использовать в g_client.c:

WP_GAUNTLET
WP_LIGHTNING
WP_SHOTGUN
WP_MACHINEGUN
WP_GRENADE_LAUNCHER
WP_ROCKET_LAUNCHER
WP_PLASMAGUN
WP_RAILGUN
WP_BFG
WP_GRAPPLING_HOOK

Надеюсь вам понравиться юзать grappling hook, которая выбирается нажатием клавиши 0 (или, если не работает, попробуйте /weapon 10 в консоли).

ВСЁ...

Это взято с http://q3mw.narod.ru/

Hosted by uCoz