Статьи по программированию под движком Gold Source
(игры Half-Life 1) и работе с SDK
Создание нового оружия
Это перевод статьи Persuter`a с http://articles.thewavelength.net/183/
В этом руководстве НЕ будет
объяснено, КАК сделать принципиально новое
оружие, ибо для каждого оружия нужен свой
код. Здесь на примере копирования типа оружия просто будет приведена
информация о тех нюансах, без которых ваше оружие не будет
работать.
Оружие мы сделаем на базе mp5,
которое будет называться просто — ExampleGun
Чтобы попасть в проект, открываем
серверную часть — рабочий файл C++ hl.dsw
Для начала давайте напишем текст программы
нашего оружия (пока не вставляя в проект), код у нас будет очень простой (фрагмент кода 1):
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
LINK_ENTITY_TO_CLASS( weapon_example, CExampleGun );
void CExampleGun::Spawn( )
{
pev->classname = MAKE_STRING("weapon_example"); // здесь имя объекта (энтити), которое надо будет вписать в файл .fgd
Precache( );
SET_MODEL(ENT(pev), "models/w_9mmAR.mdl"); // Тут должна быть модель вашего оружия
m_iId = WEAPON_EXAMPLE;
m_iDefaultAmmo = 50;
FallInit();
}
void
CExampleGun::Precache( void )
{
// Тут вы прекешите звуки и модели для вашего оружия
PRECACHE_MODEL("models/v_9mmAR.mdl");
PRECACHE_MODEL("models/w_9mmAR.mdl");
PRECACHE_MODEL("models/p_9mmAR.mdl");
PRECACHE_SOUND("items/9mmclip1.wav");
PRECACHE_SOUND("items/clipinsert1.wav");
PRECACHE_SOUND("items/cliprelease1.wav");
PRECACHE_SOUND ("weapons/hks1.wav");
PRECACHE_SOUND ("weapons/hks2.wav"); PRECACHE_SOUND ("weapons/hks3.wav");
// это для хука вашего события клиентской стороны
m_usExampleFire = PRECACHE_EVENT( 1, "events/example.sc" );
}
int CExampleGun::GetItemInfo(ItemInfo
*p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "9mm";
p->iMaxAmmo1 = 200;
p->iMaxClip = -1;
p->iSlot = 3;
// категория оружия в костюме игрока (помните также, что если
здесь вы написали например 2, то в игре будет
занята 3 категория, т. к. в коде исчисление начинается
от нуля)
p->iPosition = 4;
// позиция в категории (то же самое, что и для категории - если вам
надо занять 4 позицию, то пишите 3 в коде)
p->iFlags = 0;
p->iId = m_iId = WEAPON_EXAMPLE;
p->iWeight = MP5_WEIGHT;
p->pszAmmo2 = NULL;
p->iMaxAmmo2 = -1;
return 1;
}
int CExampleGun::AddToPlayer(
CBasePlayer *pPlayer )
{
if ( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
{
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
WRITE_BYTE( m_iId );
MESSAGE_END();
return TRUE;
}
return FALSE;
}
Когда код вашего
оружия готов, открывайте файл под названием
weapons.cpp, и примерно в районе строчки 340
сделайте UTIL_PrecacheOtherWeapon, после mp5 (фрагмент кода 2):
// glock
UTIL_PrecacheOtherWeapon( "weapon_9mmhandgun" );
UTIL_PrecacheOther( "ammo_9mmclip" );
// mp5
UTIL_PrecacheOtherWeapon( "weapon_9mmAR" );
UTIL_PrecacheOther( "ammo_9mmAR" );
UTIL_PrecacheOther( "ammo_ARgrenades" );
// Тут добавляете прекеш своего оружия
// example_weapon
UTIL_PrecacheOtherWeapon( "weapon_example" );
Сохраняете
это как example.cpp и добавляете в проект
Затем откройте файл weapons.h, и в
районе строчки 89 и создайте определение имени своего оружия
после снарка (фрагмент кода 3)
#define WEAPON_TRIPMINE 13
#define WEAPON_SATCHEL 14
#define WEAPON_SNARK 15
#define WEAPON_EXAMPLE 16
Затем идите
вниз этого же файла и добавьте класс своего
оружия под снарками. Выглядеть он должен так (фрагмент кода 4):
class CExampleGun : public CBasePlayerWeapon
{
public:
void
Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 4; }
int GetItemInfo(ItemInfo *p);
void PrimaryAttack( void );
void SecondaryAttack( void );
BOOL Deploy( void ); void
WeaponIdle( void );
int AddToPlayer( CBasePlayer* );
virtual BOOL UseDecrement( void )
{
#if defined( CLIENT_WEAPONS )
return TRUE;
#else
return FALSE;
#endif }
private: unsigned
short
m_usExampleFire;
};
После
этого если хотите, можете добавить ваше оружие в
список тех, кто будет спавниться в разбиваемых
объектах (func_breakable) Для этого откройте
func_break.cpp и в районе строчки 62 добавьте
свое оружие в список оружий, появляющихся при
разбивании объекта (фрагмент кода 5):
const char
*CBreakable::pSpawnObjects[] = {
NULL, // 0
"item_battery", //
1 "item_healthkit", //
2 "weapon_9mmhandgun", // 3
"ammo_9mmclip", // 4
"weapon_9mmAR", // 5
"ammo_9mmAR", // 6
"ammo_ARgrenades", // 7
"weapon_shotgun", // 8
"ammo_buckshot", // 9
"weapon_crossbow", // 10
"ammo_crossbow", // 11
"weapon_357", // 12
"ammo_357", // 13
"weapon_rpg", // 14
"ammo_rpgclip", // 15
"ammo_gaussclip", // 16
"weapon_handgrenade", // 17
"weapon_tripmine", // 18
"weapon_satchel", // 19
"weapon_snark", // 20
"weapon_hornetgun", // 21
"weapon_example", // 22 - ваше оружие
};
Так, с серверной
частью мы покончили - теперь идём в клиент (cl_dll.dsw)
В клиенте для начала откроем
папку hl и в неё добавим наш example.cpp. Затем
идём в файл ev_hldm.cpp и добавляем в районе
строчки 67 свое оружие (фрагмент кода 6):
void
EV_EgonStop( struct event_args_s *args ?);
void EV_HornetGunFire( struct event_args_s *args ?);
void EV_TripmineFire( struct event_args_s *args ?);
void EV_SnarkFire( struct event_args_s *args ?);
void EV_ExampleFire( struct event_args_s *args );
// ваше оружие
Идите вниз и там введите определение вашего оружия (фрагмент кода 7):
CHandGrenade
g_HandGren; CSatchel g_Satchel; CTripmine
g_Tripmine; CSqueak g_Snark;
CExampleGun g_ExampleGun // ваше оружие
Затем всё в том же
файле идите в район строчки 637 и добавьте там
свое оружие (фрагмент кода 8):
HUD_PrepEntity(
&g_HandGren , &player
); HUD_PrepEntity( &g_Satchel ,
&player ); HUD_PrepEntity(
&g_Tripmine , &player
); HUD_PrepEntity( &g_Snark , &player
); HUD_PrepEntity( &g_ExampleGun ,
&player ); // ваше
оружие
И наконец спуститесь в
район строчки 761 и добавьте (фрагмент кода 9):
case WEAPON_TRIPMINE:
pWeapon = &g_Tripmine;
break;
case WEAPON_SNARK:
pWeapon = &g_Snark;
break;
case WEAPON_EXAMPLE: // ваше оружие
pWeapon = &g_ExampleGun;
break;
Теперь
идите в файл hl_events.cpp, и там в районе
строчки 40 добавьте (фрагмент кода 10):
void EV_EgonStop(
struct event_args_s *args );
void EV_HornetGunFire( struct event_args_s *args );
void EV_TripmineFire( struct event_args_s *args );
void EV_SnarkFire( struct
event_args_s *args ); void EV_ExampleFire(
struct event_args_s *args ); // ваше оружие
Это, как вы заметили, то
же самое, что вы сделали в начале ev_hldm.cpp.
Теперь спуститесь в район строчки 88 и добавьте (фрагмент кода 11):
gEngfuncs.pfnHookEvent( "events/egon_stop.sc", EV_EgonStop );
gEngfuncs.pfnHookEvent(
"events/firehornet.sc", EV_HornetGunFire );
gEngfuncs.pfnHookEvent(
"events/tripfire.sc", EV_TripmineFire );
gEngfuncs.pfnHookEvent(
"events/snarkfire.sc", EV_SnarkFire );
gEngfuncs.pfnHookEvent( "events/example.sc",
EV_ExampleFire ); // ваше оружие
Теперь вы можете смело
компилировать. После компиляции идите в каталог со своим
модом, где создайте папку events, если таковой нет.
В events создайте файл example.sc (содержимое
этого файла можете скопировать из sc файла для mp5,
который находится в pak файле). Затем зайдите в папку
sprites своего мода и создайте там
weapon_example.txt (содержимое также можете
скопировать из mp5 и затем исправлять, так как
там нужно указать спрайты, которые будут в
отображаться в интерфейсе игрока при подборе и т. д.)
Вот пожалуй и всё, что вам надо для
создания оружия. Если хотите создавать новое
оружие с новыми эффектами, то работайте с
основным кодом оружия, который я написал самым
первым.
Спасибо за внимание!
Mitoh
Существует более простая статья "Взлом оружия — Докидываем патронов"
от Jaturkenjensirhiv о менее заковыристых вещах - изменении отдельных параметров оружия в коде [примечание от ОбаГлаза].
Комментарии к этой статье на http://articles.thewavelength.net/183/ :
Оставлен от [NL]Mox 05 января 2004 в 11:48:13
Я думаю, что это руководство не описало части про боеприпасы и наносимые повреждения...
Но оно действительно сто́ящее, об этом много вопросов на форумах. Я стану ссылаться на эту страницу чаще.
Оставлен от Persuter 07 января 2004 в 20:07:02
Я не написал, как создать новые типы боеприпасов, правда, но это просто потому, что не все хотят это делать.
(В самом деле, это часто не имеет значения для сегодняшней одержимости тактическими модами. :D)
А что касается нанесения повреждений, я предполагаю, что Вы имеете в виду функции основной атаки и вторичной.
Я сознательно не включал ни это, ни большинство исходного кода оружия,
потому что это учебник о том, что нужно сделать, а не о
настоящем программировании оружия.
P.S. Эта статья хорошо работает для SDK версии 2.3.
Оставлен от Bryan 12 марта 2004 в 17:31:41
Думаю, было бы очень полезно для остальных,
если бы Вы прошлись по использованию боеприпасов и нанесению повреждений.
это очень хорошее руководство gj.
Оставлен от jim_the_coder 16 марта 2004 в 17:50:53
"(В самом деле, это часто не имеет значения для сегодняшней одержимости тактическими модами. :D)"
Я думаю, что вы бы лучше разобрались, чем поощрять увеличение клонов CS!
Оставлен от Persuter 17 марта 2004 в 06:18:55
Хорошо, при всей серьезности не вижу никакой причины добавлять новые типы боеприпасов в эти дни.
Оставлен от Persuter 5 июня 2004 в 20:05:32
Не собираюсь портить Вам парад, но на вашем сайте нет такой статьи.
Оставлен от MIFUNE 4 мая 2005 в 23:39:06
Я пытался сделать что-то похожее на это в моем моде. Я пытался заставить оружие стрелять правой и левой ружбайкой (оно двуручное),
если вы нажимаете правую или левую кнопку мыши, то даже когда это работает (скопировал-вставил код от MP5), я не могу заставить появляться вспышку маззлфлеша в правом пистолете,
а гильзы выбрасываются только от правого пистолета и появляются в середине экрана !!!
в чём проблема?
...
|