Гостевая книга:

"Мой первый водянной пистолетик"

Здравствуй мой маленький дружок. Сегодня я расскажу тебе о том, как сделать новое оружие для твоего мода. Что нам потребуется:

Microsoft Visual studio 6.0 (а именно Microsoft Visual C++ 6.0)
Набор SDK для Half-Life. (версия 2.0 или выше)
Модель оружия в формате *.mdl ( предлагаю для начала взять автомат MP5 NAVY из Counter-Strike’а).

Для начала откроем hl.dsp (или mp.dsp, если вы пользуетесь SDK 2.0). Затем в меню Files выберем New, чтобы создать новый фаил. В открывшемся окне выберем С++ Source code а в строке File name введём название нашего оружия, что-нибудь типа weapon_mp5navy.

Наши друзья:
Оставить запись в книге Полистать книгу


Стать другом
Архив новостей:
Наш счётчик:
24/02-23/04
18/02-10/03

Обратная связь:
L-studio®
all rights reserved
   
   
 

Перед нами откроется чистый лист. Ну что ж, приступим. Для начала вставте:

// L-studio boss wepon code 1.0
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "player.h"
#include "soundent.h"
#include "gamerules.h"

Здесь мы включаем в наш код уже существующие файлы. Данный набор обязателен для любого оружия. Вставлшяем дальше:

int first_step_mp5navy = 0;

Эта переменная, которая нужна будет нам, для отображения IDLE анимации. Далее:

enum mp5navy_e
{
MP5NAVY_IDLE1 = 0,
MP5NAVY_RELOAD,
MP5NAVY_DRAW,
MP5NAVY_FIRE1,
MP5NAVY_FIRE2,
MP5NAVY_FIRE3,
};

Это список анимации нашей модели. Думаю здесь всё понятно. Следующие:

class CMP5NAVY : public CBasePlayerWeapon
{
public:
void Spawn( void );
void Precache( void );
int iItemSlot( void ) { return 3; }
int GetItemInfo(ItemInfo *p);
int AddToPlayer( CBasePlayer *pPlayer );
void PrimaryAttack( void );
void SecondaryAttack( void );
int SecondaryAmmoIndex( void );
BOOL Deploy( void );
void Reload( void );
void WeaponIdle( void );
float m_flNextAnimTime;
int m_iShell;
};
LINK_ENTITY_TO_CLASS( weapon_mp5navy, CMP5NAVY );


Здесь мы объявляем новый класс для нашего оружия: MP5NAVY. Последняя строчка служит для создания глобального имени нашего оружия, которое может быть использованно в WorldCraft’е и при создании спрайта. Далее:

int CMP MP5NAVY::SecondaryAmmoIndex( void )
{
return m_iSecondaryAmmoType;
}

Инициализирует вторичные боеприпасы. В нашем случае их нет. Следующее:

void CMP5NAVY::Spawn( )
{
pev->classname = MAKE_STRING("weapon_9mmAR");
Precache( );
SET_MODEL(ENT(pev), "models/w_mp5.mdl"); // m_iId = WEAPON_MP5NAVY; // m_iDefaultAmmo = 30; // FallInit();
}

Функция появления оружия на карте. Всё что вас может здесь интересовать, я указал в комментариях. Далее вставляем:

void CMP5NAVY::Precache( void )
{
PRECACHE_MODEL("models/v_mp5.mdl"); //
PRECACHE_MODEL("models/w_mp5.mdl");
PRECACHE_MODEL("models/p_mp5.mdl");
m_iShell = PRECACHE_MODEL ("models/shell.mdl"); //
PRECACHE_SOUND ("weapons/mp5navy.wav"); //
}

Эта функция загружает необходимые нам файлы. Следующее:

int CMP5NAVY::GetItemInfo(ItemInfo *p)
{
p->pszName = STRING(pev->classname);
p->pszAmmo1 = "9mm"; //
p->iMaxAmmo1 = 90; //
p->pszAmmo2 = NULL; //
p->iMaxAmmo2 = -1; //

p->iMaxClip = 30; //
p->iSlot = 2; //
p->iPosition = 0; //
p->iFlags = 0;
p->iId = m_iId = WEAPON_MP5NAVY;
p->iWeight = 150; //
return 1;
}

int CMP5NAVY::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;
}

BOOL CMP5NAVY::Deploy( )
{
return DefaultDeploy( "models/v_mp5.mdl", "models/p_mp5.mdl", MP5NAVY_DRAW, "mp5" );
}

Это функции информации и получения оружия игроком. Следующее:

void CMP5NAVY::PrimaryAttack()
{

if (m_iClip //

m_iClip--;
m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;
SendWeaponAnim( MP5NAVY _FIRE1 ); //
EMIT_SOUND( ENT(pev), CHAN_WEAPON, "weapons/mp5 NAVY.wav", 1, ATTN_NORM); //звук атаки
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
Vector vecSrc = m_pPlayer->GetGunPosition( );
Vector vecAiming;
vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
m_pPlayer->FireBullets( 1, vecSrc, vecAiming, VECTOR_CONE_5DEGREES, 8192, BULLET_PLAYER_MP5, 2 );

/*

Первый параметр - количество выстрелов, если ставить больше 1, то будет аналог дроби.
Второй параметр - источник стрельбы, в данном случае это игрок.
Третий параметр - направление стрельбы.
Четвертый параметр - вектор описывает каким точным будет выстрел, тоесть на сколько градусов будет отклоняться пуля (разброс).
Пятый параметр - дальность.
Шестой параметр - тип пуль, от типа зависит урон.
Седьмой параметр - количество трассирующих пуль.
*/

m_flNextPrimaryAttack = gpGlobals->time + 0.1; // время следующей атаки, т.е. интервал времени между выстрелами
// ниже приводится параметры выброса гильз, вы можете поэкспериментировать с числовыми параметрами

Vector vecShellVelocity = m_pPlayer->pev->velocity +
gpGlobals->v_right * RANDOM_FLOAT(50,70) + gpGlobals->v_up *
RANDOM_FLOAT(100,150) + gpGlobals->v_forward * 25;
EjectBrass ( pev->origin + m_pPlayer->pev->view_ofs +
gpGlobals->v_up * -12 + gpGlobals->v_forward * 18 /* gpGlobals->v_right * 6 , vecShellVelocity, pev->angles.y,
m_iShell, TE_BOUNCE_SHELL );
TraceResult tr;
tr.fAllSolid = gpGlobals->trace_allsolid;
tr.fStartSolid = gpGlobals->trace_startsolid;
tr.fInOpen = gpGlobals->trace_inopen;
tr.fInWater = gpGlobals->trace_inwater;
tr.flFraction = gpGlobals->trace_fraction;
tr.flPlaneDist = gpGlobals->trace_plane_dist;
tr.pHit = gpGlobals->trace_ent;
tr.vecEndPos = gpGlobals->trace_endpos;
//m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
tr.vecPlaneNormal = gpGlobals->trace_plane_normal;
tr.iHitgroup = gpGlobals->trace_hitgroup;
DecalGunshot( &tr , 0 );

}

Это была функция первичной атаки. Вставляем далее:

void CMP5NAVY::SecondaryAttack( void )

{

}

Функция вторичной атаки. В нашем случае у нас пока её не будет. Следующее:

void CMP5NAVY::Reload( void )
{

if(m_iClip// проверка, если в магазине осталось 29 и меньше потронов, то перезарядка работает.
DefaultReload( 30, MP5NAVY_RELOAD, 1.5 ); // количество потронов, анимация модели, время перезарядки
}

Как вы поняли это функция перезарядки. И последнее, функция IDLE состояния оружия:

void CMP5NAVY::WeaponIdle( void )
{

if(first_step_mp5navy == 0)
{
SendWeaponAnim( MP5NAVY_IDLE1 );
first_step_mp5navy = 1;

}
}

Всё код оружия готов. Теперь осталось только сделать так, чтоб его начала воспринимать непосредственно сама игра. Для этого открываем фаил wepons.cpp и после строки «UTIL_PrecacheOtherWeapon( "weapon_9mmAR" );» добавляем:

UTIL_PrecacheOtherWeapon( "weapon_mp5navy" );

Затем открываем wepons.h и после строчки «#define WEAPON_SNARK 15» добавляем:

#define WEAPON_MP5NAVY 16

Всё готова, компилируем кнопкой F7.
Теперь открываем *.fgd фаил, которым вы пользуетесь в WorldCraft’е и после строки «@PointClass base(Weapon, Targetx) = weapon_crowbar : "Crowbar" []» (почти в самом низу) добавляем:

@PointClass base(Weapon, Targetx) = weapon_mp5navy : "MP5NAVY" []

Теперь у вас появилась новая поинт-енети, добавляещее на карту ваше новое оружие.