Регистрация - или - Войти
Cry of Fear 1.0Cry of Fear 1.0

Хоррор от первого лица (Одиночная игра и Кооператив)...

20/02/2012
The Citizen Part IThe Citizen Part I

Шутер от первого лица...

20/02/2008

Создание нового ствола с новыми патронами


  • Описание
  • Ссылка и установка

Создание нового ствола

Создание нового ствола с новыми патронами


Автор / ы урока : Ghoul [BB]
Просмотров : 493 ( +1 )
Скачиваний : 0
Прислал / (а) : Streit
Дата создания : 07.04.2011 17:38:50
Источник : http://www.half-life.ru/forum
Рейтинг :
 ( 0 ) 
Поделиться :


Имеются следующие переводы : | русский |

По многочисленным просьбам, как пришедшим на мой адрес, так и на этом форуме: "А как тебе удалось сделать стока стволов, да и как вообще можно проделать такое и т.д." я подробно опишу, как добавить новое оружие, с новым типом боеприпаса к нему. Будут затронуты как клиентная, так и серверная части..

Проверено на СДК 2.2, на коем и базируется мой мод. Я не гарантирую работу и 100% совместимость данного тутора на какой-либо другой модификации, в особенности это касается системы Spirit, со всеми ее эдишнами и билдами!

Итак, приступим. Серверная часть.

func_break.cpp, в классе *CBreakable:SpawnObjects[] добавляем под аналогичными образцами строку:

Code:

"weapon_awp",

Это дает нам выпадение оружия при разбивании ящиков на карте, если установлено число, соотв. позиции оружия в этом листе.. (для мапперов)

weapons.cpp, функция W_Precache(void) Прекэшим наше оружие.

Code:

UTIL_PrecacheOtherWeapon( "weapon_awp" );

Далее переходим в weapons.h, к аналогичным функциям стандартного оружия:

Code:

#define WEAPON_awp 16 //(ваш порядковый номер, у меня он 16)

Чуть ниже, среди похожих функций другого оружия:

Code:

class Cawp : public CBasePlayerWeapon
{
   public:
   void Spawn( void );
   void Precache( void );
   int iItemSlot( void ) { return 0; }
   int GetItemInfo(ItemInfo *p);
   int AddToPlayer( CBasePlayer *pPlayer );

   void PrimaryAttack( void );
   void SecondaryAttack( void );
   BOOL Deploy( void );
   void Holster( int skiplocal = 0 );
   void Reload( void );
   void WeaponIdle( void );
   int m_iShell;


   BOOL m_fInZoom;

   virtual BOOL UseDecrement( void )
   {
     #if defined( CLIENT_WEAPONS )
       return TRUE;
     #else
       return FALSE;
     #endif
   }

   private:
   unsigned short m_usawp;
};

Здесь мы обозначили все действия, которые оружие должно совершать. Они содержатся в самом файле оружия.

С сервером все, переходим к клиенту.

Находим hl_events.cpp, и регистрируем там используемый оружием эвент: в самом верху, под аналогичными функциями

Code:

void EV_Fireawp( struct event_args_s *args );

Далее, в конце файла:

Code:

gEngfuncs.pfnHookEvent( "events/awp.sc", EV_Fireawp );

Тут все. Переходим к hl_weapons.cpp. Под CMP5 g_Mp5; ставим

Code:

Cawp g_awp;

Спускаемся ниже, ищем HUD_PrepEntity( &g_Mp5, &player ); и ставим ниже

Code:

HUD_PrepEntity( &g_awp, &player );

Еще ниже найдем:

Code:

case WEAPON_MP5:
   pWeapon = &g_Mp5;
   break;

и вставим под ним:

Code:

case WEAPON_awp:
   pWeapon = &g_awp;
   break;

Фуух, вроде все! Перейдем к ev_hldm.cpp, где создадим само оружие (вернее, его эффекты - анимация, вспышка, вытряхивание гильз)

Найдем похожий случай для МП5:

Code:

void EV_FireMP5( struct event_args_s *args );

И добавим ниже

Code:

void EV_Fireawp( struct event_args_s *args );

Далее ищем void EV_FireMP5( event_args_t *args )

И под этим, после строк коммента

Code:

//======================
// MP5 END
//======================

Вставляем:

Code:

//======================
// AWP START
//======================
enum awp_e
{
   AWP_DRAW,
   AWP_IDLE1,
   AWP_FIRE1,
   AWP_FIRE2,
   AWP_RELOAD1,
   AWP_RELOAD2,
   AWP_RELOAD3,
   AWP_IDLE2,
   AWP_HOLSTER
};

void EV_Fireawp( event_args_t *args )
{
   int idx;
   vec3_t origin;
   vec3_t angles;
   vec3_t velocity;

   vec3_t vecSrc, vecAiming;
   vec3_t up, right, forward;
   float flSpread = 0.01;

   idx = args->entindex;
   VectorCopy( args->origin, origin );
   VectorCopy( args->angles, angles );
   VectorCopy( args->velocity, velocity );

   AngleVectors( angles, forward, right, up );

   dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight (0);
   dl->origin.x = origin.x;
   dl->origin.y = origin.y;
   dl->origin.z = origin.z;
   dl->radius = gEngfuncs.pfnRandomFloat( 330, 370 );
   dl->color.r = 210;
   dl->color.g = 200;
   dl->color.b = 60;
   dl->die = gEngfuncs.GetClientTime() + 0.06;

   if ( EV_IsLocal( idx ) )
   {
     EV_MuzzleFlash();
     gEngfuncs.pEventAPI->EV_WeaponAnimation( AWP_FIRE1 + gEngfuncs.pfnRandomLong(0,1), 2 );
     V_PunchAxis( 0, -10.0 );
   }

   gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/awp1.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );//звук выстрела
   EV_GetGunPosition( args, vecSrc, origin );
   VectorCopy( forward, vecAiming );
   EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_338Magnum, 1, &tracerCount[idx-1], args->fparam1, args->fparam2 );//вылет пули
}

//======================
// AWP END
//======================

Ну вот и все. Не забываем добавить на сервере в проект wpn_awp.cpp. Но! Мы ж еще хотим, чтобы для нового оружия были новые боеприпасы, со своим уроном и т.п. Исправим!

Создание нового типа патронов. На сервере.

Откроем cbase.h, и под int ammo_9mm; поставим

Code:

int ammo_338Magnum;

Потом откроем client.cpp, под строкой

Code:

cd->vuser1.x = pl->ammo_9mm;

Втавим свою:

Code:

cd->vuser1.y = pl->ammo_338Magnum;

Потом в player.cpp, в void CBasePlayer::TabulateAmmo() { поставим

Code:

ammo_338Magnum = AmmoInventory( GetAmmoIndex( "338Magnum" ) );

Вот и все с патронами.

Новый тип пуль делается по аналогии… Примечание редактора: на этом заканчивался оригинальный текст данного тутора, но поскольку в коде оружия использованы пули BULLET_PLAYER_338Magnum которых нет в обычном хл, я написал продолжение к этому тутору которое добавляет этот тип пуль.

На сервере:

В combat.cpp:

Code:

case BULLET_PLAYER_BUCKSHOT:
   pEntity->TraceAttack(pevAttacker, gSkillData.plrDmgBuckshot, vecDir, &tr, DMG_BULLET);
   break;

case BULLET_PLAYER_357:
   pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET);
   break;

case BULLET_PLAYER_338Magnum: //Новые строчки
   pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg358Magnum, vecDir, &tr, DMG_BULLET);
   break;

В weapons.cpp :

Code:

case BULLET_PLAYER_BUCKSHOT:
case BULLET_PLAYER_357:
case BULLET_PLAYER_338Magnum: //Новая строка

В weapons.h:

Code:

BULLET_PLAYER_BUCKSHOT, // shotgun
BULLET_PLAYER_CROWBAR, // crowbar swipe
BULLET_PLAYER_338Magnum, //Новая строка

В skill.h:

Code:

float plrDmgSatchel;
float plrDmgTripmine;
float plrDmg358Magnum; //Новая строка

В game.cpp :

Code:

// Tripmine
cvar_t sk_plr_tripmine1 = {"sk_plr_tripmine1","0"};
cvar_t sk_plr_tripmine2 = {"sk_plr_tripmine2","0"};
cvar_t sk_plr_tripmine3 = {"sk_plr_tripmine3","0"};

//Новые строки
cvar_t sk_plr_358Magnum1 = {"sk_plr_358Magnum1","0"};
cvar_t sk_plr_358Magnum2 = {"sk_plr_358Magnum2","0"};
cvar_t sk_plr_358Magnum3 = {"sk_plr_358Magnum3","0"};

Далее:

Code:

// Tripmine
CVAR_REGISTER ( &sk_plr_tripmine1 );// {"sk_plr_tripmine1","0"};
CVAR_REGISTER ( &sk_plr_tripmine2 );// {"sk_plr_tripmine2","0"};
CVAR_REGISTER ( &sk_plr_tripmine3 );// {"sk_plr_tripmine3","0"};

// Новые строчки
CVAR_REGISTER ( &sk_plr_358Magnum1 );
CVAR_REGISTER ( &sk_plr_358Magnum2 );
CVAR_REGISTER ( &sk_plr_358Magnum3 );

В gamerules.cpp

Code:

// Tripmine
gSkillData.plrDmgTripmine = GetSkillCvar( "sk_plr_tripmine");

// Новые строчки
gSkillData.plrDmg358Magnum = GetSkillCvar( "sk_plr_358Magnum");

Теперь переходим на клиент

В ev_hldm.cpp

Code:

case BULLET_PLAYER_BUCKSHOT:
case BULLET_PLAYER_357:
case BULLET_PLAYER_338Magnum://новая строка

Далее:

Code:

case BULLET_PLAYER_357:

   EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
   EV_HLDM_DecalGunshot( &tr, iBulletType );

   break;

case BULLET_PLAYER_338Magnum://новые строки

   EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
   EV_HLDM_DecalGunshot( &tr, iBulletType );

   break;

В ev_hldm.h :

Code:

BULLET_PLAYER_BUCKSHOT, // shotgun
BULLET_PLAYER_CROWBAR, // crowbar swipe
BULLET_PLAYER_338Magnum,//новая строка

Теперь в skill.cfg вставляем в самый конец:

Code:

sk_plr_358Magnum1 "100"
sk_plr_358Magnum2 "100"
sk_plr_358Magnum3 "100"

Не забудьте создать файл awp.sc в папке events (содержимое можно скопировать из mp5.sc) Сам исходник Слонобоя (этот файл нужно добавить на сервер и на клиент) :

Code: wpn_awp.cpp

#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"

enum awp_e
{
   AWP_DRAW,
   AWP_IDLE1,
   AWP_FIRE1,
   AWP_FIRE2,
   AWP_RELOAD1,
   AWP_RELOAD2,
   AWP_RELOAD3,
   AWP_IDLE2,
   AWP_HOLSTER
};

LINK_ENTITY_TO_CLASS( weapon_awp, Cawp );

void Cawp::Spawn( )
{
   pev->classname = MAKE_STRING("weapon_awp");
   Precache( );
   SET_MODEL(ENT(pev), "models/w_awp.mdl");
   m_iId = WEAPON_awp;

   m_iDefaultAmmo = 10;

   FallInit();
}

void Cawp::Precache( void )
{
   PRECACHE_MODEL("models/v_awp.mdl");
   PRECACHE_MODEL("models/p_awp.mdl");
   PRECACHE_MODEL("models/w_awp.mdl");

   PRECACHE_SOUND ("weapons/awp1.wav");
   PRECACHE_SOUND ("weapons/zoom.wav");

   m_usawp = PRECACHE_EVENT( 1, "events/awp.sc" );
}

int Cawp::GetItemInfo(ItemInfo *p)
{
   p->pszName = STRING(pev->classname);
   p->pszAmmo1 = "338Magnum";
   p->iMaxAmmo1 = 30;
   p->pszAmmo2 = NULL;
   p->iMaxAmmo2 = -1;
   p->iMaxClip = 10;
   p->iSlot = 0;
   p->iPosition = 1;
   p->iFlags = 0;
   p->iId = m_iId = WEAPON_awp;
   p->iWeight = 20;

   return 1;
}

int Cawp::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 Cawp::Deploy( )
{
   return DefaultDeploy( "models/v_awp.mdl", "models/p_awp.mdl", AWP_DRAW, "mp5" );
}


void Cawp::PrimaryAttack()
{

   if (m_pPlayer->pev->waterlevel == 3)
   {
     PlayEmptySound( );
     m_flNextPrimaryAttack = 0.15;
     return;
   }

   if (m_iClip <= 0)
   {
     PlayEmptySound();
     m_flNextPrimaryAttack = 0.15;
     return;
   }

   m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
   m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;

   m_iClip--;

   int flags;
   #if defined( CLIENT_WEAPONS )
     flags = FEV_NOTHOST;
   #else
     flags = 0;
   #endif

   m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;

   m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

   Vector vecSrc = m_pPlayer->GetGunPosition( );
   Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
   Vector vecDir;

   vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, Vector( 0.00001, 0.00001, 0.00001 ), 8192, BULLET_PLAYER_338Magnum, 1, 0, m_pPlayer->pev, m_pPlayer->random_seed );

   #if defined( CLIENT_WEAPONS )
     flags = FEV_NOTHOST;
   #else
     flags = 0;
   #endif

   PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usawp, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 );

   if (!m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
     m_pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);


   m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.8;
   m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}

void Cawp::SecondaryAttack( void )
{
   if ( m_pPlayer->pev->fov ==8 )
   {
     m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 0;
     m_fInZoom = 0;
   }
   else if ( m_pPlayer->pev->fov == 40 )
   {
     m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 8;
     m_fInZoom = 1;
   }
   else if ( m_pPlayer->pev->fov == 0 )
   {
     m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 40;
     m_fInZoom = 2;
   }

   m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
   EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/zoom.wav", RANDOM_FLOAT(0.95, 1.0), ATTN_NORM, 0, 93 + RANDOM_LONG(0,0xF));//проиграть звук
}

void Cawp::Holster( int skiplocal )
{
   m_fInReload = FALSE;

   if (m_pPlayer->pev->fov != 0 )
   {
     m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 0;
     m_fInZoom = 0;
   }

   SendWeaponAnim(AWP_HOLSTER);
   m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0;
   m_flTimeWeaponIdle = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );

}

void Cawp::Reload( void )
{
   if (m_pPlayer->pev->fov != 0 )
   {
     m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 0;
     m_fInZoom = 0;
   }

   DefaultReload( 10, AWP_RELOAD1, 2.8 );
}


void Cawp::WeaponIdle( void )
{
   m_pPlayer->UpdateClientData();
   ResetEmptySound( );

   m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );

   if ( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
     return;

   int iAnim;
   switch ( RANDOM_LONG( 0, 1 ) )
   {
     case 0:
       iAnim = AWP_IDLE1;
       break;

     default:
     case 1:
       iAnim = AWP_IDLE2;
       break;
   }

   SendWeaponAnim( iAnim );

   m_flTimeWeaponIdle = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
}

class CawpAmmoClip : public CBasePlayerAmmo
{
   void Spawn( void )
   {
     Precache( );
     SET_MODEL(ENT(pev), "models/w_chainammo.mdl");
     CBasePlayerAmmo::Spawn( );
   }
   void Precache( void )
   {
     PRECACHE_MODEL ("models/w_chainammo.mdl");
     PRECACHE_SOUND("items/9mmclip1.wav");
   }
   BOOL AddAmmo( CBaseEntity *pOther )
   {
     int bResult = (pOther->GiveAmmo( 10, "338Magnum", 30) != -1);
     if (bResult)
     {
       EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
     }
     return bResult;
   }
};
LINK_ENTITY_TO_CLASS( ammo_338Magnum, CawpAmmoClip );

Спрайты, модели и звуки файле .

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



Похожие1. Исходный код снайперки - weapon_sniperrifle с оптическим прицелом
2. Новый монстр - В общем-то это самый лёгкий тутор который можно придумать.
3. субтитры из паранойи - субтитры из паранойи.
Ссылки на объект
Полная ссылка на текущем языке :
Короткая ссылка :
Ссылка на превью-картинку :
Ссылка на картинку в полном размере :
Ссылка для вашего форума или сайта
BB код ссылка:
BB код ссылка с картинкой :
BB код картинки :
HTML код ссылка:
HTML код ссылка с картинкой :
HTML код картинки :
Вы не можете комментировать, т.к. вы не зарегистрированы.
    Z7 1911 (4 skins)
    The SpecialistsZ7 1911 (4 skins)
    Gold Colts M1911A1 SD
    The SpecialistsGold Colts M1911A1 SD
    SVI Infinity Match Black
    The SpecialistsSVI Infinity Match Black
    Colt Anaconda Akimbo (4 skins)
    The SpecialistsColt Anaconda Akimbo (4 skins)