Данная страница оптимизирована под:
Internet Explorer 5.0
Разрешение 800×600
Кодировку Windows-1251


А это место под ваш баннер!



   На главную страницу
Для новичков:
   О Quake3 вообще
   О тактике
   О модах
    ·Quake 3 Arena Mods
    ·Создание Мода. Урок 1
    ·Создание Мода. Урок 2
    ·Создание Мода. Урок 3
    ·Создание Мода. Урок 4
   О скинах
   О терминалогии
Статьи:
   Changelog Quake 3 Arena v1.32
   Игроки с приставкой "HARDCORE"
   Пасхальные Яйца В Quake 3 Arena
   Насколько умны игроки в Quake?
Консоль:
   О консольных командах
   О скриптах
Файлы:
   О утилах
   О патчах
   О картах
   О модельках
   О демках
   О конфигах
Арт:
   О разделе Арт
Сайт:
   О гостевой книге
   О ссылках
   О нашем баннере
   О нас

Rambler's Top100 Игры

TopCTO Игры

Создание Мода. Урок 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

Hosted by uCoz