На главную страницу
Для новичков:
О Quake3 вообще
О тактике
О модах
·Quake 3 Arena Mods
·Создание Мода. Урок 1
·Создание Мода. Урок 2
·Создание Мода. Урок 3
·Создание Мода. Урок 4
О скинах
О терминалогии
Статьи:
Changelog Quake 3 Arena v1.32
Игроки с приставкой "HARDCORE"
Пасхальные Яйца В Quake 3 Arena
Насколько умны игроки в Quake?
Консоль:
О консольных командах
О скриптах
Файлы:
О утилах
О патчах
О картах
О модельках
О демках
О конфигах
Арт:
О разделе Арт
Сайт:
О гостевой книге
О ссылках
О нашем баннере
О нас
|
Создание Мода. Урок 3
Объеденим все что было написано ранее. Напишем мод WeaponArena. Идея уже была высказана - аналог RailArena, но тип оружия задается через консоль.
Создаем переменную
Итак, первое что нам надо сделать - создать переменную для управления типом оружия. Подробнее об этом было написано в уроке 1. Поэтому здесь ограничимся краткими заметками. Добавляем новую переменную (файл g_main.c строка 57):
vmCvar_t g_banIPs;
vmCvar_t g_filterBan;
// =============
vmCvar_t g_wa_weapon;
// =============
Для того, что бы получить доступ к переменной из консоли перейдем на строку 121 и добавим следующее:
{ &g_podiumDrop, "g_podiumDrop", "70", 0, 0, qfalse },
{ &g_allowVote, "g_allowVote", "1", 0, 0, qfalse },
// =============
{ &g_waWeapon, "g_waWeapon", "3", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, 0, qfalse }
// =============
Информация о сервере
Теперь у нас есть доступ к переменной из консоли. Для того что бы сообщить игроку что он играет в WeaponArena выведем информацию о моде на экран. Для этого в файле g_client.c (строка 814) добавим:
if ( g_gametype.integer != GT_TOURNAMENT ) {
trap_SendServerCommand( -1, va("print /"%s" S_COLOR_WHITE " entered the game/n/"", client->pers.netname) );
// =============
trap_SendServerCommand( ent-g_entities, va("print /"g_waWeapon is %s/n/"", g_waWeapon.string));
trap_SendServerCommand( ent-g_entities, va("cp /"This Server is Running WeaponArena/""));
// =============
}
А в начале файла необходимо объявить переменную g_waWeapon как внешнюю. Иначе компилятор выдаст сообщение об ошибке.
// Copyright (C) 1999-2000 Id Software, Inc.
//
#include "g_local.h"
// =============
extern vmCvar_t g_waWeapon;
// =============
Так же в файле g_local.h поменяем строку с версией игры.
// the "gameversion" client command will print this plus compile date
// =============
//#define GAMEVERSION "baseq3"
#define GAMEVERSION "WeaponArena"
// =============
Оружие и патроны
Для начала объявим переменную g_waWeapon как внешнюю.
// Copyright (C) 1999-2000 Id Software, Inc.
//
#include "g_local.h"
// =============
extern vmCvar_t g_waWeapon;
// =============
Теперь , как и в RailArena, установим в качестве исходного оружия gauntlet. Откроем файл g_client.c (строка 1008):
// positively link the client, even if the command times are weird
if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
trap_LinkEntity( ent );
}
//==============
//start the client with only the gaunlet
client->ps.stats[STAT_WEAPONS] = (1 << WP_GAUNTLET);
client->ps.weapon = WP_GAUNTLET;
//==============
// run the presend to set anything else
ClientEndFrame( ent );
Теперь, после того, как мы установили начальное оружие, надо заменить оружие и патроны на заданные. Но сперва добавим функцию копирования части строки G_GetLeft в файл g_spawn.c (строка 253 перед функцией G_CallSpawn).
void G_GetLeft(const char *pszSource, char *pszDest, int iLen)
{
int iSize; //size of string we need to copy
//see how much space we need
iSize = strlen(pszSource);
//is len less that size?
if(iLen < iSize)
iSize = iLen;
//make a copy of the string
strcpy(pszDest, pszSource);
//end the string at iSize
pszDest[iSize] = '/0';
}
Теперь изменим функцию G_CallSpawn так, что бы все оружие на карте она заменяла на заданное. Сначала посмотрим исходный код:
//==============
char szClassRoot[80]; //for holding the left part of the class name
const char WeaponArray[9][80] ={
"weapon_gauntlet",
"weapon_machinegun",
"weapon_shotgun",
"weapon_grenadelauncher",
"weapon_rocketlauncher",
"weapon_lightning",
"weapon_railgun",
"weapon_plasmagun",
"weapon_bfg"
};
const char AmmoArray[9][80] ={
"ammo_bullets",
"ammo_bullets",
"ammo_shells",
"ammo_grenades",
"ammo_rockets",
"ammo_lightning",
"ammo_slugs",
"ammo_cells",
"ammo_bfg"
};
//==============
if ( !ent->classname ) {
G_Printf ("G_CallSpawn: NULL classname/n");
return qfalse;
}
//==============
//get the left 7 of the string
G_GetLeft(ent->classname, szClassRoot, 7);
//is it weapon_?
if(Q_stricmp(szClassRoot, "weapon_") ==0)
{
strcpy(ent->classname, WeaponArray[g_waWeapon.integer]);
}
//get the left 5 of the string
G_GetLeft(ent->classname, szClassRoot, 5);
//is it ammo_?
if(Q_stricmp(szClassRoot, "ammo_") == 0)
{
strcpy(ent->classname, AmmoArray[g_waWeapon.integer]);
}
//==============
Мы создали 2 массива с именами оружия и патронов. Переменная g_waWeapon служит индексом, по которому мы получаем название оружия и патронов. В остальном переделка функции схожа с той, которую мы использовали в RailArena.
Теперь остается только откомпилировать мод и запустить его. Тип оружия можно переключать в консоли при помощи переменной g_waWeapon, которая может принимать значения от 0 до 8:
0 - Gauntlet
1 - Machinegun
2 - Shotgun
3 - Grenade Launcher
4 - Rocket Launcher
5 - Lightning
6 - Railgun
7 - Plasmagun
8 - BFG
www.u3d.agava.ru
|